viyv-db-postgres 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/LICENSE +21 -0
  2. package/dist/config.d.ts +37 -0
  3. package/dist/config.d.ts.map +1 -0
  4. package/dist/config.js +15 -0
  5. package/dist/config.js.map +1 -0
  6. package/dist/db.d.ts +9 -0
  7. package/dist/db.d.ts.map +1 -0
  8. package/dist/db.js +13 -0
  9. package/dist/db.js.map +1 -0
  10. package/dist/error-mapper.d.ts +2 -0
  11. package/dist/error-mapper.d.ts.map +1 -0
  12. package/dist/error-mapper.js +24 -0
  13. package/dist/error-mapper.js.map +1 -0
  14. package/dist/index.d.ts +8 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +19 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/logical/cte-builder.d.ts +57 -0
  19. package/dist/logical/cte-builder.d.ts.map +1 -0
  20. package/dist/logical/cte-builder.js +167 -0
  21. package/dist/logical/cte-builder.js.map +1 -0
  22. package/dist/logical/data-ops.d.ts +19 -0
  23. package/dist/logical/data-ops.d.ts.map +1 -0
  24. package/dist/logical/data-ops.js +124 -0
  25. package/dist/logical/data-ops.js.map +1 -0
  26. package/dist/logical/embedding-ops.d.ts +24 -0
  27. package/dist/logical/embedding-ops.d.ts.map +1 -0
  28. package/dist/logical/embedding-ops.js +94 -0
  29. package/dist/logical/embedding-ops.js.map +1 -0
  30. package/dist/logical/migration-ops.d.ts +10 -0
  31. package/dist/logical/migration-ops.d.ts.map +1 -0
  32. package/dist/logical/migration-ops.js +201 -0
  33. package/dist/logical/migration-ops.js.map +1 -0
  34. package/dist/logical/query-ops.d.ts +18 -0
  35. package/dist/logical/query-ops.d.ts.map +1 -0
  36. package/dist/logical/query-ops.js +193 -0
  37. package/dist/logical/query-ops.js.map +1 -0
  38. package/dist/logical/registry.d.ts +27 -0
  39. package/dist/logical/registry.d.ts.map +1 -0
  40. package/dist/logical/registry.js +79 -0
  41. package/dist/logical/registry.js.map +1 -0
  42. package/dist/logical/schema-ops.d.ts +7 -0
  43. package/dist/logical/schema-ops.d.ts.map +1 -0
  44. package/dist/logical/schema-ops.js +311 -0
  45. package/dist/logical/schema-ops.js.map +1 -0
  46. package/dist/logical/sql-parser.d.ts +11 -0
  47. package/dist/logical/sql-parser.d.ts.map +1 -0
  48. package/dist/logical/sql-parser.js +37 -0
  49. package/dist/logical/sql-parser.js.map +1 -0
  50. package/dist/logical/sql-table-refs.d.ts +18 -0
  51. package/dist/logical/sql-table-refs.d.ts.map +1 -0
  52. package/dist/logical/sql-table-refs.js +203 -0
  53. package/dist/logical/sql-table-refs.js.map +1 -0
  54. package/dist/logical/sql-tokenizer.d.ts +20 -0
  55. package/dist/logical/sql-tokenizer.d.ts.map +1 -0
  56. package/dist/logical/sql-tokenizer.js +249 -0
  57. package/dist/logical/sql-tokenizer.js.map +1 -0
  58. package/dist/logical/type-utils.d.ts +11 -0
  59. package/dist/logical/type-utils.d.ts.map +1 -0
  60. package/dist/logical/type-utils.js +42 -0
  61. package/dist/logical/type-utils.js.map +1 -0
  62. package/dist/logical/where-builder.d.ts +6 -0
  63. package/dist/logical/where-builder.d.ts.map +1 -0
  64. package/dist/logical/where-builder.js +20 -0
  65. package/dist/logical/where-builder.js.map +1 -0
  66. package/dist/schema.d.ts +926 -0
  67. package/dist/schema.d.ts.map +1 -0
  68. package/dist/schema.js +78 -0
  69. package/dist/schema.js.map +1 -0
  70. package/dist/services/postgres-service.d.ts +40 -0
  71. package/dist/services/postgres-service.d.ts.map +1 -0
  72. package/dist/services/postgres-service.js +479 -0
  73. package/dist/services/postgres-service.js.map +1 -0
  74. package/dist/services/semantic-search-service.d.ts +16 -0
  75. package/dist/services/semantic-search-service.d.ts.map +1 -0
  76. package/dist/services/semantic-search-service.js +94 -0
  77. package/dist/services/semantic-search-service.js.map +1 -0
  78. package/dist/system-migrations/001_composite_pk.d.ts +4 -0
  79. package/dist/system-migrations/001_composite_pk.d.ts.map +1 -0
  80. package/dist/system-migrations/001_composite_pk.js +23 -0
  81. package/dist/system-migrations/001_composite_pk.js.map +1 -0
  82. package/dist/system-migrations/002_schema_log_index.d.ts +4 -0
  83. package/dist/system-migrations/002_schema_log_index.d.ts.map +1 -0
  84. package/dist/system-migrations/002_schema_log_index.js +13 -0
  85. package/dist/system-migrations/002_schema_log_index.js.map +1 -0
  86. package/dist/system-migrations/index.d.ts +9 -0
  87. package/dist/system-migrations/index.d.ts.map +1 -0
  88. package/dist/system-migrations/index.js +9 -0
  89. package/dist/system-migrations/index.js.map +1 -0
  90. package/dist/system-migrations/types.d.ts +18 -0
  91. package/dist/system-migrations/types.d.ts.map +1 -0
  92. package/dist/system-migrations/types.js +28 -0
  93. package/dist/system-migrations/types.js.map +1 -0
  94. package/dist/system-migrations.d.ts +25 -0
  95. package/dist/system-migrations.d.ts.map +1 -0
  96. package/dist/system-migrations.js +66 -0
  97. package/dist/system-migrations.js.map +1 -0
  98. package/package.json +44 -0
@@ -0,0 +1,94 @@
1
+ import { sql } from 'drizzle-orm';
2
+ export async function initializeEmbeddingTable(db, dimensions) {
3
+ await db.execute(sql `CREATE EXTENSION IF NOT EXISTS vector`);
4
+ // vector(N) must be a literal in DDL — dimensions comes from config, not user input
5
+ await db.execute(sql.raw(`
6
+ CREATE TABLE IF NOT EXISTS _viyv_embeddings (
7
+ row_id UUID NOT NULL,
8
+ tenant_id TEXT NOT NULL,
9
+ table_id UUID NOT NULL REFERENCES _viyv_logical_tables(id) ON DELETE CASCADE,
10
+ embedding vector(${Number(dimensions)}) NOT NULL,
11
+ embedding_text TEXT NOT NULL DEFAULT '',
12
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
13
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
14
+ PRIMARY KEY (row_id, tenant_id)
15
+ )
16
+ `));
17
+ await db.execute(sql `
18
+ CREATE INDEX IF NOT EXISTS idx_viyv_embeddings_hnsw
19
+ ON _viyv_embeddings USING hnsw (embedding vector_cosine_ops)
20
+ `);
21
+ await db.execute(sql `
22
+ CREATE INDEX IF NOT EXISTS idx_viyv_embeddings_tenant
23
+ ON _viyv_embeddings (tenant_id, table_id)
24
+ `);
25
+ }
26
+ export async function storeEmbeddings(db, tenantId, entries) {
27
+ if (entries.length === 0)
28
+ return;
29
+ const batchSize = 500;
30
+ for (let i = 0; i < entries.length; i += batchSize) {
31
+ const batch = entries.slice(i, i + batchSize);
32
+ const values = batch.map((e) => sql `(${e.rowId}::uuid, ${tenantId}, ${e.tableId}::uuid,
33
+ ${`[${e.embedding.join(',')}]`}::vector, ${e.embeddingText}, now())`);
34
+ await db.execute(sql `
35
+ INSERT INTO _viyv_embeddings
36
+ (row_id, tenant_id, table_id, embedding, embedding_text, updated_at)
37
+ VALUES ${sql.join(values, sql `, `)}
38
+ ON CONFLICT (row_id, tenant_id) DO UPDATE SET
39
+ embedding = EXCLUDED.embedding,
40
+ embedding_text = EXCLUDED.embedding_text,
41
+ table_id = EXCLUDED.table_id,
42
+ updated_at = now()
43
+ `);
44
+ }
45
+ }
46
+ export async function searchSimilar(db, tenantId, queryVector, options) {
47
+ const vectorStr = `[${queryVector.join(',')}]`;
48
+ // Build query with parameterized values
49
+ // PostgreSQL array literal: '{uuid1,uuid2}' — drizzle doesn't auto-convert JS arrays
50
+ const tableIdsLiteral = options.tableIds?.length ? `{${options.tableIds.join(',')}}` : null;
51
+ const baseQuery = tableIdsLiteral
52
+ ? sql `SELECT
53
+ e.row_id, e.table_id,
54
+ t.name AS table_name, t.purpose AS table_purpose,
55
+ r.data,
56
+ 1 - (e.embedding <=> ${vectorStr}::vector) AS similarity
57
+ FROM _viyv_embeddings e
58
+ JOIN _viyv_logical_tables t ON e.table_id = t.id
59
+ JOIN _viyv_logical_rows r ON e.row_id = r.id AND e.tenant_id = r.tenant_id
60
+ WHERE e.tenant_id = ${tenantId}
61
+ AND e.table_id = ANY(${tableIdsLiteral}::uuid[])
62
+ AND 1 - (e.embedding <=> ${vectorStr}::vector) >= ${options.threshold}
63
+ ORDER BY e.embedding <=> ${vectorStr}::vector
64
+ LIMIT ${options.limit}`
65
+ : sql `SELECT
66
+ e.row_id, e.table_id,
67
+ t.name AS table_name, t.purpose AS table_purpose,
68
+ r.data,
69
+ 1 - (e.embedding <=> ${vectorStr}::vector) AS similarity
70
+ FROM _viyv_embeddings e
71
+ JOIN _viyv_logical_tables t ON e.table_id = t.id
72
+ JOIN _viyv_logical_rows r ON e.row_id = r.id AND e.tenant_id = r.tenant_id
73
+ WHERE e.tenant_id = ${tenantId}
74
+ AND 1 - (e.embedding <=> ${vectorStr}::vector) >= ${options.threshold}
75
+ ORDER BY e.embedding <=> ${vectorStr}::vector
76
+ LIMIT ${options.limit}`;
77
+ const result = await db.execute(baseQuery);
78
+ const rows = (result.rows ?? result);
79
+ return rows.map((row) => ({
80
+ rowId: String(row.row_id),
81
+ tableId: String(row.table_id),
82
+ tableName: String(row.table_name),
83
+ tablePurpose: row.table_purpose != null ? String(row.table_purpose) : null,
84
+ data: (typeof row.data === 'string' ? JSON.parse(row.data) : row.data),
85
+ similarity: Number(row.similarity),
86
+ }));
87
+ }
88
+ export async function deleteEmbeddingsByRowIds(db, tenantId, rowIds) {
89
+ if (rowIds.length === 0)
90
+ return;
91
+ const idsLiteral = `{${rowIds.join(',')}}`;
92
+ await db.execute(sql `DELETE FROM _viyv_embeddings WHERE tenant_id = ${tenantId} AND row_id = ANY(${idsLiteral}::uuid[])`);
93
+ }
94
+ //# sourceMappingURL=embedding-ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding-ops.js","sourceRoot":"","sources":["../../src/logical/embedding-ops.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { Migration } from 'viyv-db-core';
2
+ import type { DrizzleDb } from '../db.js';
3
+ import type { LogicalTableRegistry } from './registry.js';
4
+ export declare function getMigrationInfo(db: DrizzleDb): Promise<Migration[]>;
5
+ /**
6
+ * Rollback migrations after the target version.
7
+ * Parses structured downSql JSON and reverses logical table operations.
8
+ */
9
+ export declare function rollbackMigration(db: DrizzleDb, registry: LogicalTableRegistry, tenantId: string, targetVersion: string): Promise<void>;
10
+ //# sourceMappingURL=migration-ops.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-ops.d.ts","sourceRoot":"","sources":["../../src/logical/migration-ops.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAQ1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAY1E;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACtC,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,oBAAoB,EAC9B,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
@@ -0,0 +1,201 @@
1
+ import { and, desc, eq, sql } from 'drizzle-orm';
2
+ import { MigrationError } from 'viyv-db-core';
3
+ import { logicalColumns, logicalForeignKeys, logicalIndexes, logicalTables, migrations, } from '../schema.js';
4
+ export async function getMigrationInfo(db) {
5
+ const rows = await db.select().from(migrations).orderBy(migrations.appliedAt);
6
+ return rows.map((row) => ({
7
+ version: row.version,
8
+ description: row.description,
9
+ upSql: row.upSql,
10
+ downSql: row.downSql,
11
+ appliedAt: row.appliedAt.toISOString(),
12
+ appliedBy: row.appliedBy,
13
+ reason: row.reason,
14
+ }));
15
+ }
16
+ /**
17
+ * Rollback migrations after the target version.
18
+ * Parses structured downSql JSON and reverses logical table operations.
19
+ */
20
+ export async function rollbackMigration(db, registry, tenantId, targetVersion) {
21
+ // Verify target exists
22
+ const [target] = await db.select().from(migrations).where(eq(migrations.version, targetVersion));
23
+ if (!target) {
24
+ throw new MigrationError(`Target version "${targetVersion}" not found`);
25
+ }
26
+ // Compare timestamps entirely within PostgreSQL to avoid JS Date microsecond truncation
27
+ const laterMigrations = await db
28
+ .select()
29
+ .from(migrations)
30
+ .where(sql `${migrations.appliedAt} > (SELECT applied_at FROM _viyv_migrations WHERE version = ${targetVersion})`)
31
+ .orderBy(desc(migrations.appliedAt));
32
+ if (laterMigrations.length === 0) {
33
+ throw new MigrationError(`No migrations found after version "${targetVersion}"`);
34
+ }
35
+ await db.transaction(async (tx) => {
36
+ // Execute reverse operations in reverse chronological order
37
+ for (const migration of laterMigrations) {
38
+ await executeRollbackOp(tx, tenantId, migration.downSql);
39
+ await tx.delete(migrations).where(eq(migrations.version, migration.version));
40
+ }
41
+ });
42
+ registry.invalidate();
43
+ }
44
+ async function executeRollbackOp(tx, tenantId, downSql) {
45
+ // Skip legacy comment-style downSql (non-JSON)
46
+ if (!downSql.startsWith('{'))
47
+ return;
48
+ const op = JSON.parse(downSql);
49
+ switch (op.op) {
50
+ case 'drop_table': {
51
+ // Reverse of CREATE TABLE: delete the logical table (CASCADE)
52
+ const [table] = await tx
53
+ .select({ id: logicalTables.id })
54
+ .from(logicalTables)
55
+ .where(and(eq(logicalTables.tenantId, tenantId), eq(logicalTables.name, op.tableName)));
56
+ if (table) {
57
+ await tx.delete(logicalTables).where(eq(logicalTables.id, table.id));
58
+ }
59
+ break;
60
+ }
61
+ case 'create_table': {
62
+ // Reverse of DROP TABLE: recreate table with columns, indexes, foreign keys
63
+ const [newTable] = await tx
64
+ .insert(logicalTables)
65
+ .values({
66
+ tenantId: op.tenantId ?? tenantId,
67
+ name: op.tableName,
68
+ purpose: op.purpose ?? null,
69
+ createdBy: op.createdBy ?? null,
70
+ })
71
+ .returning();
72
+ if (op.columns && op.columns.length > 0) {
73
+ await tx.insert(logicalColumns).values(op.columns.map((c) => ({
74
+ tableId: newTable.id,
75
+ name: c.name,
76
+ type: c.type ?? 'TEXT',
77
+ nullable: c.nullable ?? true,
78
+ defaultValue: c.defaultValue ?? null,
79
+ primaryKey: c.primaryKey ?? false,
80
+ uniqueCol: c.uniqueCol ?? false,
81
+ description: c.description ?? null,
82
+ position: c.position ?? 0,
83
+ })));
84
+ }
85
+ if (op.indexes && op.indexes.length > 0) {
86
+ await tx.insert(logicalIndexes).values(op.indexes.map((i) => ({
87
+ tableId: newTable.id,
88
+ name: i.name,
89
+ columns: i.columns,
90
+ uniqueIdx: i.uniqueIdx ?? false,
91
+ })));
92
+ }
93
+ if (op.foreignKeys && op.foreignKeys.length > 0) {
94
+ await tx.insert(logicalForeignKeys).values(op.foreignKeys.map((f) => ({
95
+ tableId: newTable.id,
96
+ columnName: f.columnName,
97
+ refTableName: f.refTableName,
98
+ refColumnName: f.refColumnName,
99
+ })));
100
+ }
101
+ break;
102
+ }
103
+ case 'drop_columns': {
104
+ // Reverse of ADD COLUMNS: remove specific columns
105
+ const [table] = await tx
106
+ .select({ id: logicalTables.id })
107
+ .from(logicalTables)
108
+ .where(and(eq(logicalTables.tenantId, tenantId), eq(logicalTables.name, op.tableName)));
109
+ if (table) {
110
+ for (const colName of op.columnNames) {
111
+ await tx
112
+ .delete(logicalColumns)
113
+ .where(and(eq(logicalColumns.tableId, table.id), eq(logicalColumns.name, colName)));
114
+ }
115
+ }
116
+ break;
117
+ }
118
+ case 'add_columns': {
119
+ // Reverse of DROP COLUMNS: re-add columns with their original definitions
120
+ const [table] = await tx
121
+ .select({ id: logicalTables.id })
122
+ .from(logicalTables)
123
+ .where(and(eq(logicalTables.tenantId, tenantId), eq(logicalTables.name, op.tableName)));
124
+ if (table && op.columns && op.columns.length > 0) {
125
+ await tx.insert(logicalColumns).values(op.columns.map((c) => ({
126
+ tableId: table.id,
127
+ name: c.name,
128
+ type: c.type ?? 'TEXT',
129
+ nullable: c.nullable ?? true,
130
+ defaultValue: c.defaultValue ?? null,
131
+ primaryKey: c.primaryKey ?? false,
132
+ uniqueCol: c.uniqueCol ?? false,
133
+ description: c.description ?? null,
134
+ position: c.position ?? 0,
135
+ })));
136
+ }
137
+ break;
138
+ }
139
+ case 'modify_columns': {
140
+ // Reverse of MODIFY COLUMNS: restore original column values
141
+ const [table] = await tx
142
+ .select({ id: logicalTables.id })
143
+ .from(logicalTables)
144
+ .where(and(eq(logicalTables.tenantId, tenantId), eq(logicalTables.name, op.tableName)));
145
+ if (table && op.original) {
146
+ for (const col of op.original) {
147
+ const updates = {};
148
+ if (col.name !== undefined)
149
+ updates.name = col.name;
150
+ if (col.type !== undefined)
151
+ updates.type = col.type;
152
+ if (col.nullable !== undefined)
153
+ updates.nullable = col.nullable;
154
+ if (col.defaultValue !== undefined)
155
+ updates.defaultValue = col.defaultValue;
156
+ await tx
157
+ .update(logicalColumns)
158
+ .set(updates)
159
+ .where(and(eq(logicalColumns.tableId, table.id), eq(logicalColumns.name, col.name)));
160
+ }
161
+ }
162
+ break;
163
+ }
164
+ case 'drop_index': {
165
+ // Reverse of ADD INDEX: remove the index
166
+ const [table] = await tx
167
+ .select({ id: logicalTables.id })
168
+ .from(logicalTables)
169
+ .where(and(eq(logicalTables.tenantId, tenantId), eq(logicalTables.name, op.tableName)));
170
+ if (table) {
171
+ await tx
172
+ .delete(logicalIndexes)
173
+ .where(and(eq(logicalIndexes.tableId, table.id), eq(logicalIndexes.name, op.indexName)));
174
+ }
175
+ break;
176
+ }
177
+ case 'update_purpose': {
178
+ // Reverse: restore old purpose
179
+ await tx
180
+ .update(logicalTables)
181
+ .set({ purpose: op.oldPurpose ?? null, updatedAt: new Date() })
182
+ .where(and(eq(logicalTables.tenantId, tenantId), eq(logicalTables.name, op.tableName)));
183
+ break;
184
+ }
185
+ case 'update_description': {
186
+ // Reverse: restore old description
187
+ const [table] = await tx
188
+ .select({ id: logicalTables.id })
189
+ .from(logicalTables)
190
+ .where(and(eq(logicalTables.tenantId, tenantId), eq(logicalTables.name, op.tableName)));
191
+ if (table) {
192
+ await tx
193
+ .update(logicalColumns)
194
+ .set({ description: op.oldDescription ?? null })
195
+ .where(and(eq(logicalColumns.tableId, table.id), eq(logicalColumns.name, op.columnName)));
196
+ }
197
+ break;
198
+ }
199
+ }
200
+ }
201
+ //# sourceMappingURL=migration-ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-ops.js","sourceRoot":"","sources":["../../src/logical/migration-ops.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { QueryResult, QueryTableOptions } from 'viyv-db-core';
2
+ import type { PostgresConfig } from '../config.js';
3
+ import type { DrizzleDb } from '../db.js';
4
+ import type { LogicalTableRegistry } from './registry.js';
5
+ /**
6
+ * Execute a SELECT query with row limit enforcement.
7
+ * If the query references logical tables, rewrites them as CTEs.
8
+ */
9
+ export declare function query(db: DrizzleDb, registry: LogicalTableRegistry, tenantId: string, config: PostgresConfig, sqlStr: string, params?: unknown[]): Promise<QueryResult>;
10
+ /**
11
+ * Structured query: SQL 不要で論理テーブルを検索
12
+ */
13
+ export declare function queryTableStructured(db: DrizzleDb, registry: LogicalTableRegistry, tenantId: string, config: PostgresConfig, tableName: string, options?: QueryTableOptions): Promise<QueryResult>;
14
+ /**
15
+ * Execute raw SQL with access level checking.
16
+ */
17
+ export declare function executeSql(db: DrizzleDb, registry: LogicalTableRegistry, tenantId: string, config: PostgresConfig, sqlStr: string, params?: unknown[], accessLevel?: string): Promise<QueryResult>;
18
+ //# sourceMappingURL=query-ops.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-ops.d.ts","sourceRoot":"","sources":["../../src/logical/query-ops.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AASnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAuE1D;;;GAGG;AACH,wBAAsB,KAAK,CAC1B,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,oBAAoB,EAC9B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,OAAO,EAAE,GAChB,OAAO,CAAC,WAAW,CAAC,CA+BtB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACzC,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,oBAAoB,EAC9B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,iBAAsB,GAC7B,OAAO,CAAC,WAAW,CAAC,CAwEtB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC/B,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,oBAAoB,EAC9B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,OAAO,EAAE,EAClB,WAAW,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,WAAW,CAAC,CAyCtB"}
@@ -0,0 +1,193 @@
1
+ import { and, eq, sql } from 'drizzle-orm';
2
+ import { AccessDeniedError, SqlValidationError, TableNotFoundError, classifySql, hasAccess, isValidIdentifier, } from 'viyv-db-core';
3
+ import { logicalRows } from '../schema.js';
4
+ import { composeCteQuery } from './cte-builder.js';
5
+ import { extractTableRefs } from './sql-table-refs.js';
6
+ import { splitByPlaceholders } from './sql-tokenizer.js';
7
+ import { isNumericType } from './type-utils.js';
8
+ import { buildWhereConditions } from './where-builder.js';
9
+ // Detect any reference to system tables in SQL
10
+ const SYSTEM_TABLE_RE = /\b_viyv_\w+/i;
11
+ /**
12
+ * Build a parameterized SQL template from a raw SQL string and positional params.
13
+ * Uses quote-aware splitting to avoid replacing $N inside string literals.
14
+ */
15
+ function buildParameterizedSqlSafe(sqlStr, params) {
16
+ if (!params || params.length === 0) {
17
+ return sql.raw(sqlStr);
18
+ }
19
+ const { parts, placeholderCount } = splitByPlaceholders(sqlStr);
20
+ if (placeholderCount !== params.length) {
21
+ return sql.raw(sqlStr);
22
+ }
23
+ let result = sql.raw(parts[0]);
24
+ for (let i = 0; i < params.length; i++) {
25
+ result = sql `${result}${params[i]}${sql.raw(parts[i + 1])}`;
26
+ }
27
+ return result;
28
+ }
29
+ /** 生 SQL 実行結果 → QueryResult 変換(truncation 判定付き) */
30
+ function buildRawQueryResult(result, limit) {
31
+ const rows = (result.rows ?? []);
32
+ const truncated = rows.length > limit;
33
+ const finalRows = truncated ? rows.slice(0, limit) : rows;
34
+ const columns = finalRows.length > 0
35
+ ? Object.keys(finalRows[0])
36
+ : (result.fields ?? []).map((f) => f.name);
37
+ return { columns, rows: finalRows, rowCount: finalRows.length, truncated };
38
+ }
39
+ /** SQL 内の論理テーブル参照を解決し、バインディング配列を返す */
40
+ async function resolveLogicalBindings(db, registry, tenantId, sqlStr) {
41
+ const refs = extractTableRefs(sqlStr);
42
+ const bindings = [];
43
+ const seen = new Set();
44
+ // ユーザー CTE 定義名を先に収集 — 同名の論理テーブルより CTE を優先する
45
+ const userCteNames = new Set();
46
+ for (const ref of refs) {
47
+ if (ref.context === 'with')
48
+ userCteNames.add(ref.name);
49
+ }
50
+ for (const ref of refs) {
51
+ if (ref.context === 'with' || seen.has(ref.name) || userCteNames.has(ref.name))
52
+ continue;
53
+ seen.add(ref.name);
54
+ const isLogical = registry.has(ref.name) || (await registry.refreshIfMissing(db, tenantId, ref.name));
55
+ if (isLogical) {
56
+ const entry = registry.getTable(ref.name);
57
+ if (entry)
58
+ bindings.push({ tableName: ref.name, entry });
59
+ }
60
+ }
61
+ return bindings;
62
+ }
63
+ /**
64
+ * Execute a SELECT query with row limit enforcement.
65
+ * If the query references logical tables, rewrites them as CTEs.
66
+ */
67
+ export async function query(db, registry, tenantId, config, sqlStr, params) {
68
+ const sqlType = classifySql(sqlStr);
69
+ if (sqlType !== 'select') {
70
+ throw new SqlValidationError('query() only accepts SELECT statements. Use executeSql() for other operations.');
71
+ }
72
+ // Block access to system tables
73
+ if (SYSTEM_TABLE_RE.test(sqlStr)) {
74
+ throw new SqlValidationError('Cannot access system tables (_viyv_*)');
75
+ }
76
+ // Resolve logical table bindings
77
+ const bindings = await resolveLogicalBindings(db, registry, tenantId, sqlStr);
78
+ if (bindings.length > 0) {
79
+ const composition = composeCteQuery(bindings, tenantId, sqlStr, params, config.rowLimit);
80
+ const q = buildParameterizedSqlSafe(composition.sql, composition.params);
81
+ const result = await db.execute(q);
82
+ return buildRawQueryResult(result, config.rowLimit);
83
+ }
84
+ // Fallback: raw SQL(論理テーブルなし)
85
+ const limit = config.rowLimit;
86
+ const cleanSql = sqlStr.replace(/;\s*$/, '');
87
+ const wrappedSql = `SELECT * FROM (${cleanSql}) AS _q LIMIT ${limit + 1}`;
88
+ const q = buildParameterizedSqlSafe(wrappedSql, params);
89
+ const result = await db.execute(q);
90
+ return buildRawQueryResult(result, limit);
91
+ }
92
+ /**
93
+ * Structured query: SQL 不要で論理テーブルを検索
94
+ */
95
+ export async function queryTableStructured(db, registry, tenantId, config, tableName, options = {}) {
96
+ const entry = registry.getTable(tableName);
97
+ if (!entry)
98
+ throw new TableNotFoundError(tableName);
99
+ const limit = options.limit ?? config.rowLimit;
100
+ // 1. Build WHERE: tenant_id + table_id scope + user conditions
101
+ const whereConditions = options.where && Object.keys(options.where).length > 0
102
+ ? buildWhereConditions(options.where, entry.columns)
103
+ : [];
104
+ // 2. Build query
105
+ let q = db
106
+ .select({ data: logicalRows.data, createdAt: logicalRows.createdAt })
107
+ .from(logicalRows)
108
+ .where(and(eq(logicalRows.tenantId, tenantId), eq(logicalRows.tableId, entry.id), ...whereConditions))
109
+ .$dynamic();
110
+ // 3. ORDER BY
111
+ if (options.orderBy && options.orderBy.length > 0) {
112
+ const orderExprs = [];
113
+ for (const ob of options.orderBy) {
114
+ if (!isValidIdentifier(ob.column))
115
+ continue;
116
+ const col = entry.columns.find((c) => c.name === ob.column);
117
+ const cast = col && isNumericType(col.type) ? '::numeric' : '';
118
+ const dir = ob.direction === 'desc' ? 'DESC' : 'ASC';
119
+ orderExprs.push(sql.raw(`(data->>'${ob.column}')${cast} ${dir}`));
120
+ }
121
+ if (orderExprs.length > 0) {
122
+ q = q.orderBy(...orderExprs);
123
+ }
124
+ }
125
+ else {
126
+ q = q.orderBy(logicalRows.createdAt);
127
+ }
128
+ // 4. LIMIT / OFFSET
129
+ q = q.limit(limit + 1);
130
+ if (options.offset !== undefined) {
131
+ q = q.offset(options.offset);
132
+ }
133
+ const rows = await q;
134
+ // 5. Result mapping
135
+ const truncated = rows.length > limit;
136
+ const finalRows = truncated ? rows.slice(0, limit) : rows;
137
+ const allColumns = [...entry.columns].sort((a, b) => a.position - b.position).map((c) => c.name);
138
+ const selectedColumns = options.columns ?? allColumns;
139
+ const resultRows = finalRows.map((row) => {
140
+ const data = row.data;
141
+ const result = {};
142
+ for (const col of selectedColumns) {
143
+ result[col] = data[col] ?? null;
144
+ }
145
+ return result;
146
+ });
147
+ return {
148
+ columns: selectedColumns,
149
+ rows: resultRows,
150
+ rowCount: resultRows.length,
151
+ truncated,
152
+ };
153
+ }
154
+ /**
155
+ * Execute raw SQL with access level checking.
156
+ */
157
+ export async function executeSql(db, registry, tenantId, config, sqlStr, params, accessLevel) {
158
+ const currentAccess = accessLevel ?? config.accessLevel;
159
+ const sqlType = classifySql(sqlStr);
160
+ // Block access to system tables
161
+ if (SYSTEM_TABLE_RE.test(sqlStr)) {
162
+ throw new SqlValidationError('Cannot access system tables (_viyv_*)');
163
+ }
164
+ if (sqlType === 'dml' && !hasAccess(currentAccess, 'data')) {
165
+ throw new AccessDeniedError(sqlType, 'data', currentAccess);
166
+ }
167
+ if (sqlType === 'ddl' && !hasAccess(currentAccess, 'schema')) {
168
+ throw new AccessDeniedError(sqlType, 'schema', currentAccess);
169
+ }
170
+ // If it's a SELECT referencing logical tables, use CTE rewrite
171
+ if (sqlType === 'select') {
172
+ const bindings = await resolveLogicalBindings(db, registry, tenantId, sqlStr);
173
+ if (bindings.length > 0) {
174
+ const composition = composeCteQuery(bindings, tenantId, sqlStr, params, config.rowLimit);
175
+ const q = buildParameterizedSqlSafe(composition.sql, composition.params);
176
+ const result = await db.execute(q);
177
+ return buildRawQueryResult(result, config.rowLimit);
178
+ }
179
+ }
180
+ const q = buildParameterizedSqlSafe(sqlStr, params);
181
+ const result = await db.execute(q);
182
+ const rows = (result.rows ?? []);
183
+ const columns = rows.length > 0
184
+ ? Object.keys(rows[0])
185
+ : (result.fields ?? []).map((f) => f.name);
186
+ return {
187
+ columns,
188
+ rows,
189
+ rowCount: rows.length,
190
+ truncated: false,
191
+ };
192
+ }
193
+ //# sourceMappingURL=query-ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-ops.js","sourceRoot":"","sources":["../../src/logical/query-ops.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { DrizzleDb } from '../db.js';
2
+ export interface TableCacheEntry {
3
+ id: string;
4
+ columns: Array<{
5
+ name: string;
6
+ type: string;
7
+ nullable: boolean;
8
+ primaryKey: boolean;
9
+ uniqueCol: boolean;
10
+ defaultValue: string | null;
11
+ description: string | null;
12
+ position: number;
13
+ }>;
14
+ }
15
+ export declare class LogicalTableRegistry {
16
+ private cache;
17
+ private lastRefreshedAt;
18
+ private static readonly REFRESH_COOLDOWN_MS;
19
+ refreshIfMissing(db: DrizzleDb, tenantId: string, name: string): Promise<boolean>;
20
+ ensureLoaded(db: DrizzleDb, tenantId: string): Promise<void>;
21
+ getTableId(name: string): string | null;
22
+ getTable(name: string): TableCacheEntry | null;
23
+ has(name: string): boolean;
24
+ listTables(): Map<string, TableCacheEntry>;
25
+ invalidate(): void;
26
+ }
27
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/logical/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG1C,MAAM,WAAW,eAAe;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,OAAO,CAAC;QAClB,UAAU,EAAE,OAAO,CAAC;QACpB,SAAS,EAAE,OAAO,CAAC;QACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,QAAQ,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;CACH;AAED,qBAAa,oBAAoB;IAChC,OAAO,CAAC,KAAK,CAA6C;IAC1D,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAE9C,gBAAgB,CAAC,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYjF,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmDlE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIvC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IAI9C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC;IAI1C,UAAU,IAAI,IAAI;CAGlB"}