diff --git a/packages/cubejs-sqlite-driver/driver/SqliteDriver.js b/packages/cubejs-sqlite-driver/driver/SqliteDriver.js index dac95257dfd9e..ec6b95cafcce7 100644 --- a/packages/cubejs-sqlite-driver/driver/SqliteDriver.js +++ b/packages/cubejs-sqlite-driver/driver/SqliteDriver.js @@ -33,7 +33,7 @@ class SqliteDriver extends BaseDriver { const dataSource = config.dataSource || assertDataSource('default'); - + this.config = { database: getEnv('dbName', { dataSource }), ...config @@ -64,7 +64,7 @@ class SqliteDriver extends BaseDriver { informationSchemaQuery() { return ` - SELECT name, sql + SELECT name FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence' @@ -72,31 +72,25 @@ class SqliteDriver extends BaseDriver { `; } + tableColumnsQuery(tableName) { + return ` + SELECT name, type + FROM pragma_table_info('${tableName}') + `; + } + async tablesSchema() { const query = this.informationSchemaQuery(); const tables = await this.query(query); + const tableColumns = await Promise.all(tables.map(async table => { + const columns = await this.query(this.tableColumnsQuery(table.name)); + return [table.name, columns]; + })); + return { - main: tables.reduce((acc, table) => ({ - ...acc, - [table.name]: table.sql - // remove EOL for next .match to read full string - .replace(/\n/g, '') - // extract fields - .match(/\((.*)\)/)[1] - // split fields - .split(',') - .map((nameAndType) => { - const match = nameAndType - .trim() - // replace \t with whitespace - .replace(/\t/g, ' ') - // obtain "([|`|")?name(]|`|")? type" - .match(/([|`|"])?([^[\]"`]+)(]|`|")?\s+(\w+)/); - return { name: match[2], type: match[4] }; - }) - }), {}), + main: Object.fromEntries(tableColumns) }; } diff --git a/packages/cubejs-sqlite-driver/package.json b/packages/cubejs-sqlite-driver/package.json index 833f23b4bcc77..954802f0d740c 100644 --- a/packages/cubejs-sqlite-driver/package.json +++ b/packages/cubejs-sqlite-driver/package.json @@ -14,7 +14,8 @@ "main": "driver/SqliteDriver.js", "typings": "driver/index.d.ts", "scripts": { - "lint": "eslint **/*.js" + "lint": "eslint **/*.js", + "unit": "jest" }, "dependencies": { "@cubejs-backend/base-driver": "1.3.78", @@ -23,7 +24,8 @@ }, "license": "Apache-2.0", "devDependencies": { - "@cubejs-backend/linter": "1.3.78" + "@cubejs-backend/linter": "1.3.78", + "jest": "^29" }, "publishConfig": { "access": "public" diff --git a/packages/cubejs-sqlite-driver/test/SqliteDriver.test.js b/packages/cubejs-sqlite-driver/test/SqliteDriver.test.js new file mode 100644 index 0000000000000..2090fe2346900 --- /dev/null +++ b/packages/cubejs-sqlite-driver/test/SqliteDriver.test.js @@ -0,0 +1,53 @@ +/* globals describe, test, expect, beforeEach */ +const sqlite3 = require('sqlite3'); +const SqliteDriver = require('../driver/SqliteDriver.js'); + +describe('SqliteDriver', () => { + let driver; + + beforeEach(() => { + const db = new sqlite3.Database(':memory:'); + driver = new SqliteDriver({ db }); + }); + + test('testConnection', async () => { + await driver.testConnection(); + }); + + test('tableSchema', async () => { + await driver.query(` + CREATE TABLE users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + email TEXT UNIQUE NOT NULL, + age INTEGER, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP + ); + `); + + await driver.query(` + CREATE TABLE groups ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL + ); + `); + + const tableSchema = await driver.tablesSchema(); + + expect(tableSchema).toEqual({ + main: { + users: [ + { name: 'id', type: 'INTEGER' }, + { name: 'name', type: 'TEXT' }, + { name: 'email', type: 'TEXT' }, + { name: 'age', type: 'INTEGER' }, + { name: 'created_at', type: 'DATETIME' }, + ], + groups: [ + { name: 'id', type: 'INTEGER' }, + { name: 'name', type: 'TEXT' }, + ] + } + }); + }); +});