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.

233 lines
8.5 KiB

import AppClass from '../../../../lib/src/lifecycle/AppClass.ts'
import {Connection} from '../../db/Connection.ts'
import {Collection} from '../../../../lib/src/collection/Collection.ts'
import {Table} from './Table.ts'
import {Builder} from '../../builder/Builder.ts'
import {Join} from '../../builder/type/join/Join.ts'
export class Database extends AppClass {
private _table_cache?: Collection<Table>
protected _rename?: string
protected _owner?: string
protected _owner_override?: string
public owner(set?: string) {
if ( set ) {
this._owner_override = set
return this
} else {
return this._owner_override || this._owner
}
}
protected _encoding?: string
protected _encoding_override?: string
public encoding(set?: string) {
if ( set ) {
this._encoding_override = set
return this
} else {
return this._encoding_override || this._encoding
}
}
protected _lc_collate?: string
protected _lc_collate_override?: string
public lc_collate(set?: string) {
if ( set ) {
this._lc_collate_override = set
return this
} else {
return this._lc_collate_override || this._lc_collate
}
}
protected _lc_ctype?: string
protected _lc_ctype_override?: string
public lc_ctype(set?: string) {
if ( set ) {
this._lc_ctype_override = set
return this
} else {
return this._lc_ctype_override || this._lc_ctype
}
}
protected _tablespace?: string
protected _tablespace_override?: string
public tablespace(set?: string) {
if ( set ) {
this._tablespace_override = set
return this
} else {
return this._tablespace_override || this._tablespace
}
}
protected _is_template?: boolean
protected _is_template_override?: boolean
public is_template(set?: boolean) {
if ( typeof set !== 'undefined' ) {
this._is_template_override = set
return this
} else {
return (typeof this._is_template_override !== 'undefined' ? this._is_template_override : this._is_template)
}
}
protected _allow_conn?: boolean
protected _allow_conn_override?: boolean
public allow_conn(set?: boolean) {
if ( typeof set !== 'undefined' ) {
this._allow_conn_override = set
return this
} else {
return (typeof this._allow_conn_override !== 'undefined' ? this._allow_conn_override : this._allow_conn)
}
}
protected _conn_limit?: number
protected _conn_limit_override?: number
public connection_limit(set?: number) {
if ( typeof set !== 'undefined' ) {
this._conn_limit_override = set
} else {
return (typeof this._conn_limit_override !== 'undefined' ? this._conn_limit_override : this._conn_limit)
}
}
constructor(
public readonly connection: Connection,
public readonly name: string,
) { super() }
rename(name: string): this {
this._rename = name
return this
}
async introspect() {
this._table_cache = await this.connection.tables(this.name)
this._table_cache.each((table: Table) => table.set_database(this))
const query = (new Builder).select(
'pg_catalog.pg_get_userbyid(db.datdba) AS owner',
'pg_encoding_to_char(db.encoding) AS encoding_char',
'datcollate',
'datctype',
'tablespace.spcname AS tablespace',
'datistemplate',
'datallowconn',
'datconnlimit'
)
.from('pg_catalog.pg_database', 'db')
.join('pg_catalog.pg_tablespace', 'tablespace', (join: Join) => {
join.whereRaw('db.dattablespace', '=', 'tablespace.oid')
})
.where('db.datname', '=', this.name)
.target_connection(this.connection)
const info: any = (await query.execute()).rows.first()
if ( info ) {
this._owner = info.owner
this._encoding = info.encoding_char
this._lc_collate = info.datcollate
this._lc_ctype = info.datctype
this._tablespace = info.tablespace
this._is_template = info.datistemplate
this._allow_conn = info.datallowconn
this._conn_limit = info.datconnlimit
}
}
async tables(invalidate_cache: boolean = false) {
if ( !this._table_cache || invalidate_cache ) {
this._table_cache = await this.connection.tables(this.name)
this._table_cache.each((table: Table) => table.set_database(this))
}
return this._table_cache
}
async table(name: string, invalidate_cache: boolean = false) {
if ( !this._table_cache || invalidate_cache ) {
this._table_cache = await this.connection.tables(this.name)
this._table_cache.each((table: Table) => table.set_database(this))
}
return this._table_cache.firstWhere('name', '=', name)
}
public is_dirty() {
return (
(this._owner_override && this._owner_override !== this._owner)
|| (this._encoding_override && this._encoding_override !== this._encoding)
|| (this._lc_collate_override && this._lc_collate_override !== this._lc_collate)
|| (this._lc_ctype_override && this._lc_ctype_override !== this._lc_ctype)
|| (this._tablespace_override && this._tablespace_override !== this._tablespace)
|| (typeof this._is_template_override !== 'undefined' && this._is_template_override !== this._is_template)
|| (typeof this._allow_conn_override !== 'undefined' && this._allow_conn_override !== this._allow_conn)
|| (typeof this._conn_limit_override !== 'undefined' && this._conn_limit_override !== this._conn_limit)
|| this._rename
)
}
public async exists() {
return !!(await this.connection.database(this.name))
}
public async save() {
if ( await this.exists() ) {
const query = (new Builder).alter_database().name(this.name)
if ( this._owner_override && this._owner_override !== this._owner ) {
query.owner(this._owner_override)
}
if ( typeof this._allow_conn_override !== 'undefined' && this._allow_conn_override !== this._allow_conn ) {
if ( this._allow_conn_override ) query.allow_connections()
else query.disallow_connections()
}
if ( typeof this._conn_limit_override !== 'undefined' && this._conn_limit_override !== this._conn_limit ) {
query.connection_limit(this._conn_limit_override)
}
if ( typeof this._is_template_override !== 'undefined' && this._is_template_override !== this._is_template ) {
if ( this._is_template_override ) query.as_template()
else query.not_as_template()
}
if ( this._rename ) {
query.rename_to(this._rename)
}
if ( this._owner_override && this._owner_override !== this._owner ) {
query.owner(this._owner_override)
}
if ( this._tablespace_override && this._tablespace_override !== this._tablespace ) {
query.tablespace(this._tablespace_override)
}
if ( query.sql().trim().length < 1 ) return
await query.execute_in_connection(this.connection)
} else {
const query = (new Builder).create_database()
.name(this.name)
if ( this._owner_override ) query.owner(this._owner_override)
if ( this._is_template_override ) query.as_template()
if ( this._encoding_override ) query.encoding(this._encoding_override)
if ( this._lc_ctype_override ) query.lc_collate(this._lc_ctype_override)
if ( this._lc_ctype ) query.lc_ctype(this._lc_ctype)
if ( this._tablespace ) query.tablespace(this._tablespace)
if ( !this._allow_conn_override && typeof this._allow_conn_override !== 'undefined' ) query.disallow_connections()
if ( this._conn_limit_override && typeof this._conn_limit_override !== 'undefined' ) query.connection_limit(this._conn_limit_override)
await query.execute_in_connection(this.connection)
}
}
}