|
|
|
import { Collection } from '../util'
|
|
|
|
import {QuerySafeValue, VectorEscapeValue} from './dialect/SQLDialect'
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A single query row, as an object.
|
|
|
|
*/
|
|
|
|
export type QueryRow = { [key: string]: any }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A valid key on a model.
|
|
|
|
*/
|
|
|
|
export type ModelKey = string | number
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Collection of keys of a set of models.
|
|
|
|
*/
|
|
|
|
export type ModelKeys = ModelKey | ModelKey[] | Collection<ModelKey>
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Interface for the result of a query execution.
|
|
|
|
*/
|
|
|
|
export interface QueryResult {
|
|
|
|
rows: Collection<QueryRow>,
|
|
|
|
rowCount: number,
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SQL operator that is used to join two constraint clauses.
|
|
|
|
*/
|
|
|
|
export type ConstraintConnectionOperator = 'AND' | 'OR' | 'AND NOT' | 'OR NOT'
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SQL operator that appears in a constraint clause.
|
|
|
|
*/
|
|
|
|
export type ConstraintOperator = '&' | '>' | '>=' | '<' | '<=' | '!=' | '<=>' | '%' | '|' | '!' | '~' | '=' | '^' | 'IN' | 'NOT IN' | 'LIKE' | 'BETWEEN' | 'NOT BETWEEN' | 'IS' | 'IS NOT';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Interface for storing the various parts of a single SQL constraint.
|
|
|
|
*/
|
|
|
|
export interface ConstraintItem {
|
|
|
|
field: string,
|
|
|
|
operator: ConstraintOperator,
|
|
|
|
operand: VectorEscapeValue<any>,
|
|
|
|
preop: ConstraintConnectionOperator,
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Interface for storing a group of constraints connected by the given connection operator.
|
|
|
|
*/
|
|
|
|
export interface ConstraintGroup {
|
|
|
|
items: Constraint[],
|
|
|
|
preop: ConstraintConnectionOperator,
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if the given object is a valid ConstraintGroup.
|
|
|
|
* @param what
|
|
|
|
*/
|
|
|
|
export function isConstraintGroup(what: unknown): what is ConstraintGroup {
|
|
|
|
return typeof what === 'object' && Array.isArray((what as any).items) && (what as any).preop
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if the given object is a valid ConstraintItem
|
|
|
|
* @param what
|
|
|
|
*/
|
|
|
|
export function isConstraintItem(what: unknown): what is ConstraintItem {
|
|
|
|
return (
|
|
|
|
typeof what === 'object'
|
|
|
|
&& (what as any).field
|
|
|
|
&& (what as any).operator
|
|
|
|
&& (what as any).operand
|
|
|
|
&& (what as any).preop
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Type alias for something that can be either a single constraint or a group of them.
|
|
|
|
*/
|
|
|
|
export type Constraint = ConstraintItem | ConstraintGroup | QuerySafeValue
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Type alias for an item that refers to a field on a table.
|
|
|
|
*/
|
|
|
|
export type SpecifiedField = string | QuerySafeValue | { field: string | QuerySafeValue, alias: string }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Type alias for an item that refers to a table in a database.
|
|
|
|
*/
|
|
|
|
export type QuerySource = string | QuerySafeValue | { table: string | QuerySafeValue, alias: string }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Possible SQL order-by clause directions.
|
|
|
|
*/
|
|
|
|
export type OrderDirection = 'ASC' | 'DESC' | 'asc' | 'desc'
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Interface for storing the parts of a SQL order-by clause.
|
|
|
|
*/
|
|
|
|
export type OrderStatement = { field: string, direction: OrderDirection }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Database column types.
|
|
|
|
*/
|
|
|
|
export enum FieldType {
|
|
|
|
bigint = 'bigint',
|
|
|
|
int8 = 'bigint',
|
|
|
|
bigserial = 'bigserial',
|
|
|
|
serial8 = 'bigserial',
|
|
|
|
bit = 'bit',
|
|
|
|
bitVarying = 'bit varying',
|
|
|
|
varbit = 'bit varying',
|
|
|
|
boolean = 'boolean',
|
|
|
|
bool = 'boolean',
|
|
|
|
box = 'box',
|
|
|
|
bytea = 'bytea',
|
|
|
|
character = 'character',
|
|
|
|
char = 'character',
|
|
|
|
characterVarying = 'character varying',
|
|
|
|
varchar = 'character varying',
|
|
|
|
cidr = 'cidr',
|
|
|
|
circle = 'circle',
|
|
|
|
date = 'date',
|
|
|
|
doublePrecision = 'double precision',
|
|
|
|
float8 = 'double precision',
|
|
|
|
inet = 'inet',
|
|
|
|
integer = 'integer',
|
|
|
|
int = 'integer',
|
|
|
|
int4 = 'integer',
|
|
|
|
interval = 'interval',
|
|
|
|
json = 'json',
|
|
|
|
line = 'line',
|
|
|
|
lseg = 'lseg',
|
|
|
|
ltree = 'ltree',
|
|
|
|
macaddr = 'macaddr',
|
|
|
|
money = 'money',
|
|
|
|
numeric = 'numeric',
|
|
|
|
decimal = 'numeric',
|
|
|
|
path = 'path',
|
|
|
|
point = 'point',
|
|
|
|
polygon = 'polygon',
|
|
|
|
real = 'real',
|
|
|
|
float4 = 'real',
|
|
|
|
smallint = 'smallint',
|
|
|
|
int2 = 'smallint',
|
|
|
|
smallserial = 'smallserial',
|
|
|
|
serial2 = 'smallserial',
|
|
|
|
serial = 'serial',
|
|
|
|
serial4 = 'serial',
|
|
|
|
text = 'text',
|
|
|
|
time = 'time',
|
|
|
|
timestamp = 'timestamp',
|
|
|
|
tsquery = 'tsquery',
|
|
|
|
tsvector = 'tsvector',
|
|
|
|
txidSnapshot = 'txidSnapshot',
|
|
|
|
uuid = 'uuid',
|
|
|
|
xml = 'xml',
|
|
|
|
other = 'other',
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Given a FieldType, get the inverse (that is, the code-form name).
|
|
|
|
* @example
|
|
|
|
* ```ts
|
|
|
|
* console.log(FieldType.varchar) // => "character varying"
|
|
|
|
* console.log(inverseFieldType(FieldType.varchar)) // => "varchar"
|
|
|
|
* console.log(inverseFieldType('character varying')) // => "varchar"
|
|
|
|
* ```
|
|
|
|
* @param type
|
|
|
|
*/
|
|
|
|
export function inverseFieldType(type: FieldType): string {
|
|
|
|
return ({
|
|
|
|
bigint: 'bigint',
|
|
|
|
bigserial: 'bigserial',
|
|
|
|
bit: 'bit',
|
|
|
|
'bit varying': 'varbit',
|
|
|
|
boolean: 'boolean',
|
|
|
|
box: 'box',
|
|
|
|
bytea: 'bytea',
|
|
|
|
character: 'character',
|
|
|
|
char: 'character',
|
|
|
|
'character varying': 'varchar',
|
|
|
|
cidr: 'cidr',
|
|
|
|
circle: 'circle',
|
|
|
|
date: 'date',
|
|
|
|
'double precision': 'float8',
|
|
|
|
inet: 'inet',
|
|
|
|
integer: 'integer',
|
|
|
|
interval: 'interval',
|
|
|
|
json: 'json',
|
|
|
|
line: 'line',
|
|
|
|
lseg: 'lseg',
|
|
|
|
ltree: 'ltree',
|
|
|
|
macaddr: 'macaddr',
|
|
|
|
money: 'money',
|
|
|
|
numeric: 'numeric',
|
|
|
|
path: 'path',
|
|
|
|
point: 'point',
|
|
|
|
polygon: 'polygon',
|
|
|
|
real: 'real',
|
|
|
|
smallint: 'smallint',
|
|
|
|
smallserial: 'smallserial',
|
|
|
|
serial: 'serial',
|
|
|
|
text: 'text',
|
|
|
|
time: 'time',
|
|
|
|
timestamp: 'timestamp',
|
|
|
|
tsquery: 'tsquery',
|
|
|
|
tsvector: 'tsvector',
|
|
|
|
txidSnapshot: 'txidSnapshot',
|
|
|
|
uuid: 'uuid',
|
|
|
|
xml: 'xml',
|
|
|
|
other: 'other',
|
|
|
|
})[type]
|
|
|
|
}
|