mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-25 14:26:00 +00:00
mongo query splitter, copy as mongo insert
This commit is contained in:
@@ -228,7 +228,7 @@ function changeSetInsertToSql(
|
||||
const table = dbinfo.tables.find(x => x.schemaName == item.schemaName && x.pureName == item.pureName);
|
||||
if (table) {
|
||||
const autoIncCol = table.columns.find(x => x.autoIncrement);
|
||||
console.log('autoIncCol', autoIncCol);
|
||||
// console.log('autoIncCol', autoIncCol);
|
||||
if (autoIncCol && fields.find(x => x.targetColumn == autoIncCol.columnName)) {
|
||||
autoInc = true;
|
||||
}
|
||||
@@ -375,7 +375,7 @@ export function getChangeSetInsertedRows(changeSet: ChangeSet, name?: NamedObjec
|
||||
}
|
||||
|
||||
export function changeSetInsertNewRow(changeSet: ChangeSet, name?: NamedObjectInfo): ChangeSet {
|
||||
console.log('INSERT', name);
|
||||
// console.log('INSERT', name);
|
||||
const insertedRows = getChangeSetInsertedRows(changeSet, name);
|
||||
return {
|
||||
...changeSet,
|
||||
|
||||
@@ -89,10 +89,12 @@ export class CollectionGridDisplay extends GridDisplay {
|
||||
setConfig: ChangeConfigFunc,
|
||||
cache: GridCache,
|
||||
setCache: ChangeCacheFunc,
|
||||
loadedRows
|
||||
loadedRows,
|
||||
changeSet
|
||||
) {
|
||||
super(config, setConfig, cache, setCache, driver);
|
||||
this.columns = analyseCollectionDisplayColumns(loadedRows, this);
|
||||
const changedDocs = _.compact([...changeSet.inserts, ...changeSet.updates].map(chs => chs.document));
|
||||
this.columns = analyseCollectionDisplayColumns([...(loadedRows || []), ...changedDocs], this);
|
||||
this.filterable = true;
|
||||
this.sortable = true;
|
||||
this.editable = true;
|
||||
|
||||
@@ -8,6 +8,9 @@ export interface SplitterOptions {
|
||||
allowGoDelimiter: boolean;
|
||||
allowDollarDollarString: boolean;
|
||||
noSplit: boolean;
|
||||
doubleDashComments: boolean;
|
||||
multilineComments: boolean;
|
||||
javaScriptComments: boolean;
|
||||
}
|
||||
|
||||
export const defaultSplitterOptions: SplitterOptions = {
|
||||
@@ -20,6 +23,10 @@ export const defaultSplitterOptions: SplitterOptions = {
|
||||
allowGoDelimiter: false,
|
||||
allowDollarDollarString: false,
|
||||
noSplit: false,
|
||||
|
||||
doubleDashComments: true,
|
||||
multilineComments: true,
|
||||
javaScriptComments: false,
|
||||
};
|
||||
|
||||
export const mysqlSplitterOptions: SplitterOptions = {
|
||||
@@ -59,6 +66,14 @@ export const sqliteSplitterOptions: SplitterOptions = {
|
||||
stringEscapes: { "'": "'", '"': '"' },
|
||||
};
|
||||
|
||||
export const mongoSplitterOptions: SplitterOptions = {
|
||||
...defaultSplitterOptions,
|
||||
|
||||
stringsBegins: ["'", '"'],
|
||||
stringsEnds: { "'": "'", '"': '"' },
|
||||
stringEscapes: { "'": '\\', '"': '\\' },
|
||||
};
|
||||
|
||||
export const noSplitSplitterOptions: SplitterOptions = {
|
||||
...defaultSplitterOptions,
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ function scanToken(context: SplitLineContext): Token {
|
||||
return EOLN_TOKEN;
|
||||
}
|
||||
|
||||
if (ch == '-' && s[pos + 1] == '-') {
|
||||
if (context.options.doubleDashComments && ch == '-' && s[pos + 1] == '-') {
|
||||
while (pos < context.end && s[pos] != '\n') pos++;
|
||||
return {
|
||||
type: 'comment',
|
||||
@@ -121,7 +121,7 @@ function scanToken(context: SplitLineContext): Token {
|
||||
};
|
||||
}
|
||||
|
||||
if (ch == '/' && s[pos + 1] == '*') {
|
||||
if (context.options.multilineComments && ch == '/' && s[pos + 1] == '*') {
|
||||
pos += 2;
|
||||
while (pos < context.end) {
|
||||
if (s[pos] == '*' && s[pos + 1] == '/') break;
|
||||
@@ -222,7 +222,7 @@ export function splitQueryLine(context: SplitLineContext) {
|
||||
}
|
||||
|
||||
export function getInitialDelimiter(options: SplitterOptions) {
|
||||
return options?.allowSemicolon === false ? null : SEMICOLON
|
||||
return options?.allowSemicolon === false ? null : SEMICOLON;
|
||||
}
|
||||
export function splitQuery(sql: string, options: SplitterOptions = null): string[] {
|
||||
const usedOptions = {
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { mysqlSplitterOptions, mssqlSplitterOptions, postgreSplitterOptions, noSplitSplitterOptions } from './options';
|
||||
import {
|
||||
mysqlSplitterOptions,
|
||||
mssqlSplitterOptions,
|
||||
postgreSplitterOptions,
|
||||
mongoSplitterOptions,
|
||||
noSplitSplitterOptions,
|
||||
} from './options';
|
||||
import { splitQuery } from './splitQuery';
|
||||
|
||||
test('simple query', () => {
|
||||
@@ -77,3 +83,9 @@ test('no split', () => {
|
||||
const output = splitQuery(input, noSplitSplitterOptions);
|
||||
expect(output).toEqual(['SELECT 1;SELECT 2']);
|
||||
});
|
||||
|
||||
test('split mongo', () => {
|
||||
const input = 'db.collection.insert({x:1});db.collection.insert({y:2})';
|
||||
const output = splitQuery(input, mongoSplitterOptions);
|
||||
expect(output).toEqual(['db.collection.insert({x:1})', 'db.collection.insert({y:2})']);
|
||||
});
|
||||
|
||||
@@ -250,6 +250,7 @@
|
||||
import { showModal } from '../modals/modalTools';
|
||||
import { updateStatuBarInfo } from '../widgets/StatusBar.svelte';
|
||||
import StatusBarTabItem from '../widgets/StatusBarTabItem.svelte';
|
||||
import { findCommand } from '../commands/runCommand';
|
||||
|
||||
export let onLoadNextData = undefined;
|
||||
export let grider = undefined;
|
||||
@@ -265,6 +266,8 @@
|
||||
export let focusOnVisible = false;
|
||||
export let formViewAvailable = false;
|
||||
export let errorMessage = undefined;
|
||||
export let pureName = undefined;
|
||||
export let schemaName = undefined;
|
||||
|
||||
export let isLoadedAll;
|
||||
export let loadedTime;
|
||||
@@ -379,8 +382,8 @@
|
||||
// @ts-ignore
|
||||
const columns = colIndexes.map(col => realColumnUniqueNames[col]);
|
||||
copyRowsToClipboard(format, columns, rows, {
|
||||
schemaName: display?.baseTable?.schemaName,
|
||||
pureName: display?.baseTable?.pureName || 'target',
|
||||
schemaName,
|
||||
pureName: pureName || 'target',
|
||||
driver: display?.driver || driverBase,
|
||||
keyColumns: display?.baseTable?.primaryKey?.columns?.map(col => col.columnName) || [
|
||||
display?.columns ? display?.columns[0].columnName : columns[0],
|
||||
@@ -1218,6 +1221,12 @@
|
||||
{#if display.filterCount > 0}
|
||||
<FormStyledButton value="Reset filter" on:click={() => display.clearFilters()} />
|
||||
{/if}
|
||||
<FormStyledButton
|
||||
value="Add document"
|
||||
on:click={() => {
|
||||
findCommand('collectionTable.newJson')?.onClick();
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{:else if grider.errors && grider.errors.length > 0}
|
||||
<div>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
</div>
|
||||
|
||||
<div slot="footer">
|
||||
<FormSubmit
|
||||
<FormStyledButton
|
||||
value="Save"
|
||||
on:click={() => {
|
||||
try {
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
import { registerMenu } from '../utility/contextMenu';
|
||||
import EditJsonModal from '../modals/EditJsonModal.svelte';
|
||||
import ChangeSetGrider from '../datagrid/ChangeSetGrider';
|
||||
import { setContext } from 'svelte';
|
||||
|
||||
export let tabid;
|
||||
export let conid;
|
||||
@@ -89,7 +90,8 @@
|
||||
config.update,
|
||||
$cache,
|
||||
cache.update,
|
||||
loadedRows
|
||||
loadedRows,
|
||||
$changeSetStore?.value
|
||||
)
|
||||
: null;
|
||||
// $: console.log('LOADED ROWS MONGO', loadedRows);
|
||||
@@ -145,6 +147,9 @@
|
||||
}
|
||||
|
||||
registerMenu({ command: 'collectionTable.save', tag: 'save' }, { command: 'collectionTable.newJson', tag: 'edit' });
|
||||
|
||||
const collapsedLeftColumnStore = writable(false);
|
||||
setContext('collapsedLeftColumnStore', collapsedLeftColumnStore);
|
||||
</script>
|
||||
|
||||
<DataGrid
|
||||
|
||||
@@ -132,6 +132,11 @@ const clipboardUpdatesFormatter = () => (columns, rows, options) => {
|
||||
return dmp.s;
|
||||
};
|
||||
|
||||
const clipboardMongoInsertFormatter = () => (columns, rows, options) => {
|
||||
const { pureName } = options;
|
||||
return rows.map(row => `db.${pureName}.insert(${JSON.stringify(_.pick(row, columns), undefined, 2)});`).join('\n');
|
||||
};
|
||||
|
||||
export function formatClipboardRows(format, columns, rows, options) {
|
||||
if (format in copyRowsFormatDefs) {
|
||||
return copyRowsFormatDefs[format].formatter(columns, rows, options);
|
||||
@@ -185,4 +190,9 @@ export const copyRowsFormatDefs = {
|
||||
name: 'SQL UPDATEs',
|
||||
formatter: clipboardUpdatesFormatter(),
|
||||
},
|
||||
mongoInsert: {
|
||||
label: 'Copy as Mongo INSERTs',
|
||||
name: 'Mongo UPDATEs',
|
||||
formatter: clipboardMongoInsertFormatter(),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const _isString = require('lodash/isString');
|
||||
const { driverBase } = global.DBGATE_TOOLS;
|
||||
const Dumper = require('./Dumper');
|
||||
const { noSplitSplitterOptions } = require('dbgate-query-splitter/lib/options');
|
||||
const { mongoSplitterOptions } = require('dbgate-query-splitter/lib/options');
|
||||
|
||||
const mongoIdRegex = /^[0-9a-f]{24}$/;
|
||||
|
||||
@@ -36,7 +36,7 @@ const driver = {
|
||||
supportsDatabaseUrl: true,
|
||||
databaseUrlPlaceholder: 'e.g. mongodb://username:password@mongodb.mydomain.net/dbname',
|
||||
|
||||
getQuerySplitterOptions: () => noSplitSplitterOptions,
|
||||
getQuerySplitterOptions: () => mongoSplitterOptions,
|
||||
|
||||
showConnectionField: (field, values) => {
|
||||
if (field == 'useDatabaseUrl') return true;
|
||||
|
||||
Reference in New Issue
Block a user