Merge branch 'dbgate:master' into oracle

This commit is contained in:
Rinie Kervel
2022-10-30 08:13:51 +01:00
committed by GitHub
86 changed files with 1927 additions and 480 deletions

View File

@@ -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",

View File

@@ -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);

View File

@@ -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",

View File

@@ -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',

View File

@@ -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');
}

View File

@@ -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',

View File

@@ -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",

View File

@@ -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',
});

View File

@@ -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',

View File

@@ -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",

View File

@@ -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',

View File

@@ -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);
}

View File

@@ -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',

View File

@@ -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",

View File

@@ -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,
};
}

View File

@@ -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',

View File

@@ -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"

View File

@@ -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',

View File

@@ -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,