import * as pgLib from "pg"; export declare class ColName { static wrap(val: string): ColName; static unwrap(val: ColName): string; protected dummy: ColName; } export declare class TableName { static wrap(val: string): TableName; static unwrap(val: TableName): string; protected dummy: TableName; } export declare const enum Order { /** * Equivalent to [[AscNullsLast]] */ Asc = 0, /** * Equivalent to [[DescNullsFirst]] */ Desc = 1, AscNullsLast = 2, DescNullsFirst = 3, AscNullsFirst = 4, DescNullsLast = 5 } export declare type MakeTable = { [P in keyof T1]: Col; } & { [P in keyof T2]: Col | DefaultValue; }; export declare class Write { protected dummy: Write; } export declare type MakeCols = { [P in keyof T]: Col; }; /** * Can be used in `insert` and `update` operations, to set the value * of a column to its default value. * * This can only be used on table columns that have been declared as * "default-able" when the table was declared using [[declareTable]]. * * This is like using the `DEFAULT` keyword in SQL. */ export declare function defaultValue(): DefaultValue; /** * The type of [[defaultValue]]. You cannot instantiate values of this. */ export declare class DefaultValue { protected dummy: DefaultValue; } export declare function count(col: Col): Aggr; export declare function avg(col: Col): Aggr; export declare function sum(col: Col): Aggr; export declare function max(col: Col): Aggr; export declare function min(col: Col): Aggr; export declare function inList(lhs: Col, rhs: Col[]): Col; export declare class Aggr { protected dummy: [Aggr, s, a]; } export declare class Inner { protected dummy: [Inner, s]; } export declare type AggrCols = { [P in keyof A]: Aggr, A[P]>; }; export declare type LeftCols = { [P in keyof A]: Col; }; export declare function declareTable(tableName: string, columns: TableDeclareCols): Table; export declare type TableDeclareCols = { [P in keyof T]: [string, (val: string) => T[P]]; }; export declare class Table { readonly tableName: TableName; readonly tableCols: ColInfo[]; protected dummy: [Table, Req, Def]; } export interface ColInfo { name: ColName; propName: string; parser: (val: string) => any; } export declare function nullCol(): Col; export declare function numberCol(val: number): Col; export declare function textCol(str: string): Col; export declare function booleanCol(val: boolean): Col; /** * A database column. A column is often a literal column table, but can also * be an expression over such a column or a constant expression. * * @param s Phantom type parameter. This will never have a concrete type. It * is used only to enforce type safety * * @param a The type of the value that the Column contains */ export declare class Col { protected dummy: [Col, s, a]; } /** * Perform a conditional on a column * * SQL equivalent: `CASE` */ export declare function ifThenElse(if_: Col, then: Col, else_: Col): Col; /** * Applies the given function to the given nullable column where it isn't null, * and returns the given default value where it is. * * @param nullable A nullable column to match against * @param replacement This is the value that will be returned if the nullable column is NULL * @param f This function will be called if the nullable column is not null, and its result will be returned */ export declare function matchNull(nullable: Col, replacement: Col, f: (col: Col) => Col): Col; /** * If the second value is null, return the first value. Otherwise return the * second value. */ export declare function ifNull(replacement: Col, nullable: Col): Col; /** * Update rows of a table * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis * @param pred Which rows should be updated (the WHERE clause) * @param upd A function that returns the new values for a row. * * You may use [[defaultValue]] on "default-able" columns. * * Should have an explicit annotation of the return type, in order to catch excess properties. * See: * @return number of rows updated */ export declare function update(sqlTag: string | undefined, conn: pg.Client, table: Table, pred: (c: MakeCols) => Col, upd: (c: MakeCols) => MakeTable): Promise; /** * Update rows of a table, with a RETURNING clause * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis * @param pred Which rows should be updated (the WHERE clause) * @param upd A function that returns the new values for a row. * * You may use [[defaultValue]] on "default-able" columns. * * Should have an explicit annotation of the return type, in order to catch excess properties. * See: */ export declare function updateReturning(sqlTag: string | undefined, conn: pg.Client, table: Table, pred: (c: MakeCols) => Col, upd: (c: MakeCols) => MakeTable, returning: (c: MakeCols) => MakeCols): Promise; /** * Insert a single row into a table, with a RETURNING clause * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis */ export declare function insertReturning(sqlTag: string | undefined, conn: pg.Client, table: Table, rowValues: MakeTable, returning: (c: MakeCols) => MakeCols): Promise; /** * Insert a single row into a table * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis */ export declare function insert(sqlTag: string | undefined, conn: pg.Client, table: Table, rowValues: MakeTable): Promise; /** * Insert a single row into a table, with an ON CONFLICT DO NOTHING clause, and with a RETURNING clause * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis */ export declare function insertOnConflictDoNothingReturning(sqlTag: string | undefined, conn: pg.Client, table: Table, rowValues: MakeTable, conflictTarget: ConflictTarget, returning: (c: MakeCols) => MakeCols): Promise; /** * Insert a single row into a table, with an ON CONFLICT DO NOTHING clause * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis * @return true if the row was inserted */ export declare function insertOnConflictDoNothing(sqlTag: string | undefined, conn: pg.Client, table: Table, rowValues: MakeTable, conflictTarget: ConflictTarget): Promise; /** * Insert a single row into a table, with an ON CONFLICT DO UPDATE clause, and with a RETURNING clause * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis */ export declare function insertOnConflictDoUpdateReturning(sqlTag: string | undefined, conn: pg.Client, table: Table, rowValues: MakeTable, conflictTarget: ConflictTarget, onConflictPred: (c: MakeCols) => Col, onConflictUpdate: (c: MakeCols) => MakeTable, returning: (c: MakeCols) => MakeCols): Promise; /** * Insert a single row into a table, with an ON CONFLICT DO UPDATE clause * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis * @param onConflictPred Which rows should be updated (the WHERE clause) * * @param onConflictUpdate A function that returns the new values for a row. * * You may use [[defaultValue]] on "default-able" columns. * * Should have an explicit annotation of the return type, in order to catch excess properties. * See: * * @return If a new row was inserted returns true. * * If a conflicting row already existed but was updated returns true. * * If a conflicting row already existed and was not updated returns false. */ export declare function insertOnConflictDoUpdate(sqlTag: string | undefined, conn: pg.Client, table: Table, rowValues: MakeTable, conflictTarget: ConflictTarget, onConflictPred: (c: MakeCols) => Col, onConflictUpdate: (c: MakeCols) => MakeTable): Promise; /** * Insert multiple rows into a table, with a RETURNING clause * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis */ export declare function insertManyReturning(sqlTag: string | undefined, conn: pg.Client, table: Table, rowValues: MakeTable[], returning: (c: MakeCols) => MakeCols): Promise; /** * Insert multiple rows into a table * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis */ export declare function insertMany(sqlTag: string | undefined, conn: pg.Client, table: Table, rowValues: MakeTable[]): Promise; /** * Insert multiple rows into a table, with an ON CONFLICT DO NOTHING clause, and with a RETURNING clause * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis */ export declare function insertManyOnConflictDoNothingReturning(sqlTag: string | undefined, conn: pg.Client, table: Table, rowValues: MakeTable[], conflictTarget: ConflictTarget, returning: (c: MakeCols) => MakeCols): Promise; /** * Insert multiple rows into a table, with an ON CONFLICT DO NOTHING clause * * @return The number of rows inserted */ export declare function insertManyOnConflictDoNothing(sqlTag: string | undefined, conn: pg.Client, table: Table, rowValues: MakeTable[], conflictTarget: ConflictTarget): Promise; /** * Insert multiple rows into a table, with an ON CONFLICT DO UPDATE clause, and with a RETURNING clause * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis */ export declare function insertManyOnConflictDoUpdateReturning(sqlTag: string | undefined, conn: pg.Client, table: Table, rowValues: MakeTable[], conflictTarget: ConflictTarget, onConflictPred: (c: MakeCols) => Col, onConflictUpdate: (c: MakeCols) => MakeTable, returning: (c: MakeCols) => MakeCols): Promise; /** * Insert multiple rows into a table, with an ON CONFLICT DO UPDATE clause * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis * @param onConflictPred Which rows should be updated (the WHERE clause) * * @param onConflictUpdate A function that returns the new values for a row. * * You may use [[defaultValue]] on "default-able" columns. * * Should have an explicit annotation of the return type, in order to catch excess properties. * See: * * @return The number of newly inserted rows + the number of updated rows */ export declare function insertManyOnConflictDoUpdate(sqlTag: string | undefined, conn: pg.Client, table: Table, rowValues: MakeTable[], conflictTarget: ConflictTarget, onConflictPred: (c: MakeCols) => Col, onConflictUpdate: (c: MakeCols) => MakeTable): Promise; /** * Delete rows of a table * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis * @param pred Which rows should be deleted (the WHERE clause) * @return number of rows deleted */ export declare function delete_(sqlTag: string | undefined, conn: pg.Client, table: Table, pred: (c: MakeCols) => Col): Promise; export declare class ConflictTarget { static tableColumns(cols: (keyof Cols)[]): ConflictTarget; protected dummy: [ConflictTarget, Cols]; } export declare namespace pg { type Client = pgLib.Client; /** * Connect to a PostgreSQL database. You should call `closePg` when you are done. * * @param connection A PostgreSQL connection string, such as: * "postgres://myuser:mypassword@localhost:5432/dbname" */ function connectPg(connection: string): Promise; function closePg(conn: Client): Promise; /** * * @param connection See `connectPg` * @param action */ function withPg(connection: string, action: (conn: Client) => Promise): Promise; function query_(conn: Client, queryText: string): Promise; function query(conn: Client, queryText: string, values: any[]): Promise; } /** * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis */ export declare function query(sqlTag: string | undefined, conn: pg.Client, q: (q: Q<{}>) => MakeCols<{}, t>): Promise; /** * Similar to [[query]], but when you are certain that the query will always return * exactly 1 row. * * For example: COUNT(*) style queries * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis */ export declare function queryOne(sqlTag: string | undefined, conn: pg.Client, q: (q: Q<{}>) => MakeCols<{}, t>): Promise; /** * Similar to [[query]], but when you are certain that the query will always return * either 1 row or 0 rows. * * For example: queries that are restricted on some primary key * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis */ export declare function queryOneOrNone(sqlTag: string | undefined, conn: pg.Client, q: (q: Q<{}>) => MakeCols<{}, t>): Promise; /** * Perform a query, but stream the results rather than loading them all into * memory. * * After you call this function, you *must* call the `readAllRows` function, and * you must call it while the connection is still open (and don't close the * connection until it completes). * * @param sqlTag Will be injected as a comment into the SQL that is sent to the server. Useful for identifying the query during log analysis and performance analysis * @param rowChunkSize How many rows to read and process during each iteration */ export declare function queryStreaming(sqlTag: string | undefined, conn: pg.Client, q: (q: Q<{}>) => MakeCols<{}, t>, rowChunkSize?: number): Promise>; export declare function restrict(q: Q, expr: Col): void; export declare function groupBy(q: Q>, col: Col, a>): Aggr, a>; export declare function aggregate(q: Q, s: (q: Q>) => AggrCols): MakeCols; export declare function inQuery(lhs: Col, rhs: (q: Q) => Col): Col; /** * Does the subquery have at least one row? * * SQL equivalent: EXISTS * * @param subquery The subquery should return [[arbitrary]] (since the values, * of the resulting rows in unimportant). */ export declare function exists(subquery: (q: Q) => Col): Col; /** * The type of an [[arbitrary]] column */ export declare class Arbitrary { protected dummy: Arbitrary; } /** * An arbitrary column, useful for queries where the values of the returned * rows are not important, such as in [[exists]] queries. */ export declare function arbitrary(): Col; export declare function leftJoin(q: Q, s: (q: Q>) => MakeCols, a>, pred: (p: MakeCols) => Col): LeftCols; export declare function innerJoin(q: Q, s: (q: Q>) => MakeCols, a>, pred: (p: MakeCols) => Col): MakeCols; /** * Explicitly create an inner query. * * Sometimes it's handy, for performance reasons and otherwise, to perform a * subquery and restrict only that query before adding the result of the * query to the result set, instead of first adding the query to the result * set and restricting the whole result set afterwards. */ export declare function inner(q: Q, query: (q: Q>) => MakeCols, a>): MakeCols; /** * Create and filter an inner query, before adding it to the current result * set. * * `suchThat(q, query, p)` * is generally more efficient than * `const x = query(q); restrict(pred(x)); return x;` */ export declare function suchThat(q: Q, query: (q: Q>) => MakeCols, a>, pred: (row: MakeCols, a>) => Col, boolean>): MakeCols; export declare function select(q: Q, table: Table): MakeCols; /** * Query an ad hoc table. Each element in the given list represents one row * in the ad hoc table. */ export declare function selectValues(q: Q, vals: MakeCols[]): MakeCols; export declare function limit(q: Q, from: number, to: number, query: (q: Q>) => MakeCols, a>): MakeCols; export declare function order(q: Q, col: Col, order: Order): void; export declare function distinct(q: Q, query: (q: Q) => MakeCols): MakeCols; export declare class Q { protected dummy: [Q, s]; } /** * Will be thrown during a query, if parsing of a column fails for any of the returned rows */ export declare class ColumnParseError extends Error { readonly query: string; readonly columnValue: string; readonly parseFunction: string; readonly innerError: Error | undefined; protected __proto__: Error; constructor(message: string, query: string, columnValue: string, parseFunction: string, innerError?: Error); } /** * Is the given column null? * * This is like SQL's `IS NULL` check */ export declare function isNull(col: Col): Col; /** * Is the given column not null? * * This is like SQL's `IS NOT NULL` check * * `isNotNull(c)` is equivalent to `not(isNull(c))` */ export declare function isNotNull(col: Col): Col; /** * Boolean negation. * * This is like SQL's `NOT` operator */ export declare function not(col: Col): Col; /** * A shortcut that calls `restrict` comparing two columns for equality. * * `restrictEq(q, x, y)` is equivalent to `restrict(q, e(x, "=", y))` */ export declare function restrictEq(q: Q, lhs: Col, rhs: Col): void; /** * Returns true if the string matches the supplied pattern * * SQL equivalent: `LIKE` * * @param str The string to be matched against * @param pattern The pattern to use. May use special characters '%' and '_' */ export declare function like(str: Col, pattern: string): Col; /** * Returns true if the string matches the supplied pattern * * SQL equivalent: `LIKE` * * @param str The string to be matched against * @param pattern The pattern to use. May use special characters '%' and '_' */ export declare function like(str: Col, pattern: Col): Col; /** * Returns true if the string matches the supplied pattern, using case-insensitive matching * * SQL equivalent: `ILIKE` * * @param str The string to be matched against * @param pattern The pattern to use. May use special characters '%' and '_' */ export declare function ilike(str: Col, pattern: string): Col; /** * Returns true if the string matches the supplied pattern, using case-insensitive matching * * SQL equivalent: `ILIKE` * * @param str The string to be matched against * @param pattern The pattern to use. May use special characters '%' and '_' */ export declare function ilike(str: Col, pattern: Col): Col; export declare function e(lhs: Col, op: "=", rhs: Col): Col; export declare function e(lhs: Col, op: "!=", rhs: Col): Col; export declare function e(lhs: Col, op: ">", rhs: Col): Col; export declare function e(lhs: Col, op: "<", rhs: Col): Col; export declare function e(lhs: Col, op: ">=", rhs: Col): Col; export declare function e(lhs: Col, op: "<=", rhs: Col): Col; export declare function e(lhs: Col, op: "AND", rhs: Col): Col; export declare function e(lhs: Col, op: "OR", rhs: Col): Col; export declare function e(lhs: Col, op: "+", rhs: Col): Col; export declare function e(lhs: Col, op: "-", rhs: Col): Col; export declare function e(lhs: Col, op: "*", rhs: Col): Col; export declare function e(lhs: Col, op: "/", rhs: Col): Col; export declare function e(lhs: Col, op: "||", rhs: Col): Col; /** * Logs generated SQL strings and execution timing metrics */ export declare namespace Debug { function enableDebug(): void; function disableDebug(): void; function debugEnabled(): boolean; class QueryMetrics { protected querySQL_: string; protected stage1BeforeCompileQuery: [number, number]; protected stage2BeforeCompileSql: [number, number]; protected stage3BeforeRunQuery: [number, number]; protected stage4BeforeParseQueryResults: [number, number]; protected stage5End: [number, number]; querySQL(): string; compileQueryTime(): number; compileSqlTime(): number; runQueryTime(): number; parseQueryResultsTime(): number; totalTime(): number; } function getLastQueryMetrics(conn: pg.Client): QueryMetrics; } export declare namespace SqlType { function intParser(val: string): number; function numberParser(val: string): number; function stringParser(val: string): string; function booleanParser(val: string): boolean; } export interface StreamingRows { /** * Read in all of the results, the callback will be called multiple times, * each time with a new batch of results. */ readAllRows(action: (results: T[]) => Promise): Promise; } export declare namespace Unsafe { /** * Perform a runtime cast of a column to a specified SQL type * * @param sqlType The SQL type, such as `BIGINT` */ function unsafeCast(col: Col, sqlType: string, parser: (val: string) => b): Col; /** * A unary operation. Note that the provided function name is spliced directly * into the resulting SQL query. Thus, this function should ONLY be used to * implement well-defined functions that are missing from Zol's standard library, * and NOT in an ad hoc manner during queries. * * @param funName Name of the SQL function * @param col Argument to the function * @param parser Function that parses the raw SQL value into the return type of the function */ function unsafeFun(funName: string, col: Col, parser: (val: string) => b): Col; /** * Like [[unsafeFun]], but with two arguments. * * @param funName Name of the SQL function * @param col1 First argument to the function * @param col2 Second argument to the function * @param parser Function that parses the raw SQL value into the return type of the function */ function unsafeFun2(funName: string, col1: Col, col2: Col, parser: (val: string) => c): Col; /** * Like [[unsafeFun]], but with three arguments. * * @param funName Name of the SQL function * @param col1 First argument to the function * @param col2 Second argument to the function * @param col3 Third argument to the function * @param parser Function that parses the raw SQL value into the return type of the function */ function unsafeFun3(funName: string, col1: Col, col2: Col, col3: Col, parser: (val: string) => d): Col; /** * Like [[unsafeFun]], but with an arbitrary number of arguments. * * @param funName Name of the SQL function * @param cols Arguments to the function * @param parser Function that parses the raw SQL value into the return type of the function */ function unsafeFunN(funName: string, cols: Col[], parser: (val: string) => a): Col; /** * Create a named aggregate function. Like [[unsafeFun]], this function is generally * unsafe and should ONLY be used to implement missing backend-specific * functionality. * * @param funName Name of the SQL function * @param col Argument to the function * @param parser Function that parses the raw SQL value into the return type of the function */ function unsafeAggr(funName: string, col: Col, parser: (val: string) => b): Aggr; function unsafeBinOp(opName: string, lhs: Col, rhs: Col, parser: (val: string) => c): Col; /** * This is very unsafe. Can easily lead to SQL injections if used without care * * @param fragments * @param parser */ function unsafeRaw(fragments: (string | Col)[], parser: (val: string) => a): Col; }