mirror of
https://github.com/dbgate/dbgate
synced 2024-11-14 15:56:49 +00:00
postgre analyser supports compisite db names
This commit is contained in:
parent
f39ec26c29
commit
4ea6595ca7
@ -1,7 +1,7 @@
|
|||||||
const stableStringify = require('json-stable-stringify');
|
const stableStringify = require('json-stable-stringify');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const fp = require('lodash/fp');
|
const fp = require('lodash/fp');
|
||||||
const { testWrapper } = require('../tools');
|
const { testWrapper, extractConnection } = require('../tools');
|
||||||
const engines = require('../engines');
|
const engines = require('../engines');
|
||||||
const { runCommandOnDriver } = require('dbgate-tools');
|
const { runCommandOnDriver } = require('dbgate-tools');
|
||||||
|
|
||||||
@ -54,6 +54,25 @@ describe('Schema tests', () => {
|
|||||||
expect(structure2).toBeNull();
|
expect(structure2).toBeNull();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test.each(engines.filter(x => x.supportSchemas).map(engine => [engine.label, engine]))(
|
||||||
|
'Table inside schema - %s',
|
||||||
|
testWrapper(async (conn, driver, engine) => {
|
||||||
|
await baseStructure(conn, driver);
|
||||||
|
await runCommandOnDriver(conn, driver, dmp => dmp.createSchema('myschema'));
|
||||||
|
|
||||||
|
const schemaConnDef = {
|
||||||
|
...extractConnection(engine),
|
||||||
|
database: `${conn._database_name}::myschema`,
|
||||||
|
};
|
||||||
|
|
||||||
|
const schemaConn = await driver.connect(schemaConnDef);
|
||||||
|
await driver.query(schemaConn, `create table myschema.myt1 (id int not null primary key)`);
|
||||||
|
const structure1 = await driver.analyseFull(schemaConn);
|
||||||
|
expect(structure1.tables.length).toEqual(1);
|
||||||
|
expect(structure1.tables[0].tableName).toEqual('myt1');
|
||||||
|
})
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Base analyser test', () => {
|
describe('Base analyser test', () => {
|
||||||
|
@ -13,3 +13,16 @@ export function findDefaultSchema(schemaList: SchemaInfo[], dialect: SqlDialect)
|
|||||||
}
|
}
|
||||||
return schemaList[0]?.schemaName;
|
return schemaList[0]?.schemaName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isCompositeDbName(name: string) {
|
||||||
|
return name?.includes('::');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function splitCompositeDbName(name: string) {
|
||||||
|
const [database, schema] = name.split('::');
|
||||||
|
return { database, schema };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function extractDbNameFromComposite(name: string) {
|
||||||
|
return isCompositeDbName(name) ? splitCompositeDbName(name).database : name;
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const { DatabaseAnalyser } = require('dbgate-tools');
|
const { DatabaseAnalyser } = global.DBGATE_PACKAGES['dbgate-tools'];
|
||||||
const sql = require('./sql');
|
const sql = require('./sql');
|
||||||
|
|
||||||
function extractDataType(dataType) {
|
function extractDataType(dataType) {
|
||||||
|
@ -5,6 +5,7 @@ const Analyser = require('./Analyser');
|
|||||||
const { createClient } = require('@clickhouse/client');
|
const { createClient } = require('@clickhouse/client');
|
||||||
const createBulkInsertStream = require('./createBulkInsertStream');
|
const createBulkInsertStream = require('./createBulkInsertStream');
|
||||||
|
|
||||||
|
|
||||||
/** @type {import('dbgate-types').EngineDriver} */
|
/** @type {import('dbgate-types').EngineDriver} */
|
||||||
const driver = {
|
const driver = {
|
||||||
...driverBase,
|
...driverBase,
|
||||||
@ -15,7 +16,7 @@ const driver = {
|
|||||||
url: databaseUrl,
|
url: databaseUrl,
|
||||||
username: user,
|
username: user,
|
||||||
password: password,
|
password: password,
|
||||||
database: database,
|
database,
|
||||||
});
|
});
|
||||||
|
|
||||||
client._database_name = database;
|
client._database_name = database;
|
||||||
|
@ -81,7 +81,6 @@ const driver = {
|
|||||||
await pool.connect();
|
await pool.connect();
|
||||||
// const pool = await MongoClient.connect(mongoUrl);
|
// const pool = await MongoClient.connect(mongoUrl);
|
||||||
pool.__getDatabase = database ? () => pool.db(database) : () => pool.db();
|
pool.__getDatabase = database ? () => pool.db(database) : () => pool.db();
|
||||||
pool.__databaseName = database;
|
|
||||||
return pool;
|
return pool;
|
||||||
},
|
},
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
@ -79,11 +79,16 @@ const driver = {
|
|||||||
|
|
||||||
async connect(conn) {
|
async connect(conn) {
|
||||||
const { authType } = conn;
|
const { authType } = conn;
|
||||||
if (requireMsnodesqlv8 && (authType == 'sspi' || authType == 'sql')) {
|
const result =
|
||||||
return nativeConnect(conn);
|
requireMsnodesqlv8 && (authType == 'sspi' || authType == 'sql')
|
||||||
|
? await nativeConnect(conn)
|
||||||
|
: await tediousConnect(conn);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
result._database_name = conn.database;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tediousConnect(conn);
|
return result;
|
||||||
},
|
},
|
||||||
async close(pool) {
|
async close(pool) {
|
||||||
return pool.close();
|
return pool.close();
|
||||||
|
@ -2,7 +2,8 @@ const fp = require('lodash/fp');
|
|||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const sql = require('./sql');
|
const sql = require('./sql');
|
||||||
|
|
||||||
const { DatabaseAnalyser, isTypeString, isTypeNumeric } = global.DBGATE_PACKAGES['dbgate-tools'];
|
const { DatabaseAnalyser, isTypeString, isTypeNumeric, isCompositeDbName, splitCompositeDbName } =
|
||||||
|
global.DBGATE_PACKAGES['dbgate-tools'];
|
||||||
|
|
||||||
function normalizeTypeName(dataType) {
|
function normalizeTypeName(dataType) {
|
||||||
if (dataType == 'character varying') return 'varchar';
|
if (dataType == 'character varying') return 'varchar';
|
||||||
@ -56,7 +57,12 @@ class Analyser extends DatabaseAnalyser {
|
|||||||
|
|
||||||
createQuery(resFileName, typeFields, replacements = {}) {
|
createQuery(resFileName, typeFields, replacements = {}) {
|
||||||
const query = super.createQuery(sql[resFileName], typeFields, replacements);
|
const query = super.createQuery(sql[resFileName], typeFields, replacements);
|
||||||
return query;
|
const dbname = this.pool._database_name;
|
||||||
|
const schemaCondition = isCompositeDbName(dbname)
|
||||||
|
? `= '${splitCompositeDbName(dbname).schema}' `
|
||||||
|
: ' IS NOT NULL ';
|
||||||
|
|
||||||
|
return query.replace(/=SCHEMA_NAME_CONDITION/g, schemaCondition);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _computeSingleObjectId() {
|
async _computeSingleObjectId() {
|
||||||
|
@ -89,6 +89,7 @@ const drivers = driverBases.map(driverBase => ({
|
|||||||
await this.query(client, 'SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY');
|
await this.query(client, 'SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client._database_name = database;
|
||||||
return client;
|
return client;
|
||||||
},
|
},
|
||||||
async close(pool) {
|
async close(pool) {
|
||||||
|
@ -20,5 +20,6 @@ where
|
|||||||
or
|
or
|
||||||
('views:' || table_schema || '.' || table_name) =OBJECT_ID_CONDITION
|
('views:' || table_schema || '.' || table_name) =OBJECT_ID_CONDITION
|
||||||
)
|
)
|
||||||
|
and table_schema =SCHEMA_NAME_CONDITION
|
||||||
order by ordinal_position
|
order by ordinal_position
|
||||||
`;
|
`;
|
@ -7,5 +7,5 @@ select
|
|||||||
basecol.table_name,
|
basecol.table_name,
|
||||||
basecol.ordinal_position
|
basecol.ordinal_position
|
||||||
from information_schema.key_column_usage basecol
|
from information_schema.key_column_usage basecol
|
||||||
where ('tables:' || basecol.table_schema || '.' || basecol.table_name) =OBJECT_ID_CONDITION
|
where ('tables:' || basecol.table_schema || '.' || basecol.table_name) =OBJECT_ID_CONDITION and basecol.table_schema =SCHEMA_NAME_CONDITION
|
||||||
`;
|
`;
|
||||||
|
@ -7,4 +7,5 @@ select
|
|||||||
fk.unique_constraint_name as "unique_constraint_name",
|
fk.unique_constraint_name as "unique_constraint_name",
|
||||||
fk.unique_constraint_schema as "unique_constraint_schema"
|
fk.unique_constraint_schema as "unique_constraint_schema"
|
||||||
from information_schema.referential_constraints fk
|
from information_schema.referential_constraints fk
|
||||||
|
where fk.constraint_schema =SCHEMA_NAME_CONDITION
|
||||||
`;
|
`;
|
||||||
|
@ -5,5 +5,5 @@ select
|
|||||||
base.constraint_name as "constraint_name",
|
base.constraint_name as "constraint_name",
|
||||||
base.constraint_schema as "constraint_schema"
|
base.constraint_schema as "constraint_schema"
|
||||||
from information_schema.table_constraints base
|
from information_schema.table_constraints base
|
||||||
where ('tables:' || base.table_schema || '.' || base.table_name) =OBJECT_ID_CONDITION
|
where ('tables:' || base.table_schema || '.' || base.table_name) =OBJECT_ID_CONDITION and base.table_schema =SCHEMA_NAME_CONDITION
|
||||||
`;
|
`;
|
||||||
|
@ -4,5 +4,5 @@ select
|
|||||||
f_table_name as "pure_name",
|
f_table_name as "pure_name",
|
||||||
f_geography_column as "column_name"
|
f_geography_column as "column_name"
|
||||||
from public.geography_columns
|
from public.geography_columns
|
||||||
where ('tables:' || f_table_schema || '.' || f_table_name) =OBJECT_ID_CONDITION
|
where ('tables:' || f_table_schema || '.' || f_table_name) =OBJECT_ID_CONDITION and f_table_schema =SCHEMA_NAME_CONDITION
|
||||||
`;
|
`;
|
@ -4,5 +4,5 @@ select
|
|||||||
f_table_name as "pure_name",
|
f_table_name as "pure_name",
|
||||||
f_geometry_column as "column_name"
|
f_geometry_column as "column_name"
|
||||||
from public.geometry_columns
|
from public.geometry_columns
|
||||||
where ('tables:' || f_table_schema || '.' || f_table_name) =OBJECT_ID_CONDITION
|
where ('tables:' || f_table_schema || '.' || f_table_name) =OBJECT_ID_CONDITION and f_table_schema =SCHEMA_NAME_CONDITION
|
||||||
`;
|
`;
|
@ -19,6 +19,7 @@ module.exports = `
|
|||||||
and t.relnamespace = c.oid
|
and t.relnamespace = c.oid
|
||||||
and c.nspname != 'pg_catalog'
|
and c.nspname != 'pg_catalog'
|
||||||
and ('tables:' || c.nspname || '.' || t.relname) =OBJECT_ID_CONDITION
|
and ('tables:' || c.nspname || '.' || t.relname) =OBJECT_ID_CONDITION
|
||||||
|
and c.nspname =SCHEMA_NAME_CONDITION
|
||||||
order by
|
order by
|
||||||
t.relname
|
t.relname
|
||||||
`;
|
`;
|
||||||
|
@ -21,6 +21,7 @@ module.exports = `
|
|||||||
and t.relnamespace = c.oid
|
and t.relnamespace = c.oid
|
||||||
and c.nspname != 'pg_catalog'
|
and c.nspname != 'pg_catalog'
|
||||||
and ('tables:' || c.nspname || '.' || t.relname) =OBJECT_ID_CONDITION
|
and ('tables:' || c.nspname || '.' || t.relname) =OBJECT_ID_CONDITION
|
||||||
|
and c.nspname =SCHEMA_NAME_CONDITION
|
||||||
order by
|
order by
|
||||||
t.relname
|
t.relname
|
||||||
`;
|
`;
|
||||||
|
@ -12,6 +12,7 @@ FROM pg_catalog.pg_class
|
|||||||
WHERE pg_class.relkind = 'm'
|
WHERE pg_class.relkind = 'm'
|
||||||
AND pg_attribute.attnum >= 1
|
AND pg_attribute.attnum >= 1
|
||||||
AND ('matviews:' || pg_namespace.nspname || '.' || pg_class.relname) =OBJECT_ID_CONDITION
|
AND ('matviews:' || pg_namespace.nspname || '.' || pg_class.relname) =OBJECT_ID_CONDITION
|
||||||
|
AND pg_namespace.nspname =SCHEMA_NAME_CONDITION
|
||||||
|
|
||||||
ORDER BY pg_attribute.attnum
|
ORDER BY pg_attribute.attnum
|
||||||
`;
|
`;
|
||||||
|
@ -4,5 +4,5 @@ select
|
|||||||
schemaname as "schema_name",
|
schemaname as "schema_name",
|
||||||
md5(definition) as "hash_code"
|
md5(definition) as "hash_code"
|
||||||
from
|
from
|
||||||
pg_catalog.pg_matviews WHERE schemaname NOT LIKE 'pg_%'
|
pg_catalog.pg_matviews WHERE schemaname NOT LIKE 'pg_%' AND schemaname =SCHEMA_NAME_CONDITION
|
||||||
`;
|
`;
|
||||||
|
@ -7,4 +7,5 @@ select
|
|||||||
from
|
from
|
||||||
pg_catalog.pg_matviews WHERE schemaname NOT LIKE 'pg_%'
|
pg_catalog.pg_matviews WHERE schemaname NOT LIKE 'pg_%'
|
||||||
and ('matviews:' || schemaname || '.' || matviewname) =OBJECT_ID_CONDITION
|
and ('matviews:' || schemaname || '.' || matviewname) =OBJECT_ID_CONDITION
|
||||||
|
and schemaname =SCHEMA_NAME_CONDITION
|
||||||
`;
|
`;
|
||||||
|
@ -14,5 +14,6 @@ where
|
|||||||
and table_constraints.table_schema !~ '^_timescaledb_'
|
and table_constraints.table_schema !~ '^_timescaledb_'
|
||||||
and table_constraints.constraint_type = 'PRIMARY KEY'
|
and table_constraints.constraint_type = 'PRIMARY KEY'
|
||||||
and ('tables:' || table_constraints.table_schema || '.' || table_constraints.table_name) =OBJECT_ID_CONDITION
|
and ('tables:' || table_constraints.table_schema || '.' || table_constraints.table_name) =OBJECT_ID_CONDITION
|
||||||
|
and table_constraints.table_schema =SCHEMA_NAME_CONDITION
|
||||||
order by key_column_usage.ordinal_position
|
order by key_column_usage.ordinal_position
|
||||||
`;
|
`;
|
||||||
|
@ -6,5 +6,5 @@ select
|
|||||||
routine_type as "object_type"
|
routine_type as "object_type"
|
||||||
from
|
from
|
||||||
information_schema.routines where routine_schema != 'information_schema' and routine_schema != 'pg_catalog' and routine_schema !~ '^_timescaledb_'
|
information_schema.routines where routine_schema != 'information_schema' and routine_schema != 'pg_catalog' and routine_schema !~ '^_timescaledb_'
|
||||||
and routine_type in ('PROCEDURE', 'FUNCTION')
|
and routine_type in ('PROCEDURE', 'FUNCTION') and routine_schema =SCHEMA_NAME_CONDITION
|
||||||
`;
|
`;
|
||||||
|
@ -9,6 +9,7 @@ select
|
|||||||
max(external_language) as "language"
|
max(external_language) as "language"
|
||||||
from
|
from
|
||||||
information_schema.routines where routine_schema != 'information_schema' and routine_schema != 'pg_catalog' and routine_schema !~ '^_timescaledb_'
|
information_schema.routines where routine_schema != 'information_schema' and routine_schema != 'pg_catalog' and routine_schema !~ '^_timescaledb_'
|
||||||
|
and routine_schema =SCHEMA_NAME_CONDITION
|
||||||
and (
|
and (
|
||||||
(routine_type = 'PROCEDURE' and ('procedures:' || routine_schema || '.' || routine_name) =OBJECT_ID_CONDITION)
|
(routine_type = 'PROCEDURE' and ('procedures:' || routine_schema || '.' || routine_name) =OBJECT_ID_CONDITION)
|
||||||
or
|
or
|
||||||
|
@ -8,4 +8,5 @@ and infoTables.table_schema <> 'information_schema'
|
|||||||
and infoTables.table_schema <> 'pg_internal'
|
and infoTables.table_schema <> 'pg_internal'
|
||||||
and infoTables.table_schema !~ '^pg_toast'
|
and infoTables.table_schema !~ '^pg_toast'
|
||||||
and infoTables.table_schema !~ '^_timescaledb_'
|
and infoTables.table_schema !~ '^_timescaledb_'
|
||||||
|
and infoTables.table_schema =SCHEMA_NAME_CONDITION
|
||||||
`;
|
`;
|
||||||
|
@ -26,4 +26,5 @@ and infoTables.table_schema <> 'information_schema'
|
|||||||
and infoTables.table_schema <> 'pg_internal'
|
and infoTables.table_schema <> 'pg_internal'
|
||||||
and infoTables.table_schema !~ '^pg_toast'
|
and infoTables.table_schema !~ '^pg_toast'
|
||||||
and infoTables.table_schema !~ '^_timescaledb_'
|
and infoTables.table_schema !~ '^_timescaledb_'
|
||||||
|
and infoTables.table_schema =SCHEMA_NAME_CONDITION
|
||||||
`;
|
`;
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
module.exports = `
|
module.exports = `
|
||||||
select conname as "constraint_name" from pg_constraint where contype = 'u'
|
select conname as "constraint_name" from pg_constraint where contype = 'u' and connamespace = SCHEMA_ID_CONDITION
|
||||||
`;
|
`;
|
||||||
|
@ -4,5 +4,5 @@ select
|
|||||||
table_schema as "schema_name",
|
table_schema as "schema_name",
|
||||||
md5(view_definition) as "hash_code"
|
md5(view_definition) as "hash_code"
|
||||||
from
|
from
|
||||||
information_schema.views where table_schema != 'information_schema' and table_schema != 'pg_catalog' and table_schema !~ '^_timescaledb_'
|
information_schema.views where table_schema != 'information_schema' and table_schema != 'pg_catalog' and table_schema !~ '^_timescaledb_' and table_schema =SCHEMA_NAME_CONDITION
|
||||||
`;
|
`;
|
||||||
|
@ -6,6 +6,6 @@ select
|
|||||||
md5(view_definition) as "hash_code"
|
md5(view_definition) as "hash_code"
|
||||||
from
|
from
|
||||||
information_schema.views
|
information_schema.views
|
||||||
where table_schema != 'information_schema' and table_schema != 'pg_catalog' and table_schema !~ '^_timescaledb_'
|
where table_schema != 'information_schema' and table_schema != 'pg_catalog' and table_schema !~ '^_timescaledb_' and table_schema =SCHEMA_NAME_CONDITION
|
||||||
and ('views:' || table_schema || '.' || table_name) =OBJECT_ID_CONDITION
|
and ('views:' || table_schema || '.' || table_name) =OBJECT_ID_CONDITION
|
||||||
`;
|
`;
|
||||||
|
Loading…
Reference in New Issue
Block a user