@nicia-ai/typegraph 0.4.0 → 0.6.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.
- package/README.md +2 -2
- package/dist/{ast-CXFx6bF6.d.ts → ast-CG87Zr6p.d.ts} +2 -2
- package/dist/{ast-D-3bOanX.d.cts → ast-Cq9qrnNP.d.cts} +2 -2
- package/dist/backend/postgres/index.cjs +295 -23
- package/dist/backend/postgres/index.cjs.map +1 -1
- package/dist/backend/postgres/index.d.cts +33 -10
- package/dist/backend/postgres/index.d.ts +33 -10
- package/dist/backend/postgres/index.js +285 -5
- package/dist/backend/postgres/index.js.map +1 -1
- package/dist/backend/sqlite/index.cjs +21 -90
- package/dist/backend/sqlite/index.cjs.map +1 -1
- package/dist/backend/sqlite/index.d.cts +22 -58
- package/dist/backend/sqlite/index.d.ts +22 -58
- package/dist/backend/sqlite/index.js +3 -78
- package/dist/backend/sqlite/index.js.map +1 -1
- package/dist/backend/sqlite/local.cjs +83 -0
- package/dist/backend/sqlite/local.cjs.map +1 -0
- package/dist/backend/sqlite/local.d.cts +66 -0
- package/dist/backend/sqlite/local.d.ts +66 -0
- package/dist/backend/sqlite/local.js +77 -0
- package/dist/backend/sqlite/local.js.map +1 -0
- package/dist/chunk-23NGZHUN.cjs +2132 -0
- package/dist/chunk-23NGZHUN.cjs.map +1 -0
- package/dist/{chunk-ZO2FRJ2U.js → chunk-2DKSQNPW.js} +3 -4
- package/dist/chunk-2DKSQNPW.js.map +1 -0
- package/dist/chunk-JPO7W262.js +2093 -0
- package/dist/chunk-JPO7W262.js.map +1 -0
- package/dist/{chunk-NYDXJGA3.cjs → chunk-K5O7TOJO.cjs} +15 -16
- package/dist/chunk-K5O7TOJO.cjs.map +1 -0
- package/dist/{backend/drizzle/schema/postgres.d.ts → ddl-Bcyb4DW1.d.cts} +17 -17
- package/dist/{backend/drizzle/schema/postgres.d.cts → ddl-D7DQx8w8.d.ts} +17 -17
- package/dist/{index-DyrR_d-H.d.cts → index-QTnQwakS.d.cts} +1 -1
- package/dist/{index-DyrR_d-H.d.ts → index-QTnQwakS.d.ts} +1 -1
- package/dist/index.cjs +238 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -12
- package/dist/index.d.ts +11 -12
- package/dist/index.js +238 -1
- package/dist/index.js.map +1 -1
- package/dist/indexes/index.d.cts +5 -6
- package/dist/indexes/index.d.ts +5 -6
- package/dist/interchange/index.d.cts +5 -6
- package/dist/interchange/index.d.ts +5 -6
- package/dist/{manager-0NysX4s6.d.cts → manager-BImRiYwz.d.cts} +3 -3
- package/dist/{manager-DFKe7ql3.d.ts → manager-DGQ9UF18.d.ts} +3 -3
- package/dist/profiler/index.d.cts +7 -8
- package/dist/profiler/index.d.ts +7 -8
- package/dist/schema/index.d.cts +6 -7
- package/dist/schema/index.d.ts +6 -7
- package/dist/{backend/drizzle/schema/sqlite.d.ts → sqlite-CSJ-fgIm.d.ts} +2 -25
- package/dist/{backend/drizzle/schema/sqlite.d.cts → sqlite-FWGZLwDd.d.cts} +2 -25
- package/dist/{store-SiovWEYA.d.ts → store-CscQUG-S.d.ts} +57 -6
- package/dist/{store-DhoA5uRc.d.cts → store-DNv1yd3n.d.cts} +57 -6
- package/dist/{types-DHRsi6j9.d.cts → types-BbMn2Ycv.d.cts} +2 -2
- package/dist/{types-ZT5mlism.d.ts → types-C2rhqkg7.d.ts} +2 -2
- package/dist/{types-6EKrWTs9.d.ts → types-D5ggX07j.d.ts} +7 -3
- package/dist/{types-BL1GyVku.d.cts → types-DEMAqkA1.d.cts} +1 -1
- package/dist/{types-DCGa53O2.d.ts → types-DJZoHy5R.d.ts} +1 -1
- package/dist/{types-DTJEu_-h.d.ts → types-DolHw9pJ.d.cts} +14 -1
- package/dist/{types-DTJEu_-h.d.cts → types-DolHw9pJ.d.ts} +14 -1
- package/dist/{types-BUy-pHKH.d.cts → types-SVDEKnU6.d.cts} +7 -3
- package/package.json +6 -46
- package/dist/backend/drizzle/index.cjs +0 -40
- package/dist/backend/drizzle/index.cjs.map +0 -1
- package/dist/backend/drizzle/index.d.cts +0 -13
- package/dist/backend/drizzle/index.d.ts +0 -13
- package/dist/backend/drizzle/index.js +0 -11
- package/dist/backend/drizzle/index.js.map +0 -1
- package/dist/backend/drizzle/postgres.cjs +0 -26
- package/dist/backend/drizzle/postgres.cjs.map +0 -1
- package/dist/backend/drizzle/postgres.d.cts +0 -35
- package/dist/backend/drizzle/postgres.d.ts +0 -35
- package/dist/backend/drizzle/postgres.js +0 -9
- package/dist/backend/drizzle/postgres.js.map +0 -1
- package/dist/backend/drizzle/schema/postgres.cjs +0 -39
- package/dist/backend/drizzle/schema/postgres.cjs.map +0 -1
- package/dist/backend/drizzle/schema/postgres.js +0 -6
- package/dist/backend/drizzle/schema/postgres.js.map +0 -1
- package/dist/backend/drizzle/schema/sqlite.cjs +0 -39
- package/dist/backend/drizzle/schema/sqlite.cjs.map +0 -1
- package/dist/backend/drizzle/schema/sqlite.js +0 -6
- package/dist/backend/drizzle/schema/sqlite.js.map +0 -1
- package/dist/backend/drizzle/sqlite.cjs +0 -26
- package/dist/backend/drizzle/sqlite.cjs.map +0 -1
- package/dist/backend/drizzle/sqlite.d.cts +0 -35
- package/dist/backend/drizzle/sqlite.d.ts +0 -35
- package/dist/backend/drizzle/sqlite.js +0 -9
- package/dist/backend/drizzle/sqlite.js.map +0 -1
- package/dist/chunk-3PURVEA4.js +0 -193
- package/dist/chunk-3PURVEA4.js.map +0 -1
- package/dist/chunk-7RVSDXT3.cjs +0 -1509
- package/dist/chunk-7RVSDXT3.cjs.map +0 -1
- package/dist/chunk-LUARLSYT.cjs +0 -289
- package/dist/chunk-LUARLSYT.cjs.map +0 -1
- package/dist/chunk-NU2XNMVI.cjs +0 -201
- package/dist/chunk-NU2XNMVI.cjs.map +0 -1
- package/dist/chunk-NYDXJGA3.cjs.map +0 -1
- package/dist/chunk-OGGLFYFA.js +0 -177
- package/dist/chunk-OGGLFYFA.js.map +0 -1
- package/dist/chunk-Q6PXIKRQ.js +0 -287
- package/dist/chunk-Q6PXIKRQ.js.map +0 -1
- package/dist/chunk-SMLIWLS7.js +0 -236
- package/dist/chunk-SMLIWLS7.js.map +0 -1
- package/dist/chunk-UYMT4LO2.cjs +0 -241
- package/dist/chunk-UYMT4LO2.cjs.map +0 -1
- package/dist/chunk-XZL6MCZJ.cjs +0 -185
- package/dist/chunk-XZL6MCZJ.cjs.map +0 -1
- package/dist/chunk-ZO2FRJ2U.js.map +0 -1
- package/dist/chunk-ZQGOBVXZ.js +0 -1488
- package/dist/chunk-ZQGOBVXZ.js.map +0 -1
- package/dist/test-helpers-CIq1Hhj1.d.ts +0 -26
- package/dist/test-helpers-DPRFVky4.d.cts +0 -26
- package/dist/types-BRzHlhKC.d.cts +0 -14
- package/dist/types-BRzHlhKC.d.ts +0 -14
|
@@ -0,0 +1,2132 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk44SXEVF4_cjs = require('./chunk-44SXEVF4.cjs');
|
|
4
|
+
var chunkJQDWEX6V_cjs = require('./chunk-JQDWEX6V.cjs');
|
|
5
|
+
var sqliteCore = require('drizzle-orm/sqlite-core');
|
|
6
|
+
var pgCore = require('drizzle-orm/pg-core');
|
|
7
|
+
var drizzleOrm = require('drizzle-orm');
|
|
8
|
+
|
|
9
|
+
var DEFAULT_TABLE_NAMES = {
|
|
10
|
+
nodes: "typegraph_nodes",
|
|
11
|
+
edges: "typegraph_edges",
|
|
12
|
+
uniques: "typegraph_node_uniques",
|
|
13
|
+
schemaVersions: "typegraph_schema_versions",
|
|
14
|
+
embeddings: "typegraph_node_embeddings"
|
|
15
|
+
};
|
|
16
|
+
function createSqliteTables(names = {}, options = {}) {
|
|
17
|
+
const n = { ...DEFAULT_TABLE_NAMES, ...names };
|
|
18
|
+
const indexes = options.indexes ?? [];
|
|
19
|
+
const nodes3 = sqliteCore.sqliteTable(
|
|
20
|
+
n.nodes,
|
|
21
|
+
{
|
|
22
|
+
graphId: sqliteCore.text("graph_id").notNull(),
|
|
23
|
+
kind: sqliteCore.text("kind").notNull(),
|
|
24
|
+
id: sqliteCore.text("id").notNull(),
|
|
25
|
+
props: sqliteCore.text("props").notNull(),
|
|
26
|
+
version: sqliteCore.integer("version").notNull().default(1),
|
|
27
|
+
validFrom: sqliteCore.text("valid_from"),
|
|
28
|
+
validTo: sqliteCore.text("valid_to"),
|
|
29
|
+
createdAt: sqliteCore.text("created_at").notNull(),
|
|
30
|
+
updatedAt: sqliteCore.text("updated_at").notNull(),
|
|
31
|
+
deletedAt: sqliteCore.text("deleted_at")
|
|
32
|
+
},
|
|
33
|
+
(t) => [
|
|
34
|
+
sqliteCore.primaryKey({ columns: [t.graphId, t.kind, t.id] }),
|
|
35
|
+
sqliteCore.index(`${n.nodes}_kind_idx`).on(t.graphId, t.kind),
|
|
36
|
+
sqliteCore.index(`${n.nodes}_kind_created_idx`).on(
|
|
37
|
+
t.graphId,
|
|
38
|
+
t.kind,
|
|
39
|
+
t.deletedAt,
|
|
40
|
+
t.createdAt
|
|
41
|
+
),
|
|
42
|
+
sqliteCore.index(`${n.nodes}_deleted_idx`).on(t.graphId, t.deletedAt),
|
|
43
|
+
sqliteCore.index(`${n.nodes}_valid_idx`).on(t.graphId, t.validFrom, t.validTo),
|
|
44
|
+
...chunkJQDWEX6V_cjs.buildSqliteNodeIndexBuilders(t, indexes)
|
|
45
|
+
]
|
|
46
|
+
);
|
|
47
|
+
const edges3 = sqliteCore.sqliteTable(
|
|
48
|
+
n.edges,
|
|
49
|
+
{
|
|
50
|
+
graphId: sqliteCore.text("graph_id").notNull(),
|
|
51
|
+
id: sqliteCore.text("id").notNull(),
|
|
52
|
+
kind: sqliteCore.text("kind").notNull(),
|
|
53
|
+
fromKind: sqliteCore.text("from_kind").notNull(),
|
|
54
|
+
fromId: sqliteCore.text("from_id").notNull(),
|
|
55
|
+
toKind: sqliteCore.text("to_kind").notNull(),
|
|
56
|
+
toId: sqliteCore.text("to_id").notNull(),
|
|
57
|
+
props: sqliteCore.text("props").notNull(),
|
|
58
|
+
validFrom: sqliteCore.text("valid_from"),
|
|
59
|
+
validTo: sqliteCore.text("valid_to"),
|
|
60
|
+
createdAt: sqliteCore.text("created_at").notNull(),
|
|
61
|
+
updatedAt: sqliteCore.text("updated_at").notNull(),
|
|
62
|
+
deletedAt: sqliteCore.text("deleted_at")
|
|
63
|
+
},
|
|
64
|
+
(t) => [
|
|
65
|
+
sqliteCore.primaryKey({ columns: [t.graphId, t.id] }),
|
|
66
|
+
sqliteCore.index(`${n.edges}_kind_idx`).on(t.graphId, t.kind),
|
|
67
|
+
// Directional traversal index (outgoing): supports endpoint lookups
|
|
68
|
+
// and extra filtering by edge kind / target kind.
|
|
69
|
+
sqliteCore.index(`${n.edges}_from_idx`).on(
|
|
70
|
+
t.graphId,
|
|
71
|
+
t.fromKind,
|
|
72
|
+
t.fromId,
|
|
73
|
+
t.kind,
|
|
74
|
+
t.toKind,
|
|
75
|
+
t.deletedAt,
|
|
76
|
+
t.validTo
|
|
77
|
+
),
|
|
78
|
+
// Directional traversal index (incoming): mirrors from_idx for reverse traversals.
|
|
79
|
+
sqliteCore.index(`${n.edges}_to_idx`).on(
|
|
80
|
+
t.graphId,
|
|
81
|
+
t.toKind,
|
|
82
|
+
t.toId,
|
|
83
|
+
t.kind,
|
|
84
|
+
t.fromKind,
|
|
85
|
+
t.deletedAt,
|
|
86
|
+
t.validTo
|
|
87
|
+
),
|
|
88
|
+
sqliteCore.index(`${n.edges}_kind_created_idx`).on(
|
|
89
|
+
t.graphId,
|
|
90
|
+
t.kind,
|
|
91
|
+
t.deletedAt,
|
|
92
|
+
t.createdAt
|
|
93
|
+
),
|
|
94
|
+
sqliteCore.index(`${n.edges}_deleted_idx`).on(t.graphId, t.deletedAt),
|
|
95
|
+
sqliteCore.index(`${n.edges}_valid_idx`).on(t.graphId, t.validFrom, t.validTo),
|
|
96
|
+
sqliteCore.index(`${n.edges}_cardinality_idx`).on(
|
|
97
|
+
t.graphId,
|
|
98
|
+
t.kind,
|
|
99
|
+
t.fromKind,
|
|
100
|
+
t.fromId,
|
|
101
|
+
t.validTo
|
|
102
|
+
),
|
|
103
|
+
...chunkJQDWEX6V_cjs.buildSqliteEdgeIndexBuilders(t, indexes)
|
|
104
|
+
]
|
|
105
|
+
);
|
|
106
|
+
const uniques3 = sqliteCore.sqliteTable(
|
|
107
|
+
n.uniques,
|
|
108
|
+
{
|
|
109
|
+
graphId: sqliteCore.text("graph_id").notNull(),
|
|
110
|
+
nodeKind: sqliteCore.text("node_kind").notNull(),
|
|
111
|
+
constraintName: sqliteCore.text("constraint_name").notNull(),
|
|
112
|
+
key: sqliteCore.text("key").notNull(),
|
|
113
|
+
nodeId: sqliteCore.text("node_id").notNull(),
|
|
114
|
+
concreteKind: sqliteCore.text("concrete_kind").notNull(),
|
|
115
|
+
deletedAt: sqliteCore.text("deleted_at")
|
|
116
|
+
},
|
|
117
|
+
(t) => [
|
|
118
|
+
sqliteCore.primaryKey({
|
|
119
|
+
columns: [t.graphId, t.nodeKind, t.constraintName, t.key]
|
|
120
|
+
}),
|
|
121
|
+
sqliteCore.index(`${n.uniques}_node_idx`).on(t.graphId, t.concreteKind, t.nodeId)
|
|
122
|
+
]
|
|
123
|
+
);
|
|
124
|
+
const schemaVersions3 = sqliteCore.sqliteTable(
|
|
125
|
+
n.schemaVersions,
|
|
126
|
+
{
|
|
127
|
+
graphId: sqliteCore.text("graph_id").notNull(),
|
|
128
|
+
version: sqliteCore.integer("version").notNull(),
|
|
129
|
+
schemaHash: sqliteCore.text("schema_hash").notNull(),
|
|
130
|
+
schemaDoc: sqliteCore.text("schema_doc").notNull(),
|
|
131
|
+
createdAt: sqliteCore.text("created_at").notNull(),
|
|
132
|
+
isActive: sqliteCore.integer("is_active", { mode: "boolean" }).notNull().default(false)
|
|
133
|
+
},
|
|
134
|
+
(t) => [
|
|
135
|
+
sqliteCore.primaryKey({ columns: [t.graphId, t.version] }),
|
|
136
|
+
sqliteCore.index(`${n.schemaVersions}_active_idx`).on(t.graphId, t.isActive)
|
|
137
|
+
]
|
|
138
|
+
);
|
|
139
|
+
const embeddings3 = sqliteCore.sqliteTable(
|
|
140
|
+
n.embeddings,
|
|
141
|
+
{
|
|
142
|
+
graphId: sqliteCore.text("graph_id").notNull(),
|
|
143
|
+
nodeKind: sqliteCore.text("node_kind").notNull(),
|
|
144
|
+
nodeId: sqliteCore.text("node_id").notNull(),
|
|
145
|
+
fieldPath: sqliteCore.text("field_path").notNull(),
|
|
146
|
+
/**
|
|
147
|
+
* Embedding vector.
|
|
148
|
+
* Stored as BLOB for sqlite-vec binary format, or JSON text for fallback.
|
|
149
|
+
* For sqlite-vec: use vec_f32() to convert JSON array to binary.
|
|
150
|
+
*/
|
|
151
|
+
embedding: sqliteCore.blob("embedding", { mode: "buffer" }).notNull(),
|
|
152
|
+
/** Number of dimensions (for validation) */
|
|
153
|
+
dimensions: sqliteCore.integer("dimensions").notNull(),
|
|
154
|
+
createdAt: sqliteCore.text("created_at").notNull(),
|
|
155
|
+
updatedAt: sqliteCore.text("updated_at").notNull()
|
|
156
|
+
},
|
|
157
|
+
(t) => [
|
|
158
|
+
sqliteCore.primaryKey({
|
|
159
|
+
columns: [t.graphId, t.nodeKind, t.nodeId, t.fieldPath]
|
|
160
|
+
}),
|
|
161
|
+
// Index for looking up embeddings by node
|
|
162
|
+
sqliteCore.index(`${n.embeddings}_node_idx`).on(
|
|
163
|
+
t.graphId,
|
|
164
|
+
t.nodeKind,
|
|
165
|
+
t.nodeId
|
|
166
|
+
),
|
|
167
|
+
// Index for filtering by kind and field (used in vector search)
|
|
168
|
+
sqliteCore.index(`${n.embeddings}_kind_field_idx`).on(
|
|
169
|
+
t.graphId,
|
|
170
|
+
t.nodeKind,
|
|
171
|
+
t.fieldPath
|
|
172
|
+
)
|
|
173
|
+
]
|
|
174
|
+
);
|
|
175
|
+
return { nodes: nodes3, edges: edges3, uniques: uniques3, schemaVersions: schemaVersions3, embeddings: embeddings3 };
|
|
176
|
+
}
|
|
177
|
+
var tables = createSqliteTables();
|
|
178
|
+
var { nodes, edges, uniques, schemaVersions, embeddings } = tables;
|
|
179
|
+
var vector = pgCore.customType({
|
|
180
|
+
dataType(config) {
|
|
181
|
+
return config?.dimensions ? `vector(${config.dimensions})` : "vector";
|
|
182
|
+
},
|
|
183
|
+
toDriver(value) {
|
|
184
|
+
return `[${value.join(",")}]`;
|
|
185
|
+
},
|
|
186
|
+
fromDriver(value) {
|
|
187
|
+
if (Array.isArray(value)) {
|
|
188
|
+
return value;
|
|
189
|
+
}
|
|
190
|
+
const content = value.slice(1, -1);
|
|
191
|
+
if (content === "") {
|
|
192
|
+
return [];
|
|
193
|
+
}
|
|
194
|
+
return content.split(",").map((s) => Number.parseFloat(s.trim()));
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// src/backend/drizzle/schema/postgres.ts
|
|
199
|
+
var DEFAULT_TABLE_NAMES2 = {
|
|
200
|
+
nodes: "typegraph_nodes",
|
|
201
|
+
edges: "typegraph_edges",
|
|
202
|
+
uniques: "typegraph_node_uniques",
|
|
203
|
+
schemaVersions: "typegraph_schema_versions",
|
|
204
|
+
embeddings: "typegraph_node_embeddings"
|
|
205
|
+
};
|
|
206
|
+
function createPostgresTables(names = {}, options = {}) {
|
|
207
|
+
const n = { ...DEFAULT_TABLE_NAMES2, ...names };
|
|
208
|
+
const indexes = options.indexes ?? [];
|
|
209
|
+
const nodes3 = pgCore.pgTable(
|
|
210
|
+
n.nodes,
|
|
211
|
+
{
|
|
212
|
+
graphId: pgCore.text("graph_id").notNull(),
|
|
213
|
+
kind: pgCore.text("kind").notNull(),
|
|
214
|
+
id: pgCore.text("id").notNull(),
|
|
215
|
+
props: pgCore.jsonb("props").notNull(),
|
|
216
|
+
version: pgCore.integer("version").notNull().default(1),
|
|
217
|
+
validFrom: pgCore.timestamp("valid_from", { withTimezone: true }),
|
|
218
|
+
validTo: pgCore.timestamp("valid_to", { withTimezone: true }),
|
|
219
|
+
createdAt: pgCore.timestamp("created_at", { withTimezone: true }).notNull(),
|
|
220
|
+
updatedAt: pgCore.timestamp("updated_at", { withTimezone: true }).notNull(),
|
|
221
|
+
deletedAt: pgCore.timestamp("deleted_at", { withTimezone: true })
|
|
222
|
+
},
|
|
223
|
+
(t) => [
|
|
224
|
+
pgCore.primaryKey({ columns: [t.graphId, t.kind, t.id] }),
|
|
225
|
+
pgCore.index(`${n.nodes}_kind_idx`).on(t.graphId, t.kind),
|
|
226
|
+
pgCore.index(`${n.nodes}_kind_created_idx`).on(
|
|
227
|
+
t.graphId,
|
|
228
|
+
t.kind,
|
|
229
|
+
t.deletedAt,
|
|
230
|
+
t.createdAt
|
|
231
|
+
),
|
|
232
|
+
pgCore.index(`${n.nodes}_deleted_idx`).on(t.graphId, t.deletedAt),
|
|
233
|
+
pgCore.index(`${n.nodes}_valid_idx`).on(t.graphId, t.validFrom, t.validTo),
|
|
234
|
+
...chunkJQDWEX6V_cjs.buildPostgresNodeIndexBuilders(t, indexes)
|
|
235
|
+
]
|
|
236
|
+
);
|
|
237
|
+
const edges3 = pgCore.pgTable(
|
|
238
|
+
n.edges,
|
|
239
|
+
{
|
|
240
|
+
graphId: pgCore.text("graph_id").notNull(),
|
|
241
|
+
id: pgCore.text("id").notNull(),
|
|
242
|
+
kind: pgCore.text("kind").notNull(),
|
|
243
|
+
fromKind: pgCore.text("from_kind").notNull(),
|
|
244
|
+
fromId: pgCore.text("from_id").notNull(),
|
|
245
|
+
toKind: pgCore.text("to_kind").notNull(),
|
|
246
|
+
toId: pgCore.text("to_id").notNull(),
|
|
247
|
+
props: pgCore.jsonb("props").notNull(),
|
|
248
|
+
validFrom: pgCore.timestamp("valid_from", { withTimezone: true }),
|
|
249
|
+
validTo: pgCore.timestamp("valid_to", { withTimezone: true }),
|
|
250
|
+
createdAt: pgCore.timestamp("created_at", { withTimezone: true }).notNull(),
|
|
251
|
+
updatedAt: pgCore.timestamp("updated_at", { withTimezone: true }).notNull(),
|
|
252
|
+
deletedAt: pgCore.timestamp("deleted_at", { withTimezone: true })
|
|
253
|
+
},
|
|
254
|
+
(t) => [
|
|
255
|
+
pgCore.primaryKey({ columns: [t.graphId, t.id] }),
|
|
256
|
+
pgCore.index(`${n.edges}_kind_idx`).on(t.graphId, t.kind),
|
|
257
|
+
// Directional traversal index (outgoing): supports endpoint lookups
|
|
258
|
+
// and extra filtering by edge kind / target kind.
|
|
259
|
+
pgCore.index(`${n.edges}_from_idx`).on(
|
|
260
|
+
t.graphId,
|
|
261
|
+
t.fromKind,
|
|
262
|
+
t.fromId,
|
|
263
|
+
t.kind,
|
|
264
|
+
t.toKind,
|
|
265
|
+
t.deletedAt,
|
|
266
|
+
t.validTo
|
|
267
|
+
),
|
|
268
|
+
// Directional traversal index (incoming): mirrors from_idx for reverse traversals.
|
|
269
|
+
pgCore.index(`${n.edges}_to_idx`).on(
|
|
270
|
+
t.graphId,
|
|
271
|
+
t.toKind,
|
|
272
|
+
t.toId,
|
|
273
|
+
t.kind,
|
|
274
|
+
t.fromKind,
|
|
275
|
+
t.deletedAt,
|
|
276
|
+
t.validTo
|
|
277
|
+
),
|
|
278
|
+
pgCore.index(`${n.edges}_kind_created_idx`).on(
|
|
279
|
+
t.graphId,
|
|
280
|
+
t.kind,
|
|
281
|
+
t.deletedAt,
|
|
282
|
+
t.createdAt
|
|
283
|
+
),
|
|
284
|
+
pgCore.index(`${n.edges}_deleted_idx`).on(t.graphId, t.deletedAt),
|
|
285
|
+
pgCore.index(`${n.edges}_valid_idx`).on(t.graphId, t.validFrom, t.validTo),
|
|
286
|
+
pgCore.index(`${n.edges}_cardinality_idx`).on(
|
|
287
|
+
t.graphId,
|
|
288
|
+
t.kind,
|
|
289
|
+
t.fromKind,
|
|
290
|
+
t.fromId,
|
|
291
|
+
t.validTo
|
|
292
|
+
),
|
|
293
|
+
...chunkJQDWEX6V_cjs.buildPostgresEdgeIndexBuilders(t, indexes)
|
|
294
|
+
]
|
|
295
|
+
);
|
|
296
|
+
const uniques3 = pgCore.pgTable(
|
|
297
|
+
n.uniques,
|
|
298
|
+
{
|
|
299
|
+
graphId: pgCore.text("graph_id").notNull(),
|
|
300
|
+
nodeKind: pgCore.text("node_kind").notNull(),
|
|
301
|
+
constraintName: pgCore.text("constraint_name").notNull(),
|
|
302
|
+
key: pgCore.text("key").notNull(),
|
|
303
|
+
nodeId: pgCore.text("node_id").notNull(),
|
|
304
|
+
concreteKind: pgCore.text("concrete_kind").notNull(),
|
|
305
|
+
deletedAt: pgCore.timestamp("deleted_at", { withTimezone: true })
|
|
306
|
+
},
|
|
307
|
+
(t) => [
|
|
308
|
+
pgCore.primaryKey({
|
|
309
|
+
columns: [t.graphId, t.nodeKind, t.constraintName, t.key]
|
|
310
|
+
}),
|
|
311
|
+
pgCore.index(`${n.uniques}_node_idx`).on(t.graphId, t.concreteKind, t.nodeId)
|
|
312
|
+
]
|
|
313
|
+
);
|
|
314
|
+
const schemaVersions3 = pgCore.pgTable(
|
|
315
|
+
n.schemaVersions,
|
|
316
|
+
{
|
|
317
|
+
graphId: pgCore.text("graph_id").notNull(),
|
|
318
|
+
version: pgCore.integer("version").notNull(),
|
|
319
|
+
schemaHash: pgCore.text("schema_hash").notNull(),
|
|
320
|
+
schemaDoc: pgCore.jsonb("schema_doc").notNull(),
|
|
321
|
+
createdAt: pgCore.timestamp("created_at", { withTimezone: true }).notNull(),
|
|
322
|
+
isActive: pgCore.boolean("is_active").notNull().default(false)
|
|
323
|
+
},
|
|
324
|
+
(t) => [
|
|
325
|
+
pgCore.primaryKey({ columns: [t.graphId, t.version] }),
|
|
326
|
+
pgCore.index(`${n.schemaVersions}_active_idx`).on(t.graphId, t.isActive)
|
|
327
|
+
]
|
|
328
|
+
);
|
|
329
|
+
const embeddings3 = pgCore.pgTable(
|
|
330
|
+
n.embeddings,
|
|
331
|
+
{
|
|
332
|
+
graphId: pgCore.text("graph_id").notNull(),
|
|
333
|
+
nodeKind: pgCore.text("node_kind").notNull(),
|
|
334
|
+
nodeId: pgCore.text("node_id").notNull(),
|
|
335
|
+
fieldPath: pgCore.text("field_path").notNull(),
|
|
336
|
+
/** Embedding vector stored as native pgvector type */
|
|
337
|
+
embedding: vector("embedding").notNull(),
|
|
338
|
+
/** Number of dimensions (for validation) */
|
|
339
|
+
dimensions: pgCore.integer("dimensions").notNull(),
|
|
340
|
+
createdAt: pgCore.timestamp("created_at", { withTimezone: true }).notNull(),
|
|
341
|
+
updatedAt: pgCore.timestamp("updated_at", { withTimezone: true }).notNull()
|
|
342
|
+
},
|
|
343
|
+
(t) => [
|
|
344
|
+
pgCore.primaryKey({
|
|
345
|
+
columns: [t.graphId, t.nodeKind, t.nodeId, t.fieldPath]
|
|
346
|
+
}),
|
|
347
|
+
// Index for looking up embeddings by node
|
|
348
|
+
pgCore.index(`${n.embeddings}_node_idx`).on(
|
|
349
|
+
t.graphId,
|
|
350
|
+
t.nodeKind,
|
|
351
|
+
t.nodeId
|
|
352
|
+
),
|
|
353
|
+
// Index for filtering by kind and field (used in vector search)
|
|
354
|
+
pgCore.index(`${n.embeddings}_kind_field_idx`).on(
|
|
355
|
+
t.graphId,
|
|
356
|
+
t.nodeKind,
|
|
357
|
+
t.fieldPath
|
|
358
|
+
)
|
|
359
|
+
]
|
|
360
|
+
);
|
|
361
|
+
return { nodes: nodes3, edges: edges3, uniques: uniques3, schemaVersions: schemaVersions3, embeddings: embeddings3 };
|
|
362
|
+
}
|
|
363
|
+
var tables2 = createPostgresTables();
|
|
364
|
+
var { nodes: nodes2, edges: edges2, uniques: uniques2, schemaVersions: schemaVersions2, embeddings: embeddings2 } = tables2;
|
|
365
|
+
function getSqliteColumnType(column) {
|
|
366
|
+
switch (column.columnType) {
|
|
367
|
+
case "SQLiteText": {
|
|
368
|
+
return "TEXT";
|
|
369
|
+
}
|
|
370
|
+
case "SQLiteInteger": {
|
|
371
|
+
return "INTEGER";
|
|
372
|
+
}
|
|
373
|
+
case "SQLiteReal": {
|
|
374
|
+
return "REAL";
|
|
375
|
+
}
|
|
376
|
+
case "SQLiteBlob": {
|
|
377
|
+
return "BLOB";
|
|
378
|
+
}
|
|
379
|
+
default: {
|
|
380
|
+
return "TEXT";
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
function formatDefaultValue(value) {
|
|
385
|
+
if (value === null) return "NULL";
|
|
386
|
+
if (typeof value === "string") return `'${value}'`;
|
|
387
|
+
if (typeof value === "number") return String(value);
|
|
388
|
+
if (typeof value === "boolean") return value ? "1" : "0";
|
|
389
|
+
return JSON.stringify(value);
|
|
390
|
+
}
|
|
391
|
+
function generateSqliteCreateTableSQL(table) {
|
|
392
|
+
const config = sqliteCore.getTableConfig(table);
|
|
393
|
+
const columnDefs = [];
|
|
394
|
+
for (const column of config.columns) {
|
|
395
|
+
const parts = [
|
|
396
|
+
`"${column.name}"`,
|
|
397
|
+
getSqliteColumnType(column)
|
|
398
|
+
];
|
|
399
|
+
if (column.notNull) {
|
|
400
|
+
parts.push("NOT NULL");
|
|
401
|
+
}
|
|
402
|
+
if (column.hasDefault && column.default !== void 0) {
|
|
403
|
+
parts.push(`DEFAULT ${formatDefaultValue(column.default)}`);
|
|
404
|
+
}
|
|
405
|
+
columnDefs.push(parts.join(" "));
|
|
406
|
+
}
|
|
407
|
+
const pk = config.primaryKeys[0];
|
|
408
|
+
if (pk) {
|
|
409
|
+
const pkColumns = pk.columns.map((c) => `"${c.name}"`).join(", ");
|
|
410
|
+
columnDefs.push(`PRIMARY KEY (${pkColumns})`);
|
|
411
|
+
}
|
|
412
|
+
return `CREATE TABLE IF NOT EXISTS "${config.name}" (
|
|
413
|
+
${columnDefs.join(",\n ")}
|
|
414
|
+
);`;
|
|
415
|
+
}
|
|
416
|
+
function renderIndexColumn(col) {
|
|
417
|
+
if (col && typeof col === "object" && "name" in col) {
|
|
418
|
+
return `"${col.name}"`;
|
|
419
|
+
}
|
|
420
|
+
const sql10 = tryInlineSql(col);
|
|
421
|
+
if (sql10 !== void 0) {
|
|
422
|
+
return sql10;
|
|
423
|
+
}
|
|
424
|
+
return "unknown";
|
|
425
|
+
}
|
|
426
|
+
function tryInlineSql(value) {
|
|
427
|
+
if (value && typeof value === "object" && "getSQL" in value) {
|
|
428
|
+
const maybe = value;
|
|
429
|
+
if (typeof maybe.getSQL === "function") {
|
|
430
|
+
return inlineSql(maybe.getSQL());
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return inlineSql(value);
|
|
434
|
+
}
|
|
435
|
+
function flattenSqlChunk(chunk) {
|
|
436
|
+
if (typeof chunk === "string") {
|
|
437
|
+
return chunk;
|
|
438
|
+
}
|
|
439
|
+
if (typeof chunk === "object" && chunk !== null) {
|
|
440
|
+
if ("value" in chunk && Array.isArray(chunk.value)) {
|
|
441
|
+
return chunk.value.map((part) => flattenSqlChunk(part)).join("");
|
|
442
|
+
}
|
|
443
|
+
if ("queryChunks" in chunk && Array.isArray(chunk.queryChunks)) {
|
|
444
|
+
return chunk.queryChunks.map((part) => flattenSqlChunk(part)).join("");
|
|
445
|
+
}
|
|
446
|
+
if ("getSQL" in chunk) {
|
|
447
|
+
const maybe = chunk;
|
|
448
|
+
if (typeof maybe.getSQL === "function") {
|
|
449
|
+
return flattenSqlChunk(maybe.getSQL());
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
throw new Error(`Unable to inline SQL chunk: ${String(chunk)}`);
|
|
454
|
+
}
|
|
455
|
+
function inlineSql(value) {
|
|
456
|
+
try {
|
|
457
|
+
return flattenSqlChunk(value);
|
|
458
|
+
} catch {
|
|
459
|
+
return void 0;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
function inlineSqlOrThrow(value, context) {
|
|
463
|
+
const inlined = inlineSql(value);
|
|
464
|
+
if (inlined === void 0) {
|
|
465
|
+
throw new Error(`Unable to inline SQL for ${context}`);
|
|
466
|
+
}
|
|
467
|
+
return inlined;
|
|
468
|
+
}
|
|
469
|
+
function generateSqliteCreateIndexSQL(table) {
|
|
470
|
+
const config = sqliteCore.getTableConfig(table);
|
|
471
|
+
const statements = [];
|
|
472
|
+
for (const index3 of config.indexes) {
|
|
473
|
+
const indexConfig = index3.config;
|
|
474
|
+
const columns = indexConfig.columns.map((c) => renderIndexColumn(c)).join(", ");
|
|
475
|
+
const unique = indexConfig.unique ? "UNIQUE " : "";
|
|
476
|
+
const where = indexConfig.where ? ` WHERE ${inlineSqlOrThrow(indexConfig.where, `SQLite index "${indexConfig.name}" WHERE clause`)}` : "";
|
|
477
|
+
statements.push(
|
|
478
|
+
`CREATE ${unique}INDEX IF NOT EXISTS "${indexConfig.name}" ON "${config.name}" (${columns})${where};`
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
return statements;
|
|
482
|
+
}
|
|
483
|
+
function generateSqliteDDL(tables3 = tables) {
|
|
484
|
+
const statements = [];
|
|
485
|
+
for (const table of Object.values(tables3)) {
|
|
486
|
+
statements.push(generateSqliteCreateTableSQL(table));
|
|
487
|
+
}
|
|
488
|
+
for (const table of Object.values(tables3)) {
|
|
489
|
+
statements.push(...generateSqliteCreateIndexSQL(table));
|
|
490
|
+
}
|
|
491
|
+
return statements;
|
|
492
|
+
}
|
|
493
|
+
function generateSqliteMigrationSQL(tables3 = tables) {
|
|
494
|
+
return generateSqliteDDL(tables3).join("\n\n");
|
|
495
|
+
}
|
|
496
|
+
function getPgColumnType(column) {
|
|
497
|
+
switch (column.columnType) {
|
|
498
|
+
case "PgText": {
|
|
499
|
+
return "TEXT";
|
|
500
|
+
}
|
|
501
|
+
case "PgInteger": {
|
|
502
|
+
return "INTEGER";
|
|
503
|
+
}
|
|
504
|
+
case "PgBoolean": {
|
|
505
|
+
return "BOOLEAN";
|
|
506
|
+
}
|
|
507
|
+
case "PgJsonb": {
|
|
508
|
+
return "JSONB";
|
|
509
|
+
}
|
|
510
|
+
case "PgTimestamp": {
|
|
511
|
+
return column.config?.withTimezone ? "TIMESTAMPTZ" : "TIMESTAMP";
|
|
512
|
+
}
|
|
513
|
+
case "PgReal": {
|
|
514
|
+
return "REAL";
|
|
515
|
+
}
|
|
516
|
+
case "PgDoublePrecision": {
|
|
517
|
+
return "DOUBLE PRECISION";
|
|
518
|
+
}
|
|
519
|
+
case "PgCustomColumn": {
|
|
520
|
+
const dataType = column.getSQLType?.();
|
|
521
|
+
return dataType ?? "TEXT";
|
|
522
|
+
}
|
|
523
|
+
default: {
|
|
524
|
+
return "TEXT";
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
function formatPgDefaultValue(value) {
|
|
529
|
+
if (value === null) return "NULL";
|
|
530
|
+
if (typeof value === "string") return `'${value}'`;
|
|
531
|
+
if (typeof value === "number") return String(value);
|
|
532
|
+
if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
|
|
533
|
+
return JSON.stringify(value);
|
|
534
|
+
}
|
|
535
|
+
function generatePgCreateTableSQL(table) {
|
|
536
|
+
const config = pgCore.getTableConfig(table);
|
|
537
|
+
const columnDefs = [];
|
|
538
|
+
for (const column of config.columns) {
|
|
539
|
+
const parts = [
|
|
540
|
+
`"${column.name}"`,
|
|
541
|
+
getPgColumnType(column)
|
|
542
|
+
];
|
|
543
|
+
if (column.notNull) {
|
|
544
|
+
parts.push("NOT NULL");
|
|
545
|
+
}
|
|
546
|
+
if (column.hasDefault && column.default !== void 0) {
|
|
547
|
+
parts.push(`DEFAULT ${formatPgDefaultValue(column.default)}`);
|
|
548
|
+
}
|
|
549
|
+
columnDefs.push(parts.join(" "));
|
|
550
|
+
}
|
|
551
|
+
const pk = config.primaryKeys[0];
|
|
552
|
+
if (pk) {
|
|
553
|
+
const pkColumns = pk.columns.map((c) => `"${c.name}"`).join(", ");
|
|
554
|
+
columnDefs.push(`PRIMARY KEY (${pkColumns})`);
|
|
555
|
+
}
|
|
556
|
+
return `CREATE TABLE IF NOT EXISTS "${config.name}" (
|
|
557
|
+
${columnDefs.join(",\n ")}
|
|
558
|
+
);`;
|
|
559
|
+
}
|
|
560
|
+
function generatePgCreateIndexSQL(table) {
|
|
561
|
+
const config = pgCore.getTableConfig(table);
|
|
562
|
+
const statements = [];
|
|
563
|
+
for (const index3 of config.indexes) {
|
|
564
|
+
const indexConfig = index3.config;
|
|
565
|
+
const columns = indexConfig.columns.map((c) => renderIndexColumn(c)).join(", ");
|
|
566
|
+
const unique = indexConfig.unique ? "UNIQUE " : "";
|
|
567
|
+
const method = indexConfig.method && indexConfig.method !== "btree" ? ` USING ${indexConfig.method}` : "";
|
|
568
|
+
const where = indexConfig.where ? ` WHERE ${inlineSqlOrThrow(indexConfig.where, `PostgreSQL index "${indexConfig.name}" WHERE clause`)}` : "";
|
|
569
|
+
statements.push(
|
|
570
|
+
`CREATE ${unique}INDEX IF NOT EXISTS "${indexConfig.name}" ON "${config.name}"${method} (${columns})${where};`
|
|
571
|
+
);
|
|
572
|
+
}
|
|
573
|
+
return statements;
|
|
574
|
+
}
|
|
575
|
+
function generatePostgresDDL(tables3 = tables2) {
|
|
576
|
+
const statements = [];
|
|
577
|
+
for (const table of Object.values(tables3)) {
|
|
578
|
+
statements.push(generatePgCreateTableSQL(table));
|
|
579
|
+
}
|
|
580
|
+
for (const table of Object.values(tables3)) {
|
|
581
|
+
statements.push(...generatePgCreateIndexSQL(table));
|
|
582
|
+
}
|
|
583
|
+
return statements;
|
|
584
|
+
}
|
|
585
|
+
function generatePostgresMigrationSQL(tables3 = tables2) {
|
|
586
|
+
const extensionSql = "-- Enable pgvector extension for vector similarity search\nCREATE EXTENSION IF NOT EXISTS vector;";
|
|
587
|
+
const ddlSql = generatePostgresDDL(tables3).join("\n\n");
|
|
588
|
+
return `${extensionSql}
|
|
589
|
+
|
|
590
|
+
${ddlSql}`;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// src/backend/types.ts
|
|
594
|
+
var SQLITE_CAPABILITIES = {
|
|
595
|
+
jsonb: false,
|
|
596
|
+
// SQLite uses TEXT with json functions
|
|
597
|
+
partialIndexes: true,
|
|
598
|
+
// SQLite supports WHERE in CREATE INDEX
|
|
599
|
+
ginIndexes: false,
|
|
600
|
+
// SQLite doesn't have GIN
|
|
601
|
+
cte: true,
|
|
602
|
+
// SQLite supports WITH
|
|
603
|
+
returning: true,
|
|
604
|
+
// SQLite 3.35+ supports RETURNING
|
|
605
|
+
transactions: true
|
|
606
|
+
// SQLite supports transactions
|
|
607
|
+
};
|
|
608
|
+
var POSTGRES_CAPABILITIES = {
|
|
609
|
+
jsonb: true,
|
|
610
|
+
// PostgreSQL has native JSONB
|
|
611
|
+
partialIndexes: true,
|
|
612
|
+
ginIndexes: true,
|
|
613
|
+
cte: true,
|
|
614
|
+
returning: true,
|
|
615
|
+
transactions: true
|
|
616
|
+
// PostgreSQL supports transactions
|
|
617
|
+
};
|
|
618
|
+
var D1_CAPABILITIES = {
|
|
619
|
+
jsonb: false,
|
|
620
|
+
// D1 uses TEXT with json functions
|
|
621
|
+
partialIndexes: true,
|
|
622
|
+
ginIndexes: false,
|
|
623
|
+
cte: true,
|
|
624
|
+
returning: true,
|
|
625
|
+
transactions: false
|
|
626
|
+
// D1 does NOT support atomic transactions
|
|
627
|
+
};
|
|
628
|
+
|
|
629
|
+
// src/backend/drizzle/row-mappers.ts
|
|
630
|
+
function requireTimestamp(value, field) {
|
|
631
|
+
if (value === void 0) {
|
|
632
|
+
throw new chunk44SXEVF4_cjs.DatabaseOperationError(
|
|
633
|
+
`Expected non-null ${field} timestamp`,
|
|
634
|
+
{ operation: "select", entity: "row" }
|
|
635
|
+
);
|
|
636
|
+
}
|
|
637
|
+
return value;
|
|
638
|
+
}
|
|
639
|
+
function nowIso() {
|
|
640
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
641
|
+
}
|
|
642
|
+
function nullToUndefined(value) {
|
|
643
|
+
return value ?? void 0;
|
|
644
|
+
}
|
|
645
|
+
function formatPostgresTimestamp(value) {
|
|
646
|
+
if (value === null || value === void 0) return void 0;
|
|
647
|
+
if (value instanceof Date) return value.toISOString();
|
|
648
|
+
if (typeof value === "string") {
|
|
649
|
+
if (value.includes("T")) return value;
|
|
650
|
+
const date = new Date(value);
|
|
651
|
+
if (!Number.isNaN(date.getTime())) return date.toISOString();
|
|
652
|
+
return value;
|
|
653
|
+
}
|
|
654
|
+
return void 0;
|
|
655
|
+
}
|
|
656
|
+
function normalizeJsonColumn(value) {
|
|
657
|
+
return typeof value === "string" ? value : JSON.stringify(value ?? {});
|
|
658
|
+
}
|
|
659
|
+
var SQLITE_ROW_MAPPER_CONFIG = {
|
|
660
|
+
formatTimestamp: (value) => nullToUndefined(value),
|
|
661
|
+
normalizeJson: (value) => value
|
|
662
|
+
};
|
|
663
|
+
var POSTGRES_ROW_MAPPER_CONFIG = {
|
|
664
|
+
formatTimestamp: formatPostgresTimestamp,
|
|
665
|
+
normalizeJson: normalizeJsonColumn
|
|
666
|
+
};
|
|
667
|
+
function createNodeRowMapper(config) {
|
|
668
|
+
return (row) => ({
|
|
669
|
+
graph_id: row.graph_id,
|
|
670
|
+
kind: row.kind,
|
|
671
|
+
id: row.id,
|
|
672
|
+
props: config.normalizeJson(row.props),
|
|
673
|
+
version: row.version,
|
|
674
|
+
valid_from: nullToUndefined(config.formatTimestamp(row.valid_from)),
|
|
675
|
+
valid_to: nullToUndefined(config.formatTimestamp(row.valid_to)),
|
|
676
|
+
created_at: requireTimestamp(config.formatTimestamp(row.created_at), "created_at"),
|
|
677
|
+
updated_at: requireTimestamp(config.formatTimestamp(row.updated_at), "updated_at"),
|
|
678
|
+
deleted_at: nullToUndefined(config.formatTimestamp(row.deleted_at))
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
function createEdgeRowMapper(config) {
|
|
682
|
+
return (row) => ({
|
|
683
|
+
graph_id: row.graph_id,
|
|
684
|
+
id: row.id,
|
|
685
|
+
kind: row.kind,
|
|
686
|
+
from_kind: row.from_kind,
|
|
687
|
+
from_id: row.from_id,
|
|
688
|
+
to_kind: row.to_kind,
|
|
689
|
+
to_id: row.to_id,
|
|
690
|
+
props: config.normalizeJson(row.props),
|
|
691
|
+
valid_from: nullToUndefined(config.formatTimestamp(row.valid_from)),
|
|
692
|
+
valid_to: nullToUndefined(config.formatTimestamp(row.valid_to)),
|
|
693
|
+
created_at: requireTimestamp(config.formatTimestamp(row.created_at), "created_at"),
|
|
694
|
+
updated_at: requireTimestamp(config.formatTimestamp(row.updated_at), "updated_at"),
|
|
695
|
+
deleted_at: nullToUndefined(config.formatTimestamp(row.deleted_at))
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
function createUniqueRowMapper(config) {
|
|
699
|
+
return (row) => ({
|
|
700
|
+
graph_id: row.graph_id,
|
|
701
|
+
node_kind: row.node_kind,
|
|
702
|
+
constraint_name: row.constraint_name,
|
|
703
|
+
key: row.key,
|
|
704
|
+
node_id: row.node_id,
|
|
705
|
+
concrete_kind: row.concrete_kind,
|
|
706
|
+
deleted_at: nullToUndefined(config.formatTimestamp(row.deleted_at))
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
function createSchemaVersionRowMapper(config) {
|
|
710
|
+
return (row) => {
|
|
711
|
+
const isActiveValue = row.is_active;
|
|
712
|
+
const isActive = isActiveValue === true || isActiveValue === 1 || isActiveValue === "1";
|
|
713
|
+
return {
|
|
714
|
+
graph_id: row.graph_id,
|
|
715
|
+
version: row.version,
|
|
716
|
+
schema_hash: row.schema_hash,
|
|
717
|
+
schema_doc: config.normalizeJson(row.schema_doc),
|
|
718
|
+
created_at: requireTimestamp(config.formatTimestamp(row.created_at), "created_at"),
|
|
719
|
+
is_active: isActive
|
|
720
|
+
};
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// src/backend/drizzle/operation-backend-core.ts
|
|
725
|
+
function chunkArray(values, size) {
|
|
726
|
+
if (values.length <= size) {
|
|
727
|
+
return [values];
|
|
728
|
+
}
|
|
729
|
+
const chunks = [];
|
|
730
|
+
for (let index3 = 0; index3 < values.length; index3 += size) {
|
|
731
|
+
chunks.push(values.slice(index3, index3 + size));
|
|
732
|
+
}
|
|
733
|
+
return chunks;
|
|
734
|
+
}
|
|
735
|
+
function createCommonOperationBackend(options) {
|
|
736
|
+
const { batchConfig, execution, operationStrategy, rowMappers } = options;
|
|
737
|
+
const nowIso2 = options.nowIso ?? nowIso;
|
|
738
|
+
return {
|
|
739
|
+
async insertNode(params) {
|
|
740
|
+
const timestamp2 = nowIso2();
|
|
741
|
+
const query = operationStrategy.buildInsertNode(params, timestamp2);
|
|
742
|
+
const row = await execution.execGet(query);
|
|
743
|
+
if (!row) throw new chunk44SXEVF4_cjs.DatabaseOperationError("Insert node failed: no row returned", { operation: "insert", entity: "node" });
|
|
744
|
+
return rowMappers.toNodeRow(row);
|
|
745
|
+
},
|
|
746
|
+
async insertNodeNoReturn(params) {
|
|
747
|
+
const timestamp2 = nowIso2();
|
|
748
|
+
const query = operationStrategy.buildInsertNodeNoReturn(params, timestamp2);
|
|
749
|
+
await execution.execRun(query);
|
|
750
|
+
},
|
|
751
|
+
async insertNodesBatch(params) {
|
|
752
|
+
if (params.length === 0) {
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
const timestamp2 = nowIso2();
|
|
756
|
+
for (const chunk of chunkArray(params, batchConfig.nodeInsertBatchSize)) {
|
|
757
|
+
const query = operationStrategy.buildInsertNodesBatch(chunk, timestamp2);
|
|
758
|
+
await execution.execRun(query);
|
|
759
|
+
}
|
|
760
|
+
},
|
|
761
|
+
async insertNodesBatchReturning(params) {
|
|
762
|
+
if (params.length === 0) {
|
|
763
|
+
return [];
|
|
764
|
+
}
|
|
765
|
+
const timestamp2 = nowIso2();
|
|
766
|
+
const allRows = [];
|
|
767
|
+
for (const chunk of chunkArray(params, batchConfig.nodeInsertBatchSize)) {
|
|
768
|
+
const query = operationStrategy.buildInsertNodesBatchReturning(chunk, timestamp2);
|
|
769
|
+
const rows = await execution.execAll(query);
|
|
770
|
+
allRows.push(...rows.map((row) => rowMappers.toNodeRow(row)));
|
|
771
|
+
}
|
|
772
|
+
return allRows;
|
|
773
|
+
},
|
|
774
|
+
async getNode(graphId, kind, id) {
|
|
775
|
+
const query = operationStrategy.buildGetNode(graphId, kind, id);
|
|
776
|
+
const row = await execution.execGet(query);
|
|
777
|
+
return row ? rowMappers.toNodeRow(row) : void 0;
|
|
778
|
+
},
|
|
779
|
+
async getNodes(graphId, kind, ids) {
|
|
780
|
+
if (ids.length === 0) return [];
|
|
781
|
+
const allRows = [];
|
|
782
|
+
for (const chunk of chunkArray(ids, batchConfig.getNodesChunkSize)) {
|
|
783
|
+
const query = operationStrategy.buildGetNodes(graphId, kind, chunk);
|
|
784
|
+
const rows = await execution.execAll(query);
|
|
785
|
+
allRows.push(...rows.map((row) => rowMappers.toNodeRow(row)));
|
|
786
|
+
}
|
|
787
|
+
return allRows;
|
|
788
|
+
},
|
|
789
|
+
async updateNode(params) {
|
|
790
|
+
const timestamp2 = nowIso2();
|
|
791
|
+
const query = operationStrategy.buildUpdateNode(params, timestamp2);
|
|
792
|
+
const row = await execution.execGet(query);
|
|
793
|
+
if (!row) throw new chunk44SXEVF4_cjs.DatabaseOperationError("Update node failed: no row returned", { operation: "update", entity: "node" });
|
|
794
|
+
return rowMappers.toNodeRow(row);
|
|
795
|
+
},
|
|
796
|
+
async deleteNode(params) {
|
|
797
|
+
const timestamp2 = nowIso2();
|
|
798
|
+
const query = operationStrategy.buildDeleteNode(params, timestamp2);
|
|
799
|
+
await execution.execRun(query);
|
|
800
|
+
},
|
|
801
|
+
// IMPORTANT: This cascade is not atomic. Callers must ensure this runs
|
|
802
|
+
// within a transaction to prevent partial deletion on intermediate failure.
|
|
803
|
+
async hardDeleteNode(params) {
|
|
804
|
+
const deleteUniquesQuery = operationStrategy.buildHardDeleteUniquesByNode(
|
|
805
|
+
params.graphId,
|
|
806
|
+
params.id
|
|
807
|
+
);
|
|
808
|
+
await execution.execRun(deleteUniquesQuery);
|
|
809
|
+
const deleteEmbeddingsQuery = operationStrategy.buildHardDeleteEmbeddingsByNode(
|
|
810
|
+
params.graphId,
|
|
811
|
+
params.kind,
|
|
812
|
+
params.id
|
|
813
|
+
);
|
|
814
|
+
await execution.execRun(deleteEmbeddingsQuery);
|
|
815
|
+
const deleteEdgesQuery = operationStrategy.buildHardDeleteEdgesByNode(
|
|
816
|
+
params.graphId,
|
|
817
|
+
params.kind,
|
|
818
|
+
params.id
|
|
819
|
+
);
|
|
820
|
+
await execution.execRun(deleteEdgesQuery);
|
|
821
|
+
const query = operationStrategy.buildHardDeleteNode(params);
|
|
822
|
+
await execution.execRun(query);
|
|
823
|
+
},
|
|
824
|
+
async insertEdge(params) {
|
|
825
|
+
const timestamp2 = nowIso2();
|
|
826
|
+
const query = operationStrategy.buildInsertEdge(params, timestamp2);
|
|
827
|
+
const row = await execution.execGet(query);
|
|
828
|
+
if (!row) throw new chunk44SXEVF4_cjs.DatabaseOperationError("Insert edge failed: no row returned", { operation: "insert", entity: "edge" });
|
|
829
|
+
return rowMappers.toEdgeRow(row);
|
|
830
|
+
},
|
|
831
|
+
async insertEdgeNoReturn(params) {
|
|
832
|
+
const timestamp2 = nowIso2();
|
|
833
|
+
const query = operationStrategy.buildInsertEdgeNoReturn(params, timestamp2);
|
|
834
|
+
await execution.execRun(query);
|
|
835
|
+
},
|
|
836
|
+
async insertEdgesBatch(params) {
|
|
837
|
+
if (params.length === 0) {
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
const timestamp2 = nowIso2();
|
|
841
|
+
for (const chunk of chunkArray(params, batchConfig.edgeInsertBatchSize)) {
|
|
842
|
+
const query = operationStrategy.buildInsertEdgesBatch(chunk, timestamp2);
|
|
843
|
+
await execution.execRun(query);
|
|
844
|
+
}
|
|
845
|
+
},
|
|
846
|
+
async insertEdgesBatchReturning(params) {
|
|
847
|
+
if (params.length === 0) {
|
|
848
|
+
return [];
|
|
849
|
+
}
|
|
850
|
+
const timestamp2 = nowIso2();
|
|
851
|
+
const allRows = [];
|
|
852
|
+
for (const chunk of chunkArray(params, batchConfig.edgeInsertBatchSize)) {
|
|
853
|
+
const query = operationStrategy.buildInsertEdgesBatchReturning(chunk, timestamp2);
|
|
854
|
+
const rows = await execution.execAll(query);
|
|
855
|
+
allRows.push(...rows.map((row) => rowMappers.toEdgeRow(row)));
|
|
856
|
+
}
|
|
857
|
+
return allRows;
|
|
858
|
+
},
|
|
859
|
+
async getEdge(graphId, id) {
|
|
860
|
+
const query = operationStrategy.buildGetEdge(graphId, id);
|
|
861
|
+
const row = await execution.execGet(query);
|
|
862
|
+
return row ? rowMappers.toEdgeRow(row) : void 0;
|
|
863
|
+
},
|
|
864
|
+
async getEdges(graphId, ids) {
|
|
865
|
+
if (ids.length === 0) return [];
|
|
866
|
+
const allRows = [];
|
|
867
|
+
for (const chunk of chunkArray(ids, batchConfig.getEdgesChunkSize)) {
|
|
868
|
+
const query = operationStrategy.buildGetEdges(graphId, chunk);
|
|
869
|
+
const rows = await execution.execAll(query);
|
|
870
|
+
allRows.push(...rows.map((row) => rowMappers.toEdgeRow(row)));
|
|
871
|
+
}
|
|
872
|
+
return allRows;
|
|
873
|
+
},
|
|
874
|
+
async updateEdge(params) {
|
|
875
|
+
const timestamp2 = nowIso2();
|
|
876
|
+
const query = operationStrategy.buildUpdateEdge(params, timestamp2);
|
|
877
|
+
const row = await execution.execGet(query);
|
|
878
|
+
if (!row) throw new chunk44SXEVF4_cjs.DatabaseOperationError("Update edge failed: no row returned", { operation: "update", entity: "edge" });
|
|
879
|
+
return rowMappers.toEdgeRow(row);
|
|
880
|
+
},
|
|
881
|
+
async deleteEdge(params) {
|
|
882
|
+
const timestamp2 = nowIso2();
|
|
883
|
+
const query = operationStrategy.buildDeleteEdge(params, timestamp2);
|
|
884
|
+
await execution.execRun(query);
|
|
885
|
+
},
|
|
886
|
+
async hardDeleteEdge(params) {
|
|
887
|
+
const query = operationStrategy.buildHardDeleteEdge(params);
|
|
888
|
+
await execution.execRun(query);
|
|
889
|
+
},
|
|
890
|
+
async countEdgesFrom(params) {
|
|
891
|
+
const query = operationStrategy.buildCountEdgesFrom(params);
|
|
892
|
+
const row = await execution.execGet(query);
|
|
893
|
+
return Number(row?.count ?? 0);
|
|
894
|
+
},
|
|
895
|
+
async edgeExistsBetween(params) {
|
|
896
|
+
const query = operationStrategy.buildEdgeExistsBetween(params);
|
|
897
|
+
const row = await execution.execGet(query);
|
|
898
|
+
return row !== void 0;
|
|
899
|
+
},
|
|
900
|
+
async findEdgesConnectedTo(params) {
|
|
901
|
+
const query = operationStrategy.buildFindEdgesConnectedTo(params);
|
|
902
|
+
const rows = await execution.execAll(query);
|
|
903
|
+
return rows.map((row) => rowMappers.toEdgeRow(row));
|
|
904
|
+
},
|
|
905
|
+
async findNodesByKind(params) {
|
|
906
|
+
const query = operationStrategy.buildFindNodesByKind(params);
|
|
907
|
+
const rows = await execution.execAll(query);
|
|
908
|
+
return rows.map((row) => rowMappers.toNodeRow(row));
|
|
909
|
+
},
|
|
910
|
+
async countNodesByKind(params) {
|
|
911
|
+
const query = operationStrategy.buildCountNodesByKind(params);
|
|
912
|
+
const row = await execution.execGet(query);
|
|
913
|
+
return Number(row?.count ?? 0);
|
|
914
|
+
},
|
|
915
|
+
async findEdgesByKind(params) {
|
|
916
|
+
const query = operationStrategy.buildFindEdgesByKind(params);
|
|
917
|
+
const rows = await execution.execAll(query);
|
|
918
|
+
return rows.map((row) => rowMappers.toEdgeRow(row));
|
|
919
|
+
},
|
|
920
|
+
async countEdgesByKind(params) {
|
|
921
|
+
const query = operationStrategy.buildCountEdgesByKind(params);
|
|
922
|
+
const row = await execution.execGet(query);
|
|
923
|
+
return Number(row?.count ?? 0);
|
|
924
|
+
},
|
|
925
|
+
async insertUnique(params) {
|
|
926
|
+
const query = operationStrategy.buildInsertUnique(params);
|
|
927
|
+
const result = await execution.execGet(query);
|
|
928
|
+
if (result && result.node_id !== params.nodeId) {
|
|
929
|
+
throw new chunk44SXEVF4_cjs.UniquenessError({
|
|
930
|
+
constraintName: params.constraintName,
|
|
931
|
+
kind: params.nodeKind,
|
|
932
|
+
existingId: result.node_id,
|
|
933
|
+
newId: params.nodeId,
|
|
934
|
+
fields: []
|
|
935
|
+
});
|
|
936
|
+
}
|
|
937
|
+
},
|
|
938
|
+
async deleteUnique(params) {
|
|
939
|
+
const timestamp2 = nowIso2();
|
|
940
|
+
const query = operationStrategy.buildDeleteUnique(params, timestamp2);
|
|
941
|
+
await execution.execRun(query);
|
|
942
|
+
},
|
|
943
|
+
async checkUnique(params) {
|
|
944
|
+
const query = operationStrategy.buildCheckUnique(params);
|
|
945
|
+
const row = await execution.execGet(query);
|
|
946
|
+
return row ? rowMappers.toUniqueRow(row) : void 0;
|
|
947
|
+
},
|
|
948
|
+
async checkUniqueBatch(params) {
|
|
949
|
+
if (params.keys.length === 0) return [];
|
|
950
|
+
const query = operationStrategy.buildCheckUniqueBatch(params);
|
|
951
|
+
const rows = await execution.execAll(query);
|
|
952
|
+
return rows.map((row) => rowMappers.toUniqueRow(row));
|
|
953
|
+
},
|
|
954
|
+
async getActiveSchema(graphId) {
|
|
955
|
+
const query = operationStrategy.buildGetActiveSchema(graphId);
|
|
956
|
+
const row = await execution.execGet(query);
|
|
957
|
+
return row ? rowMappers.toSchemaVersionRow(row) : void 0;
|
|
958
|
+
},
|
|
959
|
+
async insertSchema(params) {
|
|
960
|
+
const timestamp2 = nowIso2();
|
|
961
|
+
const query = operationStrategy.buildInsertSchema(params, timestamp2);
|
|
962
|
+
const row = await execution.execGet(query);
|
|
963
|
+
if (!row) throw new chunk44SXEVF4_cjs.DatabaseOperationError("Insert schema failed: no row returned", { operation: "insert", entity: "schema" });
|
|
964
|
+
return rowMappers.toSchemaVersionRow(row);
|
|
965
|
+
},
|
|
966
|
+
async getSchemaVersion(graphId, version) {
|
|
967
|
+
const query = operationStrategy.buildGetSchemaVersion(graphId, version);
|
|
968
|
+
const row = await execution.execGet(query);
|
|
969
|
+
return row ? rowMappers.toSchemaVersionRow(row) : void 0;
|
|
970
|
+
},
|
|
971
|
+
async setActiveSchema(graphId, version) {
|
|
972
|
+
const queries = operationStrategy.buildSetActiveSchema(graphId, version);
|
|
973
|
+
await execution.execRun(queries.deactivateAll);
|
|
974
|
+
await execution.execRun(queries.activateVersion);
|
|
975
|
+
},
|
|
976
|
+
async clearGraph(graphId) {
|
|
977
|
+
const statements = operationStrategy.buildClearGraph(graphId);
|
|
978
|
+
for (const statement of statements) {
|
|
979
|
+
await execution.execRun(statement);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
};
|
|
983
|
+
}
|
|
984
|
+
function buildClearGraph(tables3, graphId) {
|
|
985
|
+
return [
|
|
986
|
+
drizzleOrm.sql`DELETE FROM ${tables3.embeddings} WHERE ${tables3.embeddings.graphId} = ${graphId}`,
|
|
987
|
+
drizzleOrm.sql`DELETE FROM ${tables3.uniques} WHERE ${tables3.uniques.graphId} = ${graphId}`,
|
|
988
|
+
drizzleOrm.sql`DELETE FROM ${tables3.edges} WHERE ${tables3.edges.graphId} = ${graphId}`,
|
|
989
|
+
drizzleOrm.sql`DELETE FROM ${tables3.nodes} WHERE ${tables3.nodes.graphId} = ${graphId}`,
|
|
990
|
+
drizzleOrm.sql`DELETE FROM ${tables3.schemaVersions} WHERE ${tables3.schemaVersions.graphId} = ${graphId}`
|
|
991
|
+
];
|
|
992
|
+
}
|
|
993
|
+
function buildTemporalConditions(table, params) {
|
|
994
|
+
const conditions = [];
|
|
995
|
+
const mode = params.temporalMode;
|
|
996
|
+
if (mode === "includeTombstones") return conditions;
|
|
997
|
+
if (params.excludeDeleted !== false) {
|
|
998
|
+
conditions.push(drizzleOrm.sql`${table.deletedAt} IS NULL`);
|
|
999
|
+
}
|
|
1000
|
+
if (mode === "current" || mode === "asOf") {
|
|
1001
|
+
const asOf = params.asOf;
|
|
1002
|
+
conditions.push(
|
|
1003
|
+
drizzleOrm.sql`(${table.validFrom} IS NULL OR ${table.validFrom} <= ${asOf})`,
|
|
1004
|
+
drizzleOrm.sql`(${table.validTo} IS NULL OR ${table.validTo} > ${asOf})`
|
|
1005
|
+
);
|
|
1006
|
+
}
|
|
1007
|
+
return conditions;
|
|
1008
|
+
}
|
|
1009
|
+
function buildFindNodesByKind(tables3, params) {
|
|
1010
|
+
const { nodes: nodes3 } = tables3;
|
|
1011
|
+
const conditions = [
|
|
1012
|
+
drizzleOrm.sql`${nodes3.graphId} = ${params.graphId}`,
|
|
1013
|
+
drizzleOrm.sql`${nodes3.kind} = ${params.kind}`,
|
|
1014
|
+
...buildTemporalConditions(nodes3, params)
|
|
1015
|
+
];
|
|
1016
|
+
const whereClause = drizzleOrm.sql.join(conditions, drizzleOrm.sql` AND `);
|
|
1017
|
+
if (params.limit !== void 0 && params.offset !== void 0) {
|
|
1018
|
+
return drizzleOrm.sql`
|
|
1019
|
+
SELECT * FROM ${nodes3}
|
|
1020
|
+
WHERE ${whereClause}
|
|
1021
|
+
ORDER BY ${nodes3.createdAt} DESC
|
|
1022
|
+
LIMIT ${params.limit} OFFSET ${params.offset}
|
|
1023
|
+
`;
|
|
1024
|
+
}
|
|
1025
|
+
if (params.limit !== void 0) {
|
|
1026
|
+
return drizzleOrm.sql`
|
|
1027
|
+
SELECT * FROM ${nodes3}
|
|
1028
|
+
WHERE ${whereClause}
|
|
1029
|
+
ORDER BY ${nodes3.createdAt} DESC
|
|
1030
|
+
LIMIT ${params.limit}
|
|
1031
|
+
`;
|
|
1032
|
+
}
|
|
1033
|
+
return drizzleOrm.sql`
|
|
1034
|
+
SELECT * FROM ${nodes3}
|
|
1035
|
+
WHERE ${whereClause}
|
|
1036
|
+
ORDER BY ${nodes3.createdAt} DESC
|
|
1037
|
+
`;
|
|
1038
|
+
}
|
|
1039
|
+
function buildCountNodesByKind(tables3, params) {
|
|
1040
|
+
const { nodes: nodes3 } = tables3;
|
|
1041
|
+
const conditions = [
|
|
1042
|
+
drizzleOrm.sql`${nodes3.graphId} = ${params.graphId}`,
|
|
1043
|
+
drizzleOrm.sql`${nodes3.kind} = ${params.kind}`,
|
|
1044
|
+
...buildTemporalConditions(nodes3, params)
|
|
1045
|
+
];
|
|
1046
|
+
const whereClause = drizzleOrm.sql.join(conditions, drizzleOrm.sql` AND `);
|
|
1047
|
+
return drizzleOrm.sql`
|
|
1048
|
+
SELECT COUNT(*) as count FROM ${nodes3}
|
|
1049
|
+
WHERE ${whereClause}
|
|
1050
|
+
`;
|
|
1051
|
+
}
|
|
1052
|
+
function buildFindEdgesByKind(tables3, params) {
|
|
1053
|
+
const { edges: edges3 } = tables3;
|
|
1054
|
+
const conditions = [
|
|
1055
|
+
drizzleOrm.sql`${edges3.graphId} = ${params.graphId}`,
|
|
1056
|
+
drizzleOrm.sql`${edges3.kind} = ${params.kind}`,
|
|
1057
|
+
...buildTemporalConditions(edges3, params)
|
|
1058
|
+
];
|
|
1059
|
+
if (params.fromKind !== void 0) {
|
|
1060
|
+
conditions.push(drizzleOrm.sql`${edges3.fromKind} = ${params.fromKind}`);
|
|
1061
|
+
}
|
|
1062
|
+
if (params.fromId !== void 0) {
|
|
1063
|
+
conditions.push(drizzleOrm.sql`${edges3.fromId} = ${params.fromId}`);
|
|
1064
|
+
}
|
|
1065
|
+
if (params.toKind !== void 0) {
|
|
1066
|
+
conditions.push(drizzleOrm.sql`${edges3.toKind} = ${params.toKind}`);
|
|
1067
|
+
}
|
|
1068
|
+
if (params.toId !== void 0) {
|
|
1069
|
+
conditions.push(drizzleOrm.sql`${edges3.toId} = ${params.toId}`);
|
|
1070
|
+
}
|
|
1071
|
+
const whereClause = drizzleOrm.sql.join(conditions, drizzleOrm.sql` AND `);
|
|
1072
|
+
if (params.limit !== void 0 && params.offset !== void 0) {
|
|
1073
|
+
return drizzleOrm.sql`
|
|
1074
|
+
SELECT * FROM ${edges3}
|
|
1075
|
+
WHERE ${whereClause}
|
|
1076
|
+
ORDER BY ${edges3.createdAt} DESC
|
|
1077
|
+
LIMIT ${params.limit} OFFSET ${params.offset}
|
|
1078
|
+
`;
|
|
1079
|
+
}
|
|
1080
|
+
if (params.limit !== void 0) {
|
|
1081
|
+
return drizzleOrm.sql`
|
|
1082
|
+
SELECT * FROM ${edges3}
|
|
1083
|
+
WHERE ${whereClause}
|
|
1084
|
+
ORDER BY ${edges3.createdAt} DESC
|
|
1085
|
+
LIMIT ${params.limit}
|
|
1086
|
+
`;
|
|
1087
|
+
}
|
|
1088
|
+
return drizzleOrm.sql`
|
|
1089
|
+
SELECT * FROM ${edges3}
|
|
1090
|
+
WHERE ${whereClause}
|
|
1091
|
+
ORDER BY ${edges3.createdAt} DESC
|
|
1092
|
+
`;
|
|
1093
|
+
}
|
|
1094
|
+
function buildCountEdgesByKind(tables3, params) {
|
|
1095
|
+
const { edges: edges3 } = tables3;
|
|
1096
|
+
const conditions = [
|
|
1097
|
+
drizzleOrm.sql`${edges3.graphId} = ${params.graphId}`,
|
|
1098
|
+
drizzleOrm.sql`${edges3.kind} = ${params.kind}`,
|
|
1099
|
+
...buildTemporalConditions(edges3, params)
|
|
1100
|
+
];
|
|
1101
|
+
if (params.fromKind !== void 0) {
|
|
1102
|
+
conditions.push(drizzleOrm.sql`${edges3.fromKind} = ${params.fromKind}`);
|
|
1103
|
+
}
|
|
1104
|
+
if (params.fromId !== void 0) {
|
|
1105
|
+
conditions.push(drizzleOrm.sql`${edges3.fromId} = ${params.fromId}`);
|
|
1106
|
+
}
|
|
1107
|
+
if (params.toKind !== void 0) {
|
|
1108
|
+
conditions.push(drizzleOrm.sql`${edges3.toKind} = ${params.toKind}`);
|
|
1109
|
+
}
|
|
1110
|
+
if (params.toId !== void 0) {
|
|
1111
|
+
conditions.push(drizzleOrm.sql`${edges3.toId} = ${params.toId}`);
|
|
1112
|
+
}
|
|
1113
|
+
const whereClause = drizzleOrm.sql.join(conditions, drizzleOrm.sql` AND `);
|
|
1114
|
+
return drizzleOrm.sql`
|
|
1115
|
+
SELECT COUNT(*) as count FROM ${edges3}
|
|
1116
|
+
WHERE ${whereClause}
|
|
1117
|
+
`;
|
|
1118
|
+
}
|
|
1119
|
+
function sqlNull(value) {
|
|
1120
|
+
return value ?? drizzleOrm.sql.raw("NULL");
|
|
1121
|
+
}
|
|
1122
|
+
function quotedColumn(column) {
|
|
1123
|
+
return drizzleOrm.sql.raw(`"${column.name.replaceAll('"', '""')}"`);
|
|
1124
|
+
}
|
|
1125
|
+
function nodeColumnList(nodes3) {
|
|
1126
|
+
return drizzleOrm.sql.raw(`"${nodes3.graphId.name}", "${nodes3.kind.name}", "${nodes3.id.name}", "${nodes3.props.name}", "${nodes3.version.name}", "${nodes3.validFrom.name}", "${nodes3.validTo.name}", "${nodes3.createdAt.name}", "${nodes3.updatedAt.name}"`);
|
|
1127
|
+
}
|
|
1128
|
+
function edgeColumnList(edges3) {
|
|
1129
|
+
return drizzleOrm.sql.raw(`"${edges3.graphId.name}", "${edges3.id.name}", "${edges3.kind.name}", "${edges3.fromKind.name}", "${edges3.fromId.name}", "${edges3.toKind.name}", "${edges3.toId.name}", "${edges3.props.name}", "${edges3.validFrom.name}", "${edges3.validTo.name}", "${edges3.createdAt.name}", "${edges3.updatedAt.name}"`);
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
// src/backend/drizzle/operations/edges.ts
|
|
1133
|
+
function buildInsertEdge(tables3, params, timestamp2) {
|
|
1134
|
+
const { edges: edges3 } = tables3;
|
|
1135
|
+
const propsJson = JSON.stringify(params.props);
|
|
1136
|
+
const columns = edgeColumnList(edges3);
|
|
1137
|
+
return drizzleOrm.sql`
|
|
1138
|
+
INSERT INTO ${edges3} (${columns})
|
|
1139
|
+
VALUES (
|
|
1140
|
+
${params.graphId}, ${params.id}, ${params.kind},
|
|
1141
|
+
${params.fromKind}, ${params.fromId}, ${params.toKind}, ${params.toId},
|
|
1142
|
+
${propsJson}, ${sqlNull(params.validFrom)}, ${sqlNull(params.validTo)},
|
|
1143
|
+
${timestamp2}, ${timestamp2}
|
|
1144
|
+
)
|
|
1145
|
+
RETURNING *
|
|
1146
|
+
`;
|
|
1147
|
+
}
|
|
1148
|
+
function buildInsertEdgeNoReturn(tables3, params, timestamp2) {
|
|
1149
|
+
const { edges: edges3 } = tables3;
|
|
1150
|
+
const propsJson = JSON.stringify(params.props);
|
|
1151
|
+
const columns = edgeColumnList(edges3);
|
|
1152
|
+
return drizzleOrm.sql`
|
|
1153
|
+
INSERT INTO ${edges3} (${columns})
|
|
1154
|
+
VALUES (
|
|
1155
|
+
${params.graphId}, ${params.id}, ${params.kind},
|
|
1156
|
+
${params.fromKind}, ${params.fromId}, ${params.toKind}, ${params.toId},
|
|
1157
|
+
${propsJson}, ${sqlNull(params.validFrom)}, ${sqlNull(params.validTo)},
|
|
1158
|
+
${timestamp2}, ${timestamp2}
|
|
1159
|
+
)
|
|
1160
|
+
`;
|
|
1161
|
+
}
|
|
1162
|
+
function buildInsertEdgesBatch(tables3, params, timestamp2) {
|
|
1163
|
+
const { edges: edges3 } = tables3;
|
|
1164
|
+
const columns = edgeColumnList(edges3);
|
|
1165
|
+
const values = params.map((edgeParams) => {
|
|
1166
|
+
const propsJson = JSON.stringify(edgeParams.props);
|
|
1167
|
+
return drizzleOrm.sql`(${edgeParams.graphId}, ${edgeParams.id}, ${edgeParams.kind}, ${edgeParams.fromKind}, ${edgeParams.fromId}, ${edgeParams.toKind}, ${edgeParams.toId}, ${propsJson}, ${sqlNull(edgeParams.validFrom)}, ${sqlNull(edgeParams.validTo)}, ${timestamp2}, ${timestamp2})`;
|
|
1168
|
+
});
|
|
1169
|
+
return drizzleOrm.sql`
|
|
1170
|
+
INSERT INTO ${edges3} (${columns})
|
|
1171
|
+
VALUES ${drizzleOrm.sql.join(values, drizzleOrm.sql`, `)}
|
|
1172
|
+
`;
|
|
1173
|
+
}
|
|
1174
|
+
function buildInsertEdgesBatchReturning(tables3, params, timestamp2) {
|
|
1175
|
+
const { edges: edges3 } = tables3;
|
|
1176
|
+
const columns = edgeColumnList(edges3);
|
|
1177
|
+
const values = params.map((edgeParams) => {
|
|
1178
|
+
const propsJson = JSON.stringify(edgeParams.props);
|
|
1179
|
+
return drizzleOrm.sql`(${edgeParams.graphId}, ${edgeParams.id}, ${edgeParams.kind}, ${edgeParams.fromKind}, ${edgeParams.fromId}, ${edgeParams.toKind}, ${edgeParams.toId}, ${propsJson}, ${sqlNull(edgeParams.validFrom)}, ${sqlNull(edgeParams.validTo)}, ${timestamp2}, ${timestamp2})`;
|
|
1180
|
+
});
|
|
1181
|
+
return drizzleOrm.sql`
|
|
1182
|
+
INSERT INTO ${edges3} (${columns})
|
|
1183
|
+
VALUES ${drizzleOrm.sql.join(values, drizzleOrm.sql`, `)}
|
|
1184
|
+
RETURNING *
|
|
1185
|
+
`;
|
|
1186
|
+
}
|
|
1187
|
+
function buildGetEdge(tables3, graphId, id) {
|
|
1188
|
+
const { edges: edges3 } = tables3;
|
|
1189
|
+
return drizzleOrm.sql`
|
|
1190
|
+
SELECT * FROM ${edges3}
|
|
1191
|
+
WHERE ${edges3.graphId} = ${graphId}
|
|
1192
|
+
AND ${edges3.id} = ${id}
|
|
1193
|
+
`;
|
|
1194
|
+
}
|
|
1195
|
+
function buildGetEdges(tables3, graphId, ids) {
|
|
1196
|
+
const { edges: edges3 } = tables3;
|
|
1197
|
+
const idPlaceholders = drizzleOrm.sql.join(
|
|
1198
|
+
ids.map((edgeId) => drizzleOrm.sql`${edgeId}`),
|
|
1199
|
+
drizzleOrm.sql`, `
|
|
1200
|
+
);
|
|
1201
|
+
return drizzleOrm.sql`
|
|
1202
|
+
SELECT * FROM ${edges3}
|
|
1203
|
+
WHERE ${edges3.graphId} = ${graphId}
|
|
1204
|
+
AND ${edges3.id} IN (${idPlaceholders})
|
|
1205
|
+
`;
|
|
1206
|
+
}
|
|
1207
|
+
function buildUpdateEdge(tables3, params, timestamp2) {
|
|
1208
|
+
const { edges: edges3 } = tables3;
|
|
1209
|
+
const propsJson = JSON.stringify(params.props);
|
|
1210
|
+
const setParts = [
|
|
1211
|
+
drizzleOrm.sql`${quotedColumn(edges3.props)} = ${propsJson}`,
|
|
1212
|
+
drizzleOrm.sql`${quotedColumn(edges3.updatedAt)} = ${timestamp2}`
|
|
1213
|
+
];
|
|
1214
|
+
if (params.validTo !== void 0) {
|
|
1215
|
+
setParts.push(drizzleOrm.sql`${quotedColumn(edges3.validTo)} = ${params.validTo}`);
|
|
1216
|
+
}
|
|
1217
|
+
if (params.clearDeleted) {
|
|
1218
|
+
setParts.push(drizzleOrm.sql`${quotedColumn(edges3.deletedAt)} = NULL`);
|
|
1219
|
+
}
|
|
1220
|
+
const setClause = drizzleOrm.sql.join(setParts, drizzleOrm.sql`, `);
|
|
1221
|
+
if (params.clearDeleted) {
|
|
1222
|
+
return drizzleOrm.sql`
|
|
1223
|
+
UPDATE ${edges3}
|
|
1224
|
+
SET ${setClause}
|
|
1225
|
+
WHERE ${edges3.graphId} = ${params.graphId}
|
|
1226
|
+
AND ${edges3.id} = ${params.id}
|
|
1227
|
+
RETURNING *
|
|
1228
|
+
`;
|
|
1229
|
+
}
|
|
1230
|
+
return drizzleOrm.sql`
|
|
1231
|
+
UPDATE ${edges3}
|
|
1232
|
+
SET ${setClause}
|
|
1233
|
+
WHERE ${edges3.graphId} = ${params.graphId}
|
|
1234
|
+
AND ${edges3.id} = ${params.id}
|
|
1235
|
+
AND ${edges3.deletedAt} IS NULL
|
|
1236
|
+
RETURNING *
|
|
1237
|
+
`;
|
|
1238
|
+
}
|
|
1239
|
+
function buildDeleteEdge(tables3, params, timestamp2) {
|
|
1240
|
+
const { edges: edges3 } = tables3;
|
|
1241
|
+
return drizzleOrm.sql`
|
|
1242
|
+
UPDATE ${edges3}
|
|
1243
|
+
SET ${quotedColumn(edges3.deletedAt)} = ${timestamp2}
|
|
1244
|
+
WHERE ${edges3.graphId} = ${params.graphId}
|
|
1245
|
+
AND ${edges3.id} = ${params.id}
|
|
1246
|
+
AND ${edges3.deletedAt} IS NULL
|
|
1247
|
+
`;
|
|
1248
|
+
}
|
|
1249
|
+
function buildHardDeleteEdge(tables3, params) {
|
|
1250
|
+
const { edges: edges3 } = tables3;
|
|
1251
|
+
return drizzleOrm.sql`
|
|
1252
|
+
DELETE FROM ${edges3}
|
|
1253
|
+
WHERE ${edges3.graphId} = ${params.graphId}
|
|
1254
|
+
AND ${edges3.id} = ${params.id}
|
|
1255
|
+
`;
|
|
1256
|
+
}
|
|
1257
|
+
function buildHardDeleteEdgesByNode(tables3, graphId, nodeKind, nodeId) {
|
|
1258
|
+
const { edges: edges3 } = tables3;
|
|
1259
|
+
return drizzleOrm.sql`
|
|
1260
|
+
DELETE FROM ${edges3}
|
|
1261
|
+
WHERE ${edges3.graphId} = ${graphId}
|
|
1262
|
+
AND (
|
|
1263
|
+
(${edges3.fromKind} = ${nodeKind} AND ${edges3.fromId} = ${nodeId})
|
|
1264
|
+
OR (${edges3.toKind} = ${nodeKind} AND ${edges3.toId} = ${nodeId})
|
|
1265
|
+
)
|
|
1266
|
+
`;
|
|
1267
|
+
}
|
|
1268
|
+
function buildCountEdgesFrom(tables3, params) {
|
|
1269
|
+
const { edges: edges3 } = tables3;
|
|
1270
|
+
if (params.activeOnly) {
|
|
1271
|
+
return drizzleOrm.sql`
|
|
1272
|
+
SELECT COUNT(*) as count FROM ${edges3}
|
|
1273
|
+
WHERE ${edges3.graphId} = ${params.graphId}
|
|
1274
|
+
AND ${edges3.kind} = ${params.edgeKind}
|
|
1275
|
+
AND ${edges3.fromKind} = ${params.fromKind}
|
|
1276
|
+
AND ${edges3.fromId} = ${params.fromId}
|
|
1277
|
+
AND ${edges3.deletedAt} IS NULL
|
|
1278
|
+
AND ${edges3.validTo} IS NULL
|
|
1279
|
+
`;
|
|
1280
|
+
}
|
|
1281
|
+
return drizzleOrm.sql`
|
|
1282
|
+
SELECT COUNT(*) as count FROM ${edges3}
|
|
1283
|
+
WHERE ${edges3.graphId} = ${params.graphId}
|
|
1284
|
+
AND ${edges3.kind} = ${params.edgeKind}
|
|
1285
|
+
AND ${edges3.fromKind} = ${params.fromKind}
|
|
1286
|
+
AND ${edges3.fromId} = ${params.fromId}
|
|
1287
|
+
AND ${edges3.deletedAt} IS NULL
|
|
1288
|
+
`;
|
|
1289
|
+
}
|
|
1290
|
+
function buildEdgeExistsBetween(tables3, params) {
|
|
1291
|
+
const { edges: edges3 } = tables3;
|
|
1292
|
+
return drizzleOrm.sql`
|
|
1293
|
+
SELECT 1 FROM ${edges3}
|
|
1294
|
+
WHERE ${edges3.graphId} = ${params.graphId}
|
|
1295
|
+
AND ${edges3.kind} = ${params.edgeKind}
|
|
1296
|
+
AND ${edges3.fromKind} = ${params.fromKind}
|
|
1297
|
+
AND ${edges3.fromId} = ${params.fromId}
|
|
1298
|
+
AND ${edges3.toKind} = ${params.toKind}
|
|
1299
|
+
AND ${edges3.toId} = ${params.toId}
|
|
1300
|
+
AND ${edges3.deletedAt} IS NULL
|
|
1301
|
+
LIMIT 1
|
|
1302
|
+
`;
|
|
1303
|
+
}
|
|
1304
|
+
function buildFindEdgesConnectedTo(tables3, params) {
|
|
1305
|
+
const { edges: edges3 } = tables3;
|
|
1306
|
+
return drizzleOrm.sql`
|
|
1307
|
+
SELECT * FROM ${edges3}
|
|
1308
|
+
WHERE ${edges3.graphId} = ${params.graphId}
|
|
1309
|
+
AND ${edges3.deletedAt} IS NULL
|
|
1310
|
+
AND ${edges3.fromKind} = ${params.nodeKind}
|
|
1311
|
+
AND ${edges3.fromId} = ${params.nodeId}
|
|
1312
|
+
UNION ALL
|
|
1313
|
+
SELECT * FROM ${edges3}
|
|
1314
|
+
WHERE ${edges3.graphId} = ${params.graphId}
|
|
1315
|
+
AND ${edges3.deletedAt} IS NULL
|
|
1316
|
+
AND ${edges3.toKind} = ${params.nodeKind}
|
|
1317
|
+
AND ${edges3.toId} = ${params.nodeId}
|
|
1318
|
+
AND NOT (
|
|
1319
|
+
${edges3.fromKind} = ${params.nodeKind}
|
|
1320
|
+
AND ${edges3.fromId} = ${params.nodeId}
|
|
1321
|
+
)
|
|
1322
|
+
`;
|
|
1323
|
+
}
|
|
1324
|
+
function buildInsertNode(tables3, params, timestamp2) {
|
|
1325
|
+
const { nodes: nodes3 } = tables3;
|
|
1326
|
+
const propsJson = JSON.stringify(params.props);
|
|
1327
|
+
const columns = nodeColumnList(nodes3);
|
|
1328
|
+
return drizzleOrm.sql`
|
|
1329
|
+
INSERT INTO ${nodes3} (${columns})
|
|
1330
|
+
VALUES (
|
|
1331
|
+
${params.graphId}, ${params.kind}, ${params.id}, ${propsJson},
|
|
1332
|
+
1, ${sqlNull(params.validFrom)}, ${sqlNull(params.validTo)},
|
|
1333
|
+
${timestamp2}, ${timestamp2}
|
|
1334
|
+
)
|
|
1335
|
+
RETURNING *
|
|
1336
|
+
`;
|
|
1337
|
+
}
|
|
1338
|
+
function buildInsertNodeNoReturn(tables3, params, timestamp2) {
|
|
1339
|
+
const { nodes: nodes3 } = tables3;
|
|
1340
|
+
const propsJson = JSON.stringify(params.props);
|
|
1341
|
+
const columns = nodeColumnList(nodes3);
|
|
1342
|
+
return drizzleOrm.sql`
|
|
1343
|
+
INSERT INTO ${nodes3} (${columns})
|
|
1344
|
+
VALUES (
|
|
1345
|
+
${params.graphId}, ${params.kind}, ${params.id}, ${propsJson},
|
|
1346
|
+
1, ${sqlNull(params.validFrom)}, ${sqlNull(params.validTo)},
|
|
1347
|
+
${timestamp2}, ${timestamp2}
|
|
1348
|
+
)
|
|
1349
|
+
`;
|
|
1350
|
+
}
|
|
1351
|
+
function buildInsertNodesBatch(tables3, params, timestamp2) {
|
|
1352
|
+
const { nodes: nodes3 } = tables3;
|
|
1353
|
+
const columns = nodeColumnList(nodes3);
|
|
1354
|
+
const values = params.map((nodeParams) => {
|
|
1355
|
+
const propsJson = JSON.stringify(nodeParams.props);
|
|
1356
|
+
return drizzleOrm.sql`(${nodeParams.graphId}, ${nodeParams.kind}, ${nodeParams.id}, ${propsJson}, 1, ${sqlNull(nodeParams.validFrom)}, ${sqlNull(nodeParams.validTo)}, ${timestamp2}, ${timestamp2})`;
|
|
1357
|
+
});
|
|
1358
|
+
return drizzleOrm.sql`
|
|
1359
|
+
INSERT INTO ${nodes3} (${columns})
|
|
1360
|
+
VALUES ${drizzleOrm.sql.join(values, drizzleOrm.sql`, `)}
|
|
1361
|
+
`;
|
|
1362
|
+
}
|
|
1363
|
+
function buildInsertNodesBatchReturning(tables3, params, timestamp2) {
|
|
1364
|
+
const { nodes: nodes3 } = tables3;
|
|
1365
|
+
const columns = nodeColumnList(nodes3);
|
|
1366
|
+
const values = params.map((nodeParams) => {
|
|
1367
|
+
const propsJson = JSON.stringify(nodeParams.props);
|
|
1368
|
+
return drizzleOrm.sql`(${nodeParams.graphId}, ${nodeParams.kind}, ${nodeParams.id}, ${propsJson}, 1, ${sqlNull(nodeParams.validFrom)}, ${sqlNull(nodeParams.validTo)}, ${timestamp2}, ${timestamp2})`;
|
|
1369
|
+
});
|
|
1370
|
+
return drizzleOrm.sql`
|
|
1371
|
+
INSERT INTO ${nodes3} (${columns})
|
|
1372
|
+
VALUES ${drizzleOrm.sql.join(values, drizzleOrm.sql`, `)}
|
|
1373
|
+
RETURNING *
|
|
1374
|
+
`;
|
|
1375
|
+
}
|
|
1376
|
+
function buildGetNode(tables3, graphId, kind, id) {
|
|
1377
|
+
const { nodes: nodes3 } = tables3;
|
|
1378
|
+
return drizzleOrm.sql`
|
|
1379
|
+
SELECT * FROM ${nodes3}
|
|
1380
|
+
WHERE ${nodes3.graphId} = ${graphId}
|
|
1381
|
+
AND ${nodes3.kind} = ${kind}
|
|
1382
|
+
AND ${nodes3.id} = ${id}
|
|
1383
|
+
`;
|
|
1384
|
+
}
|
|
1385
|
+
function buildGetNodes(tables3, graphId, kind, ids) {
|
|
1386
|
+
const { nodes: nodes3 } = tables3;
|
|
1387
|
+
const idPlaceholders = drizzleOrm.sql.join(
|
|
1388
|
+
ids.map((nodeId) => drizzleOrm.sql`${nodeId}`),
|
|
1389
|
+
drizzleOrm.sql`, `
|
|
1390
|
+
);
|
|
1391
|
+
return drizzleOrm.sql`
|
|
1392
|
+
SELECT * FROM ${nodes3}
|
|
1393
|
+
WHERE ${nodes3.graphId} = ${graphId}
|
|
1394
|
+
AND ${nodes3.kind} = ${kind}
|
|
1395
|
+
AND ${nodes3.id} IN (${idPlaceholders})
|
|
1396
|
+
`;
|
|
1397
|
+
}
|
|
1398
|
+
function buildUpdateNode(tables3, params, timestamp2) {
|
|
1399
|
+
const { nodes: nodes3 } = tables3;
|
|
1400
|
+
const propsJson = JSON.stringify(params.props);
|
|
1401
|
+
const setParts = [
|
|
1402
|
+
drizzleOrm.sql`${quotedColumn(nodes3.props)} = ${propsJson}`,
|
|
1403
|
+
drizzleOrm.sql`${quotedColumn(nodes3.updatedAt)} = ${timestamp2}`
|
|
1404
|
+
];
|
|
1405
|
+
if (params.incrementVersion) {
|
|
1406
|
+
setParts.push(
|
|
1407
|
+
drizzleOrm.sql`${quotedColumn(nodes3.version)} = ${quotedColumn(nodes3.version)} + 1`
|
|
1408
|
+
);
|
|
1409
|
+
}
|
|
1410
|
+
if (params.validTo !== void 0) {
|
|
1411
|
+
setParts.push(drizzleOrm.sql`${quotedColumn(nodes3.validTo)} = ${params.validTo}`);
|
|
1412
|
+
}
|
|
1413
|
+
if (params.clearDeleted) {
|
|
1414
|
+
setParts.push(drizzleOrm.sql`${quotedColumn(nodes3.deletedAt)} = NULL`);
|
|
1415
|
+
}
|
|
1416
|
+
const setClause = drizzleOrm.sql.join(setParts, drizzleOrm.sql`, `);
|
|
1417
|
+
if (params.clearDeleted) {
|
|
1418
|
+
return drizzleOrm.sql`
|
|
1419
|
+
UPDATE ${nodes3}
|
|
1420
|
+
SET ${setClause}
|
|
1421
|
+
WHERE ${nodes3.graphId} = ${params.graphId}
|
|
1422
|
+
AND ${nodes3.kind} = ${params.kind}
|
|
1423
|
+
AND ${nodes3.id} = ${params.id}
|
|
1424
|
+
RETURNING *
|
|
1425
|
+
`;
|
|
1426
|
+
}
|
|
1427
|
+
return drizzleOrm.sql`
|
|
1428
|
+
UPDATE ${nodes3}
|
|
1429
|
+
SET ${setClause}
|
|
1430
|
+
WHERE ${nodes3.graphId} = ${params.graphId}
|
|
1431
|
+
AND ${nodes3.kind} = ${params.kind}
|
|
1432
|
+
AND ${nodes3.id} = ${params.id}
|
|
1433
|
+
AND ${nodes3.deletedAt} IS NULL
|
|
1434
|
+
RETURNING *
|
|
1435
|
+
`;
|
|
1436
|
+
}
|
|
1437
|
+
function buildDeleteNode(tables3, params, timestamp2) {
|
|
1438
|
+
const { nodes: nodes3 } = tables3;
|
|
1439
|
+
return drizzleOrm.sql`
|
|
1440
|
+
UPDATE ${nodes3}
|
|
1441
|
+
SET ${quotedColumn(nodes3.deletedAt)} = ${timestamp2}
|
|
1442
|
+
WHERE ${nodes3.graphId} = ${params.graphId}
|
|
1443
|
+
AND ${nodes3.kind} = ${params.kind}
|
|
1444
|
+
AND ${nodes3.id} = ${params.id}
|
|
1445
|
+
AND ${nodes3.deletedAt} IS NULL
|
|
1446
|
+
`;
|
|
1447
|
+
}
|
|
1448
|
+
function buildHardDeleteNode(tables3, params) {
|
|
1449
|
+
const { nodes: nodes3 } = tables3;
|
|
1450
|
+
return drizzleOrm.sql`
|
|
1451
|
+
DELETE FROM ${nodes3}
|
|
1452
|
+
WHERE ${nodes3.graphId} = ${params.graphId}
|
|
1453
|
+
AND ${nodes3.kind} = ${params.kind}
|
|
1454
|
+
AND ${nodes3.id} = ${params.id}
|
|
1455
|
+
`;
|
|
1456
|
+
}
|
|
1457
|
+
function createSchemaDialectStrategy(dialect) {
|
|
1458
|
+
const trueLiteral = dialect === "sqlite" ? drizzleOrm.sql.raw("1") : drizzleOrm.sql.raw("TRUE");
|
|
1459
|
+
const falseLiteral = dialect === "sqlite" ? drizzleOrm.sql.raw("0") : drizzleOrm.sql.raw("FALSE");
|
|
1460
|
+
return {
|
|
1461
|
+
booleanLiteral(value) {
|
|
1462
|
+
return value ? trueLiteral : falseLiteral;
|
|
1463
|
+
}
|
|
1464
|
+
};
|
|
1465
|
+
}
|
|
1466
|
+
var SCHEMA_DIALECT_STRATEGIES = {
|
|
1467
|
+
postgres: createSchemaDialectStrategy("postgres"),
|
|
1468
|
+
sqlite: createSchemaDialectStrategy("sqlite")
|
|
1469
|
+
};
|
|
1470
|
+
function buildInsertSchema(tables3, params, timestamp2, dialect = "sqlite") {
|
|
1471
|
+
const { schemaVersions: schemaVersions3 } = tables3;
|
|
1472
|
+
const strategy = SCHEMA_DIALECT_STRATEGIES[dialect];
|
|
1473
|
+
const schemaDocumentJson = JSON.stringify(params.schemaDoc);
|
|
1474
|
+
const isActiveValue = strategy.booleanLiteral(params.isActive);
|
|
1475
|
+
const columns = drizzleOrm.sql.raw(`"${schemaVersions3.graphId.name}", "${schemaVersions3.version.name}", "${schemaVersions3.schemaHash.name}", "${schemaVersions3.schemaDoc.name}", "${schemaVersions3.createdAt.name}", "${schemaVersions3.isActive.name}"`);
|
|
1476
|
+
return drizzleOrm.sql`
|
|
1477
|
+
INSERT INTO ${schemaVersions3} (${columns})
|
|
1478
|
+
VALUES (
|
|
1479
|
+
${params.graphId}, ${params.version},
|
|
1480
|
+
${params.schemaHash}, ${schemaDocumentJson},
|
|
1481
|
+
${timestamp2}, ${isActiveValue}
|
|
1482
|
+
)
|
|
1483
|
+
RETURNING *
|
|
1484
|
+
`;
|
|
1485
|
+
}
|
|
1486
|
+
function buildGetActiveSchema(tables3, graphId, dialect = "sqlite") {
|
|
1487
|
+
const { schemaVersions: schemaVersions3 } = tables3;
|
|
1488
|
+
const strategy = SCHEMA_DIALECT_STRATEGIES[dialect];
|
|
1489
|
+
return drizzleOrm.sql`
|
|
1490
|
+
SELECT * FROM ${schemaVersions3}
|
|
1491
|
+
WHERE ${schemaVersions3.graphId} = ${graphId}
|
|
1492
|
+
AND ${schemaVersions3.isActive} = ${strategy.booleanLiteral(true)}
|
|
1493
|
+
`;
|
|
1494
|
+
}
|
|
1495
|
+
function buildGetSchemaVersion(tables3, graphId, version) {
|
|
1496
|
+
const { schemaVersions: schemaVersions3 } = tables3;
|
|
1497
|
+
return drizzleOrm.sql`
|
|
1498
|
+
SELECT * FROM ${schemaVersions3}
|
|
1499
|
+
WHERE ${schemaVersions3.graphId} = ${graphId}
|
|
1500
|
+
AND ${schemaVersions3.version} = ${version}
|
|
1501
|
+
`;
|
|
1502
|
+
}
|
|
1503
|
+
function buildSetActiveSchema(tables3, graphId, version, dialect = "sqlite") {
|
|
1504
|
+
const { schemaVersions: schemaVersions3 } = tables3;
|
|
1505
|
+
const strategy = SCHEMA_DIALECT_STRATEGIES[dialect];
|
|
1506
|
+
const deactivateAll = drizzleOrm.sql`
|
|
1507
|
+
UPDATE ${schemaVersions3}
|
|
1508
|
+
SET ${quotedColumn(schemaVersions3.isActive)} = ${strategy.booleanLiteral(false)}
|
|
1509
|
+
WHERE ${schemaVersions3.graphId} = ${graphId}
|
|
1510
|
+
`;
|
|
1511
|
+
const activateVersion = drizzleOrm.sql`
|
|
1512
|
+
UPDATE ${schemaVersions3}
|
|
1513
|
+
SET ${quotedColumn(schemaVersions3.isActive)} = ${strategy.booleanLiteral(true)}
|
|
1514
|
+
WHERE ${schemaVersions3.graphId} = ${graphId}
|
|
1515
|
+
AND ${schemaVersions3.version} = ${version}
|
|
1516
|
+
`;
|
|
1517
|
+
return { deactivateAll, activateVersion };
|
|
1518
|
+
}
|
|
1519
|
+
function buildInsertUniqueSqlite(tables3, params) {
|
|
1520
|
+
const { uniques: uniques3 } = tables3;
|
|
1521
|
+
const columns = drizzleOrm.sql.raw(`"${uniques3.graphId.name}", "${uniques3.nodeKind.name}", "${uniques3.constraintName.name}", "${uniques3.key.name}", "${uniques3.nodeId.name}", "${uniques3.concreteKind.name}", "${uniques3.deletedAt.name}"`);
|
|
1522
|
+
const conflictColumns = drizzleOrm.sql.raw(`"${uniques3.graphId.name}", "${uniques3.nodeKind.name}", "${uniques3.constraintName.name}", "${uniques3.key.name}"`);
|
|
1523
|
+
return drizzleOrm.sql`
|
|
1524
|
+
INSERT INTO ${uniques3} (${columns})
|
|
1525
|
+
VALUES (
|
|
1526
|
+
${params.graphId}, ${params.nodeKind}, ${params.constraintName},
|
|
1527
|
+
${params.key}, ${params.nodeId}, ${params.concreteKind}, ${drizzleOrm.sql.raw("NULL")}
|
|
1528
|
+
)
|
|
1529
|
+
ON CONFLICT (${conflictColumns})
|
|
1530
|
+
DO UPDATE SET
|
|
1531
|
+
${quotedColumn(uniques3.nodeId)} = CASE
|
|
1532
|
+
WHEN ${quotedColumn(uniques3.nodeId)} = ${params.nodeId} THEN ${params.nodeId}
|
|
1533
|
+
WHEN ${quotedColumn(uniques3.deletedAt)} IS NOT NULL THEN ${params.nodeId}
|
|
1534
|
+
ELSE ${quotedColumn(uniques3.nodeId)}
|
|
1535
|
+
END,
|
|
1536
|
+
${quotedColumn(uniques3.concreteKind)} = CASE
|
|
1537
|
+
WHEN ${quotedColumn(uniques3.nodeId)} = ${params.nodeId} THEN ${params.concreteKind}
|
|
1538
|
+
WHEN ${quotedColumn(uniques3.deletedAt)} IS NOT NULL THEN ${params.concreteKind}
|
|
1539
|
+
ELSE ${quotedColumn(uniques3.concreteKind)}
|
|
1540
|
+
END,
|
|
1541
|
+
${quotedColumn(uniques3.deletedAt)} = CASE
|
|
1542
|
+
WHEN ${quotedColumn(uniques3.nodeId)} = ${params.nodeId} THEN NULL
|
|
1543
|
+
WHEN ${quotedColumn(uniques3.deletedAt)} IS NOT NULL THEN NULL
|
|
1544
|
+
ELSE ${quotedColumn(uniques3.deletedAt)}
|
|
1545
|
+
END
|
|
1546
|
+
RETURNING ${quotedColumn(uniques3.nodeId)} as node_id
|
|
1547
|
+
`;
|
|
1548
|
+
}
|
|
1549
|
+
function buildInsertUniquePostgres(tables3, params) {
|
|
1550
|
+
const { uniques: uniques3 } = tables3;
|
|
1551
|
+
const columns = drizzleOrm.sql.raw(`"${uniques3.graphId.name}", "${uniques3.nodeKind.name}", "${uniques3.constraintName.name}", "${uniques3.key.name}", "${uniques3.nodeId.name}", "${uniques3.concreteKind.name}", "${uniques3.deletedAt.name}"`);
|
|
1552
|
+
const conflictColumns = drizzleOrm.sql.raw(`"${uniques3.graphId.name}", "${uniques3.nodeKind.name}", "${uniques3.constraintName.name}", "${uniques3.key.name}"`);
|
|
1553
|
+
const tableName = drizzleOrm.getTableName(uniques3);
|
|
1554
|
+
const existingColumn = (column) => drizzleOrm.sql.raw(`"${tableName}"."${column.name}"`);
|
|
1555
|
+
return drizzleOrm.sql`
|
|
1556
|
+
INSERT INTO ${uniques3} (${columns})
|
|
1557
|
+
VALUES (
|
|
1558
|
+
${params.graphId}, ${params.nodeKind}, ${params.constraintName},
|
|
1559
|
+
${params.key}, ${params.nodeId}, ${params.concreteKind}, ${drizzleOrm.sql.raw("NULL")}
|
|
1560
|
+
)
|
|
1561
|
+
ON CONFLICT (${conflictColumns})
|
|
1562
|
+
DO UPDATE SET
|
|
1563
|
+
${quotedColumn(uniques3.nodeId)} = CASE
|
|
1564
|
+
WHEN ${existingColumn(uniques3.nodeId)} = ${params.nodeId} THEN ${params.nodeId}
|
|
1565
|
+
WHEN ${existingColumn(uniques3.deletedAt)} IS NOT NULL THEN ${params.nodeId}
|
|
1566
|
+
ELSE ${existingColumn(uniques3.nodeId)}
|
|
1567
|
+
END,
|
|
1568
|
+
${quotedColumn(uniques3.concreteKind)} = CASE
|
|
1569
|
+
WHEN ${existingColumn(uniques3.nodeId)} = ${params.nodeId} THEN ${params.concreteKind}
|
|
1570
|
+
WHEN ${existingColumn(uniques3.deletedAt)} IS NOT NULL THEN ${params.concreteKind}
|
|
1571
|
+
ELSE ${existingColumn(uniques3.concreteKind)}
|
|
1572
|
+
END,
|
|
1573
|
+
${quotedColumn(uniques3.deletedAt)} = CASE
|
|
1574
|
+
WHEN ${existingColumn(uniques3.nodeId)} = ${params.nodeId} THEN NULL
|
|
1575
|
+
WHEN ${existingColumn(uniques3.deletedAt)} IS NOT NULL THEN NULL
|
|
1576
|
+
ELSE ${existingColumn(uniques3.deletedAt)}
|
|
1577
|
+
END
|
|
1578
|
+
RETURNING ${quotedColumn(uniques3.nodeId)} as node_id
|
|
1579
|
+
`;
|
|
1580
|
+
}
|
|
1581
|
+
var UNIQUE_INSERT_BUILDERS = {
|
|
1582
|
+
postgres: buildInsertUniquePostgres,
|
|
1583
|
+
sqlite: buildInsertUniqueSqlite
|
|
1584
|
+
};
|
|
1585
|
+
function buildInsertUnique(tables3, dialect, params) {
|
|
1586
|
+
const builder = UNIQUE_INSERT_BUILDERS[dialect];
|
|
1587
|
+
return builder(tables3, params);
|
|
1588
|
+
}
|
|
1589
|
+
function buildDeleteUnique(tables3, params, timestamp2) {
|
|
1590
|
+
const { uniques: uniques3 } = tables3;
|
|
1591
|
+
return drizzleOrm.sql`
|
|
1592
|
+
UPDATE ${uniques3}
|
|
1593
|
+
SET ${quotedColumn(uniques3.deletedAt)} = ${timestamp2}
|
|
1594
|
+
WHERE ${uniques3.graphId} = ${params.graphId}
|
|
1595
|
+
AND ${uniques3.nodeKind} = ${params.nodeKind}
|
|
1596
|
+
AND ${uniques3.constraintName} = ${params.constraintName}
|
|
1597
|
+
AND ${uniques3.key} = ${params.key}
|
|
1598
|
+
AND ${uniques3.deletedAt} IS NULL
|
|
1599
|
+
`;
|
|
1600
|
+
}
|
|
1601
|
+
function buildHardDeleteUniquesByNode(tables3, graphId, nodeId) {
|
|
1602
|
+
const { uniques: uniques3 } = tables3;
|
|
1603
|
+
return drizzleOrm.sql`
|
|
1604
|
+
DELETE FROM ${uniques3}
|
|
1605
|
+
WHERE ${uniques3.graphId} = ${graphId}
|
|
1606
|
+
AND ${uniques3.nodeId} = ${nodeId}
|
|
1607
|
+
`;
|
|
1608
|
+
}
|
|
1609
|
+
function buildHardDeleteEmbeddingsByNode(tables3, graphId, nodeKind, nodeId) {
|
|
1610
|
+
const { embeddings: embeddings3 } = tables3;
|
|
1611
|
+
return drizzleOrm.sql`
|
|
1612
|
+
DELETE FROM ${embeddings3}
|
|
1613
|
+
WHERE ${embeddings3.graphId} = ${graphId}
|
|
1614
|
+
AND ${embeddings3.nodeKind} = ${nodeKind}
|
|
1615
|
+
AND ${embeddings3.nodeId} = ${nodeId}
|
|
1616
|
+
`;
|
|
1617
|
+
}
|
|
1618
|
+
function buildCheckUnique(tables3, params) {
|
|
1619
|
+
const { uniques: uniques3 } = tables3;
|
|
1620
|
+
if (params.includeDeleted) {
|
|
1621
|
+
return drizzleOrm.sql`
|
|
1622
|
+
SELECT * FROM ${uniques3}
|
|
1623
|
+
WHERE ${uniques3.graphId} = ${params.graphId}
|
|
1624
|
+
AND ${uniques3.nodeKind} = ${params.nodeKind}
|
|
1625
|
+
AND ${uniques3.constraintName} = ${params.constraintName}
|
|
1626
|
+
AND ${uniques3.key} = ${params.key}
|
|
1627
|
+
`;
|
|
1628
|
+
}
|
|
1629
|
+
return drizzleOrm.sql`
|
|
1630
|
+
SELECT * FROM ${uniques3}
|
|
1631
|
+
WHERE ${uniques3.graphId} = ${params.graphId}
|
|
1632
|
+
AND ${uniques3.nodeKind} = ${params.nodeKind}
|
|
1633
|
+
AND ${uniques3.constraintName} = ${params.constraintName}
|
|
1634
|
+
AND ${uniques3.key} = ${params.key}
|
|
1635
|
+
AND ${uniques3.deletedAt} IS NULL
|
|
1636
|
+
`;
|
|
1637
|
+
}
|
|
1638
|
+
function buildCheckUniqueBatch(tables3, params) {
|
|
1639
|
+
const { uniques: uniques3 } = tables3;
|
|
1640
|
+
const keyPlaceholders = drizzleOrm.sql.join(
|
|
1641
|
+
params.keys.map((key) => drizzleOrm.sql`${key}`),
|
|
1642
|
+
drizzleOrm.sql`, `
|
|
1643
|
+
);
|
|
1644
|
+
if (params.includeDeleted) {
|
|
1645
|
+
return drizzleOrm.sql`
|
|
1646
|
+
SELECT * FROM ${uniques3}
|
|
1647
|
+
WHERE ${uniques3.graphId} = ${params.graphId}
|
|
1648
|
+
AND ${uniques3.nodeKind} = ${params.nodeKind}
|
|
1649
|
+
AND ${uniques3.constraintName} = ${params.constraintName}
|
|
1650
|
+
AND ${uniques3.key} IN (${keyPlaceholders})
|
|
1651
|
+
`;
|
|
1652
|
+
}
|
|
1653
|
+
return drizzleOrm.sql`
|
|
1654
|
+
SELECT * FROM ${uniques3}
|
|
1655
|
+
WHERE ${uniques3.graphId} = ${params.graphId}
|
|
1656
|
+
AND ${uniques3.nodeKind} = ${params.nodeKind}
|
|
1657
|
+
AND ${uniques3.constraintName} = ${params.constraintName}
|
|
1658
|
+
AND ${uniques3.key} IN (${keyPlaceholders})
|
|
1659
|
+
AND ${uniques3.deletedAt} IS NULL
|
|
1660
|
+
`;
|
|
1661
|
+
}
|
|
1662
|
+
function assertFiniteNumberArray(array, name) {
|
|
1663
|
+
for (const [index3, value] of array.entries()) {
|
|
1664
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
1665
|
+
throw new TypeError(
|
|
1666
|
+
`${name}[${index3}] must be a finite number, got: ${value}`
|
|
1667
|
+
);
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
function formatEmbeddingLiteral(embedding) {
|
|
1672
|
+
assertFiniteNumberArray(embedding, "embedding");
|
|
1673
|
+
return `[${embedding.join(",")}]`;
|
|
1674
|
+
}
|
|
1675
|
+
function buildUpsertEmbeddingPostgres(tables3, params, timestamp2) {
|
|
1676
|
+
const { embeddings: embeddings3 } = tables3;
|
|
1677
|
+
const embeddingLiteral = formatEmbeddingLiteral(params.embedding);
|
|
1678
|
+
const columns = drizzleOrm.sql.raw(
|
|
1679
|
+
`"${embeddings3.graphId.name}", "${embeddings3.nodeKind.name}", "${embeddings3.nodeId.name}", "${embeddings3.fieldPath.name}", "${embeddings3.embedding.name}", "${embeddings3.dimensions.name}", "${embeddings3.createdAt.name}", "${embeddings3.updatedAt.name}"`
|
|
1680
|
+
);
|
|
1681
|
+
const conflictColumns = drizzleOrm.sql.raw(
|
|
1682
|
+
`"${embeddings3.graphId.name}", "${embeddings3.nodeKind.name}", "${embeddings3.nodeId.name}", "${embeddings3.fieldPath.name}"`
|
|
1683
|
+
);
|
|
1684
|
+
const column = (target) => drizzleOrm.sql.raw(`"${target.name}"`);
|
|
1685
|
+
return drizzleOrm.sql`
|
|
1686
|
+
INSERT INTO ${embeddings3} (${columns})
|
|
1687
|
+
VALUES (
|
|
1688
|
+
${params.graphId}, ${params.nodeKind}, ${params.nodeId}, ${params.fieldPath},
|
|
1689
|
+
${embeddingLiteral}::vector, ${params.dimensions}, ${timestamp2}, ${timestamp2}
|
|
1690
|
+
)
|
|
1691
|
+
ON CONFLICT (${conflictColumns})
|
|
1692
|
+
DO UPDATE SET
|
|
1693
|
+
${column(embeddings3.embedding)} = ${embeddingLiteral}::vector,
|
|
1694
|
+
${column(embeddings3.dimensions)} = ${params.dimensions},
|
|
1695
|
+
${column(embeddings3.updatedAt)} = ${timestamp2}
|
|
1696
|
+
`;
|
|
1697
|
+
}
|
|
1698
|
+
function buildDeleteEmbedding(tables3, params) {
|
|
1699
|
+
const { embeddings: embeddings3 } = tables3;
|
|
1700
|
+
return drizzleOrm.sql`
|
|
1701
|
+
DELETE FROM ${embeddings3}
|
|
1702
|
+
WHERE ${embeddings3.graphId} = ${params.graphId}
|
|
1703
|
+
AND ${embeddings3.nodeKind} = ${params.nodeKind}
|
|
1704
|
+
AND ${embeddings3.nodeId} = ${params.nodeId}
|
|
1705
|
+
AND ${embeddings3.fieldPath} = ${params.fieldPath}
|
|
1706
|
+
`;
|
|
1707
|
+
}
|
|
1708
|
+
function buildGetEmbedding(tables3, graphId, nodeKind, nodeId, fieldPath) {
|
|
1709
|
+
const { embeddings: embeddings3 } = tables3;
|
|
1710
|
+
return drizzleOrm.sql`
|
|
1711
|
+
SELECT * FROM ${embeddings3}
|
|
1712
|
+
WHERE ${embeddings3.graphId} = ${graphId}
|
|
1713
|
+
AND ${embeddings3.nodeKind} = ${nodeKind}
|
|
1714
|
+
AND ${embeddings3.nodeId} = ${nodeId}
|
|
1715
|
+
AND ${embeddings3.fieldPath} = ${fieldPath}
|
|
1716
|
+
`;
|
|
1717
|
+
}
|
|
1718
|
+
function buildDistanceExpression(embeddingColumn, queryLiteral, metric) {
|
|
1719
|
+
const vectorParameter = drizzleOrm.sql`${queryLiteral}::vector`;
|
|
1720
|
+
switch (metric) {
|
|
1721
|
+
case "cosine": {
|
|
1722
|
+
return drizzleOrm.sql`(${embeddingColumn} <=> ${vectorParameter})`;
|
|
1723
|
+
}
|
|
1724
|
+
case "l2": {
|
|
1725
|
+
return drizzleOrm.sql`(${embeddingColumn} <-> ${vectorParameter})`;
|
|
1726
|
+
}
|
|
1727
|
+
case "inner_product": {
|
|
1728
|
+
return drizzleOrm.sql`(${embeddingColumn} <#> ${vectorParameter})`;
|
|
1729
|
+
}
|
|
1730
|
+
default: {
|
|
1731
|
+
const _exhaustive = metric;
|
|
1732
|
+
throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
function buildVectorSearchScoreExpression(distanceExpression, metric) {
|
|
1737
|
+
switch (metric) {
|
|
1738
|
+
case "cosine": {
|
|
1739
|
+
return drizzleOrm.sql`(1 - (${distanceExpression}))`;
|
|
1740
|
+
}
|
|
1741
|
+
case "l2":
|
|
1742
|
+
case "inner_product": {
|
|
1743
|
+
return distanceExpression;
|
|
1744
|
+
}
|
|
1745
|
+
default: {
|
|
1746
|
+
const _exhaustive = metric;
|
|
1747
|
+
throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
function buildVectorSearchMinScoreCondition(distanceExpression, metric, minScore) {
|
|
1752
|
+
switch (metric) {
|
|
1753
|
+
case "cosine": {
|
|
1754
|
+
const threshold = 1 - minScore;
|
|
1755
|
+
return drizzleOrm.sql`${distanceExpression} <= ${threshold}`;
|
|
1756
|
+
}
|
|
1757
|
+
case "l2": {
|
|
1758
|
+
return drizzleOrm.sql`${distanceExpression} <= ${minScore}`;
|
|
1759
|
+
}
|
|
1760
|
+
case "inner_product": {
|
|
1761
|
+
const negativeThreshold = -minScore;
|
|
1762
|
+
return drizzleOrm.sql`${distanceExpression} <= ${negativeThreshold}`;
|
|
1763
|
+
}
|
|
1764
|
+
default: {
|
|
1765
|
+
const _exhaustive = metric;
|
|
1766
|
+
throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
function buildVectorSearchPostgres(tables3, params) {
|
|
1771
|
+
const { embeddings: embeddings3 } = tables3;
|
|
1772
|
+
const queryLiteral = formatEmbeddingLiteral(params.queryEmbedding);
|
|
1773
|
+
if (params.minScore !== void 0 && !Number.isFinite(params.minScore)) {
|
|
1774
|
+
throw new TypeError(
|
|
1775
|
+
`minScore must be a finite number, got: ${params.minScore}`
|
|
1776
|
+
);
|
|
1777
|
+
}
|
|
1778
|
+
if (!Number.isInteger(params.limit) || params.limit <= 0) {
|
|
1779
|
+
throw new Error(`limit must be a positive integer, got: ${params.limit}`);
|
|
1780
|
+
}
|
|
1781
|
+
const embeddingColumn = drizzleOrm.sql`${embeddings3.embedding}`;
|
|
1782
|
+
const distanceExpression = buildDistanceExpression(
|
|
1783
|
+
embeddingColumn,
|
|
1784
|
+
queryLiteral,
|
|
1785
|
+
params.metric
|
|
1786
|
+
);
|
|
1787
|
+
const conditions = [
|
|
1788
|
+
drizzleOrm.sql`${embeddings3.graphId} = ${params.graphId}`,
|
|
1789
|
+
drizzleOrm.sql`${embeddings3.nodeKind} = ${params.nodeKind}`,
|
|
1790
|
+
drizzleOrm.sql`${embeddings3.fieldPath} = ${params.fieldPath}`
|
|
1791
|
+
];
|
|
1792
|
+
if (params.minScore !== void 0) {
|
|
1793
|
+
conditions.push(
|
|
1794
|
+
buildVectorSearchMinScoreCondition(
|
|
1795
|
+
distanceExpression,
|
|
1796
|
+
params.metric,
|
|
1797
|
+
params.minScore
|
|
1798
|
+
)
|
|
1799
|
+
);
|
|
1800
|
+
}
|
|
1801
|
+
const whereClause = drizzleOrm.sql.join(conditions, drizzleOrm.sql` AND `);
|
|
1802
|
+
const scoreExpression = buildVectorSearchScoreExpression(
|
|
1803
|
+
distanceExpression,
|
|
1804
|
+
params.metric
|
|
1805
|
+
);
|
|
1806
|
+
return drizzleOrm.sql`
|
|
1807
|
+
SELECT
|
|
1808
|
+
${embeddings3.nodeId} as node_id,
|
|
1809
|
+
${scoreExpression} as score
|
|
1810
|
+
FROM ${embeddings3}
|
|
1811
|
+
WHERE ${whereClause}
|
|
1812
|
+
ORDER BY ${distanceExpression} ASC
|
|
1813
|
+
LIMIT ${params.limit}
|
|
1814
|
+
`;
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
// src/backend/drizzle/operations/strategy.ts
|
|
1818
|
+
function bindTableOperationBuilders(tables3, builders) {
|
|
1819
|
+
const boundEntries = Object.entries(builders).map(([name, builder]) => {
|
|
1820
|
+
function boundBuilder(...args) {
|
|
1821
|
+
return builder(tables3, ...args);
|
|
1822
|
+
}
|
|
1823
|
+
return [name, boundBuilder];
|
|
1824
|
+
});
|
|
1825
|
+
return Object.fromEntries(boundEntries);
|
|
1826
|
+
}
|
|
1827
|
+
var COMMON_TABLE_OPERATION_BUILDERS = {
|
|
1828
|
+
buildInsertNode,
|
|
1829
|
+
buildInsertNodeNoReturn,
|
|
1830
|
+
buildInsertNodesBatch,
|
|
1831
|
+
buildInsertNodesBatchReturning,
|
|
1832
|
+
buildGetNode,
|
|
1833
|
+
buildGetNodes,
|
|
1834
|
+
buildUpdateNode,
|
|
1835
|
+
buildDeleteNode,
|
|
1836
|
+
buildHardDeleteNode,
|
|
1837
|
+
buildInsertEdge,
|
|
1838
|
+
buildInsertEdgeNoReturn,
|
|
1839
|
+
buildInsertEdgesBatch,
|
|
1840
|
+
buildInsertEdgesBatchReturning,
|
|
1841
|
+
buildGetEdge,
|
|
1842
|
+
buildGetEdges,
|
|
1843
|
+
buildUpdateEdge,
|
|
1844
|
+
buildDeleteEdge,
|
|
1845
|
+
buildHardDeleteEdge,
|
|
1846
|
+
buildHardDeleteEdgesByNode,
|
|
1847
|
+
buildCountEdgesFrom,
|
|
1848
|
+
buildEdgeExistsBetween,
|
|
1849
|
+
buildFindEdgesConnectedTo,
|
|
1850
|
+
buildFindNodesByKind,
|
|
1851
|
+
buildCountNodesByKind,
|
|
1852
|
+
buildFindEdgesByKind,
|
|
1853
|
+
buildCountEdgesByKind,
|
|
1854
|
+
buildDeleteUnique,
|
|
1855
|
+
buildHardDeleteUniquesByNode,
|
|
1856
|
+
buildHardDeleteEmbeddingsByNode,
|
|
1857
|
+
buildCheckUnique,
|
|
1858
|
+
buildCheckUniqueBatch,
|
|
1859
|
+
buildGetSchemaVersion
|
|
1860
|
+
};
|
|
1861
|
+
function createCommonOperationStrategy(tables3, dialect) {
|
|
1862
|
+
const tableOperations = bindTableOperationBuilders(
|
|
1863
|
+
tables3,
|
|
1864
|
+
COMMON_TABLE_OPERATION_BUILDERS
|
|
1865
|
+
);
|
|
1866
|
+
return {
|
|
1867
|
+
...tableOperations,
|
|
1868
|
+
buildInsertUnique(params) {
|
|
1869
|
+
return buildInsertUnique(tables3, dialect, params);
|
|
1870
|
+
},
|
|
1871
|
+
buildGetActiveSchema(graphId) {
|
|
1872
|
+
return buildGetActiveSchema(tables3, graphId, dialect);
|
|
1873
|
+
},
|
|
1874
|
+
buildInsertSchema(params, timestamp2) {
|
|
1875
|
+
return buildInsertSchema(tables3, params, timestamp2, dialect);
|
|
1876
|
+
},
|
|
1877
|
+
buildSetActiveSchema(graphId, version) {
|
|
1878
|
+
return buildSetActiveSchema(tables3, graphId, version, dialect);
|
|
1879
|
+
},
|
|
1880
|
+
buildClearGraph(graphId) {
|
|
1881
|
+
return buildClearGraph(tables3, graphId);
|
|
1882
|
+
}
|
|
1883
|
+
};
|
|
1884
|
+
}
|
|
1885
|
+
function createSqliteOperationStrategy(tables3) {
|
|
1886
|
+
return createCommonOperationStrategy(tables3, "sqlite");
|
|
1887
|
+
}
|
|
1888
|
+
function createPostgresOperationStrategy(tables3) {
|
|
1889
|
+
const common = createCommonOperationStrategy(tables3, "postgres");
|
|
1890
|
+
return {
|
|
1891
|
+
...common,
|
|
1892
|
+
buildUpsertEmbedding(params, timestamp2) {
|
|
1893
|
+
return buildUpsertEmbeddingPostgres(tables3, params, timestamp2);
|
|
1894
|
+
},
|
|
1895
|
+
buildDeleteEmbedding(params) {
|
|
1896
|
+
return buildDeleteEmbedding(tables3, params);
|
|
1897
|
+
},
|
|
1898
|
+
buildGetEmbedding(graphId, nodeKind, nodeId, fieldPath) {
|
|
1899
|
+
return buildGetEmbedding(tables3, graphId, nodeKind, nodeId, fieldPath);
|
|
1900
|
+
},
|
|
1901
|
+
buildVectorSearch(params) {
|
|
1902
|
+
return buildVectorSearchPostgres(tables3, params);
|
|
1903
|
+
}
|
|
1904
|
+
};
|
|
1905
|
+
}
|
|
1906
|
+
function assertPositiveInteger(value, name) {
|
|
1907
|
+
if (!Number.isInteger(value) || value <= 0) {
|
|
1908
|
+
throw new Error(`${name} must be a positive integer, got: ${value}`);
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
function assertSafeIdentifier(value, name) {
|
|
1912
|
+
if (!/^[a-z0-9_]+$/i.test(value)) {
|
|
1913
|
+
throw new Error(
|
|
1914
|
+
`${name} must contain only alphanumeric characters and underscores, got: ${value}`
|
|
1915
|
+
);
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
var MAX_IDENTIFIER_LENGTH = 63;
|
|
1919
|
+
function sanitizeIdentifier(s) {
|
|
1920
|
+
return s.toLowerCase().replaceAll(/[^a-z0-9_]/g, "_");
|
|
1921
|
+
}
|
|
1922
|
+
function quoteIdentifier(value) {
|
|
1923
|
+
return `"${value.replaceAll('"', '""')}"`;
|
|
1924
|
+
}
|
|
1925
|
+
function shortHash(input) {
|
|
1926
|
+
let h1 = 3735928559;
|
|
1927
|
+
let h2 = 1103547991;
|
|
1928
|
+
for (let index3 = 0; index3 < input.length; index3++) {
|
|
1929
|
+
const ch = input.codePointAt(index3);
|
|
1930
|
+
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
1931
|
+
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
1932
|
+
}
|
|
1933
|
+
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
1934
|
+
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
1935
|
+
const hi = (h2 >>> 0).toString(16).padStart(8, "0");
|
|
1936
|
+
const lo = (h1 >>> 0).toString(16).padStart(8, "0");
|
|
1937
|
+
return `${hi}${lo}`.slice(0, 8);
|
|
1938
|
+
}
|
|
1939
|
+
function generateVectorIndexName(graphId, nodeKind, fieldPath, metric = "cosine") {
|
|
1940
|
+
const parts = [
|
|
1941
|
+
"idx_emb",
|
|
1942
|
+
sanitizeIdentifier(graphId),
|
|
1943
|
+
sanitizeIdentifier(nodeKind),
|
|
1944
|
+
sanitizeIdentifier(fieldPath),
|
|
1945
|
+
metric
|
|
1946
|
+
];
|
|
1947
|
+
const name = parts.join("_");
|
|
1948
|
+
if (name.length <= MAX_IDENTIFIER_LENGTH) {
|
|
1949
|
+
return name;
|
|
1950
|
+
}
|
|
1951
|
+
const hash = shortHash(name);
|
|
1952
|
+
const truncated = name.slice(0, MAX_IDENTIFIER_LENGTH - 1 - hash.length);
|
|
1953
|
+
return `${truncated}_${hash}`;
|
|
1954
|
+
}
|
|
1955
|
+
function getOperatorClass(metric) {
|
|
1956
|
+
switch (metric) {
|
|
1957
|
+
case "cosine": {
|
|
1958
|
+
return "vector_cosine_ops";
|
|
1959
|
+
}
|
|
1960
|
+
case "l2": {
|
|
1961
|
+
return "vector_l2_ops";
|
|
1962
|
+
}
|
|
1963
|
+
case "inner_product": {
|
|
1964
|
+
return "vector_ip_ops";
|
|
1965
|
+
}
|
|
1966
|
+
default: {
|
|
1967
|
+
const _exhaustive = metric;
|
|
1968
|
+
throw new Error("Unsupported vector metric: " + String(_exhaustive));
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
function escapeSqlString(value) {
|
|
1973
|
+
const tag = `tg${crypto.randomUUID().replaceAll("-", "").slice(0, 8)}`;
|
|
1974
|
+
return `$${tag}$${value}$${tag}$`;
|
|
1975
|
+
}
|
|
1976
|
+
async function createPostgresVectorIndex(db, options) {
|
|
1977
|
+
const {
|
|
1978
|
+
graphId,
|
|
1979
|
+
nodeKind,
|
|
1980
|
+
fieldPath,
|
|
1981
|
+
dimensions,
|
|
1982
|
+
embeddingsTableName = "typegraph_node_embeddings",
|
|
1983
|
+
indexType = "hnsw",
|
|
1984
|
+
metric = "cosine",
|
|
1985
|
+
hnswM = 16,
|
|
1986
|
+
hnswEfConstruction = 64,
|
|
1987
|
+
ivfflatLists = 100
|
|
1988
|
+
} = options;
|
|
1989
|
+
assertPositiveInteger(dimensions, "dimensions");
|
|
1990
|
+
assertPositiveInteger(hnswM, "hnswM");
|
|
1991
|
+
assertPositiveInteger(hnswEfConstruction, "hnswEfConstruction");
|
|
1992
|
+
assertPositiveInteger(ivfflatLists, "ivfflatLists");
|
|
1993
|
+
const indexName = generateVectorIndexName(graphId, nodeKind, fieldPath, metric);
|
|
1994
|
+
const operatorClass = getOperatorClass(metric);
|
|
1995
|
+
const quotedEmbeddingsTableName = quoteIdentifier(embeddingsTableName);
|
|
1996
|
+
assertSafeIdentifier(indexName, "indexName");
|
|
1997
|
+
const safeGraphId = escapeSqlString(graphId);
|
|
1998
|
+
const safeNodeKind = escapeSqlString(nodeKind);
|
|
1999
|
+
const safeFieldPath = escapeSqlString(fieldPath);
|
|
2000
|
+
let indexSql;
|
|
2001
|
+
if (indexType === "hnsw") {
|
|
2002
|
+
indexSql = drizzleOrm.sql.raw(`
|
|
2003
|
+
CREATE INDEX IF NOT EXISTS ${indexName}
|
|
2004
|
+
ON ${quotedEmbeddingsTableName}
|
|
2005
|
+
USING hnsw ((embedding::vector(${dimensions})) ${operatorClass})
|
|
2006
|
+
WITH (m = ${hnswM}, ef_construction = ${hnswEfConstruction})
|
|
2007
|
+
WHERE graph_id = ${safeGraphId}
|
|
2008
|
+
AND node_kind = ${safeNodeKind}
|
|
2009
|
+
AND field_path = ${safeFieldPath}
|
|
2010
|
+
`);
|
|
2011
|
+
} else if (indexType === "ivfflat") {
|
|
2012
|
+
indexSql = drizzleOrm.sql.raw(`
|
|
2013
|
+
CREATE INDEX IF NOT EXISTS ${indexName}
|
|
2014
|
+
ON ${quotedEmbeddingsTableName}
|
|
2015
|
+
USING ivfflat ((embedding::vector(${dimensions})) ${operatorClass})
|
|
2016
|
+
WITH (lists = ${ivfflatLists})
|
|
2017
|
+
WHERE graph_id = ${safeGraphId}
|
|
2018
|
+
AND node_kind = ${safeNodeKind}
|
|
2019
|
+
AND field_path = ${safeFieldPath}
|
|
2020
|
+
`);
|
|
2021
|
+
} else {
|
|
2022
|
+
return {
|
|
2023
|
+
indexName,
|
|
2024
|
+
success: true,
|
|
2025
|
+
message: `Index type "${indexType}" not supported, skipping index creation`
|
|
2026
|
+
};
|
|
2027
|
+
}
|
|
2028
|
+
try {
|
|
2029
|
+
await db.execute(indexSql);
|
|
2030
|
+
return {
|
|
2031
|
+
indexName,
|
|
2032
|
+
success: true,
|
|
2033
|
+
message: `Created ${indexType.toUpperCase()} index "${indexName}" for ${nodeKind}.${fieldPath}`
|
|
2034
|
+
};
|
|
2035
|
+
} catch (error) {
|
|
2036
|
+
return {
|
|
2037
|
+
indexName,
|
|
2038
|
+
success: false,
|
|
2039
|
+
message: `Failed to create index: ${error instanceof Error ? error.message : String(error)}`
|
|
2040
|
+
};
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
async function dropPostgresVectorIndex(db, indexName) {
|
|
2044
|
+
assertSafeIdentifier(indexName, "indexName");
|
|
2045
|
+
try {
|
|
2046
|
+
const dropSql = drizzleOrm.sql.raw(`DROP INDEX IF EXISTS ${indexName}`);
|
|
2047
|
+
await db.execute(dropSql);
|
|
2048
|
+
return {
|
|
2049
|
+
indexName,
|
|
2050
|
+
success: true,
|
|
2051
|
+
message: `Dropped index "${indexName}"`
|
|
2052
|
+
};
|
|
2053
|
+
} catch (error) {
|
|
2054
|
+
return {
|
|
2055
|
+
indexName,
|
|
2056
|
+
success: false,
|
|
2057
|
+
message: `Failed to drop index: ${error instanceof Error ? error.message : String(error)}`
|
|
2058
|
+
};
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
function createSqliteVectorIndex(_options) {
|
|
2062
|
+
const indexName = generateVectorIndexName(
|
|
2063
|
+
_options.graphId,
|
|
2064
|
+
_options.nodeKind,
|
|
2065
|
+
_options.fieldPath,
|
|
2066
|
+
_options.metric
|
|
2067
|
+
);
|
|
2068
|
+
return {
|
|
2069
|
+
indexName,
|
|
2070
|
+
success: true,
|
|
2071
|
+
message: "SQLite/sqlite-vec uses optimized internal indexing, no explicit index needed"
|
|
2072
|
+
};
|
|
2073
|
+
}
|
|
2074
|
+
function dropSqliteVectorIndex(graphId, nodeKind, fieldPath, metric = "cosine") {
|
|
2075
|
+
const indexName = generateVectorIndexName(graphId, nodeKind, fieldPath, metric);
|
|
2076
|
+
return {
|
|
2077
|
+
indexName,
|
|
2078
|
+
success: true,
|
|
2079
|
+
message: "SQLite/sqlite-vec does not use explicit indexes"
|
|
2080
|
+
};
|
|
2081
|
+
}
|
|
2082
|
+
|
|
2083
|
+
// src/backend/drizzle/execution/types.ts
|
|
2084
|
+
function compileQueryWithDialect(db, query, backendName) {
|
|
2085
|
+
const databaseWithCompiler = db;
|
|
2086
|
+
const compiler = databaseWithCompiler.dialect;
|
|
2087
|
+
if (compiler === void 0) {
|
|
2088
|
+
throw new Error(`${backendName} backend is missing a SQL compiler`);
|
|
2089
|
+
}
|
|
2090
|
+
return compiler.sqlToQuery(query);
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2093
|
+
exports.D1_CAPABILITIES = D1_CAPABILITIES;
|
|
2094
|
+
exports.POSTGRES_CAPABILITIES = POSTGRES_CAPABILITIES;
|
|
2095
|
+
exports.POSTGRES_ROW_MAPPER_CONFIG = POSTGRES_ROW_MAPPER_CONFIG;
|
|
2096
|
+
exports.SQLITE_CAPABILITIES = SQLITE_CAPABILITIES;
|
|
2097
|
+
exports.SQLITE_ROW_MAPPER_CONFIG = SQLITE_ROW_MAPPER_CONFIG;
|
|
2098
|
+
exports.compileQueryWithDialect = compileQueryWithDialect;
|
|
2099
|
+
exports.createCommonOperationBackend = createCommonOperationBackend;
|
|
2100
|
+
exports.createEdgeRowMapper = createEdgeRowMapper;
|
|
2101
|
+
exports.createNodeRowMapper = createNodeRowMapper;
|
|
2102
|
+
exports.createPostgresOperationStrategy = createPostgresOperationStrategy;
|
|
2103
|
+
exports.createPostgresTables = createPostgresTables;
|
|
2104
|
+
exports.createPostgresVectorIndex = createPostgresVectorIndex;
|
|
2105
|
+
exports.createSchemaVersionRowMapper = createSchemaVersionRowMapper;
|
|
2106
|
+
exports.createSqliteOperationStrategy = createSqliteOperationStrategy;
|
|
2107
|
+
exports.createSqliteTables = createSqliteTables;
|
|
2108
|
+
exports.createSqliteVectorIndex = createSqliteVectorIndex;
|
|
2109
|
+
exports.createUniqueRowMapper = createUniqueRowMapper;
|
|
2110
|
+
exports.dropPostgresVectorIndex = dropPostgresVectorIndex;
|
|
2111
|
+
exports.dropSqliteVectorIndex = dropSqliteVectorIndex;
|
|
2112
|
+
exports.edges = edges;
|
|
2113
|
+
exports.edges2 = edges2;
|
|
2114
|
+
exports.embeddings = embeddings;
|
|
2115
|
+
exports.embeddings2 = embeddings2;
|
|
2116
|
+
exports.formatPostgresTimestamp = formatPostgresTimestamp;
|
|
2117
|
+
exports.generatePostgresDDL = generatePostgresDDL;
|
|
2118
|
+
exports.generatePostgresMigrationSQL = generatePostgresMigrationSQL;
|
|
2119
|
+
exports.generateSqliteDDL = generateSqliteDDL;
|
|
2120
|
+
exports.generateSqliteMigrationSQL = generateSqliteMigrationSQL;
|
|
2121
|
+
exports.generateVectorIndexName = generateVectorIndexName;
|
|
2122
|
+
exports.nodes = nodes;
|
|
2123
|
+
exports.nodes2 = nodes2;
|
|
2124
|
+
exports.nowIso = nowIso;
|
|
2125
|
+
exports.schemaVersions = schemaVersions;
|
|
2126
|
+
exports.schemaVersions2 = schemaVersions2;
|
|
2127
|
+
exports.tables = tables;
|
|
2128
|
+
exports.tables2 = tables2;
|
|
2129
|
+
exports.uniques = uniques;
|
|
2130
|
+
exports.uniques2 = uniques2;
|
|
2131
|
+
//# sourceMappingURL=chunk-23NGZHUN.cjs.map
|
|
2132
|
+
//# sourceMappingURL=chunk-23NGZHUN.cjs.map
|