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.
135 lines
4.0 KiB
135 lines
4.0 KiB
import ConnectionMutable from "./ConnectionMutable.ts";
|
|
import {Type} from "../../db/types.ts";
|
|
import {Collection} from "../../../../lib/src/collection/Collection.ts";
|
|
import {MalformedSQLGrammarError} from "./Select.ts";
|
|
|
|
export interface ColumnDefinition {
|
|
with_name: string,
|
|
with_type: Type,
|
|
type_size?: string | number,
|
|
null: boolean,
|
|
as_primary_key: boolean,
|
|
with_default?: string,
|
|
sql: (level: number) => string,
|
|
check_expression?: string,
|
|
check_no_inherit: boolean,
|
|
}
|
|
|
|
export class ColumnFluency implements ColumnDefinition {
|
|
public with_name: string = ''
|
|
public with_type: Type = Type.varchar
|
|
public null: boolean = false
|
|
public as_primary_key: boolean = false
|
|
public with_default?: string
|
|
public type_size?: string | number
|
|
public check_expression?: string
|
|
public check_no_inherit: boolean = false
|
|
|
|
public clone() {
|
|
const col = new ColumnFluency()
|
|
col.with_name = this.with_name
|
|
col.with_type = this.with_type
|
|
col.null = this.null
|
|
col.as_primary_key = this.as_primary_key
|
|
col.with_default = this.with_default
|
|
col.type_size = this.type_size
|
|
col.check_expression = this.check_expression
|
|
col.check_no_inherit = this.check_no_inherit
|
|
return col
|
|
}
|
|
|
|
public name(name: string): this {
|
|
this.with_name = name
|
|
return this
|
|
}
|
|
|
|
public type(type: Type, size?: string | number): this {
|
|
this.with_type = type
|
|
if ( size ) this.type_size = size
|
|
return this
|
|
}
|
|
|
|
public nullable() {
|
|
this.null = true
|
|
return this
|
|
}
|
|
|
|
public primary_key() {
|
|
this.as_primary_key = true
|
|
return this
|
|
}
|
|
|
|
public default(val: string) {
|
|
this.with_default = val
|
|
}
|
|
|
|
public check(expression: string, inherit: boolean = true): this {
|
|
this.check_expression = expression
|
|
this.check_no_inherit = !inherit
|
|
return this
|
|
}
|
|
|
|
public sql(level: number = 0): string {
|
|
const indent = Array(level).fill(' ').join('')
|
|
|
|
const parts = []
|
|
if ( this.null ) parts.push('NULL')
|
|
else parts.push('NOT NULL')
|
|
if ( this.as_primary_key ) parts.push('PRIMARY KEY')
|
|
if ( this.with_default ) parts.push(`DEFAULT ${this.with_default}`)
|
|
if ( this.check_expression ) {
|
|
parts.push(`CHECK (${this.check_expression})${this.check_no_inherit ? ' NO INHERIT' : ''}`)
|
|
}
|
|
|
|
return `${indent}${this.with_name} ${this.with_type}${this.type_size ? '('+this.type_size+')' : ''}${parts.length > 0 ? ' '+parts.join(' ') : ''}`
|
|
}
|
|
}
|
|
|
|
export type FluencyFunction = (col: ColumnFluency) => any
|
|
|
|
export class CreateTable<T> extends ConnectionMutable<T> {
|
|
protected _name?: string
|
|
protected _column_defs: Collection<ColumnDefinition> = new Collection<ColumnDefinition>()
|
|
|
|
constructor(name?: string) {
|
|
super()
|
|
if ( name ) this._name = name
|
|
}
|
|
|
|
sql(level: number = 0): string {
|
|
const indent = Array(level).fill(' ').join('')
|
|
|
|
if ( !this._name ) {
|
|
throw new MalformedSQLGrammarError(`Missing required table name for create statement.`)
|
|
}
|
|
|
|
const column_sql = this._column_defs.map(x => `${indent}${x.sql(level + 1)}`)
|
|
|
|
return [
|
|
`CREATE TABLE ${this._name} (`,
|
|
column_sql.join(`,\n${indent}`),
|
|
')'
|
|
].filter(x => String(x).trim()).join(`\n${indent}`)
|
|
}
|
|
|
|
name(name: string): this {
|
|
this._name = name
|
|
return this
|
|
}
|
|
|
|
column(name_or_fluency_fn: string | FluencyFunction, type?: Type, type_size?: string | number): this {
|
|
const col = new ColumnFluency()
|
|
|
|
if ( typeof name_or_fluency_fn === 'string' ) {
|
|
if ( !type ) throw new MalformedSQLGrammarError(`Missing type for column: ${name_or_fluency_fn}`)
|
|
col.name(name_or_fluency_fn)
|
|
.type(type, type_size)
|
|
} else {
|
|
name_or_fluency_fn(col)
|
|
}
|
|
|
|
this._column_defs.push(col)
|
|
return this
|
|
}
|
|
}
|