@mastra/pg 0.3.1-alpha.2 → 0.3.1-alpha.4
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/.turbo/turbo-build.log +9 -9
- package/CHANGELOG.md +17 -0
- package/dist/_tsup-dts-rollup.d.cts +14 -12
- package/dist/_tsup-dts-rollup.d.ts +14 -12
- package/dist/index.cjs +126 -52
- package/dist/index.js +126 -52
- package/package.json +4 -4
- package/src/storage/index.test.ts +216 -45
- package/src/storage/index.ts +143 -66
- package/src/vector/index.test.ts +41 -0
- package/src/vector/index.ts +31 -5
|
@@ -4,7 +4,7 @@ import type { MessageType } from '@mastra/core/memory';
|
|
|
4
4
|
import { TABLE_WORKFLOW_SNAPSHOT, TABLE_MESSAGES, TABLE_THREADS, TABLE_EVALS } from '@mastra/core/storage';
|
|
5
5
|
import type { WorkflowRunState } from '@mastra/core/workflows';
|
|
6
6
|
import pgPromise from 'pg-promise';
|
|
7
|
-
import { describe, it, expect, beforeAll, beforeEach, afterAll, afterEach } from 'vitest';
|
|
7
|
+
import { describe, it, expect, beforeAll, beforeEach, afterAll, afterEach, vi } from 'vitest';
|
|
8
8
|
|
|
9
9
|
import { PostgresStore } from '.';
|
|
10
10
|
import type { PostgresConfig } from '.';
|
|
@@ -19,6 +19,8 @@ const TEST_CONFIG: PostgresConfig = {
|
|
|
19
19
|
|
|
20
20
|
const connectionString = `postgresql://${TEST_CONFIG.user}:${TEST_CONFIG.password}@${TEST_CONFIG.host}:${TEST_CONFIG.port}/${TEST_CONFIG.database}`;
|
|
21
21
|
|
|
22
|
+
vi.setConfig({ testTimeout: 60_000, hookTimeout: 60_000 });
|
|
23
|
+
|
|
22
24
|
// Sample test data factory functions
|
|
23
25
|
const createSampleThread = () => ({
|
|
24
26
|
id: `thread-${randomUUID()}`,
|
|
@@ -29,17 +31,20 @@ const createSampleThread = () => ({
|
|
|
29
31
|
metadata: { key: 'value' },
|
|
30
32
|
});
|
|
31
33
|
|
|
32
|
-
const createSampleMessage = (threadId: string) =>
|
|
33
|
-
(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const createSampleWorkflowSnapshot = (
|
|
34
|
+
const createSampleMessage = (threadId: string): MessageType => ({
|
|
35
|
+
id: `msg-${randomUUID()}`,
|
|
36
|
+
resourceId: `resource-${randomUUID()}`,
|
|
37
|
+
role: 'user',
|
|
38
|
+
type: 'text',
|
|
39
|
+
threadId,
|
|
40
|
+
content: [{ type: 'text', text: 'Hello' }],
|
|
41
|
+
createdAt: new Date(),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const createSampleWorkflowSnapshot = (
|
|
45
|
+
status: WorkflowRunState['context']['steps'][string]['status'],
|
|
46
|
+
createdAt?: Date,
|
|
47
|
+
) => {
|
|
43
48
|
const runId = `run-${randomUUID()}`;
|
|
44
49
|
const stepId = `step-${randomUUID()}`;
|
|
45
50
|
const timestamp = createdAt || new Date();
|
|
@@ -58,9 +63,10 @@ const createSampleWorkflowSnapshot = (status: string, createdAt?: Date) => {
|
|
|
58
63
|
attempts: {},
|
|
59
64
|
},
|
|
60
65
|
activePaths: [],
|
|
66
|
+
suspendedPaths: {},
|
|
61
67
|
runId,
|
|
62
68
|
timestamp: timestamp.getTime(),
|
|
63
|
-
}
|
|
69
|
+
};
|
|
64
70
|
return { snapshot, runId, stepId };
|
|
65
71
|
};
|
|
66
72
|
|
|
@@ -82,6 +88,13 @@ const createSampleEval = (agentName: string, isTest = false) => {
|
|
|
82
88
|
};
|
|
83
89
|
};
|
|
84
90
|
|
|
91
|
+
const checkWorkflowSnapshot = (snapshot: WorkflowRunState | string, stepId: string, status: string) => {
|
|
92
|
+
if (typeof snapshot === 'string') {
|
|
93
|
+
throw new Error('Expected WorkflowRunState, got string');
|
|
94
|
+
}
|
|
95
|
+
expect(snapshot.context?.steps[stepId]?.status).toBe(status);
|
|
96
|
+
};
|
|
97
|
+
|
|
85
98
|
describe('PostgresStore', () => {
|
|
86
99
|
let store: PostgresStore;
|
|
87
100
|
|
|
@@ -233,7 +246,11 @@ describe('PostgresStore', () => {
|
|
|
233
246
|
// Retrieve messages
|
|
234
247
|
const retrievedMessages = await store.getMessages({ threadId: thread.id });
|
|
235
248
|
expect(retrievedMessages).toHaveLength(2);
|
|
236
|
-
|
|
249
|
+
const checkMessages = messages.map(m => {
|
|
250
|
+
const { resourceId, ...rest } = m;
|
|
251
|
+
return rest;
|
|
252
|
+
});
|
|
253
|
+
expect(retrievedMessages).toEqual(expect.arrayContaining(checkMessages));
|
|
237
254
|
});
|
|
238
255
|
|
|
239
256
|
it('should handle empty message array', async () => {
|
|
@@ -253,12 +270,13 @@ describe('PostgresStore', () => {
|
|
|
253
270
|
|
|
254
271
|
await store.saveMessages({ messages });
|
|
255
272
|
|
|
256
|
-
const retrievedMessages = await store.getMessages({ threadId: thread.id });
|
|
273
|
+
const retrievedMessages = await store.getMessages<MessageType>({ threadId: thread.id });
|
|
257
274
|
expect(retrievedMessages).toHaveLength(3);
|
|
258
275
|
|
|
259
276
|
// Verify order is maintained
|
|
260
277
|
retrievedMessages.forEach((msg, idx) => {
|
|
261
|
-
expect
|
|
278
|
+
// @ts-expect-error
|
|
279
|
+
expect(msg.content[0].text).toBe(messages[idx].content[0].text);
|
|
262
280
|
});
|
|
263
281
|
});
|
|
264
282
|
|
|
@@ -338,11 +356,17 @@ describe('PostgresStore', () => {
|
|
|
338
356
|
const snapshot = {
|
|
339
357
|
status: 'running',
|
|
340
358
|
context: {
|
|
359
|
+
steps: {},
|
|
341
360
|
stepResults: {},
|
|
342
361
|
attempts: {},
|
|
343
362
|
triggerData: { type: 'manual' },
|
|
344
363
|
},
|
|
345
|
-
|
|
364
|
+
value: {},
|
|
365
|
+
activePaths: [],
|
|
366
|
+
suspendedPaths: {},
|
|
367
|
+
runId,
|
|
368
|
+
timestamp: new Date().getTime(),
|
|
369
|
+
};
|
|
346
370
|
|
|
347
371
|
await store.persistWorkflowSnapshot({
|
|
348
372
|
workflowName,
|
|
@@ -373,28 +397,40 @@ describe('PostgresStore', () => {
|
|
|
373
397
|
const initialSnapshot = {
|
|
374
398
|
status: 'running',
|
|
375
399
|
context: {
|
|
400
|
+
steps: {},
|
|
376
401
|
stepResults: {},
|
|
377
402
|
attempts: {},
|
|
378
403
|
triggerData: { type: 'manual' },
|
|
379
404
|
},
|
|
405
|
+
value: {},
|
|
406
|
+
activePaths: [],
|
|
407
|
+
suspendedPaths: {},
|
|
408
|
+
runId,
|
|
409
|
+
timestamp: new Date().getTime(),
|
|
380
410
|
};
|
|
381
411
|
|
|
382
412
|
await store.persistWorkflowSnapshot({
|
|
383
413
|
workflowName,
|
|
384
414
|
runId,
|
|
385
|
-
snapshot: initialSnapshot
|
|
415
|
+
snapshot: initialSnapshot,
|
|
386
416
|
});
|
|
387
417
|
|
|
388
418
|
const updatedSnapshot = {
|
|
389
419
|
status: 'completed',
|
|
390
420
|
context: {
|
|
421
|
+
steps: {},
|
|
391
422
|
stepResults: {
|
|
392
423
|
'step-1': { status: 'success', result: { data: 'test' } },
|
|
393
424
|
},
|
|
394
425
|
attempts: { 'step-1': 1 },
|
|
395
426
|
triggerData: { type: 'manual' },
|
|
396
427
|
},
|
|
397
|
-
|
|
428
|
+
value: {},
|
|
429
|
+
activePaths: [],
|
|
430
|
+
suspendedPaths: {},
|
|
431
|
+
runId,
|
|
432
|
+
timestamp: new Date().getTime(),
|
|
433
|
+
};
|
|
398
434
|
|
|
399
435
|
await store.persistWorkflowSnapshot({
|
|
400
436
|
workflowName,
|
|
@@ -432,6 +468,7 @@ describe('PostgresStore', () => {
|
|
|
432
468
|
dependencies: ['step-3', 'step-4'],
|
|
433
469
|
},
|
|
434
470
|
},
|
|
471
|
+
steps: {},
|
|
435
472
|
attempts: { 'step-1': 1, 'step-2': 0 },
|
|
436
473
|
triggerData: {
|
|
437
474
|
type: 'scheduled',
|
|
@@ -453,6 +490,7 @@ describe('PostgresStore', () => {
|
|
|
453
490
|
status: 'waiting',
|
|
454
491
|
},
|
|
455
492
|
],
|
|
493
|
+
suspendedPaths: {},
|
|
456
494
|
runId: runId,
|
|
457
495
|
timestamp: Date.now(),
|
|
458
496
|
};
|
|
@@ -460,7 +498,7 @@ describe('PostgresStore', () => {
|
|
|
460
498
|
await store.persistWorkflowSnapshot({
|
|
461
499
|
workflowName,
|
|
462
500
|
runId,
|
|
463
|
-
snapshot: complexSnapshot
|
|
501
|
+
snapshot: complexSnapshot,
|
|
464
502
|
});
|
|
465
503
|
|
|
466
504
|
const loadedSnapshot = await store.loadWorkflowSnapshot({
|
|
@@ -486,8 +524,8 @@ describe('PostgresStore', () => {
|
|
|
486
524
|
const workflowName1 = 'default_test_1';
|
|
487
525
|
const workflowName2 = 'default_test_2';
|
|
488
526
|
|
|
489
|
-
const { snapshot: workflow1, runId: runId1, stepId: stepId1 } = createSampleWorkflowSnapshot('
|
|
490
|
-
const { snapshot: workflow2, runId: runId2, stepId: stepId2 } = createSampleWorkflowSnapshot('
|
|
527
|
+
const { snapshot: workflow1, runId: runId1, stepId: stepId1 } = createSampleWorkflowSnapshot('success');
|
|
528
|
+
const { snapshot: workflow2, runId: runId2, stepId: stepId2 } = createSampleWorkflowSnapshot('failed');
|
|
491
529
|
|
|
492
530
|
await store.persistWorkflowSnapshot({ workflowName: workflowName1, runId: runId1, snapshot: workflow1 });
|
|
493
531
|
await new Promise(resolve => setTimeout(resolve, 10)); // Small delay to ensure different timestamps
|
|
@@ -498,17 +536,17 @@ describe('PostgresStore', () => {
|
|
|
498
536
|
expect(total).toBe(2);
|
|
499
537
|
expect(runs[0]!.workflowName).toBe(workflowName2); // Most recent first
|
|
500
538
|
expect(runs[1]!.workflowName).toBe(workflowName1);
|
|
501
|
-
const firstSnapshot = runs[0]!.snapshot
|
|
502
|
-
const secondSnapshot = runs[1]!.snapshot
|
|
503
|
-
|
|
504
|
-
|
|
539
|
+
const firstSnapshot = runs[0]!.snapshot;
|
|
540
|
+
const secondSnapshot = runs[1]!.snapshot;
|
|
541
|
+
checkWorkflowSnapshot(firstSnapshot, stepId2, 'failed');
|
|
542
|
+
checkWorkflowSnapshot(secondSnapshot, stepId1, 'success');
|
|
505
543
|
});
|
|
506
544
|
|
|
507
545
|
it('filters by workflow name', async () => {
|
|
508
546
|
const workflowName1 = 'filter_test_1';
|
|
509
547
|
const workflowName2 = 'filter_test_2';
|
|
510
548
|
|
|
511
|
-
const { snapshot: workflow1, runId: runId1, stepId: stepId1 } = createSampleWorkflowSnapshot('
|
|
549
|
+
const { snapshot: workflow1, runId: runId1, stepId: stepId1 } = createSampleWorkflowSnapshot('success');
|
|
512
550
|
const { snapshot: workflow2, runId: runId2 } = createSampleWorkflowSnapshot('failed');
|
|
513
551
|
|
|
514
552
|
await store.persistWorkflowSnapshot({ workflowName: workflowName1, runId: runId1, snapshot: workflow1 });
|
|
@@ -519,8 +557,8 @@ describe('PostgresStore', () => {
|
|
|
519
557
|
expect(runs).toHaveLength(1);
|
|
520
558
|
expect(total).toBe(1);
|
|
521
559
|
expect(runs[0]!.workflowName).toBe(workflowName1);
|
|
522
|
-
const snapshot = runs[0]!.snapshot
|
|
523
|
-
|
|
560
|
+
const snapshot = runs[0]!.snapshot;
|
|
561
|
+
checkWorkflowSnapshot(snapshot, stepId1, 'success');
|
|
524
562
|
});
|
|
525
563
|
|
|
526
564
|
it('filters by date range', async () => {
|
|
@@ -531,9 +569,9 @@ describe('PostgresStore', () => {
|
|
|
531
569
|
const workflowName2 = 'date_test_2';
|
|
532
570
|
const workflowName3 = 'date_test_3';
|
|
533
571
|
|
|
534
|
-
const { snapshot: workflow1, runId: runId1 } = createSampleWorkflowSnapshot('
|
|
535
|
-
const { snapshot: workflow2, runId: runId2, stepId: stepId2 } = createSampleWorkflowSnapshot('
|
|
536
|
-
const { snapshot: workflow3, runId: runId3, stepId: stepId3 } = createSampleWorkflowSnapshot('
|
|
572
|
+
const { snapshot: workflow1, runId: runId1 } = createSampleWorkflowSnapshot('success');
|
|
573
|
+
const { snapshot: workflow2, runId: runId2, stepId: stepId2 } = createSampleWorkflowSnapshot('failed');
|
|
574
|
+
const { snapshot: workflow3, runId: runId3, stepId: stepId3 } = createSampleWorkflowSnapshot('suspended');
|
|
537
575
|
|
|
538
576
|
await store.insert({
|
|
539
577
|
tableName: TABLE_WORKFLOW_SNAPSHOT,
|
|
@@ -574,10 +612,10 @@ describe('PostgresStore', () => {
|
|
|
574
612
|
expect(runs).toHaveLength(2);
|
|
575
613
|
expect(runs[0]!.workflowName).toBe(workflowName3);
|
|
576
614
|
expect(runs[1]!.workflowName).toBe(workflowName2);
|
|
577
|
-
const firstSnapshot = runs[0]!.snapshot
|
|
578
|
-
const secondSnapshot = runs[1]!.snapshot
|
|
579
|
-
|
|
580
|
-
|
|
615
|
+
const firstSnapshot = runs[0]!.snapshot;
|
|
616
|
+
const secondSnapshot = runs[1]!.snapshot;
|
|
617
|
+
checkWorkflowSnapshot(firstSnapshot, stepId3, 'suspended');
|
|
618
|
+
checkWorkflowSnapshot(secondSnapshot, stepId2, 'failed');
|
|
581
619
|
});
|
|
582
620
|
|
|
583
621
|
it('handles pagination', async () => {
|
|
@@ -585,9 +623,9 @@ describe('PostgresStore', () => {
|
|
|
585
623
|
const workflowName2 = 'page_test_2';
|
|
586
624
|
const workflowName3 = 'page_test_3';
|
|
587
625
|
|
|
588
|
-
const { snapshot: workflow1, runId: runId1, stepId: stepId1 } = createSampleWorkflowSnapshot('
|
|
589
|
-
const { snapshot: workflow2, runId: runId2, stepId: stepId2 } = createSampleWorkflowSnapshot('
|
|
590
|
-
const { snapshot: workflow3, runId: runId3, stepId: stepId3 } = createSampleWorkflowSnapshot('
|
|
626
|
+
const { snapshot: workflow1, runId: runId1, stepId: stepId1 } = createSampleWorkflowSnapshot('success');
|
|
627
|
+
const { snapshot: workflow2, runId: runId2, stepId: stepId2 } = createSampleWorkflowSnapshot('failed');
|
|
628
|
+
const { snapshot: workflow3, runId: runId3, stepId: stepId3 } = createSampleWorkflowSnapshot('suspended');
|
|
591
629
|
|
|
592
630
|
await store.persistWorkflowSnapshot({ workflowName: workflowName1, runId: runId1, snapshot: workflow1 });
|
|
593
631
|
await new Promise(resolve => setTimeout(resolve, 10)); // Small delay to ensure different timestamps
|
|
@@ -601,18 +639,119 @@ describe('PostgresStore', () => {
|
|
|
601
639
|
expect(page1.total).toBe(3); // Total count of all records
|
|
602
640
|
expect(page1.runs[0]!.workflowName).toBe(workflowName3);
|
|
603
641
|
expect(page1.runs[1]!.workflowName).toBe(workflowName2);
|
|
604
|
-
const firstSnapshot = page1.runs[0]!.snapshot
|
|
605
|
-
const secondSnapshot = page1.runs[1]!.snapshot
|
|
606
|
-
|
|
607
|
-
|
|
642
|
+
const firstSnapshot = page1.runs[0]!.snapshot;
|
|
643
|
+
const secondSnapshot = page1.runs[1]!.snapshot;
|
|
644
|
+
checkWorkflowSnapshot(firstSnapshot, stepId3, 'suspended');
|
|
645
|
+
checkWorkflowSnapshot(secondSnapshot, stepId2, 'failed');
|
|
608
646
|
|
|
609
647
|
// Get second page
|
|
610
648
|
const page2 = await store.getWorkflowRuns({ limit: 2, offset: 2 });
|
|
611
649
|
expect(page2.runs).toHaveLength(1);
|
|
612
650
|
expect(page2.total).toBe(3);
|
|
613
651
|
expect(page2.runs[0]!.workflowName).toBe(workflowName1);
|
|
614
|
-
const snapshot = page2.runs[0]!.snapshot
|
|
615
|
-
|
|
652
|
+
const snapshot = page2.runs[0]!.snapshot;
|
|
653
|
+
checkWorkflowSnapshot(snapshot, stepId1, 'success');
|
|
654
|
+
});
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
describe('getWorkflowRunById', () => {
|
|
658
|
+
const workflowName = 'workflow-id-test';
|
|
659
|
+
let runId: string;
|
|
660
|
+
let stepId: string;
|
|
661
|
+
|
|
662
|
+
beforeEach(async () => {
|
|
663
|
+
// Insert a workflow run for positive test
|
|
664
|
+
const sample = createSampleWorkflowSnapshot('success');
|
|
665
|
+
runId = sample.runId;
|
|
666
|
+
stepId = sample.stepId;
|
|
667
|
+
await store.insert({
|
|
668
|
+
tableName: TABLE_WORKFLOW_SNAPSHOT,
|
|
669
|
+
record: {
|
|
670
|
+
workflow_name: workflowName,
|
|
671
|
+
run_id: runId,
|
|
672
|
+
resourceId: 'resource-abc',
|
|
673
|
+
snapshot: sample.snapshot,
|
|
674
|
+
createdAt: new Date(),
|
|
675
|
+
updatedAt: new Date(),
|
|
676
|
+
},
|
|
677
|
+
});
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
it('should retrieve a workflow run by ID', async () => {
|
|
681
|
+
const found = await store.getWorkflowRunById({
|
|
682
|
+
runId,
|
|
683
|
+
workflowName,
|
|
684
|
+
});
|
|
685
|
+
expect(found).not.toBeNull();
|
|
686
|
+
expect(found?.runId).toBe(runId);
|
|
687
|
+
checkWorkflowSnapshot(found?.snapshot!, stepId, 'success');
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
it('should return null for non-existent workflow run ID', async () => {
|
|
691
|
+
const notFound = await store.getWorkflowRunById({
|
|
692
|
+
runId: 'non-existent-id',
|
|
693
|
+
workflowName,
|
|
694
|
+
});
|
|
695
|
+
expect(notFound).toBeNull();
|
|
696
|
+
});
|
|
697
|
+
});
|
|
698
|
+
describe('getWorkflowRuns with resourceId', () => {
|
|
699
|
+
const workflowName = 'workflow-id-test';
|
|
700
|
+
let resourceId: string;
|
|
701
|
+
let runIds: string[] = [];
|
|
702
|
+
|
|
703
|
+
beforeEach(async () => {
|
|
704
|
+
// Insert multiple workflow runs for the same resourceId
|
|
705
|
+
resourceId = 'resource-shared';
|
|
706
|
+
for (const status of ['success', 'failed']) {
|
|
707
|
+
const sample = createSampleWorkflowSnapshot(status as WorkflowRunState['context']['steps'][string]['status']);
|
|
708
|
+
runIds.push(sample.runId);
|
|
709
|
+
await store.insert({
|
|
710
|
+
tableName: TABLE_WORKFLOW_SNAPSHOT,
|
|
711
|
+
record: {
|
|
712
|
+
workflow_name: workflowName,
|
|
713
|
+
run_id: sample.runId,
|
|
714
|
+
resourceId,
|
|
715
|
+
snapshot: sample.snapshot,
|
|
716
|
+
createdAt: new Date(),
|
|
717
|
+
updatedAt: new Date(),
|
|
718
|
+
},
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
// Insert a run with a different resourceId
|
|
722
|
+
const other = createSampleWorkflowSnapshot('waiting');
|
|
723
|
+
await store.insert({
|
|
724
|
+
tableName: TABLE_WORKFLOW_SNAPSHOT,
|
|
725
|
+
record: {
|
|
726
|
+
workflow_name: workflowName,
|
|
727
|
+
run_id: other.runId,
|
|
728
|
+
resourceId: 'resource-other',
|
|
729
|
+
snapshot: other.snapshot,
|
|
730
|
+
createdAt: new Date(),
|
|
731
|
+
updatedAt: new Date(),
|
|
732
|
+
},
|
|
733
|
+
});
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
it('should retrieve all workflow runs by resourceId', async () => {
|
|
737
|
+
const { runs } = await store.getWorkflowRuns({
|
|
738
|
+
resourceId,
|
|
739
|
+
workflowName,
|
|
740
|
+
});
|
|
741
|
+
expect(Array.isArray(runs)).toBe(true);
|
|
742
|
+
expect(runs.length).toBeGreaterThanOrEqual(2);
|
|
743
|
+
for (const run of runs) {
|
|
744
|
+
expect(run.resourceId).toBe(resourceId);
|
|
745
|
+
}
|
|
746
|
+
});
|
|
747
|
+
|
|
748
|
+
it('should return an empty array if no workflow runs match resourceId', async () => {
|
|
749
|
+
const { runs } = await store.getWorkflowRuns({
|
|
750
|
+
resourceId: 'non-existent-resource',
|
|
751
|
+
workflowName,
|
|
752
|
+
});
|
|
753
|
+
expect(Array.isArray(runs)).toBe(true);
|
|
754
|
+
expect(runs.length).toBe(0);
|
|
616
755
|
});
|
|
617
756
|
});
|
|
618
757
|
|
|
@@ -699,6 +838,38 @@ describe('PostgresStore', () => {
|
|
|
699
838
|
});
|
|
700
839
|
});
|
|
701
840
|
|
|
841
|
+
describe('hasColumn', () => {
|
|
842
|
+
const tempTable = 'temp_test_table';
|
|
843
|
+
|
|
844
|
+
beforeEach(async () => {
|
|
845
|
+
// Always try to drop the table before each test, ignore errors if it doesn't exist
|
|
846
|
+
try {
|
|
847
|
+
await store['db'].query(`DROP TABLE IF EXISTS ${tempTable}`);
|
|
848
|
+
} catch {
|
|
849
|
+
/* ignore */
|
|
850
|
+
}
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
it('returns true if the column exists', async () => {
|
|
854
|
+
await store['db'].query(`CREATE TABLE ${tempTable} (id SERIAL PRIMARY KEY, resourceId TEXT)`);
|
|
855
|
+
expect(await store['hasColumn'](tempTable, 'resourceId')).toBe(true);
|
|
856
|
+
});
|
|
857
|
+
|
|
858
|
+
it('returns false if the column does not exist', async () => {
|
|
859
|
+
await store['db'].query(`CREATE TABLE ${tempTable} (id SERIAL PRIMARY KEY)`);
|
|
860
|
+
expect(await store['hasColumn'](tempTable, 'resourceId')).toBe(false);
|
|
861
|
+
});
|
|
862
|
+
|
|
863
|
+
afterEach(async () => {
|
|
864
|
+
// Always try to drop the table after each test, ignore errors if it doesn't exist
|
|
865
|
+
try {
|
|
866
|
+
await store['db'].query(`DROP TABLE IF EXISTS ${tempTable}`);
|
|
867
|
+
} catch {
|
|
868
|
+
/* ignore */
|
|
869
|
+
}
|
|
870
|
+
});
|
|
871
|
+
});
|
|
872
|
+
|
|
702
873
|
describe('Schema Support', () => {
|
|
703
874
|
const customSchema = 'mastra_test';
|
|
704
875
|
let customSchemaStore: PostgresStore;
|