@mastra/lance 0.2.10 → 0.2.11-alpha.1
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/CHANGELOG.md +18 -0
- package/package.json +17 -4
- package/.turbo/turbo-build.log +0 -4
- package/eslint.config.js +0 -6
- package/src/index.ts +0 -2
- package/src/storage/domains/legacy-evals/index.ts +0 -156
- package/src/storage/domains/memory/index.ts +0 -1000
- package/src/storage/domains/operations/index.ts +0 -489
- package/src/storage/domains/scores/index.ts +0 -243
- package/src/storage/domains/traces/index.ts +0 -212
- package/src/storage/domains/utils.ts +0 -158
- package/src/storage/domains/workflows/index.ts +0 -245
- package/src/storage/index.test.ts +0 -10
- package/src/storage/index.ts +0 -494
- package/src/vector/filter.test.ts +0 -295
- package/src/vector/filter.ts +0 -443
- package/src/vector/index.test.ts +0 -1493
- package/src/vector/index.ts +0 -941
- package/src/vector/types.ts +0 -16
- package/tsconfig.build.json +0 -9
- package/tsconfig.json +0 -5
- package/tsup.config.ts +0 -17
- package/vitest.config.ts +0 -11
|
@@ -1,489 +0,0 @@
|
|
|
1
|
-
import type { Connection } from '@lancedb/lancedb';
|
|
2
|
-
import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';
|
|
3
|
-
import { StoreOperations } from '@mastra/core/storage';
|
|
4
|
-
import type { TABLE_NAMES, StorageColumn } from '@mastra/core/storage';
|
|
5
|
-
import { Utf8, Int32, Float32, Binary, Schema, Field, Float64 } from 'apache-arrow';
|
|
6
|
-
import type { DataType } from 'apache-arrow';
|
|
7
|
-
import { getPrimaryKeys, getTableSchema, processResultWithTypeConversion, validateKeyTypes } from '../utils';
|
|
8
|
-
|
|
9
|
-
export class StoreOperationsLance extends StoreOperations {
|
|
10
|
-
client: Connection;
|
|
11
|
-
constructor({ client }: { client: Connection }) {
|
|
12
|
-
super();
|
|
13
|
-
this.client = client;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
protected getDefaultValue(type: StorageColumn['type']): string {
|
|
17
|
-
switch (type) {
|
|
18
|
-
case 'text':
|
|
19
|
-
return "''";
|
|
20
|
-
case 'timestamp':
|
|
21
|
-
return 'CURRENT_TIMESTAMP';
|
|
22
|
-
case 'integer':
|
|
23
|
-
case 'bigint':
|
|
24
|
-
return '0';
|
|
25
|
-
case 'jsonb':
|
|
26
|
-
return "'{}'";
|
|
27
|
-
case 'uuid':
|
|
28
|
-
return "''";
|
|
29
|
-
default:
|
|
30
|
-
return super.getDefaultValue(type);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async hasColumn(tableName: TABLE_NAMES, columnName: string): Promise<boolean> {
|
|
35
|
-
const table = await this.client.openTable(tableName);
|
|
36
|
-
const schema = await table.schema();
|
|
37
|
-
return schema.fields.some(field => field.name === columnName);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
private translateSchema(schema: Record<string, StorageColumn>): Schema {
|
|
41
|
-
const fields = Object.entries(schema).map(([name, column]) => {
|
|
42
|
-
// Convert string type to Arrow DataType
|
|
43
|
-
let arrowType: DataType;
|
|
44
|
-
switch (column.type.toLowerCase()) {
|
|
45
|
-
case 'text':
|
|
46
|
-
case 'uuid':
|
|
47
|
-
arrowType = new Utf8();
|
|
48
|
-
break;
|
|
49
|
-
case 'int':
|
|
50
|
-
case 'integer':
|
|
51
|
-
arrowType = new Int32();
|
|
52
|
-
break;
|
|
53
|
-
case 'bigint':
|
|
54
|
-
arrowType = new Float64();
|
|
55
|
-
break;
|
|
56
|
-
case 'float':
|
|
57
|
-
arrowType = new Float32();
|
|
58
|
-
break;
|
|
59
|
-
case 'jsonb':
|
|
60
|
-
case 'json':
|
|
61
|
-
arrowType = new Utf8();
|
|
62
|
-
break;
|
|
63
|
-
case 'binary':
|
|
64
|
-
arrowType = new Binary();
|
|
65
|
-
break;
|
|
66
|
-
case 'timestamp':
|
|
67
|
-
arrowType = new Float64();
|
|
68
|
-
break;
|
|
69
|
-
default:
|
|
70
|
-
// Default to string for unknown types
|
|
71
|
-
arrowType = new Utf8();
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Create a field with the appropriate arrow type
|
|
75
|
-
return new Field(name, arrowType, column.nullable ?? true);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
return new Schema(fields);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
async createTable({
|
|
82
|
-
tableName,
|
|
83
|
-
schema,
|
|
84
|
-
}: {
|
|
85
|
-
tableName: TABLE_NAMES;
|
|
86
|
-
schema: Record<string, StorageColumn>;
|
|
87
|
-
}): Promise<void> {
|
|
88
|
-
try {
|
|
89
|
-
if (!this.client) {
|
|
90
|
-
throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
|
|
91
|
-
}
|
|
92
|
-
if (!tableName) {
|
|
93
|
-
throw new Error('tableName is required for createTable.');
|
|
94
|
-
}
|
|
95
|
-
if (!schema) {
|
|
96
|
-
throw new Error('schema is required for createTable.');
|
|
97
|
-
}
|
|
98
|
-
} catch (error) {
|
|
99
|
-
throw new MastraError(
|
|
100
|
-
{
|
|
101
|
-
id: 'STORAGE_LANCE_STORAGE_CREATE_TABLE_INVALID_ARGS',
|
|
102
|
-
domain: ErrorDomain.STORAGE,
|
|
103
|
-
category: ErrorCategory.USER,
|
|
104
|
-
details: { tableName },
|
|
105
|
-
},
|
|
106
|
-
error,
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
try {
|
|
111
|
-
const arrowSchema = this.translateSchema(schema);
|
|
112
|
-
await this.client.createEmptyTable(tableName, arrowSchema);
|
|
113
|
-
} catch (error: any) {
|
|
114
|
-
if (error.message?.includes('already exists')) {
|
|
115
|
-
this.logger.debug(`Table '${tableName}' already exists, skipping create`);
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
throw new MastraError(
|
|
119
|
-
{
|
|
120
|
-
id: 'STORAGE_LANCE_STORAGE_CREATE_TABLE_FAILED',
|
|
121
|
-
domain: ErrorDomain.STORAGE,
|
|
122
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
123
|
-
details: { tableName },
|
|
124
|
-
},
|
|
125
|
-
error,
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
async dropTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {
|
|
131
|
-
try {
|
|
132
|
-
if (!this.client) {
|
|
133
|
-
throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
|
|
134
|
-
}
|
|
135
|
-
if (!tableName) {
|
|
136
|
-
throw new Error('tableName is required for dropTable.');
|
|
137
|
-
}
|
|
138
|
-
} catch (validationError: any) {
|
|
139
|
-
throw new MastraError(
|
|
140
|
-
{
|
|
141
|
-
id: 'STORAGE_LANCE_STORAGE_DROP_TABLE_INVALID_ARGS',
|
|
142
|
-
domain: ErrorDomain.STORAGE,
|
|
143
|
-
category: ErrorCategory.USER,
|
|
144
|
-
text: validationError.message,
|
|
145
|
-
details: { tableName },
|
|
146
|
-
},
|
|
147
|
-
validationError,
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
try {
|
|
152
|
-
await this.client.dropTable(tableName);
|
|
153
|
-
} catch (error: any) {
|
|
154
|
-
if (error.toString().includes('was not found') || error.message?.includes('Table not found')) {
|
|
155
|
-
this.logger.debug(`Table '${tableName}' does not exist, skipping drop`);
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
throw new MastraError(
|
|
159
|
-
{
|
|
160
|
-
id: 'STORAGE_LANCE_STORAGE_DROP_TABLE_FAILED',
|
|
161
|
-
domain: ErrorDomain.STORAGE,
|
|
162
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
163
|
-
details: { tableName },
|
|
164
|
-
},
|
|
165
|
-
error,
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
async alterTable({
|
|
171
|
-
tableName,
|
|
172
|
-
schema,
|
|
173
|
-
ifNotExists,
|
|
174
|
-
}: {
|
|
175
|
-
tableName: string;
|
|
176
|
-
schema: Record<string, StorageColumn>;
|
|
177
|
-
ifNotExists: string[];
|
|
178
|
-
}): Promise<void> {
|
|
179
|
-
try {
|
|
180
|
-
if (!this.client) {
|
|
181
|
-
throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
|
|
182
|
-
}
|
|
183
|
-
if (!tableName) {
|
|
184
|
-
throw new Error('tableName is required for alterTable.');
|
|
185
|
-
}
|
|
186
|
-
if (!schema) {
|
|
187
|
-
throw new Error('schema is required for alterTable.');
|
|
188
|
-
}
|
|
189
|
-
if (!ifNotExists || ifNotExists.length === 0) {
|
|
190
|
-
this.logger.debug('No columns specified to add in alterTable, skipping.');
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
} catch (validationError: any) {
|
|
194
|
-
throw new MastraError(
|
|
195
|
-
{
|
|
196
|
-
id: 'STORAGE_LANCE_STORAGE_ALTER_TABLE_INVALID_ARGS',
|
|
197
|
-
domain: ErrorDomain.STORAGE,
|
|
198
|
-
category: ErrorCategory.USER,
|
|
199
|
-
text: validationError.message,
|
|
200
|
-
details: { tableName },
|
|
201
|
-
},
|
|
202
|
-
validationError,
|
|
203
|
-
);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
try {
|
|
207
|
-
const table = await this.client.openTable(tableName);
|
|
208
|
-
const currentSchema = await table.schema();
|
|
209
|
-
const existingFields = new Set(currentSchema.fields.map((f: any) => f.name));
|
|
210
|
-
|
|
211
|
-
const typeMap: Record<string, string> = {
|
|
212
|
-
text: 'string',
|
|
213
|
-
integer: 'int',
|
|
214
|
-
bigint: 'bigint',
|
|
215
|
-
timestamp: 'timestamp',
|
|
216
|
-
jsonb: 'string',
|
|
217
|
-
uuid: 'string',
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
// Find columns to add
|
|
221
|
-
const columnsToAdd = ifNotExists
|
|
222
|
-
.filter(col => schema[col] && !existingFields.has(col))
|
|
223
|
-
.map(col => {
|
|
224
|
-
const colDef = schema[col];
|
|
225
|
-
return {
|
|
226
|
-
name: col,
|
|
227
|
-
valueSql: colDef?.nullable
|
|
228
|
-
? `cast(NULL as ${typeMap[colDef.type ?? 'text']})`
|
|
229
|
-
: `cast(${this.getDefaultValue(colDef?.type ?? 'text')} as ${typeMap[colDef?.type ?? 'text']})`,
|
|
230
|
-
};
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
if (columnsToAdd.length > 0) {
|
|
234
|
-
await table.addColumns(columnsToAdd);
|
|
235
|
-
this.logger?.info?.(`Added columns [${columnsToAdd.map(c => c.name).join(', ')}] to table ${tableName}`);
|
|
236
|
-
}
|
|
237
|
-
} catch (error: any) {
|
|
238
|
-
throw new MastraError(
|
|
239
|
-
{
|
|
240
|
-
id: 'STORAGE_LANCE_STORAGE_ALTER_TABLE_FAILED',
|
|
241
|
-
domain: ErrorDomain.STORAGE,
|
|
242
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
243
|
-
details: { tableName },
|
|
244
|
-
},
|
|
245
|
-
error,
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
async clearTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {
|
|
251
|
-
try {
|
|
252
|
-
if (!this.client) {
|
|
253
|
-
throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
|
|
254
|
-
}
|
|
255
|
-
if (!tableName) {
|
|
256
|
-
throw new Error('tableName is required for clearTable.');
|
|
257
|
-
}
|
|
258
|
-
} catch (validationError: any) {
|
|
259
|
-
throw new MastraError(
|
|
260
|
-
{
|
|
261
|
-
id: 'STORAGE_LANCE_STORAGE_CLEAR_TABLE_INVALID_ARGS',
|
|
262
|
-
domain: ErrorDomain.STORAGE,
|
|
263
|
-
category: ErrorCategory.USER,
|
|
264
|
-
text: validationError.message,
|
|
265
|
-
details: { tableName },
|
|
266
|
-
},
|
|
267
|
-
validationError,
|
|
268
|
-
);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
try {
|
|
272
|
-
const table = await this.client.openTable(tableName);
|
|
273
|
-
|
|
274
|
-
// delete function always takes a predicate as an argument, so we use '1=1' to delete all records because it is always true.
|
|
275
|
-
await table.delete('1=1');
|
|
276
|
-
} catch (error: any) {
|
|
277
|
-
throw new MastraError(
|
|
278
|
-
{
|
|
279
|
-
id: 'STORAGE_LANCE_STORAGE_CLEAR_TABLE_FAILED',
|
|
280
|
-
domain: ErrorDomain.STORAGE,
|
|
281
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
282
|
-
details: { tableName },
|
|
283
|
-
},
|
|
284
|
-
error,
|
|
285
|
-
);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
async insert({ tableName, record }: { tableName: string; record: Record<string, any> }): Promise<void> {
|
|
290
|
-
try {
|
|
291
|
-
if (!this.client) {
|
|
292
|
-
throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
|
|
293
|
-
}
|
|
294
|
-
if (!tableName) {
|
|
295
|
-
throw new Error('tableName is required for insert.');
|
|
296
|
-
}
|
|
297
|
-
if (!record || Object.keys(record).length === 0) {
|
|
298
|
-
throw new Error('record is required and cannot be empty for insert.');
|
|
299
|
-
}
|
|
300
|
-
} catch (validationError: any) {
|
|
301
|
-
throw new MastraError(
|
|
302
|
-
{
|
|
303
|
-
id: 'STORAGE_LANCE_STORAGE_INSERT_INVALID_ARGS',
|
|
304
|
-
domain: ErrorDomain.STORAGE,
|
|
305
|
-
category: ErrorCategory.USER,
|
|
306
|
-
text: validationError.message,
|
|
307
|
-
details: { tableName },
|
|
308
|
-
},
|
|
309
|
-
validationError,
|
|
310
|
-
);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
try {
|
|
314
|
-
const table = await this.client.openTable(tableName);
|
|
315
|
-
|
|
316
|
-
const primaryId = getPrimaryKeys(tableName as TABLE_NAMES);
|
|
317
|
-
|
|
318
|
-
const processedRecord = { ...record };
|
|
319
|
-
|
|
320
|
-
for (const key in processedRecord) {
|
|
321
|
-
if (
|
|
322
|
-
processedRecord[key] !== null &&
|
|
323
|
-
typeof processedRecord[key] === 'object' &&
|
|
324
|
-
!(processedRecord[key] instanceof Date)
|
|
325
|
-
) {
|
|
326
|
-
this.logger.debug('Converting object to JSON string: ', processedRecord[key]);
|
|
327
|
-
processedRecord[key] = JSON.stringify(processedRecord[key]);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
console.log(await table.schema());
|
|
331
|
-
|
|
332
|
-
await table.mergeInsert(primaryId).whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([processedRecord]);
|
|
333
|
-
} catch (error: any) {
|
|
334
|
-
throw new MastraError(
|
|
335
|
-
{
|
|
336
|
-
id: 'STORAGE_LANCE_STORAGE_INSERT_FAILED',
|
|
337
|
-
domain: ErrorDomain.STORAGE,
|
|
338
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
339
|
-
details: { tableName },
|
|
340
|
-
},
|
|
341
|
-
error,
|
|
342
|
-
);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
async batchInsert({ tableName, records }: { tableName: string; records: Record<string, any>[] }): Promise<void> {
|
|
347
|
-
try {
|
|
348
|
-
if (!this.client) {
|
|
349
|
-
throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
|
|
350
|
-
}
|
|
351
|
-
if (!tableName) {
|
|
352
|
-
throw new Error('tableName is required for batchInsert.');
|
|
353
|
-
}
|
|
354
|
-
if (!records || records.length === 0) {
|
|
355
|
-
throw new Error('records array is required and cannot be empty for batchInsert.');
|
|
356
|
-
}
|
|
357
|
-
} catch (validationError: any) {
|
|
358
|
-
throw new MastraError(
|
|
359
|
-
{
|
|
360
|
-
id: 'STORAGE_LANCE_STORAGE_BATCH_INSERT_INVALID_ARGS',
|
|
361
|
-
domain: ErrorDomain.STORAGE,
|
|
362
|
-
category: ErrorCategory.USER,
|
|
363
|
-
text: validationError.message,
|
|
364
|
-
details: { tableName },
|
|
365
|
-
},
|
|
366
|
-
validationError,
|
|
367
|
-
);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
try {
|
|
371
|
-
const table = await this.client.openTable(tableName);
|
|
372
|
-
|
|
373
|
-
const primaryId = getPrimaryKeys(tableName as TABLE_NAMES);
|
|
374
|
-
|
|
375
|
-
const processedRecords = records.map(record => {
|
|
376
|
-
const processedRecord = { ...record };
|
|
377
|
-
|
|
378
|
-
// Convert values based on schema type
|
|
379
|
-
for (const key in processedRecord) {
|
|
380
|
-
// Skip null/undefined values
|
|
381
|
-
if (processedRecord[key] == null) continue;
|
|
382
|
-
|
|
383
|
-
if (
|
|
384
|
-
processedRecord[key] !== null &&
|
|
385
|
-
typeof processedRecord[key] === 'object' &&
|
|
386
|
-
!(processedRecord[key] instanceof Date)
|
|
387
|
-
) {
|
|
388
|
-
processedRecord[key] = JSON.stringify(processedRecord[key]);
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
return processedRecord;
|
|
393
|
-
});
|
|
394
|
-
|
|
395
|
-
console.log(processedRecords);
|
|
396
|
-
|
|
397
|
-
await table.mergeInsert(primaryId).whenMatchedUpdateAll().whenNotMatchedInsertAll().execute(processedRecords);
|
|
398
|
-
} catch (error: any) {
|
|
399
|
-
throw new MastraError(
|
|
400
|
-
{
|
|
401
|
-
id: 'STORAGE_LANCE_STORAGE_BATCH_INSERT_FAILED',
|
|
402
|
-
domain: ErrorDomain.STORAGE,
|
|
403
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
404
|
-
details: { tableName },
|
|
405
|
-
},
|
|
406
|
-
error,
|
|
407
|
-
);
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
async load({ tableName, keys }: { tableName: TABLE_NAMES; keys: Record<string, any> }): Promise<any> {
|
|
412
|
-
try {
|
|
413
|
-
if (!this.client) {
|
|
414
|
-
throw new Error('LanceDB client not initialized. Call LanceStorage.create() first.');
|
|
415
|
-
}
|
|
416
|
-
if (!tableName) {
|
|
417
|
-
throw new Error('tableName is required for load.');
|
|
418
|
-
}
|
|
419
|
-
if (!keys || Object.keys(keys).length === 0) {
|
|
420
|
-
throw new Error('keys are required and cannot be empty for load.');
|
|
421
|
-
}
|
|
422
|
-
} catch (validationError: any) {
|
|
423
|
-
throw new MastraError(
|
|
424
|
-
{
|
|
425
|
-
id: 'STORAGE_LANCE_STORAGE_LOAD_INVALID_ARGS',
|
|
426
|
-
domain: ErrorDomain.STORAGE,
|
|
427
|
-
category: ErrorCategory.USER,
|
|
428
|
-
text: validationError.message,
|
|
429
|
-
details: { tableName },
|
|
430
|
-
},
|
|
431
|
-
validationError,
|
|
432
|
-
);
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
try {
|
|
436
|
-
const table = await this.client.openTable(tableName);
|
|
437
|
-
const tableSchema = await getTableSchema({ tableName, client: this.client });
|
|
438
|
-
const query = table.query();
|
|
439
|
-
|
|
440
|
-
// Build filter condition with 'and' between all conditions
|
|
441
|
-
if (Object.keys(keys).length > 0) {
|
|
442
|
-
// Validate key types against schema
|
|
443
|
-
validateKeyTypes(keys, tableSchema);
|
|
444
|
-
|
|
445
|
-
const filterConditions = Object.entries(keys)
|
|
446
|
-
.map(([key, value]) => {
|
|
447
|
-
// Check if key is in camelCase and wrap it in backticks if it is
|
|
448
|
-
const isCamelCase = /^[a-z][a-zA-Z]*$/.test(key) && /[A-Z]/.test(key);
|
|
449
|
-
const quotedKey = isCamelCase ? `\`${key}\`` : key;
|
|
450
|
-
|
|
451
|
-
// Handle different types appropriately
|
|
452
|
-
if (typeof value === 'string') {
|
|
453
|
-
return `${quotedKey} = '${value}'`;
|
|
454
|
-
} else if (value === null) {
|
|
455
|
-
return `${quotedKey} IS NULL`;
|
|
456
|
-
} else {
|
|
457
|
-
// For numbers, booleans, etc.
|
|
458
|
-
return `${quotedKey} = ${value}`;
|
|
459
|
-
}
|
|
460
|
-
})
|
|
461
|
-
.join(' AND ');
|
|
462
|
-
|
|
463
|
-
this.logger.debug('where clause generated: ' + filterConditions);
|
|
464
|
-
query.where(filterConditions);
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
const result = await query.limit(1).toArray();
|
|
468
|
-
|
|
469
|
-
if (result.length === 0) {
|
|
470
|
-
this.logger.debug('No record found');
|
|
471
|
-
return null;
|
|
472
|
-
}
|
|
473
|
-
// Process the result with type conversions
|
|
474
|
-
return processResultWithTypeConversion(result[0], tableSchema);
|
|
475
|
-
} catch (error: any) {
|
|
476
|
-
// If it's already a MastraError (e.g. from validateKeyTypes if we change it later), rethrow
|
|
477
|
-
if (error instanceof MastraError) throw error;
|
|
478
|
-
throw new MastraError(
|
|
479
|
-
{
|
|
480
|
-
id: 'STORAGE_LANCE_STORAGE_LOAD_FAILED',
|
|
481
|
-
domain: ErrorDomain.STORAGE,
|
|
482
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
483
|
-
details: { tableName, keyCount: Object.keys(keys).length, firstKey: Object.keys(keys)[0] ?? '' },
|
|
484
|
-
},
|
|
485
|
-
error,
|
|
486
|
-
);
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
}
|