import {Schema} from './Schema' import {SQLiteConnection} from '../connection/SQLiteConnection' import {Awaitable} from '../../util' import {TableBuilder} from './TableBuilder' import {Builder} from '../builder/Builder' import {raw} from '../dialect/SQLDialect' export class SQLiteSchema extends Schema { constructor( connection: SQLiteConnection, ) { super(connection) } hasColumn(table: string, name: string): Awaitable { return (new Builder()).connection(this.connection) .select(raw('*')) .from(`pragma_table_info(${this.connection.dialect().escape(table)})`) // FIXME: probably needs to be raw(...) .where('name', '=', name) .exists() } hasColumns(table: string, name: string[]): Awaitable { return (new Builder()).connection(this.connection) .select(raw('*')) .from(`pragma_table_info(${this.connection.dialect().escape(table)})`) // FIXME: probably needs to be raw(...) .whereIn('name', name) .get() .count() .then(num => num === name.length) } hasTable(name: string): Awaitable { return (new Builder()).connection(this.connection) .select(raw('*')) .from('sqlite_master') .where('type', '=', 'table') .where('name', '=', name) .exists() } table(table: string): Awaitable { return this.populateTable(new TableBuilder(table)) } protected async populateTable(table: TableBuilder): Promise { if ( !(await this.hasTable(table.name)) ) { return table } // Load the existing columns await (new Builder()).connection(this.connection) .select(raw('*')) .from(raw(`pragma_table_info(${this.connection.dialect().escape(table.name)})`)) .get() .each(col => { table.column(col.name) .type(col.type) .pipe(line => { return line.unless(col.notnull, builder => builder.nullable()) .when(col.dflt_value, builder => builder.default(raw(col.dflt_value))) .when(col.pk, builder => builder.primary()) }) .flagAsExistingInSchema() }) // TODO: Load the existing constraints // TODO: Look up and apply the check constraints // Look up table indexes await (new Builder()).connection(this.connection) .select(raw('*')) .from(raw(`pragma_index_list(${this.connection.dialect().escape(table.name)})`)) .get() .each(async idx => { const indexBuilder = table.index(idx.name) .pipe(line => line.when(idx.unique, builder => builder.unique())) const idxColumns = await (new Builder()).connection(this.connection) .select(raw('*')) .from(raw(`pragma_index_xinfo(${this.connection.dialect().escape(idx.name)})`)) .whereNotNull('name') .get() .pluck('name') idxColumns.whereDefined() .each(col => indexBuilder.field(col)) indexBuilder.flagAsExistingInSchema() }) return table.flagAsExistingInSchema() } }