@adonisjs/lucid
Version:
SQL ORM built on top of Active Record pattern
210 lines (209 loc) • 6.6 kB
JavaScript
/*
* @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");
}
}