Skip to content

Commit 070e6e0

Browse files
fix(sqlite-driver): Use pragma_table_info to fetch table columns (#10031)
* Add test for tablesSchema * Use pragma_table_info to fetch table columns * Rename test to unit * Update package.json I think It's enough to just call a `jest` as it will find out all the tests in expected place --------- Co-authored-by: Konstantin Burkalev <[email protected]>
1 parent b46565b commit 070e6e0

File tree

3 files changed

+72
-23
lines changed

3 files changed

+72
-23
lines changed

packages/cubejs-sqlite-driver/driver/SqliteDriver.js

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class SqliteDriver extends BaseDriver {
3333
const dataSource =
3434
config.dataSource ||
3535
assertDataSource('default');
36-
36+
3737
this.config = {
3838
database: getEnv('dbName', { dataSource }),
3939
...config
@@ -64,39 +64,33 @@ class SqliteDriver extends BaseDriver {
6464

6565
informationSchemaQuery() {
6666
return `
67-
SELECT name, sql
67+
SELECT name
6868
FROM sqlite_master
6969
WHERE type='table'
7070
AND name!='sqlite_sequence'
7171
ORDER BY name
7272
`;
7373
}
7474

75+
tableColumnsQuery(tableName) {
76+
return `
77+
SELECT name, type
78+
FROM pragma_table_info('${tableName}')
79+
`;
80+
}
81+
7582
async tablesSchema() {
7683
const query = this.informationSchemaQuery();
7784

7885
const tables = await this.query(query);
7986

87+
const tableColumns = await Promise.all(tables.map(async table => {
88+
const columns = await this.query(this.tableColumnsQuery(table.name));
89+
return [table.name, columns];
90+
}));
91+
8092
return {
81-
main: tables.reduce((acc, table) => ({
82-
...acc,
83-
[table.name]: table.sql
84-
// remove EOL for next .match to read full string
85-
.replace(/\n/g, '')
86-
// extract fields
87-
.match(/\((.*)\)/)[1]
88-
// split fields
89-
.split(',')
90-
.map((nameAndType) => {
91-
const match = nameAndType
92-
.trim()
93-
// replace \t with whitespace
94-
.replace(/\t/g, ' ')
95-
// obtain "([|`|")?name(]|`|")? type"
96-
.match(/([|`|"])?([^[\]"`]+)(]|`|")?\s+(\w+)/);
97-
return { name: match[2], type: match[4] };
98-
})
99-
}), {}),
93+
main: Object.fromEntries(tableColumns)
10094
};
10195
}
10296

packages/cubejs-sqlite-driver/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"main": "driver/SqliteDriver.js",
1515
"typings": "driver/index.d.ts",
1616
"scripts": {
17-
"lint": "eslint **/*.js"
17+
"lint": "eslint **/*.js",
18+
"unit": "jest"
1819
},
1920
"dependencies": {
2021
"@cubejs-backend/base-driver": "1.3.78",
@@ -23,7 +24,8 @@
2324
},
2425
"license": "Apache-2.0",
2526
"devDependencies": {
26-
"@cubejs-backend/linter": "1.3.78"
27+
"@cubejs-backend/linter": "1.3.78",
28+
"jest": "^29"
2729
},
2830
"publishConfig": {
2931
"access": "public"
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/* globals describe, test, expect, beforeEach */
2+
const sqlite3 = require('sqlite3');
3+
const SqliteDriver = require('../driver/SqliteDriver.js');
4+
5+
describe('SqliteDriver', () => {
6+
let driver;
7+
8+
beforeEach(() => {
9+
const db = new sqlite3.Database(':memory:');
10+
driver = new SqliteDriver({ db });
11+
});
12+
13+
test('testConnection', async () => {
14+
await driver.testConnection();
15+
});
16+
17+
test('tableSchema', async () => {
18+
await driver.query(`
19+
CREATE TABLE users (
20+
id INTEGER PRIMARY KEY AUTOINCREMENT,
21+
name TEXT NOT NULL,
22+
email TEXT UNIQUE NOT NULL,
23+
age INTEGER,
24+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
25+
);
26+
`);
27+
28+
await driver.query(`
29+
CREATE TABLE groups (
30+
id INTEGER PRIMARY KEY AUTOINCREMENT,
31+
name TEXT NOT NULL
32+
);
33+
`);
34+
35+
const tableSchema = await driver.tablesSchema();
36+
37+
expect(tableSchema).toEqual({
38+
main: {
39+
users: [
40+
{ name: 'id', type: 'INTEGER' },
41+
{ name: 'name', type: 'TEXT' },
42+
{ name: 'email', type: 'TEXT' },
43+
{ name: 'age', type: 'INTEGER' },
44+
{ name: 'created_at', type: 'DATETIME' },
45+
],
46+
groups: [
47+
{ name: 'id', type: 'INTEGER' },
48+
{ name: 'name', type: 'TEXT' },
49+
]
50+
}
51+
});
52+
});
53+
});

0 commit comments

Comments
 (0)