mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-01 06:13:59 +00:00
set null, various fixes
This commit is contained in:
@@ -33,9 +33,12 @@ class SqlDumper {
|
|||||||
this.putRaw("'");
|
this.putRaw("'");
|
||||||
}
|
}
|
||||||
putValue(value) {
|
putValue(value) {
|
||||||
if (_.isString(value)) this.putStringValue(value);
|
if (value === null) this.putRaw('NULL');
|
||||||
if (_.isNumber(value)) this.putRaw(value.toString());
|
if (value === true) this.putRaw('1');
|
||||||
if (_.isDate(value)) this.putStringValue(moment(value).toISOString());
|
if (value === false) this.putRaw('0');
|
||||||
|
else if (_.isString(value)) this.putStringValue(value);
|
||||||
|
else if (_.isNumber(value)) this.putRaw(value.toString());
|
||||||
|
else if (_.isDate(value)) this.putStringValue(moment(value).toISOString());
|
||||||
}
|
}
|
||||||
putCmd(format, ...args) {
|
putCmd(format, ...args) {
|
||||||
this.put(format, ...args);
|
this.put(format, ...args);
|
||||||
@@ -77,7 +80,7 @@ class SqlDumper {
|
|||||||
}
|
}
|
||||||
putFormattedList(c, collection) {
|
putFormattedList(c, collection) {
|
||||||
if (!collection) return;
|
if (!collection) return;
|
||||||
this.putCollection(', ', collection, item => this.putFormattedValue(c, item));
|
this.putCollection(', ', collection, (item) => this.putFormattedValue(c, item));
|
||||||
}
|
}
|
||||||
/** @param format {string} */
|
/** @param format {string} */
|
||||||
put(format, ...args) {
|
put(format, ...args) {
|
||||||
@@ -198,7 +201,7 @@ class SqlDumper {
|
|||||||
/** @param table {import('@dbgate/types').TableInfo} */
|
/** @param table {import('@dbgate/types').TableInfo} */
|
||||||
createTable(table) {
|
createTable(table) {
|
||||||
this.put('^create ^table %f ( &>&n', table);
|
this.put('^create ^table %f ( &>&n', table);
|
||||||
this.putCollection(',&n', table.columns, col => {
|
this.putCollection(',&n', table.columns, (col) => {
|
||||||
this.put('%i ', col.columnName);
|
this.put('%i ', col.columnName);
|
||||||
this.columnDefinition(col);
|
this.columnDefinition(col);
|
||||||
});
|
});
|
||||||
@@ -209,11 +212,11 @@ class SqlDumper {
|
|||||||
}
|
}
|
||||||
this.put(
|
this.put(
|
||||||
' ^primary ^key (%,i)',
|
' ^primary ^key (%,i)',
|
||||||
table.primaryKey.columns.map(x => x.columnName)
|
table.primaryKey.columns.map((x) => x.columnName)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (table.foreignKeys) {
|
if (table.foreignKeys) {
|
||||||
table.foreignKeys.forEach(fk => {
|
table.foreignKeys.forEach((fk) => {
|
||||||
this.put(',&n');
|
this.put(',&n');
|
||||||
this.createForeignKeyFore(fk);
|
this.createForeignKeyFore(fk);
|
||||||
});
|
});
|
||||||
@@ -243,9 +246,9 @@ class SqlDumper {
|
|||||||
if (fk.constraintName != null) this.put('^constraint %i ', fk.constraintName);
|
if (fk.constraintName != null) this.put('^constraint %i ', fk.constraintName);
|
||||||
this.put(
|
this.put(
|
||||||
'^foreign ^key (%,i) ^references %f (%,i)',
|
'^foreign ^key (%,i) ^references %f (%,i)',
|
||||||
fk.columns.map(x => x.columnName),
|
fk.columns.map((x) => x.columnName),
|
||||||
{ schemaName: fk.refSchemaName, pureName: fk.refTableName },
|
{ schemaName: fk.refSchemaName, pureName: fk.refTableName },
|
||||||
fk.columns.map(x => x.refColumnName)
|
fk.columns.map((x) => x.refColumnName)
|
||||||
);
|
);
|
||||||
if (fk.deleteAction) this.put(' ^on ^delete %k', fk.deleteAction);
|
if (fk.deleteAction) this.put(' ^on ^delete %k', fk.deleteAction);
|
||||||
if (fk.updateAction) this.put(' ^on ^update %k', fk.updateAction);
|
if (fk.updateAction) this.put(' ^on ^update %k', fk.updateAction);
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { DropDownMenuItem, DropDownMenuDivider } from '../modals/DropDownMenu';
|
import { DropDownMenuItem, DropDownMenuDivider } from '../modals/DropDownMenu';
|
||||||
|
|
||||||
export default function DataGridContextMenu({ copy, revertRowChanges, deleteSelectedRows, insertNewRow, reload }) {
|
export default function DataGridContextMenu({
|
||||||
|
copy,
|
||||||
|
revertRowChanges,
|
||||||
|
deleteSelectedRows,
|
||||||
|
insertNewRow,
|
||||||
|
setNull,
|
||||||
|
reload,
|
||||||
|
}) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DropDownMenuItem onClick={reload} keyText="F5">
|
<DropDownMenuItem onClick={reload} keyText="F5">
|
||||||
@@ -20,6 +27,10 @@ export default function DataGridContextMenu({ copy, revertRowChanges, deleteSele
|
|||||||
<DropDownMenuItem onClick={insertNewRow} keyText="Insert">
|
<DropDownMenuItem onClick={insertNewRow} keyText="Insert">
|
||||||
Insert new row
|
Insert new row
|
||||||
</DropDownMenuItem>
|
</DropDownMenuItem>
|
||||||
|
<DropDownMenuDivider />
|
||||||
|
<DropDownMenuItem onClick={setNull} keyText="Ctrl+0">
|
||||||
|
Set NULL
|
||||||
|
</DropDownMenuItem>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -530,6 +530,7 @@ export default function DataGridCore(props) {
|
|||||||
deleteSelectedRows={deleteSelectedRows}
|
deleteSelectedRows={deleteSelectedRows}
|
||||||
insertNewRow={insertNewRow}
|
insertNewRow={insertNewRow}
|
||||||
reload={() => display.reload()}
|
reload={() => display.reload()}
|
||||||
|
setNull={setNull}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -654,6 +655,22 @@ export default function DataGridCore(props) {
|
|||||||
setChangeSet(chs);
|
setChangeSet(chs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setNull() {
|
||||||
|
let chs = changeSet;
|
||||||
|
selectedCells.filter(isRegularCell).forEach((cell) => {
|
||||||
|
chs = setChangeSetValue(
|
||||||
|
chs,
|
||||||
|
display.getChangeSetField(
|
||||||
|
loadedAndInsertedRows[cell[0]],
|
||||||
|
realColumnUniqueNames[cell[1]],
|
||||||
|
cell[0] >= loadedRows.length ? cell[0] - loadedRows.length : null
|
||||||
|
),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
});
|
||||||
|
setChangeSet(chs);
|
||||||
|
}
|
||||||
|
|
||||||
function copyToClipboard() {
|
function copyToClipboard() {
|
||||||
const rowIndexes = _.uniq(selectedCells.map((x) => x[0])).sort();
|
const rowIndexes = _.uniq(selectedCells.map((x) => x[0])).sort();
|
||||||
const lines = rowIndexes.map((rowIndex) => {
|
const lines = rowIndexes.map((rowIndex) => {
|
||||||
@@ -844,6 +861,11 @@ export default function DataGridCore(props) {
|
|||||||
// this.saveAndFocus();
|
// this.saveAndFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event.keyCode == keycodes.n0 && event.ctrlKey) {
|
||||||
|
event.preventDefault();
|
||||||
|
setNull();
|
||||||
|
}
|
||||||
|
|
||||||
if (event.keyCode == keycodes.r && event.ctrlKey) {
|
if (event.keyCode == keycodes.r && event.ctrlKey) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
revertRowChanges();
|
revertRowChanges();
|
||||||
|
|||||||
@@ -68,8 +68,7 @@ const TableBodyCell = styled.td`
|
|||||||
`}
|
`}
|
||||||
|
|
||||||
${(props) =>
|
${(props) =>
|
||||||
props.isFocusedColumn
|
props.isFocusedColumn &&
|
||||||
&&
|
|
||||||
`
|
`
|
||||||
background-color: lightgoldenrodyellow;
|
background-color: lightgoldenrodyellow;
|
||||||
`}
|
`}
|
||||||
@@ -123,11 +122,31 @@ const AutoFillPoint = styled.div`
|
|||||||
cursor: crosshair;
|
cursor: crosshair;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
function makeBulletString(value) {
|
||||||
|
return _.pad('', value.length, '•');
|
||||||
|
}
|
||||||
|
|
||||||
|
function highlightSpecialCharacters(value) {
|
||||||
|
value = value.replace(/\n/g, '↲');
|
||||||
|
value = value.replace(/\r/g, '');
|
||||||
|
value = value.replace(/^(\s+)/, makeBulletString);
|
||||||
|
value = value.replace(/(\s+)$/, makeBulletString);
|
||||||
|
value = value.replace(/(\s\s+)/g, makeBulletString);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dateTimeRegex = /\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d\d\d)?Z?/;
|
||||||
|
|
||||||
function CellFormattedValue({ value }) {
|
function CellFormattedValue({ value }) {
|
||||||
if (value == null) return <NullSpan>(NULL)</NullSpan>;
|
if (value == null) return <NullSpan>(NULL)</NullSpan>;
|
||||||
if (_.isDate(value)) return moment(value).format('YYYY-MM-DD HH:mm:ss');
|
if (_.isDate(value)) return moment(value).format('YYYY-MM-DD HH:mm:ss');
|
||||||
if (value === true) return '1';
|
if (value === true) return '1';
|
||||||
if (value === false) return '0';
|
if (value === false) return '0';
|
||||||
|
if (_.isNumber(value)) return value.toLocaleString();
|
||||||
|
if (_.isString(value)) {
|
||||||
|
if (dateTimeRegex.test(value)) return moment(value).format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
return highlightSpecialCharacters(value);
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,14 +29,18 @@ export const VerticalSplitHandle = styled.div`
|
|||||||
background-color: #ccc;
|
background-color: #ccc;
|
||||||
height: ${theme.splitter.thickness}px;
|
height: ${theme.splitter.thickness}px;
|
||||||
cursor: row-resize;
|
cursor: row-resize;
|
||||||
z-index: 1;
|
&:hover {
|
||||||
|
background-color: #AAA;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const HorizontalSplitHandle = styled.div`
|
export const HorizontalSplitHandle = styled.div`
|
||||||
background-color: #ccc;
|
background-color: #ccc;
|
||||||
width: ${theme.splitter.thickness}px;
|
width: ${theme.splitter.thickness}px;
|
||||||
cursor: col-resize;
|
cursor: col-resize;
|
||||||
z-index: 1;
|
&:hover {
|
||||||
|
background-color: #AAA;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ChildContainer1 = styled.div`
|
const ChildContainer1 = styled.div`
|
||||||
@@ -45,6 +49,7 @@ const ChildContainer1 = styled.div`
|
|||||||
// flex-grow: 1;
|
// flex-grow: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ChildContainer2 = styled.div`
|
const ChildContainer2 = styled.div`
|
||||||
@@ -54,6 +59,7 @@ const ChildContainer2 = styled.div`
|
|||||||
// flex-grow: 1;
|
// flex-grow: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function useSplitterDrag(axes, onResize) {
|
export function useSplitterDrag(axes, onResize) {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ const StyledIconSpan = styled.span`
|
|||||||
const ButtonDivInner = styled.div`
|
const ButtonDivInner = styled.div`
|
||||||
position: relative;
|
position: relative;
|
||||||
top: ${(props) => props.patchY}px;
|
top: ${(props) => props.patchY}px;
|
||||||
|
white-space: nowrap;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default function ToolbarButton({ children, onClick, icon = undefined, disabled = undefined, patchY = 2 }) {
|
export default function ToolbarButton({ children, onClick, icon = undefined, disabled = undefined, patchY = 2 }) {
|
||||||
|
|||||||
Reference in New Issue
Block a user