mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-20 17:06:01 +00:00
Merge branch 'dbgate:master' into oracle
This commit is contained in:
@@ -32,7 +32,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"dbgate-plugin-tools": "^1.0.7",
|
||||
"dbgate-query-splitter": "^4.9.0",
|
||||
"dbgate-query-splitter": "^4.9.2",
|
||||
"webpack": "^4.42.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"dbgate-tools": "^5.0.0-alpha.1",
|
||||
|
||||
@@ -9,7 +9,9 @@ const AbstractCursor = require('mongodb').AbstractCursor;
|
||||
const createBulkInsertStream = require('./createBulkInsertStream');
|
||||
|
||||
function transformMongoData(row) {
|
||||
return _.mapValues(row, (v) => (v && v.constructor == ObjectId ? { $oid: v.toString() } : v));
|
||||
return _.cloneDeepWith(row, (x) => {
|
||||
if (x && x.constructor == ObjectId) return { $oid: x.toString() };
|
||||
});
|
||||
}
|
||||
|
||||
async function readCursor(cursor, options) {
|
||||
@@ -207,6 +209,10 @@ const driver = {
|
||||
if (options.countDocuments) {
|
||||
const count = await collection.countDocuments(convertObjectId(options.condition) || {});
|
||||
return { count };
|
||||
} else if (options.aggregate) {
|
||||
let cursor = await collection.aggregate(options.aggregate);
|
||||
const rows = await cursor.toArray();
|
||||
return { rows: rows.map(transformMongoData) };
|
||||
} else {
|
||||
// console.log('options.condition', JSON.stringify(options.condition, undefined, 2));
|
||||
let cursor = await collection.find(convertObjectId(options.condition) || {});
|
||||
@@ -276,6 +282,11 @@ const driver = {
|
||||
await db.createCollection('collection1');
|
||||
},
|
||||
|
||||
async dropDatabase(pool, name) {
|
||||
const db = pool.db(name);
|
||||
await db.dropDatabase();
|
||||
},
|
||||
|
||||
async loadFieldValues(pool, name, field, search) {
|
||||
try {
|
||||
const collection = pool.__getDatabase().collection(name.pureName);
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"dbgate-plugin-tools": "^1.0.7",
|
||||
"dbgate-query-splitter": "^4.9.0",
|
||||
"dbgate-query-splitter": "^4.9.2",
|
||||
"webpack": "^4.42.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"dbgate-tools": "^5.0.0-alpha.1",
|
||||
|
||||
@@ -134,7 +134,7 @@ async function tediousStream(pool, sql, options) {
|
||||
const { message, lineNumber, procName } = info;
|
||||
options.info({
|
||||
message,
|
||||
line: lineNumber,
|
||||
line: lineNumber != null && lineNumber > 0 ? lineNumber - 1 : lineNumber,
|
||||
procedure: procName,
|
||||
time: new Date(),
|
||||
severity: 'info',
|
||||
@@ -144,7 +144,7 @@ async function tediousStream(pool, sql, options) {
|
||||
const { message, lineNumber, procName } = error;
|
||||
options.info({
|
||||
message,
|
||||
line: lineNumber,
|
||||
line: lineNumber != null && lineNumber > 0 ? lineNumber - 1 : lineNumber,
|
||||
procedure: procName,
|
||||
time: new Date(),
|
||||
severity: 'error',
|
||||
|
||||
@@ -16,6 +16,16 @@ class MsSqlDumper extends SqlDumper {
|
||||
}
|
||||
}
|
||||
|
||||
dropDatabase(name) {
|
||||
this.putCmd(
|
||||
`USE master;
|
||||
ALTER DATABASE %i SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
|
||||
DROP DATABASE %i`,
|
||||
name,
|
||||
name
|
||||
);
|
||||
}
|
||||
|
||||
autoIncrement() {
|
||||
this.put(' ^identity');
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ const dialect = {
|
||||
rangeSelect: true,
|
||||
offsetFetchRangeSyntax: true,
|
||||
rowNumberOverPaging: true,
|
||||
defaultSchemaName: 'dbo',
|
||||
stringEscapeChar: "'",
|
||||
fallbackDataType: 'nvarchar(max)',
|
||||
explicitDropConstraint: false,
|
||||
@@ -130,7 +131,10 @@ const driver = {
|
||||
(field == 'trustServerCertificate' && values.authType != 'sql' && values.authType != 'sspi') ||
|
||||
(field == 'windowsDomain' && values.authType != 'sql' && values.authType != 'sspi'),
|
||||
// (field == 'useDatabaseUrl' && values.authType != 'sql' && values.authType != 'sspi')
|
||||
getQuerySplitterOptions: () => mssqlSplitterOptions,
|
||||
getQuerySplitterOptions: usage =>
|
||||
usage == 'editor'
|
||||
? { ...mssqlSplitterOptions, adaptiveGoSplit: true, ignoreComments: true, preventSingleLineSplit: true }
|
||||
: mssqlSplitterOptions,
|
||||
|
||||
engine: 'mssql@dbgate-plugin-mssql',
|
||||
title: 'Microsoft SQL Server',
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"devDependencies": {
|
||||
"antares-mysql-dumper": "^0.0.1",
|
||||
"dbgate-plugin-tools": "^1.0.7",
|
||||
"dbgate-query-splitter": "^4.9.0",
|
||||
"dbgate-query-splitter": "^4.9.2",
|
||||
"dbgate-tools": "^5.0.0-alpha.1",
|
||||
"mysql2": "^2.3.3",
|
||||
"webpack": "^4.42.0",
|
||||
|
||||
@@ -112,11 +112,10 @@ const drivers = driverBases.map(driverBase => ({
|
||||
|
||||
const handleError = error => {
|
||||
console.log('ERROR', error);
|
||||
const { message, lineNumber, procName } = error;
|
||||
const { message } = error;
|
||||
options.info({
|
||||
message,
|
||||
line: lineNumber,
|
||||
procedure: procName,
|
||||
line: 0,
|
||||
time: new Date(),
|
||||
severity: 'error',
|
||||
});
|
||||
|
||||
@@ -108,7 +108,11 @@ const mysqlDriverBase = {
|
||||
dumperClass: Dumper,
|
||||
dialect,
|
||||
defaultPort: 3306,
|
||||
getQuerySplitterOptions: () => mysqlSplitterOptions,
|
||||
getQuerySplitterOptions: usage =>
|
||||
usage == 'editor'
|
||||
? { ...mysqlSplitterOptions, ignoreComments: true, preventSingleLineSplit: true }
|
||||
: mysqlSplitterOptions,
|
||||
|
||||
readOnlySessions: true,
|
||||
supportsDatabaseDump: true,
|
||||
authTypeLabel: 'Connection mode',
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"dbgate-plugin-tools": "^1.0.7",
|
||||
"dbgate-query-splitter": "^4.9.0",
|
||||
"dbgate-query-splitter": "^4.9.2",
|
||||
"dbgate-tools": "^5.0.0-alpha.1",
|
||||
"lodash": "^4.17.21",
|
||||
"pg": "^8.7.1",
|
||||
|
||||
@@ -147,10 +147,14 @@ const drivers = driverBases.map(driverBase => ({
|
||||
|
||||
query.on('error', error => {
|
||||
console.log('ERROR', error);
|
||||
const { message, lineNumber, procName } = error;
|
||||
const { message, position, procName } = error;
|
||||
let line = null;
|
||||
if (position) {
|
||||
line = sql.substring(0, parseInt(position)).replace(/[^\n]/g, '').length;
|
||||
}
|
||||
options.info({
|
||||
message,
|
||||
line: lineNumber,
|
||||
line,
|
||||
procedure: procName,
|
||||
time: new Date(),
|
||||
severity: 'error',
|
||||
|
||||
@@ -26,6 +26,10 @@ class Dumper extends SqlDumper {
|
||||
}
|
||||
}
|
||||
|
||||
dropDatabase(name) {
|
||||
this.putCmd('^drop ^database %i ^with(^force)', name);
|
||||
}
|
||||
|
||||
dropRecreatedTempTable(tmptable) {
|
||||
this.putCmd('^drop ^table %i ^cascade', tmptable);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ const spatialTypes = ['GEOGRAPHY'];
|
||||
const dialect = {
|
||||
rangeSelect: true,
|
||||
ilike: true,
|
||||
defaultSchemaName: 'public',
|
||||
// stringEscapeChar: '\\',
|
||||
stringEscapeChar: "'",
|
||||
fallbackDataType: 'varchar',
|
||||
@@ -105,7 +106,10 @@ const postgresDriverBase = {
|
||||
dialect,
|
||||
// showConnectionField: (field, values) =>
|
||||
// ['server', 'port', 'user', 'password', 'defaultDatabase', 'singleDatabase'].includes(field),
|
||||
getQuerySplitterOptions: () => postgreSplitterOptions,
|
||||
getQuerySplitterOptions: usage =>
|
||||
usage == 'editor'
|
||||
? { ...postgreSplitterOptions, ignoreComments: true, preventSingleLineSplit: true }
|
||||
: postgreSplitterOptions,
|
||||
readOnlySessions: true,
|
||||
|
||||
databaseUrlPlaceholder: 'e.g. postgresql://user:password@localhost:5432/default_database',
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"dbgate-plugin-tools": "^1.0.7",
|
||||
"dbgate-query-splitter": "^4.9.0",
|
||||
"dbgate-query-splitter": "^4.9.2",
|
||||
"dbgate-tools": "^5.0.0-alpha.1",
|
||||
"lodash": "^4.17.21",
|
||||
"webpack": "^4.42.0",
|
||||
|
||||
@@ -81,7 +81,7 @@ function splitCommandLine(str) {
|
||||
const driver = {
|
||||
...driverBase,
|
||||
analyserClass: Analyser,
|
||||
async connect({ server, port, password, database, useDatabaseUrl, databaseUrl }) {
|
||||
async connect({ server, port, password, database, useDatabaseUrl, databaseUrl, treeKeySeparator }) {
|
||||
let db = 0;
|
||||
let pool;
|
||||
if (useDatabaseUrl) {
|
||||
@@ -95,6 +95,7 @@ const driver = {
|
||||
password,
|
||||
db,
|
||||
});
|
||||
pool.__treeKeySeparator = treeKeySeparator || ':';
|
||||
}
|
||||
|
||||
return pool;
|
||||
@@ -164,9 +165,9 @@ const driver = {
|
||||
},
|
||||
|
||||
async loadKeys(pool, root = '', filter = null) {
|
||||
const keys = await this.getKeys(pool, root ? `${root}:*` : '*');
|
||||
const keys = await this.getKeys(pool, root ? `${root}${pool.__treeKeySeparator}*` : '*');
|
||||
const keysFiltered = keys.filter((x) => filterName(filter, x));
|
||||
const res = this.extractKeysFromLevel(root, keysFiltered);
|
||||
const res = this.extractKeysFromLevel(pool, root, keysFiltered);
|
||||
await this.enrichKeyInfo(pool, res);
|
||||
return res;
|
||||
},
|
||||
@@ -196,13 +197,13 @@ const driver = {
|
||||
return res;
|
||||
},
|
||||
|
||||
extractKeysFromLevel(root, keys) {
|
||||
const prefix = root ? `${root}:` : '';
|
||||
const rootSplit = _.compact(root.split(':'));
|
||||
extractKeysFromLevel(pool, root, keys) {
|
||||
const prefix = root ? `${root}${pool.__treeKeySeparator}` : '';
|
||||
const rootSplit = _.compact(root.split(pool.__treeKeySeparator));
|
||||
const res = {};
|
||||
for (const key of keys) {
|
||||
if (!key.startsWith(prefix)) continue;
|
||||
const keySplit = key.split(':');
|
||||
const keySplit = key.split(pool.__treeKeySeparator);
|
||||
if (keySplit.length > rootSplit.length) {
|
||||
const text = keySplit[rootSplit.length];
|
||||
if (keySplit.length == rootSplit.length + 1) {
|
||||
@@ -216,9 +217,9 @@ const driver = {
|
||||
res[dctKey].count++;
|
||||
} else {
|
||||
res[dctKey] = {
|
||||
text: text + ':*',
|
||||
text: text + pool.__treeKeySeparator + '*',
|
||||
type: 'dir',
|
||||
root: keySplit.slice(0, rootSplit.length + 1).join(':'),
|
||||
root: keySplit.slice(0, rootSplit.length + 1).join(pool.__treeKeySeparator),
|
||||
count: 1,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -78,9 +78,9 @@ const driver = {
|
||||
showConnectionField: (field, values) => {
|
||||
if (field == 'useDatabaseUrl') return true;
|
||||
if (values.useDatabaseUrl) {
|
||||
return ['databaseUrl', 'isReadOnly'].includes(field);
|
||||
return ['databaseUrl', 'isReadOnly', 'treeKeySeparator'].includes(field);
|
||||
}
|
||||
return ['server', 'port', 'password', 'isReadOnly'].includes(field);
|
||||
return ['server', 'port', 'password', 'isReadOnly', 'treeKeySeparator'].includes(field);
|
||||
},
|
||||
|
||||
showConnectionTab: (field) => field == 'sshTunnel',
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"devDependencies": {
|
||||
"dbgate-tools": "^5.0.0-alpha.1",
|
||||
"dbgate-plugin-tools": "^1.0.4",
|
||||
"dbgate-query-splitter": "^4.9.0",
|
||||
"dbgate-query-splitter": "^4.9.2",
|
||||
"byline": "^5.0.0",
|
||||
"webpack": "^4.42.0",
|
||||
"webpack-cli": "^3.3.11"
|
||||
|
||||
@@ -104,10 +104,10 @@ const driver = {
|
||||
inTransaction();
|
||||
} catch (error) {
|
||||
console.log('ERROR', error);
|
||||
const { message, lineNumber, procName } = error;
|
||||
const { message, procName } = error;
|
||||
options.info({
|
||||
message,
|
||||
line: lineNumber,
|
||||
line: 0,
|
||||
procedure: procName,
|
||||
time: new Date(),
|
||||
severity: 'error',
|
||||
|
||||
@@ -50,7 +50,14 @@ const driver = {
|
||||
singleDatabase: true,
|
||||
defaultDatabase: getDatabaseFileLabel(connection.databaseFile),
|
||||
}),
|
||||
getQuerySplitterOptions: (usage) => (usage == 'stream' ? noSplitSplitterOptions : sqliteSplitterOptions),
|
||||
|
||||
getQuerySplitterOptions: (usage) =>
|
||||
usage == 'editor'
|
||||
? { ...sqliteSplitterOptions, ignoreComments: true, preventSingleLineSplit: true }
|
||||
: usage == 'stream'
|
||||
? noSplitSplitterOptions
|
||||
: sqliteSplitterOptions,
|
||||
|
||||
// isFileDatabase: true,
|
||||
isElectronOnly: true,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user