mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-28 23:26:00 +00:00
clickhouse tests WIP
This commit is contained in:
@@ -7,7 +7,9 @@ const { getAlterDatabaseScript, extendDatabaseInfo, generateDbPairingId } = requ
|
|||||||
|
|
||||||
function flatSource() {
|
function flatSource() {
|
||||||
return _.flatten(
|
return _.flatten(
|
||||||
engines.map(engine => (engine.objects || []).map(object => [engine.label, object.type, object, engine]))
|
engines
|
||||||
|
.filter(x => !x.skipReferences)
|
||||||
|
.map(engine => (engine.objects || []).map(object => [engine.label, object.type, object, engine]))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +43,7 @@ async function testDatabaseDiff(conn, driver, mangle, createObject = null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('Alter database', () => {
|
describe('Alter database', () => {
|
||||||
test.each(engines.map(engine => [engine.label, engine]))(
|
test.each(engines.filter(x => !x.skipReferences).map(engine => [engine.label, engine]))(
|
||||||
'Drop referenced table - %s',
|
'Drop referenced table - %s',
|
||||||
testWrapper(async (conn, driver, engine) => {
|
testWrapper(async (conn, driver, engine) => {
|
||||||
await testDatabaseDiff(conn, driver, db => {
|
await testDatabaseDiff(conn, driver, db => {
|
||||||
|
|||||||
@@ -6,39 +6,44 @@ const engines = require('../engines');
|
|||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const { getAlterTableScript, extendDatabaseInfo, generateDbPairingId } = require('dbgate-tools');
|
const { getAlterTableScript, extendDatabaseInfo, generateDbPairingId } = require('dbgate-tools');
|
||||||
|
|
||||||
function pickImportantTableInfo(table) {
|
function pickImportantTableInfo(engine, table) {
|
||||||
|
const props = ['columnName'];
|
||||||
|
if (!engine.skipNullability) props.push('notNull');
|
||||||
|
if (!engine.skipAutoIncrement) props.push('autoIncrement');
|
||||||
return {
|
return {
|
||||||
pureName: table.pureName,
|
pureName: table.pureName,
|
||||||
columns: table.columns
|
columns: table.columns.filter(x => x.columnName != 'rowid').map(fp.pick(props)),
|
||||||
.filter(x => x.columnName != 'rowid')
|
|
||||||
.map(fp.pick(['columnName', 'notNull', 'autoIncrement'])),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkTableStructure(t1, t2) {
|
function checkTableStructure(engine, t1, t2) {
|
||||||
// expect(t1.pureName).toEqual(t2.pureName)
|
// expect(t1.pureName).toEqual(t2.pureName)
|
||||||
expect(pickImportantTableInfo(t1)).toEqual(pickImportantTableInfo(t2));
|
expect(pickImportantTableInfo(engine, t1)).toEqual(pickImportantTableInfo(engine, t2));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testTableDiff(conn, driver, mangle) {
|
async function testTableDiff(engine, conn, driver, mangle) {
|
||||||
await driver.query(conn, `create table t0 (id int not null primary key)`);
|
await driver.query(conn, `create table t0 (id int not null primary key)`);
|
||||||
|
|
||||||
await driver.query(
|
await driver.query(
|
||||||
conn,
|
conn,
|
||||||
`create table t1 (
|
`create table t1 (
|
||||||
col_pk int not null primary key,
|
col_pk int not null primary key,
|
||||||
col_std int null,
|
col_std int,
|
||||||
col_def int null default 12,
|
col_def int default 12,
|
||||||
col_fk int null references t0(id),
|
${engine.skipReferences ? '' : 'col_fk int references t0(id),'}
|
||||||
col_idx int null,
|
col_idx int,
|
||||||
col_uq int null unique,
|
col_uq int ${engine.skipUnique ? '' : 'unique'} ,
|
||||||
col_ref int null unique
|
col_ref int ${engine.skipUnique ? '' : 'unique'}
|
||||||
)`
|
)`
|
||||||
);
|
);
|
||||||
|
|
||||||
await driver.query(conn, `create index idx1 on t1(col_idx)`);
|
if (!engine.skipIndexes) {
|
||||||
|
await driver.query(conn, `create index idx1 on t1(col_idx)`);
|
||||||
|
}
|
||||||
|
|
||||||
await driver.query(conn, `create table t2 (id int not null primary key, fkval int null references t1(col_ref))`);
|
if (!engine.skipReferences) {
|
||||||
|
await driver.query(conn, `create table t2 (id int not null primary key, fkval int null references t1(col_ref))`);
|
||||||
|
}
|
||||||
|
|
||||||
const tget = x => x.tables.find(y => y.pureName == 't1');
|
const tget = x => x.tables.find(y => y.pureName == 't1');
|
||||||
const structure1 = generateDbPairingId(extendDatabaseInfo(await driver.analyseFull(conn)));
|
const structure1 = generateDbPairingId(extendDatabaseInfo(await driver.analyseFull(conn)));
|
||||||
@@ -53,7 +58,7 @@ async function testTableDiff(conn, driver, mangle) {
|
|||||||
|
|
||||||
const structure2Real = extendDatabaseInfo(await driver.analyseFull(conn));
|
const structure2Real = extendDatabaseInfo(await driver.analyseFull(conn));
|
||||||
|
|
||||||
checkTableStructure(tget(structure2Real), tget(structure2));
|
checkTableStructure(engine, tget(structure2Real), tget(structure2));
|
||||||
// expect(stableStringify(structure2)).toEqual(stableStringify(structure2Real));
|
// expect(stableStringify(structure2)).toEqual(stableStringify(structure2Real));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +77,7 @@ describe('Alter table', () => {
|
|||||||
test.each(engines.map(engine => [engine.label, engine]))(
|
test.each(engines.map(engine => [engine.label, engine]))(
|
||||||
'Add column - %s',
|
'Add column - %s',
|
||||||
testWrapper(async (conn, driver, engine) => {
|
testWrapper(async (conn, driver, engine) => {
|
||||||
await testTableDiff(conn, driver, tbl => {
|
await testTableDiff(engine, conn, driver, tbl => {
|
||||||
tbl.columns.push({
|
tbl.columns.push({
|
||||||
columnName: 'added',
|
columnName: 'added',
|
||||||
dataType: 'int',
|
dataType: 'int',
|
||||||
@@ -87,7 +92,7 @@ describe('Alter table', () => {
|
|||||||
test.each(engines_columns_source())(
|
test.each(engines_columns_source())(
|
||||||
'Drop column - %s - %s',
|
'Drop column - %s - %s',
|
||||||
testWrapper(async (conn, driver, column, engine) => {
|
testWrapper(async (conn, driver, column, engine) => {
|
||||||
await testTableDiff(conn, driver, tbl => (tbl.columns = tbl.columns.filter(x => x.columnName != column)));
|
await testTableDiff(engine, conn, driver, tbl => (tbl.columns = tbl.columns.filter(x => x.columnName != column)));
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -95,6 +100,7 @@ describe('Alter table', () => {
|
|||||||
'Change nullability - %s - %s',
|
'Change nullability - %s - %s',
|
||||||
testWrapper(async (conn, driver, column, engine) => {
|
testWrapper(async (conn, driver, column, engine) => {
|
||||||
await testTableDiff(
|
await testTableDiff(
|
||||||
|
engine,
|
||||||
conn,
|
conn,
|
||||||
driver,
|
driver,
|
||||||
tbl => (tbl.columns = tbl.columns.map(x => (x.columnName == column ? { ...x, notNull: true } : x)))
|
tbl => (tbl.columns = tbl.columns.map(x => (x.columnName == column ? { ...x, notNull: true } : x)))
|
||||||
@@ -106,6 +112,7 @@ describe('Alter table', () => {
|
|||||||
'Rename column - %s - %s',
|
'Rename column - %s - %s',
|
||||||
testWrapper(async (conn, driver, column, engine) => {
|
testWrapper(async (conn, driver, column, engine) => {
|
||||||
await testTableDiff(
|
await testTableDiff(
|
||||||
|
engine,
|
||||||
conn,
|
conn,
|
||||||
driver,
|
driver,
|
||||||
tbl => (tbl.columns = tbl.columns.map(x => (x.columnName == column ? { ...x, columnName: 'col_renamed' } : x)))
|
tbl => (tbl.columns = tbl.columns.map(x => (x.columnName == column ? { ...x, columnName: 'col_renamed' } : x)))
|
||||||
@@ -116,7 +123,7 @@ describe('Alter table', () => {
|
|||||||
test.each(engines.map(engine => [engine.label, engine]))(
|
test.each(engines.map(engine => [engine.label, engine]))(
|
||||||
'Drop index - %s',
|
'Drop index - %s',
|
||||||
testWrapper(async (conn, driver, engine) => {
|
testWrapper(async (conn, driver, engine) => {
|
||||||
await testTableDiff(conn, driver, tbl => {
|
await testTableDiff(engine, conn, driver, tbl => {
|
||||||
tbl.indexes = [];
|
tbl.indexes = [];
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,7 +2,11 @@ const engines = require('../engines');
|
|||||||
const { splitQuery } = require('dbgate-query-splitter');
|
const { splitQuery } = require('dbgate-query-splitter');
|
||||||
const { testWrapper } = require('../tools');
|
const { testWrapper } = require('../tools');
|
||||||
|
|
||||||
const initSql = ['CREATE TABLE t1 (id int)', 'INSERT INTO t1 (id) VALUES (1)', 'INSERT INTO t1 (id) VALUES (2)'];
|
const initSql = [
|
||||||
|
'CREATE TABLE t1 (id int primary key)',
|
||||||
|
'INSERT INTO t1 (id) VALUES (1)',
|
||||||
|
'INSERT INTO t1 (id) VALUES (2)',
|
||||||
|
];
|
||||||
|
|
||||||
expect.extend({
|
expect.extend({
|
||||||
dataRow(row, expected) {
|
dataRow(row, expected) {
|
||||||
@@ -64,7 +68,7 @@ describe('Query', () => {
|
|||||||
test.each(engines.map(engine => [engine.label, engine]))(
|
test.each(engines.map(engine => [engine.label, engine]))(
|
||||||
'Simple query - %s',
|
'Simple query - %s',
|
||||||
testWrapper(async (conn, driver, engine) => {
|
testWrapper(async (conn, driver, engine) => {
|
||||||
for (const sql of initSql) await driver.query(conn, sql);
|
for (const sql of initSql) await driver.query(conn, sql, { discardResult: true });
|
||||||
|
|
||||||
const res = await driver.query(conn, 'SELECT id FROM t1 ORDER BY id');
|
const res = await driver.query(conn, 'SELECT id FROM t1 ORDER BY id');
|
||||||
expect(res.columns).toEqual([
|
expect(res.columns).toEqual([
|
||||||
@@ -87,7 +91,7 @@ describe('Query', () => {
|
|||||||
test.each(engines.map(engine => [engine.label, engine]))(
|
test.each(engines.map(engine => [engine.label, engine]))(
|
||||||
'Simple stream query - %s',
|
'Simple stream query - %s',
|
||||||
testWrapper(async (conn, driver, engine) => {
|
testWrapper(async (conn, driver, engine) => {
|
||||||
for (const sql of initSql) await driver.query(conn, sql);
|
for (const sql of initSql) await driver.query(conn, sql, { discardResult: true });
|
||||||
const results = await executeStream(driver, conn, 'SELECT id FROM t1 ORDER BY id');
|
const results = await executeStream(driver, conn, 'SELECT id FROM t1 ORDER BY id');
|
||||||
expect(results.length).toEqual(1);
|
expect(results.length).toEqual(1);
|
||||||
const res = results[0];
|
const res = results[0];
|
||||||
@@ -100,7 +104,7 @@ describe('Query', () => {
|
|||||||
test.each(engines.map(engine => [engine.label, engine]))(
|
test.each(engines.map(engine => [engine.label, engine]))(
|
||||||
'More queries - %s',
|
'More queries - %s',
|
||||||
testWrapper(async (conn, driver, engine) => {
|
testWrapper(async (conn, driver, engine) => {
|
||||||
for (const sql of initSql) await driver.query(conn, sql);
|
for (const sql of initSql) await driver.query(conn, sql, { discardResult: true });
|
||||||
const results = await executeStream(
|
const results = await executeStream(
|
||||||
driver,
|
driver,
|
||||||
conn,
|
conn,
|
||||||
@@ -124,7 +128,7 @@ describe('Query', () => {
|
|||||||
const results = await executeStream(
|
const results = await executeStream(
|
||||||
driver,
|
driver,
|
||||||
conn,
|
conn,
|
||||||
'CREATE TABLE t1 (id int); INSERT INTO t1 (id) VALUES (1); INSERT INTO t1 (id) VALUES (2); SELECT id FROM t1 ORDER BY id; '
|
'CREATE TABLE t1 (id int primary key); INSERT INTO t1 (id) VALUES (1); INSERT INTO t1 (id) VALUES (2); SELECT id FROM t1 ORDER BY id; '
|
||||||
);
|
);
|
||||||
expect(results.length).toEqual(1);
|
expect(results.length).toEqual(1);
|
||||||
|
|
||||||
@@ -146,14 +150,15 @@ describe('Query', () => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
test.each(engines.map(engine => [engine.label, engine]))(
|
test.each(engines.filter(x => !x.skipDataModifications).map(engine => [engine.label, engine]))(
|
||||||
'Save data query - %s',
|
'Save data query - %s',
|
||||||
testWrapper(async (conn, driver, engine) => {
|
testWrapper(async (conn, driver, engine) => {
|
||||||
for (const sql of initSql) await driver.query(conn, sql);
|
for (const sql of initSql) await driver.query(conn, sql, { discardResult: true });
|
||||||
|
|
||||||
await driver.script(
|
await driver.script(
|
||||||
conn,
|
conn,
|
||||||
'INSERT INTO t1 (id) VALUES (3);INSERT INTO t1 (id) VALUES (4);UPDATE t1 SET id=10 WHERE id=1;DELETE FROM t1 WHERE id=2;'
|
'INSERT INTO t1 (id) VALUES (3);INSERT INTO t1 (id) VALUES (4);UPDATE t1 SET id=10 WHERE id=1;DELETE FROM t1 WHERE id=2;',
|
||||||
|
{ discardResult: true }
|
||||||
);
|
);
|
||||||
const res = await driver.query(conn, 'SELECT COUNT(*) AS cnt FROM t1');
|
const res = await driver.query(conn, 'SELECT COUNT(*) AS cnt FROM t1');
|
||||||
// console.log(res);
|
// console.log(res);
|
||||||
|
|||||||
@@ -26,15 +26,23 @@ services:
|
|||||||
# environment:
|
# environment:
|
||||||
# - MYSQL_ROOT_PASSWORD=Pwd2020Db
|
# - MYSQL_ROOT_PASSWORD=Pwd2020Db
|
||||||
|
|
||||||
mssql:
|
clickhouse:
|
||||||
image: mcr.microsoft.com/mssql/server
|
image: bitnami/clickhouse:24.8.4
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- 15002:1433
|
- 15005:8123
|
||||||
environment:
|
environment:
|
||||||
- ACCEPT_EULA=Y
|
- CLICKHOUSE_ADMIN_PASSWORD=Pwd2020Db
|
||||||
- SA_PASSWORD=Pwd2020Db
|
|
||||||
- MSSQL_PID=Express
|
# mssql:
|
||||||
|
# image: mcr.microsoft.com/mssql/server
|
||||||
|
# restart: always
|
||||||
|
# ports:
|
||||||
|
# - 15002:1433
|
||||||
|
# environment:
|
||||||
|
# - ACCEPT_EULA=Y
|
||||||
|
# - SA_PASSWORD=Pwd2020Db
|
||||||
|
# - MSSQL_PID=Express
|
||||||
|
|
||||||
# cockroachdb:
|
# cockroachdb:
|
||||||
# image: cockroachdb/cockroach
|
# image: cockroachdb/cockroach
|
||||||
|
|||||||
@@ -129,6 +129,25 @@ const engines = [
|
|||||||
skipOnCI: true,
|
skipOnCI: true,
|
||||||
objects: [views, matviews],
|
objects: [views, matviews],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'ClickHouse',
|
||||||
|
connection: {
|
||||||
|
engine: 'clickhouse@dbgate-plugin-clickhouse',
|
||||||
|
databaseUrl: 'http://clickhouse:8123',
|
||||||
|
password: 'Pwd2020Db',
|
||||||
|
},
|
||||||
|
local: {
|
||||||
|
databaseUrl: 'http://localhost:15005',
|
||||||
|
},
|
||||||
|
// skipOnCI: true,
|
||||||
|
objects: [views],
|
||||||
|
skipDataModifications: true,
|
||||||
|
skipReferences: true,
|
||||||
|
skipIndexes: true,
|
||||||
|
skipNullability: true,
|
||||||
|
skipUnique: true,
|
||||||
|
skipAutoIncrement:true
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const filterLocal = [
|
const filterLocal = [
|
||||||
@@ -137,8 +156,9 @@ const filterLocal = [
|
|||||||
'-MariaDB',
|
'-MariaDB',
|
||||||
'-PostgreSQL',
|
'-PostgreSQL',
|
||||||
'-SQL Server',
|
'-SQL Server',
|
||||||
'SQLite',
|
'-SQLite',
|
||||||
'-CockroachDB',
|
'-CockroachDB',
|
||||||
|
'ClickHouse',
|
||||||
];
|
];
|
||||||
|
|
||||||
const enginesPostgre = engines.filter(x => x.label == 'PostgreSQL');
|
const enginesPostgre = engines.filter(x => x.label == 'PostgreSQL');
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ const driver = {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const dataSet = await resultSet.json();
|
const dataSet = await resultSet.json();
|
||||||
|
if (!dataSet?.[0]) {
|
||||||
|
return {
|
||||||
|
rows: [],
|
||||||
|
columns: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const columns = dataSet[0].map((columnName, i) => ({
|
const columns = dataSet[0].map((columnName, i) => ({
|
||||||
columnName,
|
columnName,
|
||||||
@@ -207,6 +213,10 @@ const driver = {
|
|||||||
const dataset = await resultSet.json();
|
const dataset = await resultSet.json();
|
||||||
return dataset;
|
return dataset;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async close(client) {
|
||||||
|
return client.close();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = driver;
|
module.exports = driver;
|
||||||
|
|||||||
Reference in New Issue
Block a user