UNPKG

@adonisjs/lucid

Version:

SQL ORM built on top of Active Record pattern

210 lines (209 loc) 6.6 kB
/* * @adonisjs/lucid * * (c) Harminder Virk <virk@adonisjs.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ export class BaseSqliteDialect { client; config; supportsAdvisoryLocks = false; supportsViews = true; supportsTypes = false; supportsDomains = false; supportsReturningStatement = false; /** * Reference to the database version. Knex.js fetches the version after * the first database query, so it will be set to undefined initially */ version; /** * The default format for datetime column. The date formats is * valid for luxon date parsing library */ dateTimeFormat = 'yyyy-MM-dd HH:mm:ss'; constructor(client, config) { this.client = client; this.config = config; this.version = this.client.getReadClient().context['client'].version; } /** * Returns a filter function to omit tables, views and * types from the excludeList */ #omitFromExcludeList(excludeList) { if (!excludeList) { return () => true; } return (name) => { return !excludeList.includes(name); }; } /** * Returns an array of table names */ async getAllTables() { const tables = await this.client .query() .from('sqlite_master') .select('name as table_name') .where('type', 'table') .whereNot('name', 'like', 'sqlite_%') .orderBy('name', 'asc'); return tables.map(({ table_name }) => table_name); } async getAllTablesWithSchema() { const tables = await this.getAllTables(); return tables.map((name) => ({ name })); } /** * Returns the primary key column names for a given table */ async getPrimaryKeys(tableName) { const ref = this.client.getWriteClient().ref(tableName).toSQL().sql; const result = await this.client.rawQuery(`PRAGMA table_info(${ref})`); return result .filter((row) => row.pk > 0) .sort((a, b) => a.pk - b.pk) .map((row) => row.name); } /** * Returns an array of all views names */ async getAllViews() { const tables = await this.client .query() .from('sqlite_master') .select('name as table_name') .where('type', 'view') .whereNot('name', 'like', 'sqlite_%') .orderBy('name', 'asc'); return tables.map(({ table_name }) => table_name); } /** * Returns an array of all types names */ async getAllTypes() { throw new Error("Sqlite doesn't support types"); } /** * Returns an array of all domains names */ async getAllDomains() { throw new Error("Sqlite doesn't support domains"); } /** * Truncate SQLITE tables */ async truncate(table) { return this.client.knexQuery().table(table).truncate(); } /** * Truncates all the tables that are in the database. * * You may exclude certain tables from getting truncated by providing them * under the "excludeTables" list. * * @example * ```ts * // Truncate all tables * await dialect.truncateAllTables() * * // Exclude the users table * await dialect.truncateAllTables(['users']) * ``` */ async truncateAllTables(excludeTables) { const tables = await this.getAllTables(); const knex = this.client.getWriteClient(); /** * Collecting the tables to be dropped. We ignore tables from the exclude * tables list. */ const tablesToTrunacte = tables.filter(this.#omitFromExcludeList(excludeTables)); if (tablesToTrunacte.length) { const pragma = await knex.raw('PRAGMA foreign_keys;'); const hasForeignKeys = pragma[0].foreign_keys === 1; if (hasForeignKeys) { await knex.raw('PRAGMA foreign_keys = OFF;'); } try { for (let table of tablesToTrunacte) { await knex.table(table).truncate(); } } finally { if (hasForeignKeys) { await knex.raw('PRAGMA foreign_keys = ON;'); } } } } /** * Drop all tables inside the database */ async dropAllTables() { const tables = await this.getAllTables(); /** * Check for foreign key pragma and turn it off if enabled * so that we can drop tables without any issues */ const pragma = await this.client.rawQuery('PRAGMA foreign_keys;'); if (pragma[0].foreign_keys === 1) { await this.client.rawQuery('PRAGMA foreign_keys = OFF;'); } /** * Drop all tables */ const knex = this.client.getWriteClient(); const promises = tables .filter((table) => !this.config.wipe?.ignoreTables?.includes(table)) .map((table) => { const ref = knex.ref(table).toSQL().sql; return this.client.rawQuery(`DROP TABLE ${ref};`); }); await Promise.all(promises); /** * Restore foreign key pragma to it's original value */ if (pragma[0].foreign_keys === 1) { await this.client.rawQuery('PRAGMA foreign_keys = ON;'); } } /** * Drop all views inside the database */ async dropAllViews() { await this.client.rawQuery('PRAGMA writable_schema = 1;'); await this.client.rawQuery(`delete from sqlite_schema where type = 'view';`); await this.client.rawQuery('PRAGMA writable_schema = 0;'); await this.client.rawQuery('VACUUM;'); } /** * Drop all custom types inside the database */ async dropAllTypes() { throw new Error("Sqlite doesn't support types"); } /** * Drop all custom domains inside the database */ async dropAllDomains() { throw new Error("Sqlite doesn't support domains"); } /** * Attempts to add advisory lock to the database and * returns it's status. */ getAdvisoryLock() { throw new Error("Sqlite doesn't support advisory locks"); } /** * Releases the advisory lock */ releaseAdvisoryLock() { throw new Error("Sqlite doesn't support advisory locks"); } }