95 lines
3.4 KiB
TypeScript
95 lines
3.4 KiB
TypeScript
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<boolean> {
|
|
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<boolean> {
|
|
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<boolean> {
|
|
return (new Builder()).connection(this.connection)
|
|
.select(raw('*'))
|
|
.from('sqlite_master')
|
|
.where('type', '=', 'table')
|
|
.where('name', '=', name)
|
|
.exists()
|
|
}
|
|
|
|
table(table: string): Awaitable<TableBuilder> {
|
|
return this.populateTable(new TableBuilder(table))
|
|
}
|
|
|
|
protected async populateTable(table: TableBuilder): Promise<TableBuilder> {
|
|
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()
|
|
}
|
|
}
|