You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lib/src/orm/schema/SQLiteSchema.ts

95 lines
3.4 KiB

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()
}
}