rename klo to ktx

This commit is contained in:
Andrey Avtomonov 2026-05-10 23:51:24 +02:00
parent 1a42152e6f
commit 3ce510b55b
704 changed files with 10205 additions and 10255 deletions

View file

@ -1,10 +1,10 @@
import { describe, expect, it, vi } from 'vitest';
import {
createPostgresLiveDatabaseIntrospection,
isKloPostgresConnectionConfig,
KloPostgresScanConnector,
isKtxPostgresConnectionConfig,
KtxPostgresScanConnector,
postgresPoolConfigFromConfig,
type KloPostgresPoolFactory,
type KtxPostgresPoolFactory,
} from './index.js';
interface FakeQueryResult {
@ -12,7 +12,7 @@ interface FakeQueryResult {
fields?: Array<{ name: string; dataTypeID: number }>;
}
function fakePoolFactory(results: Map<string, FakeQueryResult>): KloPostgresPoolFactory {
function fakePoolFactory(results: Map<string, FakeQueryResult>): KtxPostgresPoolFactory {
const query = vi.fn(async (sql: string, params?: unknown[]) => {
const normalized = sql.replace(/\s+/g, ' ').trim();
for (const [key, value] of results.entries()) {
@ -100,11 +100,11 @@ function metadataResults(): Map<string, FakeQueryResult> {
]);
}
describe('KloPostgresScanConnector', () => {
describe('KtxPostgresScanConnector', () => {
it('resolves configuration safely', () => {
expect(isKloPostgresConnectionConfig({ driver: 'postgres', url: 'env:DATABASE_URL', readonly: true })).toBe(true);
expect(isKloPostgresConnectionConfig({ driver: 'postgresql', host: 'db', database: 'analytics' })).toBe(true);
expect(isKloPostgresConnectionConfig({ driver: 'mysql', host: 'db' })).toBe(false);
expect(isKtxPostgresConnectionConfig({ driver: 'postgres', url: 'env:DATABASE_URL', readonly: true })).toBe(true);
expect(isKtxPostgresConnectionConfig({ driver: 'postgresql', host: 'db', database: 'analytics' })).toBe(true);
expect(isKtxPostgresConnectionConfig({ driver: 'mysql', host: 'db' })).toBe(false);
expect(
postgresPoolConfigFromConfig({
connectionId: 'warehouse',
@ -138,7 +138,7 @@ describe('KloPostgresScanConnector', () => {
});
it('introspects schemas, tables, views, primary keys, comments, row counts, and foreign keys', async () => {
const connector = new KloPostgresScanConnector({
const connector = new KtxPostgresScanConnector({
connectionId: 'warehouse',
connection: {
driver: 'postgres',
@ -197,7 +197,7 @@ describe('KloPostgresScanConnector', () => {
});
it('runs samples, distinct values, statistics, read-only SQL, and schema listing', async () => {
const connector = new KloPostgresScanConnector({
const connector = new KtxPostgresScanConnector({
connectionId: 'warehouse',
connection: {
driver: 'postgres',
@ -298,7 +298,7 @@ describe('KloPostgresScanConnector', () => {
it('does not end the pool before introspection completes', async () => {
let endCalled = false;
const endAwarePoolFactory: KloPostgresPoolFactory = {
const endAwarePoolFactory: KtxPostgresPoolFactory = {
createPool() {
const inner = fakePoolFactory(metadataResults()).createPool({
max: 1,

View file

@ -1,28 +1,28 @@
import { readFileSync } from 'node:fs';
import { homedir } from 'node:os';
import { resolve } from 'node:path';
import { assertReadOnlySql, limitSqlForExecution } from '@klo/context/connections';
import { assertReadOnlySql, limitSqlForExecution } from '@ktx/context/connections';
import {
createKloConnectorCapabilities,
type KloColumnSampleInput,
type KloColumnSampleResult,
type KloColumnStatsInput,
type KloColumnStatsResult,
type KloQueryResult,
type KloReadOnlyQueryInput,
type KloScanConnector,
type KloScanContext,
type KloScanInput,
type KloSchemaColumn,
type KloSchemaForeignKey,
type KloSchemaSnapshot,
type KloSchemaTable,
type KloTableRef,
type KloTableSampleInput,
type KloTableSampleResult,
} from '@klo/context/scan';
createKtxConnectorCapabilities,
type KtxColumnSampleInput,
type KtxColumnSampleResult,
type KtxColumnStatsInput,
type KtxColumnStatsResult,
type KtxQueryResult,
type KtxReadOnlyQueryInput,
type KtxScanConnector,
type KtxScanContext,
type KtxScanInput,
type KtxSchemaColumn,
type KtxSchemaForeignKey,
type KtxSchemaSnapshot,
type KtxSchemaTable,
type KtxTableRef,
type KtxTableSampleInput,
type KtxTableSampleResult,
} from '@ktx/context/scan';
import { Pool } from 'pg';
import { KloPostgresDialect } from './dialect.js';
import { KtxPostgresDialect } from './dialect.js';
const PG_OID_TYPE_MAP: Record<number, string> = {
16: 'boolean',
@ -45,7 +45,7 @@ const PG_OID_TYPE_MAP: Record<number, string> = {
1016: 'bigint[]',
};
export interface KloPostgresConnectionConfig {
export interface KtxPostgresConnectionConfig {
driver?: string;
host?: string;
port?: number;
@ -62,7 +62,7 @@ export interface KloPostgresConnectionConfig {
[key: string]: unknown;
}
export interface KloPostgresPoolConfig {
export interface KtxPostgresPoolConfig {
host?: string;
port?: number;
database?: string;
@ -76,72 +76,72 @@ export interface KloPostgresPoolConfig {
ssl?: { rejectUnauthorized: boolean };
}
interface KloPostgresQueryResult {
interface KtxPostgresQueryResult {
fields?: Array<{ name: string; dataTypeID: number }>;
rows: Record<string, unknown>[];
}
interface KloPostgresClient {
query(sql: string, params?: unknown[]): Promise<KloPostgresQueryResult>;
interface KtxPostgresClient {
query(sql: string, params?: unknown[]): Promise<KtxPostgresQueryResult>;
release(): void;
}
interface KloPostgresPool {
connect(): Promise<KloPostgresClient>;
interface KtxPostgresPool {
connect(): Promise<KtxPostgresClient>;
end(): Promise<void>;
}
export interface KloPostgresPoolFactory {
createPool(config: KloPostgresPoolConfig): KloPostgresPool;
export interface KtxPostgresPoolFactory {
createPool(config: KtxPostgresPoolConfig): KtxPostgresPool;
}
interface KloPostgresResolvedEndpoint {
interface KtxPostgresResolvedEndpoint {
host: string;
port: number;
close?: () => Promise<void>;
}
export interface KloPostgresEndpointResolver {
export interface KtxPostgresEndpointResolver {
resolve(input: {
host: string;
port: number;
connection: KloPostgresConnectionConfig;
}): Promise<KloPostgresResolvedEndpoint>;
connection: KtxPostgresConnectionConfig;
}): Promise<KtxPostgresResolvedEndpoint>;
}
export interface KloPostgresScanConnectorOptions {
export interface KtxPostgresScanConnectorOptions {
connectionId: string;
connection: KloPostgresConnectionConfig | undefined;
poolFactory?: KloPostgresPoolFactory;
endpointResolver?: KloPostgresEndpointResolver;
connection: KtxPostgresConnectionConfig | undefined;
poolFactory?: KtxPostgresPoolFactory;
endpointResolver?: KtxPostgresEndpointResolver;
env?: NodeJS.ProcessEnv;
now?: () => Date;
}
export interface KloPostgresReadOnlyQueryInput extends KloReadOnlyQueryInput {
export interface KtxPostgresReadOnlyQueryInput extends KtxReadOnlyQueryInput {
params?: Record<string, unknown> | unknown[];
}
export interface KloPostgresColumnDistinctValuesOptions {
export interface KtxPostgresColumnDistinctValuesOptions {
maxCardinality: number;
limit: number;
sampleSize?: number;
}
export interface KloPostgresColumnDistinctValuesResult {
export interface KtxPostgresColumnDistinctValuesResult {
values: string[] | null;
cardinality: number;
}
export interface KloPostgresColumnStatisticsResult {
export interface KtxPostgresColumnStatisticsResult {
cardinalityByColumn: Map<string, number>;
}
export interface KloPostgresTableSampleResult extends KloTableSampleResult {
export interface KtxPostgresTableSampleResult extends KtxTableSampleResult {
headerTypes?: string[];
}
type PostgresTableRef = Pick<KloTableRef, 'name'> & Partial<Pick<KloTableRef, 'catalog' | 'db'>>;
type PostgresTableRef = Pick<KtxTableRef, 'name'> & Partial<Pick<KtxTableRef, 'catalog' | 'db'>>;
interface PostgresTableRow {
table_name: string;
@ -190,8 +190,8 @@ interface PostgresStatsRow {
estimated_cardinality: unknown;
}
class DefaultPostgresPoolFactory implements KloPostgresPoolFactory {
createPool(config: KloPostgresPoolConfig): KloPostgresPool {
class DefaultPostgresPoolFactory implements KtxPostgresPoolFactory {
createPool(config: KtxPostgresPoolConfig): KtxPostgresPool {
return new Pool(config);
}
}
@ -216,7 +216,7 @@ function primaryKeyMap(rows: PostgresPrimaryKeyRow[]): Map<string, Set<string>>
return grouped;
}
function queryRows(result: KloPostgresQueryResult): unknown[][] {
function queryRows(result: KtxPostgresQueryResult): unknown[][] {
const headers = (result.fields ?? []).map((field) => field.name);
return result.rows.map((row) => headers.map((header) => row[header]));
}
@ -227,8 +227,8 @@ function finiteNumber(value: unknown): number | null {
}
function stringConfigValue(
connection: KloPostgresConnectionConfig | undefined,
key: keyof KloPostgresConnectionConfig,
connection: KtxPostgresConnectionConfig | undefined,
key: keyof KtxPostgresConnectionConfig,
env: NodeJS.ProcessEnv,
): string | undefined {
const value = connection?.[key];
@ -251,7 +251,7 @@ function numberValue(value: unknown): number | undefined {
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
}
function parsePostgresUrl(url: string): Partial<KloPostgresConnectionConfig> {
function parsePostgresUrl(url: string): Partial<KtxPostgresConnectionConfig> {
const parsed = new URL(url);
return {
host: parsed.hostname,
@ -262,29 +262,29 @@ function parsePostgresUrl(url: string): Partial<KloPostgresConnectionConfig> {
};
}
function schemasFromConnection(connection: KloPostgresConnectionConfig): string[] {
function schemasFromConnection(connection: KtxPostgresConnectionConfig): string[] {
if (Array.isArray(connection.schemas) && connection.schemas.length > 0) {
return connection.schemas.filter((schema): schema is string => typeof schema === 'string' && schema.length > 0);
}
return typeof connection.schema === 'string' && connection.schema.length > 0 ? [connection.schema] : ['public'];
}
function searchPathSchemasFromConnection(connection: KloPostgresConnectionConfig): string[] {
function searchPathSchemasFromConnection(connection: KtxPostgresConnectionConfig): string[] {
const schemas = schemasFromConnection(connection);
return schemas.includes('public') ? schemas : [...schemas, 'public'];
}
export function isKloPostgresConnectionConfig(connection: KloPostgresConnectionConfig | undefined): boolean {
export function isKtxPostgresConnectionConfig(connection: KtxPostgresConnectionConfig | undefined): boolean {
const driver = String(connection?.driver ?? '').toLowerCase();
return driver === 'postgres' || driver === 'postgresql';
}
export function postgresPoolConfigFromConfig(input: {
connectionId: string;
connection: KloPostgresConnectionConfig | undefined;
connection: KtxPostgresConnectionConfig | undefined;
env?: NodeJS.ProcessEnv;
}): KloPostgresPoolConfig {
if (!isKloPostgresConnectionConfig(input.connection)) {
}): KtxPostgresPoolConfig {
if (!isKtxPostgresConnectionConfig(input.connection)) {
throw new Error(`Native PostgreSQL connector cannot run driver "${input.connection?.driver ?? 'unknown'}"`);
}
if (input.connection?.readonly !== true) {
@ -294,7 +294,7 @@ export function postgresPoolConfigFromConfig(input: {
const env = input.env ?? process.env;
const referencedUrl = stringConfigValue(input.connection, 'url', env);
const urlConfig = referencedUrl ? parsePostgresUrl(referencedUrl) : {};
const merged: KloPostgresConnectionConfig = { ...urlConfig, ...input.connection };
const merged: KtxPostgresConnectionConfig = { ...urlConfig, ...input.connection };
const host = stringConfigValue(merged, 'host', env);
const database = stringConfigValue(merged, 'database', env);
const user = stringConfigValue(merged, 'username', env) ?? stringConfigValue(merged, 'user', env);
@ -310,7 +310,7 @@ export function postgresPoolConfigFromConfig(input: {
throw new Error(`Native PostgreSQL connector requires connections.${input.connectionId}.username, user, or url`);
}
const config: KloPostgresPoolConfig = {
const config: KtxPostgresPoolConfig = {
max: 10,
idleTimeoutMillis: 30_000,
connectionTimeoutMillis: 10_000,
@ -328,10 +328,10 @@ export function postgresPoolConfigFromConfig(input: {
return config;
}
export class KloPostgresScanConnector implements KloScanConnector {
export class KtxPostgresScanConnector implements KtxScanConnector {
readonly id: string;
readonly driver = 'postgres' as const;
readonly capabilities = createKloConnectorCapabilities({
readonly capabilities = createKtxConnectorCapabilities({
tableSampling: true,
columnSampling: true,
columnStats: true,
@ -342,16 +342,16 @@ export class KloPostgresScanConnector implements KloScanConnector {
});
private readonly connectionId: string;
private readonly connection: KloPostgresConnectionConfig;
private readonly poolConfig: KloPostgresPoolConfig;
private readonly poolFactory: KloPostgresPoolFactory;
private readonly endpointResolver?: KloPostgresEndpointResolver;
private readonly connection: KtxPostgresConnectionConfig;
private readonly poolConfig: KtxPostgresPoolConfig;
private readonly poolFactory: KtxPostgresPoolFactory;
private readonly endpointResolver?: KtxPostgresEndpointResolver;
private readonly now: () => Date;
private readonly dialect = new KloPostgresDialect();
private pool: KloPostgresPool | null = null;
private resolvedEndpoint: KloPostgresResolvedEndpoint | null = null;
private readonly dialect = new KtxPostgresDialect();
private pool: KtxPostgresPool | null = null;
private resolvedEndpoint: KtxPostgresResolvedEndpoint | null = null;
constructor(options: KloPostgresScanConnectorOptions) {
constructor(options: KtxPostgresScanConnectorOptions) {
this.connectionId = options.connectionId;
this.connection = options.connection ?? {};
this.poolConfig = postgresPoolConfigFromConfig({
@ -374,10 +374,10 @@ export class KloPostgresScanConnector implements KloScanConnector {
}
}
async introspect(input: KloScanInput, _ctx: KloScanContext): Promise<KloSchemaSnapshot> {
async introspect(input: KtxScanInput, _ctx: KtxScanContext): Promise<KtxSchemaSnapshot> {
this.assertConnection(input.connectionId);
const schemas = schemasFromConnection(this.connection);
const allTables: KloSchemaTable[] = [];
const allTables: KtxSchemaTable[] = [];
for (const schema of schemas) {
const tables = await this.loadSchemaTables(schema);
allTables.push(...tables);
@ -398,7 +398,7 @@ export class KloPostgresScanConnector implements KloScanConnector {
};
}
async sampleTable(input: KloTableSampleInput, _ctx: KloScanContext): Promise<KloPostgresTableSampleResult> {
async sampleTable(input: KtxTableSampleInput, _ctx: KtxScanContext): Promise<KtxPostgresTableSampleResult> {
this.assertConnection(input.connectionId);
const result = await this.query(this.dialect.generateSampleQuery(this.qTableName(input.table), input.limit, input.columns));
return {
@ -409,7 +409,7 @@ export class KloPostgresScanConnector implements KloScanConnector {
};
}
async sampleColumn(input: KloColumnSampleInput, _ctx: KloScanContext): Promise<KloColumnSampleResult> {
async sampleColumn(input: KtxColumnSampleInput, _ctx: KtxScanContext): Promise<KtxColumnSampleResult> {
this.assertConnection(input.connectionId);
const result = await this.query(
this.dialect.generateColumnSampleQuery(this.qTableName(input.table), input.column, input.limit),
@ -418,7 +418,7 @@ export class KloPostgresScanConnector implements KloScanConnector {
return { values, nullCount: null, distinctCount: null };
}
async columnStats(input: KloColumnStatsInput, _ctx: KloScanContext): Promise<KloColumnStatsResult | null> {
async columnStats(input: KtxColumnStatsInput, _ctx: KtxScanContext): Promise<KtxColumnStatsResult | null> {
const stats = await this.getColumnStatistics(input.table);
const value = stats?.cardinalityByColumn.get(input.column);
return value === undefined
@ -426,7 +426,7 @@ export class KloPostgresScanConnector implements KloScanConnector {
: { min: null, max: null, average: null, nullCount: null, distinctCount: value };
}
async executeReadOnly(input: KloPostgresReadOnlyQueryInput, _ctx: KloScanContext): Promise<KloQueryResult> {
async executeReadOnly(input: KtxPostgresReadOnlyQueryInput, _ctx: KtxScanContext): Promise<KtxQueryResult> {
this.assertConnection(input.connectionId);
const limitedSql = limitSqlForExecution(assertReadOnlySql(input.sql), input.maxRows);
const prepared = Array.isArray(input.params)
@ -437,10 +437,10 @@ export class KloPostgresScanConnector implements KloScanConnector {
}
async getColumnDistinctValues(
table: KloTableRef,
table: KtxTableRef,
columnName: string,
options: KloPostgresColumnDistinctValuesOptions,
): Promise<KloPostgresColumnDistinctValuesResult | null> {
options: KtxPostgresColumnDistinctValuesOptions,
): Promise<KtxPostgresColumnDistinctValuesResult | null> {
const sampleSize = options.sampleSize ?? 10000;
const tableName = this.qTableName(table);
const quotedColumn = this.dialect.quoteIdentifier(columnName);
@ -466,7 +466,7 @@ export class KloPostgresScanConnector implements KloScanConnector {
};
}
async getColumnStatistics(table: KloTableRef): Promise<KloPostgresColumnStatisticsResult | null> {
async getColumnStatistics(table: KtxTableRef): Promise<KtxPostgresColumnStatisticsResult | null> {
const schema = table.db ?? schemasFromConnection(this.connection)[0] ?? 'public';
const sql = this.dialect.generateColumnStatisticsQuery(schema, table.name);
if (!sql) {
@ -522,7 +522,7 @@ export class KloPostgresScanConnector implements KloScanConnector {
}
}
private async loadSchemaTables(schema: string): Promise<KloSchemaTable[]> {
private async loadSchemaTables(schema: string): Promise<KtxSchemaTable[]> {
const tables = await this.queryRaw<PostgresTableRow>(
`
SELECT
@ -617,7 +617,7 @@ export class KloPostgresScanConnector implements KloScanConnector {
columns: PostgresColumnRow[],
primaryKeys: Set<string>,
foreignKeys: PostgresForeignKeyRow[],
): KloSchemaTable {
): KtxSchemaTable {
const kind = table.table_kind === 'v' ? 'view' : 'table';
return {
catalog: null,
@ -631,7 +631,7 @@ export class KloPostgresScanConnector implements KloScanConnector {
};
}
private toSchemaColumn(column: PostgresColumnRow, primaryKeys: Set<string>): KloSchemaColumn {
private toSchemaColumn(column: PostgresColumnRow, primaryKeys: Set<string>): KtxSchemaColumn {
return {
name: column.column_name,
nativeType: column.data_type,
@ -643,7 +643,7 @@ export class KloPostgresScanConnector implements KloScanConnector {
};
}
private toSchemaForeignKey(row: PostgresForeignKeyRow): KloSchemaForeignKey {
private toSchemaForeignKey(row: PostgresForeignKeyRow): KtxSchemaForeignKey {
return {
fromColumn: row.column_name,
toCatalog: null,
@ -654,7 +654,7 @@ export class KloPostgresScanConnector implements KloScanConnector {
};
}
private async getPool(): Promise<KloPostgresPool> {
private async getPool(): Promise<KtxPostgresPool> {
if (!this.pool) {
let config = { ...this.poolConfig };
if (this.endpointResolver) {
@ -682,7 +682,7 @@ export class KloPostgresScanConnector implements KloScanConnector {
}
}
private async query(sql: string, params?: Record<string, unknown> | unknown[]): Promise<KloQueryResult> {
private async query(sql: string, params?: Record<string, unknown> | unknown[]): Promise<KtxQueryResult> {
const pool = await this.getPool();
const client = await pool.connect();
try {

View file

@ -1,8 +1,8 @@
import { describe, expect, it } from 'vitest';
import { KloPostgresDialect } from './dialect.js';
import { KtxPostgresDialect } from './dialect.js';
describe('KloPostgresDialect', () => {
const dialect = new KloPostgresDialect();
describe('KtxPostgresDialect', () => {
const dialect = new KtxPostgresDialect();
it('quotes identifiers and formats schema-qualified tables', () => {
expect(dialect.quoteIdentifier('order"items')).toBe('"order""items"');
@ -10,7 +10,7 @@ describe('KloPostgresDialect', () => {
expect(dialect.formatTableName({ catalog: null, db: null, name: 'orders' })).toBe('"orders"');
});
it('maps native PostgreSQL types to KLO dimension types', () => {
it('maps native PostgreSQL types to KTX dimension types', () => {
expect(dialect.mapToDimensionType('timestamp with time zone')).toBe('time');
expect(dialect.mapToDimensionType('numeric(12,2)')).toBe('number');
expect(dialect.mapToDimensionType('uuid')).toBe('string');

View file

@ -1,11 +1,11 @@
import type { KloSchemaDimensionType, KloTableRef } from '@klo/context/scan';
import type { KtxSchemaDimensionType, KtxTableRef } from '@ktx/context/scan';
type PostgresTableNameRef = Pick<KloTableRef, 'name'> & Partial<Pick<KloTableRef, 'catalog' | 'db'>>;
type PostgresTableNameRef = Pick<KtxTableRef, 'name'> & Partial<Pick<KtxTableRef, 'catalog' | 'db'>>;
export class KloPostgresDialect {
export class KtxPostgresDialect {
readonly type = 'postgresql';
private readonly typeMappings: Record<string, KloSchemaDimensionType> = {
private readonly typeMappings: Record<string, KtxSchemaDimensionType> = {
timestamp: 'time',
'timestamp without time zone': 'time',
'timestamp with time zone': 'time',
@ -54,7 +54,7 @@ export class KloPostgresDialect {
return nativeType;
}
mapToDimensionType(nativeType: string): KloSchemaDimensionType {
mapToDimensionType(nativeType: string): KtxSchemaDimensionType {
if (!nativeType) {
return 'string';
}

View file

@ -1,14 +1,14 @@
import { describe, expect, it, vi } from 'vitest';
import { KloPostgresHistoricSqlQueryClient } from './historic-sql-query-client.js';
import type { KloPostgresPoolConfig, KloPostgresPoolFactory } from './connector.js';
import { KtxPostgresHistoricSqlQueryClient } from './historic-sql-query-client.js';
import type { KtxPostgresPoolConfig, KtxPostgresPoolFactory } from './connector.js';
describe('KloPostgresHistoricSqlQueryClient', () => {
describe('KtxPostgresHistoricSqlQueryClient', () => {
it('executes parameterized read-only SQL through the native Postgres connector pool', async () => {
const queryCalls: Array<{ sql: string; params?: unknown[] }> = [];
const release = vi.fn();
const end = vi.fn(async () => {});
const poolFactory: KloPostgresPoolFactory = {
createPool(_config: KloPostgresPoolConfig) {
const poolFactory: KtxPostgresPoolFactory = {
createPool(_config: KtxPostgresPoolConfig) {
return {
async connect() {
return {
@ -26,7 +26,7 @@ describe('KloPostgresHistoricSqlQueryClient', () => {
};
},
};
const client = new KloPostgresHistoricSqlQueryClient({
const client = new KtxPostgresHistoricSqlQueryClient({
connectionId: 'warehouse',
connection: {
driver: 'postgres',

View file

@ -1,15 +1,15 @@
import type { KloPostgresQueryClient } from '@klo/context/ingest';
import { KloPostgresScanConnector, type KloPostgresScanConnectorOptions } from './connector.js';
import type { KtxPostgresQueryClient } from '@ktx/context/ingest';
import { KtxPostgresScanConnector, type KtxPostgresScanConnectorOptions } from './connector.js';
export type KloPostgresHistoricSqlQueryClientOptions = KloPostgresScanConnectorOptions;
export type KtxPostgresHistoricSqlQueryClientOptions = KtxPostgresScanConnectorOptions;
export class KloPostgresHistoricSqlQueryClient implements KloPostgresQueryClient {
export class KtxPostgresHistoricSqlQueryClient implements KtxPostgresQueryClient {
private readonly connectionId: string;
private readonly connector: KloPostgresScanConnector;
private readonly connector: KtxPostgresScanConnector;
constructor(options: KloPostgresHistoricSqlQueryClientOptions) {
constructor(options: KtxPostgresHistoricSqlQueryClientOptions) {
this.connectionId = options.connectionId;
this.connector = new KloPostgresScanConnector(options);
this.connector = new KtxPostgresScanConnector(options);
}
async executeQuery(

View file

@ -1,21 +1,21 @@
export { KloPostgresDialect } from './dialect.js';
export { KtxPostgresDialect } from './dialect.js';
export {
isKloPostgresConnectionConfig,
KloPostgresScanConnector,
isKtxPostgresConnectionConfig,
KtxPostgresScanConnector,
postgresPoolConfigFromConfig,
type KloPostgresColumnDistinctValuesOptions,
type KloPostgresColumnDistinctValuesResult,
type KloPostgresColumnStatisticsResult,
type KloPostgresConnectionConfig,
type KloPostgresEndpointResolver,
type KloPostgresPoolConfig,
type KloPostgresPoolFactory,
type KloPostgresReadOnlyQueryInput,
type KloPostgresScanConnectorOptions,
type KloPostgresTableSampleResult,
type KtxPostgresColumnDistinctValuesOptions,
type KtxPostgresColumnDistinctValuesResult,
type KtxPostgresColumnStatisticsResult,
type KtxPostgresConnectionConfig,
type KtxPostgresEndpointResolver,
type KtxPostgresPoolConfig,
type KtxPostgresPoolFactory,
type KtxPostgresReadOnlyQueryInput,
type KtxPostgresScanConnectorOptions,
type KtxPostgresTableSampleResult,
} from './connector.js';
export {
KloPostgresHistoricSqlQueryClient,
type KloPostgresHistoricSqlQueryClientOptions,
KtxPostgresHistoricSqlQueryClient,
type KtxPostgresHistoricSqlQueryClientOptions,
} from './historic-sql-query-client.js';
export { createPostgresLiveDatabaseIntrospection } from './live-database-introspection.js';

View file

@ -1,16 +1,16 @@
import type { LiveDatabaseIntrospectionPort } from '@klo/context/ingest';
import type { KloProjectConnectionConfig } from '@klo/context/project';
import type { LiveDatabaseIntrospectionPort } from '@ktx/context/ingest';
import type { KtxProjectConnectionConfig } from '@ktx/context/project';
import {
KloPostgresScanConnector,
type KloPostgresConnectionConfig,
type KloPostgresEndpointResolver,
type KloPostgresPoolFactory,
KtxPostgresScanConnector,
type KtxPostgresConnectionConfig,
type KtxPostgresEndpointResolver,
type KtxPostgresPoolFactory,
} from './connector.js';
interface CreatePostgresLiveDatabaseIntrospectionOptions {
connections: Record<string, KloProjectConnectionConfig>;
poolFactory?: KloPostgresPoolFactory;
endpointResolver?: KloPostgresEndpointResolver;
connections: Record<string, KtxProjectConnectionConfig>;
poolFactory?: KtxPostgresPoolFactory;
endpointResolver?: KtxPostgresEndpointResolver;
now?: () => Date;
}
@ -19,8 +19,8 @@ export function createPostgresLiveDatabaseIntrospection(
): LiveDatabaseIntrospectionPort {
return {
async extractSchema(connectionId: string) {
const connection = options.connections[connectionId] as KloPostgresConnectionConfig | undefined;
const connector = new KloPostgresScanConnector({
const connection = options.connections[connectionId] as KtxPostgresConnectionConfig | undefined;
const connector = new KtxPostgresScanConnector({
connectionId,
connection,
poolFactory: options.poolFactory,

View file

@ -1,13 +1,13 @@
import { describe, expect, it } from 'vitest';
describe('@klo/connector-postgres package exports', () => {
describe('@ktx/connector-postgres package exports', () => {
it('exports the connector, dialect, and live-database adapter', async () => {
const connector = await import('./index.js');
expect(connector.KloPostgresDialect).toBeTypeOf('function');
expect(connector.KloPostgresScanConnector).toBeTypeOf('function');
expect(connector.KloPostgresHistoricSqlQueryClient).toBeTypeOf('function');
expect(connector.KtxPostgresDialect).toBeTypeOf('function');
expect(connector.KtxPostgresScanConnector).toBeTypeOf('function');
expect(connector.KtxPostgresHistoricSqlQueryClient).toBeTypeOf('function');
expect(connector.createPostgresLiveDatabaseIntrospection).toBeTypeOf('function');
expect(connector.isKloPostgresConnectionConfig).toBeTypeOf('function');
expect(connector.isKtxPostgresConnectionConfig).toBeTypeOf('function');
expect(connector.postgresPoolConfigFromConfig).toBeTypeOf('function');
});
});