Initial commit - Event Planner application
This commit is contained in:
80
node_modules/kysely/dist/esm/dialect/postgres/postgres-adapter.d.ts
generated
vendored
Normal file
80
node_modules/kysely/dist/esm/dialect/postgres/postgres-adapter.d.ts
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
import type { Kysely } from '../../kysely.js';
|
||||
import { DialectAdapterBase } from '../dialect-adapter-base.js';
|
||||
import type { MigrationLockOptions } from '../dialect-adapter.js';
|
||||
export declare class PostgresAdapter extends DialectAdapterBase {
|
||||
/**
|
||||
* Whether or not this dialect supports transactional DDL.
|
||||
*
|
||||
* If this is true, migrations are executed inside a transaction.
|
||||
*/
|
||||
get supportsTransactionalDdl(): boolean;
|
||||
/**
|
||||
* Whether or not this dialect supports the `returning` in inserts
|
||||
* updates and deletes.
|
||||
*/
|
||||
get supportsReturning(): boolean;
|
||||
/**
|
||||
* This method is used to acquire a lock for the migrations so that
|
||||
* it's not possible for two migration operations to run in parallel.
|
||||
*
|
||||
* Most dialects have explicit locks that can be used, like advisory locks
|
||||
* in PostgreSQL and the get_lock function in MySQL.
|
||||
*
|
||||
* If the dialect doesn't have explicit locks the {@link MigrationLockOptions.lockTable}
|
||||
* created by Kysely can be used instead. You can access it through the `options` object.
|
||||
* The lock table has two columns `id` and `is_locked` and there's only one row in the table
|
||||
* whose id is {@link MigrationLockOptions.lockRowId}. `is_locked` is an integer. Kysely
|
||||
* takes care of creating the lock table and inserting the one single row to it before this
|
||||
* method is executed. If the dialect supports schemas and the user has specified a custom
|
||||
* schema in their migration settings, the options object also contains the schema name in
|
||||
* {@link MigrationLockOptions.lockTableSchema}.
|
||||
*
|
||||
* Here's an example of how you might implement this method for a dialect that doesn't
|
||||
* have explicit locks but supports `FOR UPDATE` row locks and transactional DDL:
|
||||
*
|
||||
* ```ts
|
||||
* import { DialectAdapterBase, type MigrationLockOptions, Kysely } from 'kysely'
|
||||
*
|
||||
* export class MyAdapter extends DialectAdapterBase {
|
||||
* override async acquireMigrationLock(
|
||||
* db: Kysely<any>,
|
||||
* options: MigrationLockOptions
|
||||
* ): Promise<void> {
|
||||
* const queryDb = options.lockTableSchema
|
||||
* ? db.withSchema(options.lockTableSchema)
|
||||
* : db
|
||||
*
|
||||
* // Since our imaginary dialect supports transactional DDL and has
|
||||
* // row locks, we can simply take a row lock here and it will guarantee
|
||||
* // all subsequent calls to this method from other transactions will
|
||||
* // wait until this transaction finishes.
|
||||
* await queryDb
|
||||
* .selectFrom(options.lockTable)
|
||||
* .selectAll()
|
||||
* .where('id', '=', options.lockRowId)
|
||||
* .forUpdate()
|
||||
* .execute()
|
||||
* }
|
||||
*
|
||||
* override async releaseMigrationLock() {
|
||||
* // noop
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* If `supportsTransactionalDdl` is `true` then the `db` passed to this method
|
||||
* is a transaction inside which the migrations will be executed. Otherwise
|
||||
* `db` is a single connection (session) that will be used to execute the
|
||||
* migrations.
|
||||
*/
|
||||
acquireMigrationLock(db: Kysely<any>, _opt: MigrationLockOptions): Promise<void>;
|
||||
/**
|
||||
* Releases the migration lock. See {@link acquireMigrationLock}.
|
||||
*
|
||||
* If `supportsTransactionalDdl` is `true` then the `db` passed to this method
|
||||
* is a transaction inside which the migrations were executed. Otherwise `db`
|
||||
* is a single connection (session) that was used to execute the migrations
|
||||
* and the `acquireMigrationLock` call.
|
||||
*/
|
||||
releaseMigrationLock(_db: Kysely<any>, _opt: MigrationLockOptions): Promise<void>;
|
||||
}
|
||||
22
node_modules/kysely/dist/esm/dialect/postgres/postgres-adapter.js
generated
vendored
Normal file
22
node_modules/kysely/dist/esm/dialect/postgres/postgres-adapter.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
/// <reference types="./postgres-adapter.d.ts" />
|
||||
import { sql } from '../../raw-builder/sql.js';
|
||||
import { DialectAdapterBase } from '../dialect-adapter-base.js';
|
||||
// Random id for our transaction lock.
|
||||
const LOCK_ID = BigInt('3853314791062309107');
|
||||
export class PostgresAdapter extends DialectAdapterBase {
|
||||
get supportsTransactionalDdl() {
|
||||
return true;
|
||||
}
|
||||
get supportsReturning() {
|
||||
return true;
|
||||
}
|
||||
async acquireMigrationLock(db, _opt) {
|
||||
// Acquire a transaction level advisory lock.
|
||||
await sql `select pg_advisory_xact_lock(${sql.lit(LOCK_ID)})`.execute(db);
|
||||
}
|
||||
async releaseMigrationLock(_db, _opt) {
|
||||
// Nothing to do here. `pg_advisory_xact_lock` is automatically released at the
|
||||
// end of the transaction and since `supportsTransactionalDdl` true, we know
|
||||
// the `db` instance passed to acquireMigrationLock is actually a transaction.
|
||||
}
|
||||
}
|
||||
68
node_modules/kysely/dist/esm/dialect/postgres/postgres-dialect-config.d.ts
generated
vendored
Normal file
68
node_modules/kysely/dist/esm/dialect/postgres/postgres-dialect-config.d.ts
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
import type { DatabaseConnection } from '../../driver/database-connection.js';
|
||||
/**
|
||||
* Config for the PostgreSQL dialect.
|
||||
*/
|
||||
export interface PostgresDialectConfig {
|
||||
/**
|
||||
* A postgres Pool instance or a function that returns one.
|
||||
*
|
||||
* If a function is provided, it's called once when the first query is executed.
|
||||
*
|
||||
* https://node-postgres.com/apis/pool
|
||||
*/
|
||||
pool: PostgresPool | (() => Promise<PostgresPool>);
|
||||
/**
|
||||
* https://github.com/brianc/node-postgres/tree/master/packages/pg-cursor
|
||||
*
|
||||
* ```ts
|
||||
* import { PostgresDialect } from 'kysely'
|
||||
* import { Pool } from 'pg'
|
||||
* import Cursor from 'pg-cursor'
|
||||
* // or import * as Cursor from 'pg-cursor'
|
||||
*
|
||||
* new PostgresDialect({
|
||||
* cursor: Cursor,
|
||||
* pool: new Pool('postgres://localhost:5432/mydb')
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
cursor?: PostgresCursorConstructor;
|
||||
/**
|
||||
* Called once for each created connection.
|
||||
*/
|
||||
onCreateConnection?: (connection: DatabaseConnection) => Promise<void>;
|
||||
/**
|
||||
* Called every time a connection is acquired from the pool.
|
||||
*/
|
||||
onReserveConnection?: (connection: DatabaseConnection) => Promise<void>;
|
||||
}
|
||||
/**
|
||||
* This interface is the subset of pg driver's `Pool` class that
|
||||
* kysely needs.
|
||||
*
|
||||
* We don't use the type from `pg` here to not have a dependency to it.
|
||||
*
|
||||
* https://node-postgres.com/apis/pool
|
||||
*/
|
||||
export interface PostgresPool {
|
||||
connect(): Promise<PostgresPoolClient>;
|
||||
end(): Promise<void>;
|
||||
}
|
||||
export interface PostgresPoolClient {
|
||||
query<R>(sql: string, parameters: ReadonlyArray<unknown>): Promise<PostgresQueryResult<R>>;
|
||||
query<R>(cursor: PostgresCursor<R>): PostgresCursor<R>;
|
||||
release(): void;
|
||||
}
|
||||
export interface PostgresCursor<T> {
|
||||
read(rowsCount: number): Promise<T[]>;
|
||||
close(): Promise<void>;
|
||||
}
|
||||
export type PostgresCursorConstructor = new <T>(sql: string, parameters: unknown[]) => PostgresCursor<T>;
|
||||
export interface PostgresQueryResult<R> {
|
||||
command: 'UPDATE' | 'DELETE' | 'INSERT' | 'SELECT' | 'MERGE';
|
||||
rowCount: number;
|
||||
rows: R[];
|
||||
}
|
||||
export interface PostgresStream<T> {
|
||||
[Symbol.asyncIterator](): AsyncIterableIterator<T>;
|
||||
}
|
||||
2
node_modules/kysely/dist/esm/dialect/postgres/postgres-dialect-config.js
generated
vendored
Normal file
2
node_modules/kysely/dist/esm/dialect/postgres/postgres-dialect-config.js
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/// <reference types="./postgres-dialect-config.d.ts" />
|
||||
export {};
|
||||
61
node_modules/kysely/dist/esm/dialect/postgres/postgres-dialect.d.ts
generated
vendored
Normal file
61
node_modules/kysely/dist/esm/dialect/postgres/postgres-dialect.d.ts
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
import type { Driver } from '../../driver/driver.js';
|
||||
import type { Kysely } from '../../kysely.js';
|
||||
import type { QueryCompiler } from '../../query-compiler/query-compiler.js';
|
||||
import type { Dialect } from '../dialect.js';
|
||||
import type { DatabaseIntrospector } from '../database-introspector.js';
|
||||
import type { DialectAdapter } from '../dialect-adapter.js';
|
||||
import type { PostgresDialectConfig } from './postgres-dialect-config.js';
|
||||
/**
|
||||
* PostgreSQL dialect that uses the [pg](https://node-postgres.com/) library.
|
||||
*
|
||||
* The constructor takes an instance of {@link PostgresDialectConfig}.
|
||||
*
|
||||
* ```ts
|
||||
* import { Pool } from 'pg'
|
||||
*
|
||||
* new PostgresDialect({
|
||||
* pool: new Pool({
|
||||
* database: 'some_db',
|
||||
* host: 'localhost',
|
||||
* })
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* If you want the pool to only be created once it's first used, `pool`
|
||||
* can be a function:
|
||||
*
|
||||
* ```ts
|
||||
* import { Pool } from 'pg'
|
||||
*
|
||||
* new PostgresDialect({
|
||||
* pool: async () => new Pool({
|
||||
* database: 'some_db',
|
||||
* host: 'localhost',
|
||||
* })
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
export declare class PostgresDialect implements Dialect {
|
||||
#private;
|
||||
constructor(config: PostgresDialectConfig);
|
||||
/**
|
||||
* Creates a driver for the dialect.
|
||||
*/
|
||||
createDriver(): Driver;
|
||||
/**
|
||||
* Creates a query compiler for the dialect.
|
||||
*/
|
||||
createQueryCompiler(): QueryCompiler;
|
||||
/**
|
||||
* Creates an adapter for the dialect.
|
||||
*/
|
||||
createAdapter(): DialectAdapter;
|
||||
/**
|
||||
* Creates a database introspector that can be used to get database metadata
|
||||
* such as the table names and column names of those tables.
|
||||
*
|
||||
* `db` never has any plugins installed. It's created using
|
||||
* {@link Kysely.withoutPlugins}.
|
||||
*/
|
||||
createIntrospector(db: Kysely<any>): DatabaseIntrospector;
|
||||
}
|
||||
53
node_modules/kysely/dist/esm/dialect/postgres/postgres-dialect.js
generated
vendored
Normal file
53
node_modules/kysely/dist/esm/dialect/postgres/postgres-dialect.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
/// <reference types="./postgres-dialect.d.ts" />
|
||||
import { PostgresDriver } from './postgres-driver.js';
|
||||
import { PostgresIntrospector } from './postgres-introspector.js';
|
||||
import { PostgresQueryCompiler } from './postgres-query-compiler.js';
|
||||
import { PostgresAdapter } from './postgres-adapter.js';
|
||||
/**
|
||||
* PostgreSQL dialect that uses the [pg](https://node-postgres.com/) library.
|
||||
*
|
||||
* The constructor takes an instance of {@link PostgresDialectConfig}.
|
||||
*
|
||||
* ```ts
|
||||
* import { Pool } from 'pg'
|
||||
*
|
||||
* new PostgresDialect({
|
||||
* pool: new Pool({
|
||||
* database: 'some_db',
|
||||
* host: 'localhost',
|
||||
* })
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* If you want the pool to only be created once it's first used, `pool`
|
||||
* can be a function:
|
||||
*
|
||||
* ```ts
|
||||
* import { Pool } from 'pg'
|
||||
*
|
||||
* new PostgresDialect({
|
||||
* pool: async () => new Pool({
|
||||
* database: 'some_db',
|
||||
* host: 'localhost',
|
||||
* })
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
export class PostgresDialect {
|
||||
#config;
|
||||
constructor(config) {
|
||||
this.#config = config;
|
||||
}
|
||||
createDriver() {
|
||||
return new PostgresDriver(this.#config);
|
||||
}
|
||||
createQueryCompiler() {
|
||||
return new PostgresQueryCompiler();
|
||||
}
|
||||
createAdapter() {
|
||||
return new PostgresAdapter();
|
||||
}
|
||||
createIntrospector(db) {
|
||||
return new PostgresIntrospector(db);
|
||||
}
|
||||
}
|
||||
55
node_modules/kysely/dist/esm/dialect/postgres/postgres-driver.d.ts
generated
vendored
Normal file
55
node_modules/kysely/dist/esm/dialect/postgres/postgres-driver.d.ts
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
import type { DatabaseConnection, QueryResult } from '../../driver/database-connection.js';
|
||||
import type { Driver, TransactionSettings } from '../../driver/driver.js';
|
||||
import { CompiledQuery } from '../../query-compiler/compiled-query.js';
|
||||
import type { QueryCompiler } from '../../query-compiler/query-compiler.js';
|
||||
import type { PostgresCursorConstructor, PostgresDialectConfig, PostgresPoolClient } from './postgres-dialect-config.js';
|
||||
declare const PRIVATE_RELEASE_METHOD: unique symbol;
|
||||
export declare class PostgresDriver implements Driver {
|
||||
#private;
|
||||
constructor(config: PostgresDialectConfig);
|
||||
/**
|
||||
* Initializes the driver.
|
||||
*
|
||||
* After calling this method the driver should be usable and `acquireConnection` etc.
|
||||
* methods should be callable.
|
||||
*/
|
||||
init(): Promise<void>;
|
||||
/**
|
||||
* Acquires a new connection from the pool.
|
||||
*/
|
||||
acquireConnection(): Promise<DatabaseConnection>;
|
||||
/**
|
||||
* Begins a transaction.
|
||||
*/
|
||||
beginTransaction(connection: DatabaseConnection, settings: TransactionSettings): Promise<void>;
|
||||
/**
|
||||
* Commits a transaction.
|
||||
*/
|
||||
commitTransaction(connection: DatabaseConnection): Promise<void>;
|
||||
/**
|
||||
* Rolls back a transaction.
|
||||
*/
|
||||
rollbackTransaction(connection: DatabaseConnection): Promise<void>;
|
||||
savepoint(connection: DatabaseConnection, savepointName: string, compileQuery: QueryCompiler['compileQuery']): Promise<void>;
|
||||
rollbackToSavepoint(connection: DatabaseConnection, savepointName: string, compileQuery: QueryCompiler['compileQuery']): Promise<void>;
|
||||
releaseSavepoint(connection: DatabaseConnection, savepointName: string, compileQuery: QueryCompiler['compileQuery']): Promise<void>;
|
||||
/**
|
||||
* Releases a connection back to the pool.
|
||||
*/
|
||||
releaseConnection(connection: PostgresConnection): Promise<void>;
|
||||
/**
|
||||
* Destroys the driver and releases all resources.
|
||||
*/
|
||||
destroy(): Promise<void>;
|
||||
}
|
||||
interface PostgresConnectionOptions {
|
||||
cursor: PostgresCursorConstructor | null;
|
||||
}
|
||||
declare class PostgresConnection implements DatabaseConnection {
|
||||
#private;
|
||||
constructor(client: PostgresPoolClient, options: PostgresConnectionOptions);
|
||||
executeQuery<O>(compiledQuery: CompiledQuery): Promise<QueryResult<O>>;
|
||||
streamQuery<O>(compiledQuery: CompiledQuery, chunkSize: number): AsyncIterableIterator<QueryResult<O>>;
|
||||
[PRIVATE_RELEASE_METHOD](): void;
|
||||
}
|
||||
export {};
|
||||
131
node_modules/kysely/dist/esm/dialect/postgres/postgres-driver.js
generated
vendored
Normal file
131
node_modules/kysely/dist/esm/dialect/postgres/postgres-driver.js
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
/// <reference types="./postgres-driver.d.ts" />
|
||||
import { parseSavepointCommand } from '../../parser/savepoint-parser.js';
|
||||
import { CompiledQuery } from '../../query-compiler/compiled-query.js';
|
||||
import { isFunction, freeze } from '../../util/object-utils.js';
|
||||
import { createQueryId } from '../../util/query-id.js';
|
||||
import { extendStackTrace } from '../../util/stack-trace-utils.js';
|
||||
const PRIVATE_RELEASE_METHOD = Symbol();
|
||||
export class PostgresDriver {
|
||||
#config;
|
||||
#connections = new WeakMap();
|
||||
#pool;
|
||||
constructor(config) {
|
||||
this.#config = freeze({ ...config });
|
||||
}
|
||||
async init() {
|
||||
this.#pool = isFunction(this.#config.pool)
|
||||
? await this.#config.pool()
|
||||
: this.#config.pool;
|
||||
}
|
||||
async acquireConnection() {
|
||||
const client = await this.#pool.connect();
|
||||
let connection = this.#connections.get(client);
|
||||
if (!connection) {
|
||||
connection = new PostgresConnection(client, {
|
||||
cursor: this.#config.cursor ?? null,
|
||||
});
|
||||
this.#connections.set(client, connection);
|
||||
// The driver must take care of calling `onCreateConnection` when a new
|
||||
// connection is created. The `pg` module doesn't provide an async hook
|
||||
// for the connection creation. We need to call the method explicitly.
|
||||
if (this.#config.onCreateConnection) {
|
||||
await this.#config.onCreateConnection(connection);
|
||||
}
|
||||
}
|
||||
if (this.#config.onReserveConnection) {
|
||||
await this.#config.onReserveConnection(connection);
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
async beginTransaction(connection, settings) {
|
||||
if (settings.isolationLevel || settings.accessMode) {
|
||||
let sql = 'start transaction';
|
||||
if (settings.isolationLevel) {
|
||||
sql += ` isolation level ${settings.isolationLevel}`;
|
||||
}
|
||||
if (settings.accessMode) {
|
||||
sql += ` ${settings.accessMode}`;
|
||||
}
|
||||
await connection.executeQuery(CompiledQuery.raw(sql));
|
||||
}
|
||||
else {
|
||||
await connection.executeQuery(CompiledQuery.raw('begin'));
|
||||
}
|
||||
}
|
||||
async commitTransaction(connection) {
|
||||
await connection.executeQuery(CompiledQuery.raw('commit'));
|
||||
}
|
||||
async rollbackTransaction(connection) {
|
||||
await connection.executeQuery(CompiledQuery.raw('rollback'));
|
||||
}
|
||||
async savepoint(connection, savepointName, compileQuery) {
|
||||
await connection.executeQuery(compileQuery(parseSavepointCommand('savepoint', savepointName), createQueryId()));
|
||||
}
|
||||
async rollbackToSavepoint(connection, savepointName, compileQuery) {
|
||||
await connection.executeQuery(compileQuery(parseSavepointCommand('rollback to', savepointName), createQueryId()));
|
||||
}
|
||||
async releaseSavepoint(connection, savepointName, compileQuery) {
|
||||
await connection.executeQuery(compileQuery(parseSavepointCommand('release', savepointName), createQueryId()));
|
||||
}
|
||||
async releaseConnection(connection) {
|
||||
connection[PRIVATE_RELEASE_METHOD]();
|
||||
}
|
||||
async destroy() {
|
||||
if (this.#pool) {
|
||||
const pool = this.#pool;
|
||||
this.#pool = undefined;
|
||||
await pool.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
class PostgresConnection {
|
||||
#client;
|
||||
#options;
|
||||
constructor(client, options) {
|
||||
this.#client = client;
|
||||
this.#options = options;
|
||||
}
|
||||
async executeQuery(compiledQuery) {
|
||||
try {
|
||||
const { command, rowCount, rows } = await this.#client.query(compiledQuery.sql, [...compiledQuery.parameters]);
|
||||
return {
|
||||
numAffectedRows: command === 'INSERT' ||
|
||||
command === 'UPDATE' ||
|
||||
command === 'DELETE' ||
|
||||
command === 'MERGE'
|
||||
? BigInt(rowCount)
|
||||
: undefined,
|
||||
rows: rows ?? [],
|
||||
};
|
||||
}
|
||||
catch (err) {
|
||||
throw extendStackTrace(err, new Error());
|
||||
}
|
||||
}
|
||||
async *streamQuery(compiledQuery, chunkSize) {
|
||||
if (!this.#options.cursor) {
|
||||
throw new Error("'cursor' is not present in your postgres dialect config. It's required to make streaming work in postgres.");
|
||||
}
|
||||
if (!Number.isInteger(chunkSize) || chunkSize <= 0) {
|
||||
throw new Error('chunkSize must be a positive integer');
|
||||
}
|
||||
const cursor = this.#client.query(new this.#options.cursor(compiledQuery.sql, compiledQuery.parameters.slice()));
|
||||
try {
|
||||
while (true) {
|
||||
const rows = await cursor.read(chunkSize);
|
||||
if (rows.length === 0) {
|
||||
break;
|
||||
}
|
||||
yield {
|
||||
rows,
|
||||
};
|
||||
}
|
||||
}
|
||||
finally {
|
||||
await cursor.close();
|
||||
}
|
||||
}
|
||||
[PRIVATE_RELEASE_METHOD]() {
|
||||
this.#client.release();
|
||||
}
|
||||
}
|
||||
20
node_modules/kysely/dist/esm/dialect/postgres/postgres-introspector.d.ts
generated
vendored
Normal file
20
node_modules/kysely/dist/esm/dialect/postgres/postgres-introspector.d.ts
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import type { DatabaseIntrospector, DatabaseMetadata, DatabaseMetadataOptions, SchemaMetadata, TableMetadata } from '../database-introspector.js';
|
||||
import type { Kysely } from '../../kysely.js';
|
||||
export declare class PostgresIntrospector implements DatabaseIntrospector {
|
||||
#private;
|
||||
constructor(db: Kysely<any>);
|
||||
/**
|
||||
* Get schema metadata.
|
||||
*/
|
||||
getSchemas(): Promise<SchemaMetadata[]>;
|
||||
/**
|
||||
* Get tables and views metadata.
|
||||
*/
|
||||
getTables(options?: DatabaseMetadataOptions): Promise<TableMetadata[]>;
|
||||
/**
|
||||
* Get the database metadata such as table and column names.
|
||||
*
|
||||
* @deprecated Use getTables() instead.
|
||||
*/
|
||||
getMetadata(options?: DatabaseMetadataOptions): Promise<DatabaseMetadata>;
|
||||
}
|
||||
97
node_modules/kysely/dist/esm/dialect/postgres/postgres-introspector.js
generated
vendored
Normal file
97
node_modules/kysely/dist/esm/dialect/postgres/postgres-introspector.js
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
/// <reference types="./postgres-introspector.d.ts" />
|
||||
import { DEFAULT_MIGRATION_LOCK_TABLE, DEFAULT_MIGRATION_TABLE, } from '../../migration/migrator.js';
|
||||
import { freeze } from '../../util/object-utils.js';
|
||||
import { sql } from '../../raw-builder/sql.js';
|
||||
export class PostgresIntrospector {
|
||||
#db;
|
||||
constructor(db) {
|
||||
this.#db = db;
|
||||
}
|
||||
async getSchemas() {
|
||||
let rawSchemas = await this.#db
|
||||
.selectFrom('pg_catalog.pg_namespace')
|
||||
.select('nspname')
|
||||
.$castTo()
|
||||
.execute();
|
||||
return rawSchemas.map((it) => ({ name: it.nspname }));
|
||||
}
|
||||
async getTables(options = { withInternalKyselyTables: false }) {
|
||||
let query = this.#db
|
||||
// column
|
||||
.selectFrom('pg_catalog.pg_attribute as a')
|
||||
// table
|
||||
.innerJoin('pg_catalog.pg_class as c', 'a.attrelid', 'c.oid')
|
||||
// table schema
|
||||
.innerJoin('pg_catalog.pg_namespace as ns', 'c.relnamespace', 'ns.oid')
|
||||
// column data type
|
||||
.innerJoin('pg_catalog.pg_type as typ', 'a.atttypid', 'typ.oid')
|
||||
// column data type schema
|
||||
.innerJoin('pg_catalog.pg_namespace as dtns', 'typ.typnamespace', 'dtns.oid')
|
||||
.select([
|
||||
'a.attname as column',
|
||||
'a.attnotnull as not_null',
|
||||
'a.atthasdef as has_default',
|
||||
'c.relname as table',
|
||||
'c.relkind as table_type',
|
||||
'ns.nspname as schema',
|
||||
'typ.typname as type',
|
||||
'dtns.nspname as type_schema',
|
||||
sql `col_description(a.attrelid, a.attnum)`.as('column_description'),
|
||||
sql `pg_get_serial_sequence(quote_ident(ns.nspname) || '.' || quote_ident(c.relname), a.attname)`.as('auto_incrementing'),
|
||||
])
|
||||
.where('c.relkind', 'in', [
|
||||
'r' /*regular table*/,
|
||||
'v' /*view*/,
|
||||
'p' /*partitioned table*/,
|
||||
])
|
||||
.where('ns.nspname', '!~', '^pg_')
|
||||
.where('ns.nspname', '!=', 'information_schema')
|
||||
// Filter out internal cockroachdb schema
|
||||
.where('ns.nspname', '!=', 'crdb_internal')
|
||||
// Only schemas where we are allowed access
|
||||
.where(sql `has_schema_privilege(ns.nspname, 'USAGE')`)
|
||||
// No system columns
|
||||
.where('a.attnum', '>=', 0)
|
||||
.where('a.attisdropped', '!=', true)
|
||||
.orderBy('ns.nspname')
|
||||
.orderBy('c.relname')
|
||||
.orderBy('a.attnum')
|
||||
.$castTo();
|
||||
if (!options.withInternalKyselyTables) {
|
||||
query = query
|
||||
.where('c.relname', '!=', DEFAULT_MIGRATION_TABLE)
|
||||
.where('c.relname', '!=', DEFAULT_MIGRATION_LOCK_TABLE);
|
||||
}
|
||||
const rawColumns = await query.execute();
|
||||
return this.#parseTableMetadata(rawColumns);
|
||||
}
|
||||
async getMetadata(options) {
|
||||
return {
|
||||
tables: await this.getTables(options),
|
||||
};
|
||||
}
|
||||
#parseTableMetadata(columns) {
|
||||
return columns.reduce((tables, it) => {
|
||||
let table = tables.find((tbl) => tbl.name === it.table && tbl.schema === it.schema);
|
||||
if (!table) {
|
||||
table = freeze({
|
||||
name: it.table,
|
||||
isView: it.table_type === 'v',
|
||||
schema: it.schema,
|
||||
columns: [],
|
||||
});
|
||||
tables.push(table);
|
||||
}
|
||||
table.columns.push(freeze({
|
||||
name: it.column,
|
||||
dataType: it.type,
|
||||
dataTypeSchema: it.type_schema,
|
||||
isNullable: !it.not_null,
|
||||
isAutoIncrementing: it.auto_incrementing !== null,
|
||||
hasDefaultValue: it.has_default,
|
||||
comment: it.column_description ?? undefined,
|
||||
}));
|
||||
return tables;
|
||||
}, []);
|
||||
}
|
||||
}
|
||||
4
node_modules/kysely/dist/esm/dialect/postgres/postgres-query-compiler.d.ts
generated
vendored
Normal file
4
node_modules/kysely/dist/esm/dialect/postgres/postgres-query-compiler.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { DefaultQueryCompiler } from '../../query-compiler/default-query-compiler.js';
|
||||
export declare class PostgresQueryCompiler extends DefaultQueryCompiler {
|
||||
protected sanitizeIdentifier(identifier: string): string;
|
||||
}
|
||||
8
node_modules/kysely/dist/esm/dialect/postgres/postgres-query-compiler.js
generated
vendored
Normal file
8
node_modules/kysely/dist/esm/dialect/postgres/postgres-query-compiler.js
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/// <reference types="./postgres-query-compiler.d.ts" />
|
||||
import { DefaultQueryCompiler } from '../../query-compiler/default-query-compiler.js';
|
||||
const ID_WRAP_REGEX = /"/g;
|
||||
export class PostgresQueryCompiler extends DefaultQueryCompiler {
|
||||
sanitizeIdentifier(identifier) {
|
||||
return identifier.replace(ID_WRAP_REGEX, '""');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user