@eventualize/relational-storage-adapter 1.0.0 → 2.0.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/package.json +17 -3
- package/prisma.config.d.ts +0 -3
- package/prisma.config.js +0 -15
- package/prisma.config.js.map +0 -1
- package/prisma.config.ts +0 -16
- package/src/EvDbPrismaStorageAdapter.ts +0 -305
- package/src/EvDbPrismaStorageAdmin.ts +0 -27
- package/src/EvDbRelationalStorageAdapterQueries.ts +0 -118
- package/src/generated/prisma/browser.ts +0 -34
- package/src/generated/prisma/client.ts +0 -56
- package/src/generated/prisma/commonInputTypes.ts +0 -459
- package/src/generated/prisma/enums.ts +0 -15
- package/src/generated/prisma/internal/class.ts +0 -210
- package/src/generated/prisma/internal/prismaNamespace.ts +0 -1029
- package/src/generated/prisma/internal/prismaNamespaceBrowser.ts +0 -169
- package/src/generated/prisma/models/events.ts +0 -1339
- package/src/generated/prisma/models/outbox.ts +0 -1420
- package/src/generated/prisma/models/snapshot.ts +0 -1246
- package/src/generated/prisma/models.ts +0 -14
- package/tsconfig.json +0 -21
package/package.json
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eventualize/relational-storage-adapter",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/outsidenote/eventualize-js",
|
|
8
|
+
"directory": "packages/relational-storage-adapter"
|
|
9
|
+
},
|
|
5
10
|
"main": "dist/index.js",
|
|
6
11
|
"types": "dist/index.d.ts",
|
|
7
12
|
"exports": {
|
|
@@ -9,7 +14,13 @@
|
|
|
9
14
|
"import": "./dist/index.js",
|
|
10
15
|
"types": "./dist/index.d.ts"
|
|
11
16
|
},
|
|
12
|
-
"./*":
|
|
17
|
+
"./*": {
|
|
18
|
+
"import": "./dist/*.js",
|
|
19
|
+
"types": "./dist/*.d.ts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
13
24
|
},
|
|
14
25
|
"scripts": {
|
|
15
26
|
"build": "tsc --build",
|
|
@@ -25,5 +36,8 @@
|
|
|
25
36
|
"devDependencies": {
|
|
26
37
|
"dotenv": "^17.2.3",
|
|
27
38
|
"prisma": "^7.1.0"
|
|
28
|
-
}
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist"
|
|
42
|
+
]
|
|
29
43
|
}
|
package/prisma.config.d.ts
DELETED
package/prisma.config.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// This file was generated by Prisma and assumes you have installed the following:
|
|
2
|
-
// npm install --save-dev prisma dotenv
|
|
3
|
-
import "dotenv/config";
|
|
4
|
-
import { defineConfig, env } from "prisma/config";
|
|
5
|
-
console.log('database url:', env("DATABASE_URL"));
|
|
6
|
-
export default defineConfig({
|
|
7
|
-
schema: "prisma/schema.prisma",
|
|
8
|
-
migrations: {
|
|
9
|
-
path: "prisma/migrations",
|
|
10
|
-
},
|
|
11
|
-
datasource: {
|
|
12
|
-
url: env("DATABASE_URL"),
|
|
13
|
-
},
|
|
14
|
-
});
|
|
15
|
-
//# sourceMappingURL=prisma.config.js.map
|
package/prisma.config.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prisma.config.js","sourceRoot":"","sources":["prisma.config.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,uCAAuC;AACvC,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC,CAAA;AAEjD,eAAe,YAAY,CAAC;IAC1B,MAAM,EAAE,sBAAsB;IAC9B,UAAU,EAAE;QACV,IAAI,EAAE,mBAAmB;KAC1B;IACD,UAAU,EAAE;QACV,GAAG,EAAE,GAAG,CAAC,cAAc,CAAC;KACzB;CACF,CAAC,CAAC"}
|
package/prisma.config.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
// This file was generated by Prisma and assumes you have installed the following:
|
|
2
|
-
// npm install --save-dev prisma dotenv
|
|
3
|
-
import "dotenv/config";
|
|
4
|
-
import { defineConfig, env } from "prisma/config";
|
|
5
|
-
|
|
6
|
-
console.log('database url:', env("DATABASE_URL"))
|
|
7
|
-
|
|
8
|
-
export default defineConfig({
|
|
9
|
-
schema: "prisma/schema.prisma",
|
|
10
|
-
migrations: {
|
|
11
|
-
path: "prisma/migrations",
|
|
12
|
-
},
|
|
13
|
-
datasource: {
|
|
14
|
-
url: env("DATABASE_URL"),
|
|
15
|
-
},
|
|
16
|
-
});
|
|
@@ -1,305 +0,0 @@
|
|
|
1
|
-
import { IEvDbPayloadData } from '@eventualize/types/IEvDbEventPayload';
|
|
2
|
-
import IEvDbEventMetadata from '@eventualize/types/IEvDbEventMetadata';
|
|
3
|
-
import EvDbStreamCursor from '@eventualize/types/EvDbStreamCursor';
|
|
4
|
-
import EvDbMessage from '@eventualize/types/EvDbMessage';
|
|
5
|
-
import IEvDbStorageSnapshotAdapter from '@eventualize/types/IEvDbStorageSnapshotAdapter';
|
|
6
|
-
import IEvDbStorageStreamAdapter from '@eventualize/types/IEvDbStorageStreamAdapter';
|
|
7
|
-
import EvDbStreamAddress from '@eventualize/types/EvDbStreamAddress';
|
|
8
|
-
import EvDbViewAddress from '@eventualize/types/EvDbViewAddress';
|
|
9
|
-
import { EvDbStoredSnapshotResultRaw } from '@eventualize/types/EvDbStoredSnapshotResult';
|
|
10
|
-
import { EvDbStoredSnapshotData } from '@eventualize/types/EvDbStoredSnapshotData';
|
|
11
|
-
import EvDbEvent from '@eventualize/types/EvDbEvent';
|
|
12
|
-
import StreamStoreAffected from '@eventualize/types/StreamStoreAffected';
|
|
13
|
-
import EvDbContinuousFetchOptions from '@eventualize/types/EvDbContinuousFetchOptions';
|
|
14
|
-
import EvDbMessageFilter from '@eventualize/types/EvDbMessageFilter';
|
|
15
|
-
import { EvDbShardName } from '@eventualize/types/primitiveTypes';
|
|
16
|
-
|
|
17
|
-
import { Prisma } from './generated/prisma/client.js';
|
|
18
|
-
import { PrismaQueryProvider } from './EvDbRelationalStorageAdapterQueries.js';
|
|
19
|
-
// import { eventsCreateManyInput } from './generated/prisma/models';
|
|
20
|
-
|
|
21
|
-
// Type definitions for records
|
|
22
|
-
export interface EvDbEventRecord extends IEvDbEventMetadata {
|
|
23
|
-
id: string;
|
|
24
|
-
payload: IEvDbPayloadData;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface EvDbSnapshotRecord {
|
|
28
|
-
id: string;
|
|
29
|
-
streamType: string;
|
|
30
|
-
streamId: string;
|
|
31
|
-
viewName: string;
|
|
32
|
-
offset: bigint;
|
|
33
|
-
state: IEvDbPayloadData;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface IEvDbOutboxTransformer {
|
|
37
|
-
transform(message: EvDbMessage): EvDbMessage;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export interface EvDbStorageContext {
|
|
41
|
-
schema?: string;
|
|
42
|
-
shortId: string;
|
|
43
|
-
id: string;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const serializePayload = (payload: IEvDbPayloadData) => Buffer.from(JSON.stringify(payload), 'utf-8');
|
|
47
|
-
const deserializePayload = (payload: any): IEvDbPayloadData => {
|
|
48
|
-
if (!!payload && typeof payload == 'object') {
|
|
49
|
-
return payload;
|
|
50
|
-
}
|
|
51
|
-
return {};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Prisma-based storage adapter for EvDb
|
|
56
|
-
* Replaces SQL Server-specific adapter with database-agnostic Prisma implementation
|
|
57
|
-
*/
|
|
58
|
-
export class EvDbPrismaStorageAdapter implements IEvDbStorageSnapshotAdapter, IEvDbStorageStreamAdapter {
|
|
59
|
-
private readonly queryProvider: PrismaQueryProvider;
|
|
60
|
-
protected readonly databaseType: string = 'prisma';
|
|
61
|
-
|
|
62
|
-
constructor(
|
|
63
|
-
private readonly prisma: any,
|
|
64
|
-
) {
|
|
65
|
-
this.queryProvider = new PrismaQueryProvider(prisma);
|
|
66
|
-
}
|
|
67
|
-
getFromOutbox(filter: EvDbMessageFilter, options?: EvDbContinuousFetchOptions | null): Promise<AsyncIterable<EvDbMessage>> {
|
|
68
|
-
throw new Error('Method not implemented.');
|
|
69
|
-
}
|
|
70
|
-
getFromOutboxAsync(shard: EvDbShardName, filter: EvDbMessageFilter, options?: EvDbContinuousFetchOptions | null, cancellation?: AbortSignal): AsyncIterable<EvDbMessage> {
|
|
71
|
-
throw new Error('Method not implemented.');
|
|
72
|
-
}
|
|
73
|
-
getRecordsFromOutboxAsync(filter: EvDbMessageFilter, options?: EvDbContinuousFetchOptions | null, cancellation?: AbortSignal): AsyncIterable<EvDbMessage>;
|
|
74
|
-
getRecordsFromOutboxAsync(shard: EvDbShardName, filter: EvDbMessageFilter, options?: EvDbContinuousFetchOptions | null, cancellation?: AbortSignal): AsyncIterable<EvDbMessage>;
|
|
75
|
-
getRecordsFromOutboxAsync(shard: unknown, filter?: unknown, options?: unknown, cancellation?: unknown): AsyncIterable<EvDbMessage> {
|
|
76
|
-
throw new Error('Method not implemented.');
|
|
77
|
-
}
|
|
78
|
-
subscribeToMessageAsync(handler: (message: EvDbMessage) => Promise<void>, filter: EvDbMessageFilter, options?: EvDbContinuousFetchOptions | null): Promise<void>;
|
|
79
|
-
subscribeToMessageAsync(handler: (message: EvDbMessage) => Promise<void>, shard: EvDbShardName, filter: EvDbMessageFilter, options?: EvDbContinuousFetchOptions | null): Promise<void>;
|
|
80
|
-
subscribeToMessageAsync(handler: unknown, shard: unknown, filter?: unknown, options?: unknown): Promise<void> {
|
|
81
|
-
throw new Error('Method not implemented.');
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Store stream events in a transaction
|
|
86
|
-
*/
|
|
87
|
-
async storeStreamAsync(
|
|
88
|
-
events: ReadonlyArray<EvDbEvent>,
|
|
89
|
-
messages: ReadonlyArray<EvDbMessage>,
|
|
90
|
-
): Promise<StreamStoreAffected> {
|
|
91
|
-
try {
|
|
92
|
-
const eventsToInsert: Prisma.eventsCreateInput[] = events.map((event) => {
|
|
93
|
-
const streamCursor = event.streamCursor as EvDbStreamCursor;
|
|
94
|
-
return {
|
|
95
|
-
id: crypto.randomUUID(),
|
|
96
|
-
stream_type: streamCursor.streamType,
|
|
97
|
-
stream_id: streamCursor.streamId,
|
|
98
|
-
offset: streamCursor.offset,
|
|
99
|
-
event_type: event.eventType,
|
|
100
|
-
captured_by: event.capturedBy,
|
|
101
|
-
captured_at: event.capturedAt,
|
|
102
|
-
payload: event.payload,
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
const messagesToInsert: Prisma.outboxCreateInput[] = messages.map(message => {
|
|
107
|
-
const streamCursor = message.streamCursor as EvDbStreamCursor;
|
|
108
|
-
return {
|
|
109
|
-
id: message.id,
|
|
110
|
-
stream_type: streamCursor.streamType,
|
|
111
|
-
stream_id: streamCursor.streamId,
|
|
112
|
-
offset: streamCursor.offset,
|
|
113
|
-
event_type: message.eventType,
|
|
114
|
-
channel: message.channel,
|
|
115
|
-
message_type: message.messageType,
|
|
116
|
-
captured_by: message.capturedBy,
|
|
117
|
-
captured_at: message.capturedAt,
|
|
118
|
-
stored_at: message.storedAt,
|
|
119
|
-
payload: message.payload,
|
|
120
|
-
serialize_type: 'json',
|
|
121
|
-
}
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
const storeEventsQuery = this.queryProvider.saveEvents(eventsToInsert);
|
|
125
|
-
const storeMessagesQuery = this.queryProvider.saveMessages(messagesToInsert);
|
|
126
|
-
|
|
127
|
-
const queryResult = await this.prisma.$transaction([
|
|
128
|
-
storeEventsQuery,
|
|
129
|
-
storeMessagesQuery
|
|
130
|
-
]);
|
|
131
|
-
|
|
132
|
-
const numEvents = queryResult[0].count;
|
|
133
|
-
const numMessages = queryResult[1].count;
|
|
134
|
-
return new StreamStoreAffected(numEvents, numMessages);
|
|
135
|
-
} catch (error) {
|
|
136
|
-
if (this.isOccException(error)) {
|
|
137
|
-
throw new Error('OPTIMISTIC_CONCURRENCY_VIOLATION');
|
|
138
|
-
}
|
|
139
|
-
throw error;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Store outbox messages in a transaction
|
|
145
|
-
*/
|
|
146
|
-
async storeOutboxMessagesAsync(
|
|
147
|
-
shardName: EvDbShardName,
|
|
148
|
-
records: EvDbMessage[],
|
|
149
|
-
): Promise<number> {
|
|
150
|
-
throw new Error('Method not implemented.');
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Get the last offset for a stream
|
|
155
|
-
*/
|
|
156
|
-
async getLastOffsetAsync(
|
|
157
|
-
streamAddress: EvDbStreamAddress
|
|
158
|
-
): Promise<number> {
|
|
159
|
-
try {
|
|
160
|
-
const { streamType, streamId } = streamAddress;
|
|
161
|
-
const result = await this.queryProvider.getLastOffset(streamType, streamId);
|
|
162
|
-
return Number(result?.offset ?? -1);
|
|
163
|
-
} catch (error) {
|
|
164
|
-
throw error;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Get events for a stream since a specific offset
|
|
170
|
-
*/
|
|
171
|
-
async *getEventsAsync(
|
|
172
|
-
streamCursor: EvDbStreamCursor,
|
|
173
|
-
pageSize: number = 100
|
|
174
|
-
): AsyncGenerator<EvDbEvent, void, undefined> {
|
|
175
|
-
const { streamType, streamId } = streamCursor;
|
|
176
|
-
let currentOffset = streamCursor.offset;
|
|
177
|
-
while (true) {
|
|
178
|
-
try {
|
|
179
|
-
const events = await this.queryProvider.getEvents(
|
|
180
|
-
streamType,
|
|
181
|
-
streamId,
|
|
182
|
-
currentOffset
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
if (events.length === 0) {
|
|
186
|
-
break;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
for (const event of events) {
|
|
190
|
-
yield new EvDbEvent(
|
|
191
|
-
event.event_type,
|
|
192
|
-
new EvDbStreamCursor(event.stream_type, event.stream_id, Number(event.offset)),
|
|
193
|
-
{ payloadType: event.event_type, payload: deserializePayload(event.payload) },
|
|
194
|
-
event.captured_at,
|
|
195
|
-
event.captured_by, event.stored_at
|
|
196
|
-
);
|
|
197
|
-
currentOffset = Math.max(currentOffset, Number(event.offset))
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (events.length < pageSize) {
|
|
201
|
-
break; // Reached the end of the stream in the last page
|
|
202
|
-
}
|
|
203
|
-
} catch (error) {
|
|
204
|
-
throw error;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Get messages from outbox with optional filtering
|
|
211
|
-
*/
|
|
212
|
-
async getMessagesAsync(
|
|
213
|
-
shardName: EvDbShardName,
|
|
214
|
-
sinceDate: Date,
|
|
215
|
-
channels?: string[],
|
|
216
|
-
messageTypes?: string[],
|
|
217
|
-
cancellationToken?: AbortSignal
|
|
218
|
-
): Promise<EvDbMessage[]> {
|
|
219
|
-
try {
|
|
220
|
-
const tableName = this.getTableNameForShard(shardName);
|
|
221
|
-
const messages = await this.queryProvider.getMessages(
|
|
222
|
-
tableName,
|
|
223
|
-
sinceDate,
|
|
224
|
-
channels,
|
|
225
|
-
messageTypes
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
return messages as EvDbMessage[];
|
|
229
|
-
} catch (error) {
|
|
230
|
-
throw error;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Get snapshot for a stream view
|
|
236
|
-
*/
|
|
237
|
-
async getSnapshotAsync(
|
|
238
|
-
viewAddress: EvDbViewAddress
|
|
239
|
-
): Promise<EvDbStoredSnapshotResultRaw> {
|
|
240
|
-
const { streamType, streamId, viewName } = viewAddress;
|
|
241
|
-
try {
|
|
242
|
-
const snapshot = await this.queryProvider.getSnapshot(
|
|
243
|
-
streamType,
|
|
244
|
-
streamId,
|
|
245
|
-
viewName
|
|
246
|
-
);
|
|
247
|
-
|
|
248
|
-
if (!snapshot) return EvDbStoredSnapshotResultRaw.Empty;
|
|
249
|
-
|
|
250
|
-
return new EvDbStoredSnapshotResultRaw(
|
|
251
|
-
Number(snapshot.offset),
|
|
252
|
-
snapshot.stored_at,
|
|
253
|
-
deserializePayload(snapshot.state),
|
|
254
|
-
);
|
|
255
|
-
} catch (error) {
|
|
256
|
-
throw error;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Save a snapshot
|
|
262
|
-
*/
|
|
263
|
-
async storeSnapshotAsync(record: EvDbStoredSnapshotData): Promise<void> {
|
|
264
|
-
try {
|
|
265
|
-
await this.queryProvider.saveSnapshot({
|
|
266
|
-
id: record.id,
|
|
267
|
-
stream_type: record.streamType,
|
|
268
|
-
stream_id: record.streamId,
|
|
269
|
-
view_name: record.viewName,
|
|
270
|
-
offset: record.offset,
|
|
271
|
-
state: record.state,
|
|
272
|
-
stored_at: new Date(),
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
} catch (error) {
|
|
276
|
-
throw error;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Check if an exception is an optimistic concurrency conflict
|
|
282
|
-
*/
|
|
283
|
-
private isOccException(error: unknown): boolean {
|
|
284
|
-
// P2002 = Unique constraint violation
|
|
285
|
-
// P2034 = Transaction conflict
|
|
286
|
-
const anyError = error as any;
|
|
287
|
-
return !!error && anyError?.code === 'P2002' || anyError.code === 'P2034';
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* Get table name for shard
|
|
292
|
-
*/
|
|
293
|
-
private getTableNameForShard(shardName: EvDbShardName): string {
|
|
294
|
-
throw new Error('Method not implemented.');
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Close the database connection
|
|
299
|
-
*/
|
|
300
|
-
async close(): Promise<void> {
|
|
301
|
-
await this.prisma.$disconnect();
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
export default EvDbPrismaStorageAdapter;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import IEvDbStorageAdmin from "@eventualize/types/IEvDbStorageAdmin";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export default class EvDbPrismaStorageAdmin implements IEvDbStorageAdmin {
|
|
5
|
-
constructor(private prisma: any) { }
|
|
6
|
-
async clearEnvironmentAsync(): Promise<void> {
|
|
7
|
-
await Promise.all([
|
|
8
|
-
this.prisma.events.deleteMany({}),
|
|
9
|
-
this.prisma.snapshot.deleteMany({}),
|
|
10
|
-
this.prisma.outbox.deleteMany({}),
|
|
11
|
-
]);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
createEnvironmentAsync(): Promise<void> {
|
|
15
|
-
throw new Error("Method not implemented.");
|
|
16
|
-
}
|
|
17
|
-
destroyEnvironmentAsync(): Promise<void> {
|
|
18
|
-
throw new Error('Method not implemented.');
|
|
19
|
-
}
|
|
20
|
-
async close(): Promise<void> {
|
|
21
|
-
await this.prisma.$disconnect();
|
|
22
|
-
}
|
|
23
|
-
disposeAsync(): Promise<void> {
|
|
24
|
-
throw new Error("Method not implemented.");
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
}
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { PrismaClient, Prisma } from './generated/prisma/client.js';
|
|
2
|
-
|
|
3
|
-
// ============================================================================
|
|
4
|
-
// Prisma-based Query Methods (Type-safe alternatives to raw SQL)
|
|
5
|
-
// ============================================================================
|
|
6
|
-
|
|
7
|
-
export class PrismaQueryProvider {
|
|
8
|
-
constructor(private prisma: PrismaClient) { }
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Get the last offset for a stream using Prisma
|
|
12
|
-
*/
|
|
13
|
-
async getLastOffset(stream_type: string, stream_id: string) {
|
|
14
|
-
return this.prisma.events.findFirst({
|
|
15
|
-
where: { stream_type, stream_id },
|
|
16
|
-
select: { offset: true },
|
|
17
|
-
orderBy: { offset: 'desc' },
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Get events for a stream since an offset using Prisma
|
|
23
|
-
*/
|
|
24
|
-
async getEvents(stream_type: string, stream_id: string, since_offset: number, pageSize: number = 100) {
|
|
25
|
-
return this.prisma.events.findMany({
|
|
26
|
-
where: {
|
|
27
|
-
stream_type,
|
|
28
|
-
stream_id,
|
|
29
|
-
offset: { gte: since_offset },
|
|
30
|
-
},
|
|
31
|
-
select: {
|
|
32
|
-
id: true,
|
|
33
|
-
stream_type: true,
|
|
34
|
-
stream_id: true,
|
|
35
|
-
offset: true,
|
|
36
|
-
event_type: true,
|
|
37
|
-
captured_at: true,
|
|
38
|
-
captured_by: true,
|
|
39
|
-
payload: true,
|
|
40
|
-
stored_at: true
|
|
41
|
-
},
|
|
42
|
-
take: pageSize
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Get messages with filtering using Prisma
|
|
48
|
-
*/
|
|
49
|
-
async getMessages(table_name: string, since_date: Date, channels?: string[], message_types?: string[]) {
|
|
50
|
-
const now = new Date();
|
|
51
|
-
const oneSecondAgo = new Date(now.getTime() - 1000);
|
|
52
|
-
|
|
53
|
-
// Note: This assumes a dynamic table name approach
|
|
54
|
-
// In Prisma, you'd typically use $queryRawUnsafe for dynamic table names
|
|
55
|
-
const whereClause: any = {
|
|
56
|
-
stored_at: { gte: since_date, lt: oneSecondAgo },
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
if (channels && channels.length > 0) {
|
|
60
|
-
whereClause.channel = { in: channels };
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (message_types && message_types.length > 0) {
|
|
64
|
-
whereClause.messageType = { in: message_types };
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// This would need to be adapted based on your actual Prisma schema
|
|
68
|
-
return this.prisma.$queryRawUnsafe(
|
|
69
|
-
`SELECT * FROM ${table_name} WHERE stored_at >= $1 AND stored_at < $2`,
|
|
70
|
-
since_date,
|
|
71
|
-
oneSecondAgo
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Save events in batch using Prisma
|
|
77
|
-
*/
|
|
78
|
-
saveEvents(events: Array<Prisma.eventsCreateInput>) {
|
|
79
|
-
return this.prisma.events.createMany({ data: events });
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Save messages in batch using Prisma
|
|
84
|
-
*/
|
|
85
|
-
saveMessages(messages: Array<Prisma.outboxCreateInput>) {
|
|
86
|
-
return this.prisma.outbox.createMany({ data: messages });
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Get snapshot using Prisma
|
|
91
|
-
*/
|
|
92
|
-
async getSnapshot(streamType: string, streamId: string, viewName: string) {
|
|
93
|
-
return this.prisma.snapshot.findFirst({
|
|
94
|
-
where: {
|
|
95
|
-
stream_type: streamType,
|
|
96
|
-
stream_id: streamId,
|
|
97
|
-
view_name: viewName,
|
|
98
|
-
},
|
|
99
|
-
select: {
|
|
100
|
-
state: true,
|
|
101
|
-
stored_at: true,
|
|
102
|
-
offset: true,
|
|
103
|
-
},
|
|
104
|
-
orderBy: {
|
|
105
|
-
offset: 'desc',
|
|
106
|
-
},
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Save snapshot using Prisma
|
|
112
|
-
*/
|
|
113
|
-
async saveSnapshot(data: Prisma.snapshotCreateInput) {
|
|
114
|
-
return this.prisma.snapshot.create({
|
|
115
|
-
data,
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
3
|
-
/* eslint-disable */
|
|
4
|
-
// biome-ignore-all lint: generated file
|
|
5
|
-
// @ts-nocheck
|
|
6
|
-
/*
|
|
7
|
-
* This file should be your main import to use Prisma-related types and utilities in a browser.
|
|
8
|
-
* Use it to get access to models, enums, and input types.
|
|
9
|
-
*
|
|
10
|
-
* This file does not contain a `PrismaClient` class, nor several other helpers that are intended as server-side only.
|
|
11
|
-
* See `client.ts` for the standard, server-side entry point.
|
|
12
|
-
*
|
|
13
|
-
* 🟢 You can import this file directly.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import * as Prisma from './internal/prismaNamespaceBrowser.js'
|
|
17
|
-
export { Prisma }
|
|
18
|
-
export * as $Enums from './enums.js'
|
|
19
|
-
export * from './enums.js';
|
|
20
|
-
/**
|
|
21
|
-
* Model events
|
|
22
|
-
* This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info.
|
|
23
|
-
*/
|
|
24
|
-
export type events = Prisma.eventsModel
|
|
25
|
-
/**
|
|
26
|
-
* Model outbox
|
|
27
|
-
* This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info.
|
|
28
|
-
*/
|
|
29
|
-
export type outbox = Prisma.outboxModel
|
|
30
|
-
/**
|
|
31
|
-
* Model snapshot
|
|
32
|
-
* This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info.
|
|
33
|
-
*/
|
|
34
|
-
export type snapshot = Prisma.snapshotModel
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
3
|
-
/* eslint-disable */
|
|
4
|
-
// biome-ignore-all lint: generated file
|
|
5
|
-
// @ts-nocheck
|
|
6
|
-
/*
|
|
7
|
-
* This file should be your main import to use Prisma. Through it you get access to all the models, enums, and input types.
|
|
8
|
-
* If you're looking for something you can import in the client-side of your application, please refer to the `browser.ts` file instead.
|
|
9
|
-
*
|
|
10
|
-
* 🟢 You can import this file directly.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import * as process from 'node:process'
|
|
14
|
-
import * as path from 'node:path'
|
|
15
|
-
import { fileURLToPath } from 'node:url'
|
|
16
|
-
globalThis['__dirname'] = path.dirname(fileURLToPath(import.meta.url))
|
|
17
|
-
|
|
18
|
-
import * as runtime from "@prisma/client/runtime/client"
|
|
19
|
-
import * as $Enums from "./enums.js"
|
|
20
|
-
import * as $Class from "./internal/class.js"
|
|
21
|
-
import * as Prisma from "./internal/prismaNamespace.js"
|
|
22
|
-
|
|
23
|
-
export * as $Enums from './enums.js'
|
|
24
|
-
export * from "./enums.js"
|
|
25
|
-
/**
|
|
26
|
-
* ## Prisma Client
|
|
27
|
-
*
|
|
28
|
-
* Type-safe database client for TypeScript
|
|
29
|
-
* @example
|
|
30
|
-
* ```
|
|
31
|
-
* const prisma = new PrismaClient()
|
|
32
|
-
* // Fetch zero or more Events
|
|
33
|
-
* const events = await prisma.events.findMany()
|
|
34
|
-
* ```
|
|
35
|
-
*
|
|
36
|
-
* Read more in our [docs](https://pris.ly/d/client).
|
|
37
|
-
*/
|
|
38
|
-
export const PrismaClient = $Class.getPrismaClientClass()
|
|
39
|
-
export type PrismaClient<LogOpts extends Prisma.LogLevel = never, OmitOpts extends Prisma.PrismaClientOptions["omit"] = Prisma.PrismaClientOptions["omit"], ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = $Class.PrismaClient<LogOpts, OmitOpts, ExtArgs>
|
|
40
|
-
export { Prisma }
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Model events
|
|
44
|
-
* This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info.
|
|
45
|
-
*/
|
|
46
|
-
export type events = Prisma.eventsModel
|
|
47
|
-
/**
|
|
48
|
-
* Model outbox
|
|
49
|
-
* This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info.
|
|
50
|
-
*/
|
|
51
|
-
export type outbox = Prisma.outboxModel
|
|
52
|
-
/**
|
|
53
|
-
* Model snapshot
|
|
54
|
-
* This table contains check constraints and requires additional setup for migrations. Visit https://pris.ly/d/check-constraints for more info.
|
|
55
|
-
*/
|
|
56
|
-
export type snapshot = Prisma.snapshotModel
|