import knex, { Transaction } from 'knex'; import { DbDriver, DbDriverQueryStatementConfig, DbDriverDmlStatementConfig, SerializedRecord, Table, TableManager } from '@proteinjs/db'; import { KnexConfig } from './KnexConfig'; import { Statement } from '@proteinjs/db-query'; /** * Knex driver (configured for MariaDb) for ProteinJs Db */ export declare class KnexDriver implements DbDriver { private static KNEX; /** The per-operation deadline when `KnexConfig.operationDeadlineMs` is unset (see getOperationDeadlineMs). */ private static readonly DEFAULT_OPERATION_DEADLINE_MS; private logger; private config; private knexConfig; getTable: ((name: string) => Table) | undefined; constructor(config: KnexConfig, getTable?: (name: string) => Table); getKnex(): knex; getDbName(): string; createDbIfNotExists(): Promise; /** * Create the named database. MariaDB has no create-with-schema operation (Spanner's * `CreateDatabase.extra_statements`), so passing `ddl` here is an error rather than a quiet * second apply path — load the schema through `TableManager` after creating. */ createDb(name: string, options?: { ddl?: string[]; }): Promise; /** Drop the named database. */ dropDb(name: string): Promise; dbExists(databaseName: string): Promise; start(): Promise; stop(): Promise; private setMaxAllowedPacketSize; getTableManager(): TableManager; /** * MariaDB is case insensitive by default. * If we want to query with case sensitivity, prepend the column name with the `BINARY` keyword. * @returns identifier to be used in SQL statement, may contain modifier if using case sensitivity */ handleCaseSensitivity(tableName: string, columnName: string, caseSensitive: boolean): string; runQuery(generateStatement: (config: DbDriverQueryStatementConfig) => Statement, transaction?: Transaction): Promise; runDml(generateStatement: (config: DbDriverDmlStatementConfig) => Statement, transaction?: Transaction): Promise; /** * Execute a transaction. * @param fn all db operations within this function will be part of this transaction * @returns the return value of the `fn` */ runTransaction(fn: (transaction: Transaction) => Promise): Promise; /** * The deadline every statement runs under — `KnexConfig.operationDeadlineMs`, 60 s when unset — * and the one place the driver reads it: the deadline this reports is the deadline runQuery * enforces (the query layer's timeout, cancelling the statement on the server when it fires). */ getOperationDeadlineMs(): number; /** * The backend refusing a row because a row with the same key is already there: MySQL's * ER_DUP_ENTRY (errno 1062), the `code` on the vendor error this driver rethrows untouched — a * primary-key collision and a unique index's refusal alike. */ isDuplicateKeyError(error: unknown): boolean; /** * The one line a failed statement writes. What is THROWN is the vendor's error itself, untouched * (runQuery rethrows it); this is only what the driver PRINTS of it. * * The vendor error is not safe to print as it is: the query layer rewrites a failed query's * `message` to the SQL with its bindings INTERPOLATED, and the client library's error carries * the same formatted text as `sql` — every bound value of the statement, on any line the error * reaches. So the line carries the SQL text (placeholders only), the parameters DESCRIBED * (describeParams) and a summary of the failure: the error's name, the vendor's codes and the * server's own message (`sqlMessage` — which can itself quote a value, e.g. a colliding key; the * driver prints it as it always has). The vendor error itself, and the values as bound, ride * the line only behind the dev-only switch (KnexLogValues). * * `params` is whatever the statement carried. `Statement` types it as an array, but the query * layer also accepts a bindings dictionary (and wraps anything else as one binding), and * runQuery forwards what it was handed — so nothing here may assume a shape. The line is * written through writeStatementLine: it sits on the way to a `throw`, and must never be the * reason something else is thrown. */ private logFailure; /** * The ONE door a statement's log line is written through — the owner of the rule that writing * a line can NEVER change what the driver throws. A statement line is written on the way to a * `throw`, so whatever goes wrong while building or writing it — a log writer that is down, a * serializer meeting a value it cannot print (a bigint or a throwing `toJSON`, under the values * switch), a helper meeting a shape nobody foresaw — is caught HERE and reported as one FIXED * line that carries nothing of the statement; the caller then throws exactly what it was going * to throw. If the logger itself is what failed, the fixed line fails too and is dropped: * nothing is left to write with. */ private writeStatementLine; /** * A statement's bound parameters as a LOG LINE carries them — the one owner of that form: by * position, the KIND of each value and, for strings, arrays and bytes, its LENGTH. Never a * value: a parameter is row content (a presented token, a credential hash, an address), and a * log line outlives and out-travels the row it came from. The SQL text beside it carries `?` * placeholders only, so position + kind + length is what locates a failure (which parameter was * null, which was oversized) without quoting it. * * The shapes are the query layer's own: positional bindings (an array) are described by * POSITION; a bindings DICTIONARY (a plain object, bound to `:name` placeholders) by entry * NAME; no bindings describe nothing; and anything else — null, a scalar, a Map, a Date — is * what the query layer binds as ONE parameter, so it is described as one. * * TOTAL, for any input: a value that cannot be read is described as `unreadable` * (describeParam), and bindings that cannot even be walked are the one word `unreadable`. */ private describeParams; /** * One bound value, described: its kind, a length for strings, arrays and bytes, null named. The * value is READ in here (`read`), so a read that throws — an accessor, a revoked proxy — is * described as `unreadable` and its neighbours still are described. A length that is not a * number is no length: nothing a value says about itself rides the line but that one number. */ private describeParam; /** The kind of a bound value — a word, never the value. */ private paramKind; /** Whether bindings are a DICTIONARY — a plain object, which the query layer binds by entry name. */ private isDictionary; } //# sourceMappingURL=KnexDriver.d.ts.map