import { ColumnBuilder } from "./columnbuilder.ts" ; import type { Adapter } from "../adapters/adapter.ts" ; import { quote } from "../utils/dialect.ts" ; import { Foreign , ForeignActions } from "./foreign.ts" ; export interface CreateTableOptions { createIfNotExists ? : boolean ; } /**
 * The table builder
 */ export class TableBuilder { private options : Required < CreateTableOptions > ; private columns : ( ColumnBuilder | string ) [ ] = [ ] ; private extras : string [ ] = [ ] ; constructor ( /** Table name on the database */ private tableName , /** The database adapter */ private adapter , /** Other options */ options ? ) { this . options = Object . assign ( { } , { createIfNotExists : false } , options ) ; } /**
     * Add an auto incremented primary key called `id`
     */ public id ( ) { return this . bigIncrements ( "id" ) . primary ( ) ; } param name public increments ( name ) { const column = new ColumnBuilder ( name , "increments" ) ; this . columns . push ( column ) ; return column ; } param name public bigIncrements ( name ) { const column = new ColumnBuilder ( name , "bigIncrements" ) ; this . columns . push ( column ) ; return column ; } param name public smallIncrements ( name ) { const column = new ColumnBuilder ( name , "smallIncrements" ) ; this . columns . push ( column ) ; return column ; } param name public varchar ( name , length ? ) { const column = new ColumnBuilder ( name , "varchar" , length ) ; this . columns . push ( column ) ; return column ; } param name public text ( name ) { const column = new ColumnBuilder ( name , "text" ) ; this . columns . push ( column ) ; return column ; } param name public integer ( name ) { const column = new ColumnBuilder ( name , "integer" ) ; this . columns . push ( column ) ; return column ; } param name public bigInteger ( name ) { const column = new ColumnBuilder ( name , "bigInteger" ) ; this . columns . push ( column ) ; return column ; } param name public smallInteger ( name ) { const column = new ColumnBuilder ( name , "smallInteger" ) ; this . columns . push ( column ) ; return column ; } param name public datetime ( name ) { const column = new ColumnBuilder ( name , "datetime" ) ; this . columns . push ( column ) ; return column ; } param name public date ( name ) { const column = new ColumnBuilder ( name , "date" ) ; this . columns . push ( column ) ; return column ; } param name public timestamps ( ) { const createdAt = new ColumnBuilder ( "created_at" , "datetime" ) ; const updatedAt = new ColumnBuilder ( "updated_at" , "datetime" ) ; this . columns = this . columns . concat ( createdAt , updatedAt ) ; return [ createdAt , updatedAt ] ; } param name public boolean ( name ) { const column = new ColumnBuilder ( name , "boolean" ) ; this . columns . push ( column ) ; return column ; } param sql public custom ( sql ) { this . columns . push ( sql ) ; } param name public foreignId ( name , tableName , options ? ) { let column ; if ( this . adapter . dialect === "sqlite" ) { column = this . integer ( name ) ; } else { column = this . bigInteger ( name ) ; } this . extras . push ( new Foreign ( { ... options , referencedTableName : tableName , referencedColumns : [ "id" ] , columns : [ name ] } ) . toSQL ( this . adapter . dialect ) ) ; return column ; } /**
     * Generate SQL statement for creating the table
     */ public toSQL ( ) { const sql = [ `CREATE TABLE` ] ; if ( this . options . createIfNotExists ) { sql . push ( "IF NOT EXISTS" ) ; } sql . push ( quote ( this . tableName , this . adapter . dialect ) ) ; const columns = this . columns . map ( ( column ) : string => { return column instanceof ColumnBuilder ? column . toSQL ( this . adapter . dialect ) : column ; } ) ; for ( const extraQuery of this . extras ) { columns . push ( extraQuery ) ; } sql . push ( `(${ [ ... columns ] . join ( ", " ) })` ) ; return sql . join ( " " ) + ";" ; } /**
     * Execute the SQL query
     */ public async execute ( ) { await this . adapter . query ( this . toSQL ( ) ) ; } }