@shivaedev/sql 0.0.0-stage → 0.21.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/CHANGELOG.md +269 -0
- package/LICENSE +21 -0
- package/README.md +614 -2
- package/dist/SchemaComponent.d.ts +9 -0
- package/dist/SchemaComponent.d.ts.map +1 -0
- package/dist/SchemaComponent.js +6 -0
- package/dist/SchemaComponent.js.map +1 -0
- package/dist/WorkerRelease.d.ts +14 -0
- package/dist/WorkerRelease.d.ts.map +1 -0
- package/dist/WorkerRelease.js +30 -0
- package/dist/WorkerRelease.js.map +1 -0
- package/dist/advisoryXactLock.d.ts +10 -0
- package/dist/advisoryXactLock.d.ts.map +1 -0
- package/dist/advisoryXactLock.js +18 -0
- package/dist/advisoryXactLock.js.map +1 -0
- package/dist/aggregateColumn.d.ts +8 -0
- package/dist/aggregateColumn.d.ts.map +1 -0
- package/dist/aggregateColumn.js +44 -0
- package/dist/aggregateColumn.js.map +1 -0
- package/dist/aggregateQuery.d.ts +51 -0
- package/dist/aggregateQuery.d.ts.map +1 -0
- package/dist/aggregateQuery.js +2 -0
- package/dist/aggregateQuery.js.map +1 -0
- package/dist/assertPostgresMigrations.d.ts +7 -0
- package/dist/assertPostgresMigrations.d.ts.map +1 -0
- package/dist/assertPostgresMigrations.js +20 -0
- package/dist/assertPostgresMigrations.js.map +1 -0
- package/dist/batchWrites.d.ts +16 -0
- package/dist/batchWrites.d.ts.map +1 -0
- package/dist/batchWrites.js +49 -0
- package/dist/batchWrites.js.map +1 -0
- package/dist/clientOptions.d.ts +8 -0
- package/dist/clientOptions.d.ts.map +1 -0
- package/dist/clientOptions.js +8 -0
- package/dist/clientOptions.js.map +1 -0
- package/dist/compositeRepository.d.ts +41 -0
- package/dist/compositeRepository.d.ts.map +1 -0
- package/dist/compositeRepository.js +38 -0
- package/dist/compositeRepository.js.map +1 -0
- package/dist/conditionalUpsert.d.ts +59 -0
- package/dist/conditionalUpsert.d.ts.map +1 -0
- package/dist/conditionalUpsert.js +28 -0
- package/dist/conditionalUpsert.js.map +1 -0
- package/dist/conflictWrites.d.ts +45 -0
- package/dist/conflictWrites.d.ts.map +1 -0
- package/dist/conflictWrites.js +40 -0
- package/dist/conflictWrites.js.map +1 -0
- package/dist/coordinateWorkerRelease.d.ts +5 -0
- package/dist/coordinateWorkerRelease.d.ts.map +1 -0
- package/dist/coordinateWorkerRelease.js +30 -0
- package/dist/coordinateWorkerRelease.js.map +1 -0
- package/dist/insertFromSelect.d.ts +24 -0
- package/dist/insertFromSelect.d.ts.map +1 -0
- package/dist/insertFromSelect.js +15 -0
- package/dist/insertFromSelect.js.map +1 -0
- package/dist/latestPerGroup.d.ts +11 -0
- package/dist/latestPerGroup.d.ts.map +1 -0
- package/dist/latestPerGroup.js +51 -0
- package/dist/latestPerGroup.js.map +1 -0
- package/dist/listenForChanges.d.ts +5 -0
- package/dist/listenForChanges.d.ts.map +1 -0
- package/dist/listenForChanges.js +75 -0
- package/dist/listenForChanges.js.map +1 -0
- package/dist/makeAggregate.d.ts +8 -0
- package/dist/makeAggregate.d.ts.map +1 -0
- package/dist/makeAggregate.js +38 -0
- package/dist/makeAggregate.js.map +1 -0
- package/dist/makeConflictClause.d.ts +10 -0
- package/dist/makeConflictClause.d.ts.map +1 -0
- package/dist/makeConflictClause.js +41 -0
- package/dist/makeConflictClause.js.map +1 -0
- package/dist/makeQueryClauses.d.ts +14 -0
- package/dist/makeQueryClauses.d.ts.map +1 -0
- package/dist/makeQueryClauses.js +20 -0
- package/dist/makeQueryClauses.js.map +1 -0
- package/dist/migrationConvention.d.ts +3 -0
- package/dist/migrationConvention.d.ts.map +1 -0
- package/dist/migrationConvention.js +3 -0
- package/dist/migrationConvention.js.map +1 -0
- package/dist/migrations.d.ts +12 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +41 -0
- package/dist/migrations.js.map +1 -0
- package/dist/migrationsFromDirectory.d.ts +4 -0
- package/dist/migrationsFromDirectory.d.ts.map +1 -0
- package/dist/migrationsFromDirectory.js +7 -0
- package/dist/migrationsFromDirectory.js.map +1 -0
- package/dist/notifyPayload.d.ts +7 -0
- package/dist/notifyPayload.d.ts.map +1 -0
- package/dist/notifyPayload.js +31 -0
- package/dist/notifyPayload.js.map +1 -0
- package/dist/pendingPostgresMigrations.d.ts +24 -0
- package/dist/pendingPostgresMigrations.d.ts.map +1 -0
- package/dist/pendingPostgresMigrations.js +30 -0
- package/dist/pendingPostgresMigrations.js.map +1 -0
- package/dist/pinnedGroups.d.ts +22 -0
- package/dist/pinnedGroups.d.ts.map +1 -0
- package/dist/pinnedGroups.js +35 -0
- package/dist/pinnedGroups.js.map +1 -0
- package/dist/postgresChanges.d.ts +20 -0
- package/dist/postgresChanges.d.ts.map +1 -0
- package/dist/postgresChanges.js +26 -0
- package/dist/postgresChanges.js.map +1 -0
- package/dist/postgresRelease.d.ts +9 -0
- package/dist/postgresRelease.d.ts.map +1 -0
- package/dist/postgresRelease.js +39 -0
- package/dist/postgresRelease.js.map +1 -0
- package/dist/releaseWorkers.d.ts +8 -0
- package/dist/releaseWorkers.d.ts.map +1 -0
- package/dist/releaseWorkers.js +26 -0
- package/dist/releaseWorkers.js.map +1 -0
- package/dist/repository.d.ts +66 -0
- package/dist/repository.d.ts.map +1 -0
- package/dist/repository.js +43 -0
- package/dist/repository.js.map +1 -0
- package/dist/repositoryChanges.d.ts +9 -0
- package/dist/repositoryChanges.d.ts.map +1 -0
- package/dist/repositoryChanges.js +32 -0
- package/dist/repositoryChanges.js.map +1 -0
- package/dist/repositoryFilter.d.ts +43 -0
- package/dist/repositoryFilter.d.ts.map +1 -0
- package/dist/repositoryFilter.js +69 -0
- package/dist/repositoryFilter.js.map +1 -0
- package/dist/repositoryQueries.d.ts +26 -0
- package/dist/repositoryQueries.d.ts.map +1 -0
- package/dist/repositoryQueries.js +49 -0
- package/dist/repositoryQueries.js.map +1 -0
- package/dist/repositoryWrites.d.ts +18 -0
- package/dist/repositoryWrites.d.ts.map +1 -0
- package/dist/repositoryWrites.js +49 -0
- package/dist/repositoryWrites.js.map +1 -0
- package/dist/testing.d.ts +12 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +29 -0
- package/dist/testing.js.map +1 -0
- package/dist/transact.d.ts +18 -0
- package/dist/transact.d.ts.map +1 -0
- package/dist/transact.js +43 -0
- package/dist/transact.js.map +1 -0
- package/dist/tupleIn.d.ts +19 -0
- package/dist/tupleIn.d.ts.map +1 -0
- package/dist/tupleIn.js +20 -0
- package/dist/tupleIn.js.map +1 -0
- package/dist/versionedRepository.d.ts +37 -0
- package/dist/versionedRepository.d.ts.map +1 -0
- package/dist/versionedRepository.js +63 -0
- package/dist/versionedRepository.js.map +1 -0
- package/dist/versionedStatements.d.ts +25 -0
- package/dist/versionedStatements.d.ts.map +1 -0
- package/dist/versionedStatements.js +75 -0
- package/dist/versionedStatements.js.map +1 -0
- package/package.json +74 -3
- package/src/SchemaComponent.ts +12 -0
- package/src/WorkerRelease.ts +38 -0
- package/src/advisoryXactLock.ts +17 -0
- package/src/aggregateColumn.ts +49 -0
- package/src/aggregateQuery.ts +57 -0
- package/src/assertPostgresMigrations.ts +24 -0
- package/src/batchWrites.ts +69 -0
- package/src/clientOptions.ts +16 -0
- package/src/compositeRepository.ts +101 -0
- package/src/conditionalUpsert.ts +97 -0
- package/src/conflictWrites.ts +93 -0
- package/src/coordinateWorkerRelease.ts +33 -0
- package/src/insertFromSelect.ts +47 -0
- package/src/latestPerGroup.ts +58 -0
- package/src/listenForChanges.ts +97 -0
- package/src/makeAggregate.ts +64 -0
- package/src/makeConflictClause.ts +53 -0
- package/src/makeQueryClauses.ts +36 -0
- package/src/migrationConvention.ts +2 -0
- package/src/migrations.ts +58 -0
- package/src/migrationsFromDirectory.ts +7 -0
- package/src/notifyPayload.ts +34 -0
- package/src/pendingPostgresMigrations.ts +42 -0
- package/src/pinnedGroups.ts +46 -0
- package/src/postgresChanges.ts +48 -0
- package/src/postgresRelease.ts +41 -0
- package/src/releaseWorkers.ts +32 -0
- package/src/repository.ts +147 -0
- package/src/repositoryChanges.ts +49 -0
- package/src/repositoryFilter.ts +108 -0
- package/src/repositoryQueries.ts +107 -0
- package/src/repositoryWrites.ts +70 -0
- package/src/testing.ts +38 -0
- package/src/transact.ts +70 -0
- package/src/tupleIn.ts +44 -0
- package/src/versionedRepository.ts +108 -0
- package/src/versionedStatements.ts +90 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaComponent.d.ts","sourceRoot":"","sources":["../src/SchemaComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAEtD,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,KAAK;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IACzE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,CAAC,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;CACtF;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,gDAE1F"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { Migrator } from "effect/sql";
|
|
3
|
+
export function runSchemaComponent(name, effect) {
|
|
4
|
+
return effect.pipe(Effect.mapError((cause) => new Migrator.MigrationError({ cause, kind: "Failed", message: `Schema component ${name} failed.` })));
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=SchemaComponent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaComponent.js","sourceRoot":"","sources":["../src/SchemaComponent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAkB,MAAM,YAAY,CAAC;AAQtD,MAAM,UAAU,kBAAkB,CAAO,IAAY,EAAE,MAAoC;IAC1F,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,QAAQ,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,oBAAoB,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AACrJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Context, Effect, type Scope } from "effect";
|
|
2
|
+
declare const WorkerRelease_base: Context.ServiceClass<WorkerRelease, "@shivaedev/sql/WorkerRelease", {
|
|
3
|
+
readonly register: <E>(control: (active: boolean) => Effect.Effect<void, E>) => Effect.Effect<void, E, Scope.Scope>;
|
|
4
|
+
}>;
|
|
5
|
+
export declare class WorkerRelease extends WorkerRelease_base {
|
|
6
|
+
}
|
|
7
|
+
export declare const makeWorkerRelease: () => Effect.Effect<{
|
|
8
|
+
service: {
|
|
9
|
+
readonly register: <E>(control: (active: boolean) => Effect.Effect<void, E>) => Effect.Effect<void, E, Scope.Scope>;
|
|
10
|
+
};
|
|
11
|
+
setActive: (next: boolean) => Effect.Effect<void, unknown, never>;
|
|
12
|
+
}, never, never>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=WorkerRelease.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkerRelease.d.ts","sourceRoot":"","sources":["../src/WorkerRelease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,KAAK,EAAa,MAAM,QAAQ,CAAC;;uBAK3C,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC;;AAHrH,qBAAa,aAAc,SAAQ,kBAKA;CAAG;AAEtC,eAAO,MAAM,iBAAiB;;2BAJT,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC;;sBAqBjG,OAAO;gBAWzB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Context, Effect, Semaphore } from "effect";
|
|
2
|
+
export class WorkerRelease extends Context.Service()("@shivaedev/sql/WorkerRelease") {
|
|
3
|
+
}
|
|
4
|
+
export const makeWorkerRelease = Effect.fn("EffectSql.makeWorkerRelease")(function* () {
|
|
5
|
+
const mutex = Semaphore.makeUnsafe(1);
|
|
6
|
+
const controls = new Set();
|
|
7
|
+
let active = false;
|
|
8
|
+
const locked = mutex.withPermits(1);
|
|
9
|
+
function register(control) {
|
|
10
|
+
const attach = Effect.gen(function* () {
|
|
11
|
+
controls.add(control);
|
|
12
|
+
yield* control(active);
|
|
13
|
+
});
|
|
14
|
+
const detach = Effect.sync(() => {
|
|
15
|
+
controls.delete(control);
|
|
16
|
+
});
|
|
17
|
+
return Effect.acquireRelease(locked(attach), () => locked(detach));
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
service: WorkerRelease.of({ register }),
|
|
21
|
+
setActive: (next) => locked(Effect.gen(function* () {
|
|
22
|
+
if (next === active) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
active = next;
|
|
26
|
+
yield* Effect.forEach(controls, (control) => control(active), { concurrency: "unbounded", discard: true });
|
|
27
|
+
})).pipe(Effect.uninterruptible),
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=WorkerRelease.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkerRelease.js","sourceRoot":"","sources":["../src/WorkerRelease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAc,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEhE,MAAM,OAAO,aAAc,SAAQ,OAAO,CAAC,OAAO,EAK/C,CAAC,8BAA8B,CAAC;CAAG;AAEtC,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAAC,6BAA6B,CAAC,CAAC,QAAQ,CAAC;IAClF,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAqD,CAAC;IAC9E,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACpC,SAAS,QAAQ,CAAI,OAAoD;QACxE,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACtB,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;YAC/B,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACpE,CAAC;IACD,OAAO;QACN,OAAO,EAAE,aAAa,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC;QACvC,SAAS,EAAE,CAAC,IAAa,EAAE,EAAE,CAC5B,MAAM,CACL,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACnB,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBACrB,OAAO;YACR,CAAC;YACD,MAAM,GAAG,IAAI,CAAC;YACd,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5G,CAAC,CAAC,CACF,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;KAC/B,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { SqlClient } from "effect/sql";
|
|
3
|
+
declare const AdvisoryLockOutsideTransaction_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
4
|
+
readonly _tag: "AdvisoryLockOutsideTransaction";
|
|
5
|
+
} & Readonly<A>;
|
|
6
|
+
export declare class AdvisoryLockOutsideTransaction extends AdvisoryLockOutsideTransaction_base {
|
|
7
|
+
}
|
|
8
|
+
export declare const advisoryXactLock: (key: string | bigint) => Effect.Effect<undefined, AdvisoryLockOutsideTransaction | import("effect/sql/SqlError").SqlError, SqlClient.SqlClient>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=advisoryXactLock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advisoryXactLock.d.ts","sourceRoot":"","sources":["../src/advisoryXactLock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,MAAM,EAAU,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;;;;AAEvC,qBAAa,8BAA+B,SAAQ,mCAAkD;CAAG;AAEzG,eAAO,MAAM,gBAAgB,kJAW3B,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Data, Effect, Option } from "effect";
|
|
2
|
+
import { SqlClient } from "effect/sql";
|
|
3
|
+
export class AdvisoryLockOutsideTransaction extends Data.TaggedError("AdvisoryLockOutsideTransaction") {
|
|
4
|
+
}
|
|
5
|
+
export const advisoryXactLock = Effect.fn("EffectSql.advisoryXactLock")(function* (key) {
|
|
6
|
+
const sql = yield* SqlClient.SqlClient;
|
|
7
|
+
const transaction = yield* Effect.serviceOption(sql.transactionService);
|
|
8
|
+
if (Option.isNone(transaction)) {
|
|
9
|
+
return yield* new AdvisoryLockOutsideTransaction();
|
|
10
|
+
}
|
|
11
|
+
if (typeof key === "string") {
|
|
12
|
+
yield* sql `select pg_advisory_xact_lock(hashtextextended(${key}, 0))`;
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
yield* sql `select pg_advisory_xact_lock(${String(key)}::bigint)`;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=advisoryXactLock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advisoryXactLock.js","sourceRoot":"","sources":["../src/advisoryXactLock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,OAAO,8BAA+B,SAAQ,IAAI,CAAC,WAAW,CAAC,gCAAgC,CAAC;CAAG;AAEzG,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,EAAE,CAAC,4BAA4B,CAAC,CAAC,QAAQ,CAAC,EAAE,GAAoB;IACtG,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC;IACvC,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACxE,IAAI,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC,CAAC,IAAI,8BAA8B,EAAE,CAAC;IACpD,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC7B,KAAK,CAAC,CAAC,GAAG,CAAA,iDAAiD,GAAG,OAAO,CAAC;IACvE,CAAC;SAAM,CAAC;QACP,KAAK,CAAC,CAAC,GAAG,CAAA,gCAAgC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC;IAClE,CAAC;AACF,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import type { SqlClient } from "effect/sql";
|
|
3
|
+
export declare function aggregateColumn(sql: SqlClient.SqlClient, fieldAt: (key: string) => Effect.Effect<Schema.Constraint, Schema.SchemaError>): (name: string, expression: object) => Effect.Effect<{
|
|
4
|
+
column: import("effect/sql/Statement").Statement<import("effect/sql/SqlConnection").Row>;
|
|
5
|
+
order: import("effect/sql/Statement").Statement<import("effect/sql/SqlConnection").Row>;
|
|
6
|
+
schema: Schema.Constraint;
|
|
7
|
+
}, Schema.SchemaError, never>;
|
|
8
|
+
//# sourceMappingURL=aggregateColumn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregateColumn.d.ts","sourceRoot":"","sources":["../src/aggregateColumn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAa,MAAM,QAAQ,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAgC5C,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,WAAW,CAAC;;;;8BAevI"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Effect, Schema, SchemaAST } from "effect";
|
|
2
|
+
const Expression = Schema.Tuple([Schema.Tuple([Schema.Literals(["count", "sum", "avg", "min", "max", "boolOr", "boolAnd"]), Schema.String])]);
|
|
3
|
+
const functions = { avg: "avg", boolAnd: "bool_and", boolOr: "bool_or", count: "count", max: "max", min: "min", sum: "sum" };
|
|
4
|
+
function isNumber(ast) {
|
|
5
|
+
if (ast._tag === "Union") {
|
|
6
|
+
return ast.types.some(isNumber);
|
|
7
|
+
}
|
|
8
|
+
if (ast._tag === "Suspend") {
|
|
9
|
+
return isNumber(ast.thunk());
|
|
10
|
+
}
|
|
11
|
+
return ast._tag === "Number" || (ast._tag === "Literal" && typeof ast.literal === "number");
|
|
12
|
+
}
|
|
13
|
+
function resultSchema(operation, field) {
|
|
14
|
+
switch (operation) {
|
|
15
|
+
case "count":
|
|
16
|
+
return Schema.NumberFromString;
|
|
17
|
+
case "sum":
|
|
18
|
+
case "avg":
|
|
19
|
+
return isNumber(SchemaAST.toType(field.ast)) ? Schema.NumberFromString : Schema.BigDecimalFromString;
|
|
20
|
+
case "boolOr":
|
|
21
|
+
case "boolAnd":
|
|
22
|
+
return Schema.Boolean;
|
|
23
|
+
case "min":
|
|
24
|
+
case "max":
|
|
25
|
+
return field;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export function aggregateColumn(sql, fieldAt) {
|
|
29
|
+
return Effect.fnUntraced(function* (name, expression) {
|
|
30
|
+
const [[operation, key]] = yield* Schema.decodeUnknownEffect(Expression)(Object.entries(expression));
|
|
31
|
+
const countRows = operation === "count" && key === "*";
|
|
32
|
+
const field = countRows ? Schema.Number : yield* fieldAt(key);
|
|
33
|
+
const operand = countRows ? sql `*` : sql `${sql(key)}`;
|
|
34
|
+
const aggregate = sql `${sql.literal(functions[operation])}(${operand})`;
|
|
35
|
+
const text = operation === "count" || operation === "sum" || operation === "avg";
|
|
36
|
+
const Result = resultSchema(operation, field);
|
|
37
|
+
return {
|
|
38
|
+
column: sql `${text ? sql `cast(${aggregate} as text)` : aggregate} as ${sql(name)}`,
|
|
39
|
+
order: aggregate,
|
|
40
|
+
schema: operation === "count" ? Result : Schema.NullOr(Result),
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=aggregateColumn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregateColumn.js","sourceRoot":"","sources":["../src/aggregateColumn.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { BigDecimal, Effect, Schema } from "effect";
|
|
2
|
+
import type { Model } from "effect/schema";
|
|
3
|
+
import type { SqlError } from "effect/sql/SqlError";
|
|
4
|
+
import type { FindManyFilter, OrderedValue } from "#repositoryFilter.ts";
|
|
5
|
+
type Row<T extends Model.Any> = Schema.Struct.Type<T["fields"]>;
|
|
6
|
+
type Key<T extends Model.Any> = Extract<keyof T["fields"] & keyof Row<T>, string>;
|
|
7
|
+
type FieldsOfType<T extends Model.Any, TValue> = {
|
|
8
|
+
[TKey in Key<T>]: [NonNullable<Row<T>[TKey]>] extends [TValue] ? TKey : never;
|
|
9
|
+
}[Key<T>];
|
|
10
|
+
interface Operands<T extends Model.Any> {
|
|
11
|
+
avg: FieldsOfType<T, number | BigDecimal.BigDecimal>;
|
|
12
|
+
boolAnd: FieldsOfType<T, boolean>;
|
|
13
|
+
boolOr: FieldsOfType<T, boolean>;
|
|
14
|
+
count: "*" | Key<T>;
|
|
15
|
+
max: FieldsOfType<T, OrderedValue>;
|
|
16
|
+
min: FieldsOfType<T, OrderedValue>;
|
|
17
|
+
sum: FieldsOfType<T, number | BigDecimal.BigDecimal>;
|
|
18
|
+
}
|
|
19
|
+
export type AggregateExpression<T extends Model.Any> = {
|
|
20
|
+
[TOperation in keyof Operands<T>]: {
|
|
21
|
+
readonly [TKey in TOperation]: Operands<T>[TKey];
|
|
22
|
+
} & {
|
|
23
|
+
readonly [TKey in Exclude<keyof Operands<T>, TOperation>]?: never;
|
|
24
|
+
};
|
|
25
|
+
}[keyof Operands<T>];
|
|
26
|
+
type AggregateValue<T extends Model.Any, TExpression> = TExpression extends {
|
|
27
|
+
readonly count: unknown;
|
|
28
|
+
} ? number : TExpression extends {
|
|
29
|
+
readonly boolOr: unknown;
|
|
30
|
+
} | {
|
|
31
|
+
readonly boolAnd: unknown;
|
|
32
|
+
} ? boolean | null : TExpression extends {
|
|
33
|
+
readonly [TKey in infer TOperation]: infer TField;
|
|
34
|
+
} ? TOperation extends "sum" | "avg" | "min" | "max" ? TField extends Key<T> ? Row<T>[TField] | null : never : never : never;
|
|
35
|
+
export interface AggregateQuery<T extends Model.Any, TGroup extends readonly Key<T>[], TAggregates> {
|
|
36
|
+
readonly aggregates: TAggregates & {
|
|
37
|
+
readonly [TKey in TGroup[number]]?: never;
|
|
38
|
+
};
|
|
39
|
+
readonly groupBy: TGroup;
|
|
40
|
+
readonly limit?: number;
|
|
41
|
+
readonly orderBy?: readonly {
|
|
42
|
+
readonly field: TGroup[number] | Extract<keyof TAggregates, string>;
|
|
43
|
+
readonly direction: "asc" | "desc";
|
|
44
|
+
}[];
|
|
45
|
+
readonly where?: FindManyFilter<T>;
|
|
46
|
+
}
|
|
47
|
+
export type Aggregate<T extends Model.Any> = <const TGroup extends readonly [Key<T>, ...Key<T>[]], const TAggregates extends Readonly<Record<string, AggregateExpression<T>>>>(query: AggregateQuery<T, TGroup, TAggregates>) => Effect.Effect<Array<{
|
|
48
|
+
readonly [TName in TGroup[number] | keyof TAggregates]: TName extends TGroup[number] ? Row<T>[TName] : AggregateValue<T, TAggregates[TName]>;
|
|
49
|
+
}>, SqlError | Schema.SchemaError, T["fields"][Key<T>]["EncodingServices"] | T["fields"][Key<T>]["DecodingServices"]>;
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=aggregateQuery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregateQuery.d.ts","sourceRoot":"","sources":["../src/aggregateQuery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregateQuery.js","sourceRoot":"","sources":["../src/aggregateQuery.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { Migrator } from "effect/sql";
|
|
3
|
+
import type { PostgresMigrationOptions } from "./migrations.ts";
|
|
4
|
+
import { type PendingPostgresMigrations } from "./pendingPostgresMigrations.ts";
|
|
5
|
+
export declare const assertPostgresMigrations: <R>(options: Pick<PostgresMigrationOptions<R>, "components" | "loader" | "release" | "table">) => Effect.Effect<undefined, Migrator.MigrationError | import("effect/sql/SqlError").SqlError, R | import("effect/sql/SqlClient").SqlClient>;
|
|
6
|
+
export declare function postgresMigrationError(pending: PendingPostgresMigrations): Migrator.MigrationError;
|
|
7
|
+
//# sourceMappingURL=assertPostgresMigrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertPostgresMigrations.d.ts","sourceRoot":"","sources":["../src/assertPostgresMigrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,KAAK,yBAAyB,EAA6B,MAAM,gCAAgC,CAAC;AAE3G,eAAO,MAAM,wBAAwB,GAA8D,CAAC,wOAOlG,CAAC;AAEH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,yBAAyB,2BASxE"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { Migrator } from "effect/sql";
|
|
3
|
+
import { pendingPostgresMigrations } from "./pendingPostgresMigrations.js";
|
|
4
|
+
export const assertPostgresMigrations = Effect.fn("EffectSql.assertPostgresMigrations")(function* (options) {
|
|
5
|
+
const pending = yield* pendingPostgresMigrations(options);
|
|
6
|
+
if (pending.migrations.length > 0 || pending.components.length > 0) {
|
|
7
|
+
return yield* Effect.fail(postgresMigrationError(pending));
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
export function postgresMigrationError(pending) {
|
|
11
|
+
const details = [
|
|
12
|
+
...pending.migrations.map(({ id, name }) => `migration ${id} (${name})`),
|
|
13
|
+
...pending.components.map(({ name, detail }) => `component ${name}: ${detail}`),
|
|
14
|
+
];
|
|
15
|
+
return new Migrator.MigrationError({
|
|
16
|
+
kind: "BadState",
|
|
17
|
+
message: `Database migrations are not current: ${details.join("; ")}. Run the deployment migration command.`,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=assertPostgresMigrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertPostgresMigrations.js","sourceRoot":"","sources":["../src/assertPostgresMigrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAkC,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAE3G,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC,EAAE,CAAC,oCAAoC,CAAC,CAAC,QAAQ,CAAC,EAChG,OAAyF;IAEzF,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC;IAC1D,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpE,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5D,CAAC;AACF,CAAC,CAAC,CAAC;AAEH,MAAM,UAAU,sBAAsB,CAAC,OAAkC;IACxE,MAAM,OAAO,GAAG;QACf,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,aAAa,EAAE,KAAK,IAAI,GAAG,CAAC;QACxE,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,aAAa,IAAI,KAAK,MAAM,EAAE,CAAC;KAC/E,CAAC;IACF,OAAO,IAAI,QAAQ,CAAC,cAAc,CAAC;QAClC,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,wCAAwC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,yCAAyC;KAC5G,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import type { Model } from "effect/schema";
|
|
3
|
+
import type { SqlClient } from "effect/sql";
|
|
4
|
+
import type { SqlError } from "effect/sql/SqlError";
|
|
5
|
+
import type { Fragment } from "effect/sql/Statement";
|
|
6
|
+
import type { RepositoryChanges } from "./repositoryChanges.ts";
|
|
7
|
+
export type InsertMany<TModel extends Model.Any, TServices = never> = (inputs: readonly TModel["insert"]["Type"][]) => Effect.Effect<TModel["Type"][], SqlError | Schema.SchemaError, TModel["insert"]["EncodingServices"] | TModel["DecodingServices"] | TServices>;
|
|
8
|
+
export interface BatchWrites<TModel extends Model.Any> {
|
|
9
|
+
readonly insertMany: InsertMany<TModel>;
|
|
10
|
+
}
|
|
11
|
+
export declare function makeInsertMany<TServices = never>(model: Model.Any, sql: SqlClient.SqlClient, options: {
|
|
12
|
+
readonly tableName: string;
|
|
13
|
+
readonly spanPrefix: string;
|
|
14
|
+
readonly changes: RepositoryChanges;
|
|
15
|
+
}, operation: string, prepare?: (row: Readonly<Record<string, unknown>>) => Effect.Effect<Fragment, Schema.SchemaError, TServices>): (inputs: readonly unknown[]) => Effect.Effect<unknown[], Schema.SchemaError | SqlError, unknown>;
|
|
16
|
+
//# sourceMappingURL=batchWrites.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batchWrites.d.ts","sourceRoot":"","sources":["../src/batchWrites.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,MAAM,MAAM,UAAU,CAAC,MAAM,SAAS,KAAK,CAAC,GAAG,EAAE,SAAS,GAAG,KAAK,IAAI,CACrE,MAAM,EAAE,SAAS,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,KACvC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,kBAAkB,CAAC,GAAG,MAAM,CAAC,kBAAkB,CAAC,GAAG,SAAS,CAAC,CAAC;AAEnJ,MAAM,WAAW,WAAW,CAAC,MAAM,SAAS,KAAK,CAAC,GAAG;IACpD,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;CACxC;AAED,wBAAgB,cAAc,CAAC,SAAS,GAAG,KAAK,EAC/C,KAAK,EAAE,KAAK,CAAC,GAAG,EAChB,GAAG,EAAE,SAAS,CAAC,SAAS,EACxB,OAAO,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,EACzG,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,SAAS,CAA+B,YAKzH,SAAS,OAAO,EAAE,sEA2ClC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
export function makeInsertMany(model, sql, options, operation, prepare = () => Effect.succeed(sql ``)) {
|
|
3
|
+
const encode = Schema.encodeEffect(model.insert);
|
|
4
|
+
const record = Schema.decodeUnknownEffect(Schema.Record(Schema.String, Schema.Unknown));
|
|
5
|
+
const decode = Schema.decodeUnknownEffect(Schema.Array(model));
|
|
6
|
+
return (inputs) => Effect.gen(function* () {
|
|
7
|
+
if (inputs.length === 0) {
|
|
8
|
+
return [];
|
|
9
|
+
}
|
|
10
|
+
const rows = yield* Effect.forEach(inputs, (input) => Effect.flatMap(encode(input), record));
|
|
11
|
+
const columns = [...new Set(rows.flatMap(Object.keys))];
|
|
12
|
+
if (columns.length === 0) {
|
|
13
|
+
columns.push(...Object.keys(model.fields).slice(0, 1));
|
|
14
|
+
}
|
|
15
|
+
const names = sql.csv(columns.map((column) => sql `${sql(column)}`));
|
|
16
|
+
const chunkSize = Math.max(1, Math.min(1000, Math.floor(10_000 / columns.length)));
|
|
17
|
+
const results = [];
|
|
18
|
+
const changedRows = [];
|
|
19
|
+
let chunk = [];
|
|
20
|
+
let parameters = 0;
|
|
21
|
+
let suffix = sql ``;
|
|
22
|
+
const flush = Effect.gen(function* () {
|
|
23
|
+
const returned = yield* sql `insert into ${sql(options.tableName)} (${names}) values ${sql.csv(chunk)} ${suffix} returning *`;
|
|
24
|
+
changedRows.push(...returned);
|
|
25
|
+
for (const row of yield* decode(returned)) {
|
|
26
|
+
results.push(row);
|
|
27
|
+
}
|
|
28
|
+
chunk = [];
|
|
29
|
+
parameters = 0;
|
|
30
|
+
});
|
|
31
|
+
for (const row of rows) {
|
|
32
|
+
const value = sql `(${sql.csv(columns.map((column) => (Object.hasOwn(row, column) ? sql `${row[column]}` : sql `default`)))})`;
|
|
33
|
+
const size = value.compile()[1].length;
|
|
34
|
+
const prepared = yield* prepare(row);
|
|
35
|
+
const suffixSize = sql `${prepared}`.compile()[1].length;
|
|
36
|
+
// Bound native fragment size as well as PostgreSQL's 65,535 bind parameters.
|
|
37
|
+
if (chunk.length > 0 && (chunk.length === chunkSize || parameters + size + suffixSize > 10_000)) {
|
|
38
|
+
yield* flush;
|
|
39
|
+
}
|
|
40
|
+
suffix = prepared;
|
|
41
|
+
chunk.push(value);
|
|
42
|
+
parameters += size;
|
|
43
|
+
}
|
|
44
|
+
yield* flush;
|
|
45
|
+
yield* options.changes.record(changedRows);
|
|
46
|
+
return results;
|
|
47
|
+
}).pipe(options.changes.write, Effect.withSpan(`${options.spanPrefix}.${operation}`));
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=batchWrites.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batchWrites.js","sourceRoot":"","sources":["../src/batchWrites.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface SqlNameTransforms {
|
|
2
|
+
readonly transformQueryNames?: ((name: string) => string) | undefined;
|
|
3
|
+
readonly transformResultNames?: ((name: string) => string) | undefined;
|
|
4
|
+
}
|
|
5
|
+
export declare function clientOptions<TOptions extends object>(options: TOptions, { snakeCase }?: {
|
|
6
|
+
readonly snakeCase?: boolean;
|
|
7
|
+
}): TOptions & SqlNameTransforms;
|
|
8
|
+
//# sourceMappingURL=clientOptions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientOptions.d.ts","sourceRoot":"","sources":["../src/clientOptions.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,CAAC;IACtE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,CAAC;CACvE;AAED,wBAAgB,aAAa,CAAC,QAAQ,SAAS,MAAM,EACpD,OAAO,EAAE,QAAQ,EACjB,EAAE,SAAgB,EAAE,GAAE;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACzD,QAAQ,GAAG,iBAAiB,CAK9B"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { camelToSnake, snakeToCamel } from "effect/String";
|
|
2
|
+
export function clientOptions(options, { snakeCase = true } = {}) {
|
|
3
|
+
return {
|
|
4
|
+
...(snakeCase ? { transformQueryNames: camelToSnake, transformResultNames: snakeToCamel } : {}),
|
|
5
|
+
...options,
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=clientOptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientOptions.js","sourceRoot":"","sources":["../src/clientOptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAO3D,MAAM,UAAU,aAAa,CAC5B,OAAiB,EACjB,EAAE,SAAS,GAAG,IAAI,EAAE,GAAqC,EAAE;IAE3D,OAAO;QACN,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,mBAAmB,EAAE,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/F,GAAG,OAAO;KACV,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Cause } from "effect";
|
|
2
|
+
import { Effect, Schema } from "effect";
|
|
3
|
+
import type { Model } from "effect/schema";
|
|
4
|
+
import { type SqlClient } from "effect/sql";
|
|
5
|
+
import type { SqlError } from "effect/sql/SqlError";
|
|
6
|
+
import { type RepositoryChanges } from "#repositoryChanges.ts";
|
|
7
|
+
import type { RepositoryListFilter } from "#repositoryFilter.ts";
|
|
8
|
+
import type { IdColumn, NativeRepository } from "#versionedRepository.ts";
|
|
9
|
+
export type CompositeKey<TModel extends Model.Any> = readonly [IdColumn<TModel>, IdColumn<TModel>, ...IdColumn<TModel>[]];
|
|
10
|
+
export type PrimaryKey<TModel extends Model.Any> = IdColumn<TModel> | CompositeKey<TModel>;
|
|
11
|
+
type DeleteWhere<TModel extends Model.Any> = (where: RepositoryListFilter<TModel>) => Effect.Effect<void, SqlError | Schema.SchemaError, TModel["fields"][keyof TModel["fields"]]["EncodingServices"]>;
|
|
12
|
+
interface Update<TModel extends Model.Any> {
|
|
13
|
+
(input: TModel["update"]["Type"], options: {
|
|
14
|
+
readonly onMissing: "fail";
|
|
15
|
+
}): Effect.Effect<TModel["Type"], SqlError | Schema.SchemaError | Cause.NoSuchElementError, TModel["update"]["EncodingServices"] | TModel["DecodingServices"]>;
|
|
16
|
+
(input: TModel["update"]["Type"]): Effect.Effect<TModel["Type"], SqlError | Schema.SchemaError, TModel["update"]["EncodingServices"] | TModel["DecodingServices"]>;
|
|
17
|
+
}
|
|
18
|
+
export type Repository<TModel extends Model.Any, TId extends PrimaryKey<TModel>> = [TId] extends [IdColumn<TModel>] ? Omit<NativeRepository<TModel, Extract<TId, IdColumn<TModel>>>, "delete" | "update"> & {
|
|
19
|
+
readonly delete: NativeRepository<TModel, Extract<TId, IdColumn<TModel>>>["delete"] & DeleteWhere<TModel>;
|
|
20
|
+
readonly update: Update<TModel>;
|
|
21
|
+
} : TId extends CompositeKey<TModel> ? Omit<NativeRepository<TModel, TId[number]>, "findById" | "delete" | "update"> & {
|
|
22
|
+
readonly update: Update<TModel>;
|
|
23
|
+
readonly findById: (id: Pick<TModel["Type"], TId[number]>) => Effect.Effect<TModel["Type"], SqlError | Schema.SchemaError | Cause.NoSuchElementError, TModel["DecodingServices"] | TModel["fields"][TId[number]]["EncodingServices"]>;
|
|
24
|
+
readonly delete: ((id: Pick<TModel["Type"], TId[number]>) => Effect.Effect<void, SqlError | Schema.SchemaError, TModel["fields"][TId[number]]["EncodingServices"]>) & DeleteWhere<TModel>;
|
|
25
|
+
} : never;
|
|
26
|
+
export declare function makeCompositeCrud(model: Model.Any, sql: SqlClient.SqlClient, options: {
|
|
27
|
+
readonly columns: readonly string[];
|
|
28
|
+
readonly tableName: string;
|
|
29
|
+
readonly spanPrefix: string;
|
|
30
|
+
}, supplied?: RepositoryChanges): {
|
|
31
|
+
delete: (id: unknown) => Effect.Effect<void, Schema.SchemaError | SqlError, unknown>;
|
|
32
|
+
insert: (input: unknown) => Effect.Effect<unknown, Schema.SchemaError | SqlError, unknown>;
|
|
33
|
+
insertVoid: (input: unknown) => Effect.Effect<void, Schema.SchemaError | SqlError, unknown>;
|
|
34
|
+
update: (input: unknown, settings?: {
|
|
35
|
+
readonly onMissing: "fail";
|
|
36
|
+
}) => Effect.Effect<unknown, Cause.NoSuchElementError | Schema.SchemaError | SqlError, unknown>;
|
|
37
|
+
updateVoid: (input: unknown) => Effect.Effect<void, Schema.SchemaError | SqlError, unknown>;
|
|
38
|
+
findById: (id: unknown) => Effect.Effect<unknown, Cause.NoSuchElementError | Schema.SchemaError | SqlError, unknown>;
|
|
39
|
+
};
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=compositeRepository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compositeRepository.d.ts","sourceRoot":"","sources":["../src/compositeRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { SqlSchema } from "effect/sql";
|
|
3
|
+
import { repositoryChanges } from "#repositoryChanges.ts";
|
|
4
|
+
import { repositoryWrites } from "#repositoryWrites.ts";
|
|
5
|
+
export function makeCompositeCrud(model, sql, options, supplied) {
|
|
6
|
+
const { columns, tableName, spanPrefix } = options;
|
|
7
|
+
const fields = Object.fromEntries(columns.map((column) => {
|
|
8
|
+
const field = model.fields[column];
|
|
9
|
+
if (field === undefined) {
|
|
10
|
+
throw new Error(`Unknown ID column: ${column}`);
|
|
11
|
+
}
|
|
12
|
+
return [column, field];
|
|
13
|
+
}));
|
|
14
|
+
const Key = columns.length === 1 ? model.fields[columns[0] ?? ""] : Schema.Struct(fields);
|
|
15
|
+
if (Key === undefined) {
|
|
16
|
+
throw new Error("Unknown repository ID column");
|
|
17
|
+
}
|
|
18
|
+
const record = Schema.decodeUnknownEffect(Schema.Record(Schema.String, Schema.Unknown));
|
|
19
|
+
function predicate(input) {
|
|
20
|
+
return sql.and(columns.map((column) => sql `${sql(column)} = ${input[column]}`));
|
|
21
|
+
}
|
|
22
|
+
const find = SqlSchema.findOne({
|
|
23
|
+
execute: (input) => Effect.flatMap(record(columns.length === 1 ? { [columns[0] ?? ""]: input } : input), (key) => sql `select * from ${sql(tableName)} where ${predicate(key)}`),
|
|
24
|
+
Request: Key,
|
|
25
|
+
Result: model,
|
|
26
|
+
});
|
|
27
|
+
const changes = supplied ?? {
|
|
28
|
+
record: (rows) => Effect.flatMap(repositoryChanges(sql, tableName, columns), (boundary) => boundary.record(rows)),
|
|
29
|
+
write(effect) {
|
|
30
|
+
return Effect.flatMap(repositoryChanges(sql, tableName, columns), (boundary) => boundary.write(effect));
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
return {
|
|
34
|
+
...repositoryWrites(model, sql, { ...options, idColumns: columns }, changes),
|
|
35
|
+
findById: (id) => find(id).pipe(Effect.withSpan(`${spanPrefix}.findById`)),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=compositeRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compositeRepository.js","sourceRoot":"","sources":["../src/compositeRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import type { Model } from "effect/schema";
|
|
3
|
+
import type { SqlClient } from "effect/sql";
|
|
4
|
+
import type { SqlError } from "effect/sql/SqlError";
|
|
5
|
+
import type { Comparisons, FindManyFilter } from "#repositoryFilter.ts";
|
|
6
|
+
import type { RepositoryChanges } from "./repositoryChanges.ts";
|
|
7
|
+
type Fields<TModel extends Model.Any> = Schema.Struct.Type<TModel["fields"]>;
|
|
8
|
+
interface Incoming<TModel extends Model.Any, TValue> {
|
|
9
|
+
readonly excluded: {
|
|
10
|
+
[TKey in keyof Fields<TModel>]: [Fields<TModel>[TKey]] extends [TValue] ? TKey : never;
|
|
11
|
+
}[keyof Fields<TModel>];
|
|
12
|
+
}
|
|
13
|
+
export type UpsertFilter<TModel extends Model.Any> = {
|
|
14
|
+
readonly [TKey in keyof Fields<TModel>]?: FindManyFilter<TModel>[TKey] | Incoming<TModel, Fields<TModel>[TKey]> | Comparisons<Fields<TModel>[TKey], NonNullable<Fields<TModel>[TKey]> | Incoming<TModel, NonNullable<Fields<TModel>[TKey]>>>;
|
|
15
|
+
};
|
|
16
|
+
export type UpsertResult<TRow> = {
|
|
17
|
+
readonly _tag: "Inserted";
|
|
18
|
+
readonly row: TRow;
|
|
19
|
+
} | {
|
|
20
|
+
readonly _tag: "Updated";
|
|
21
|
+
readonly row: TRow;
|
|
22
|
+
} | {
|
|
23
|
+
readonly _tag: "Unchanged";
|
|
24
|
+
};
|
|
25
|
+
export interface ConditionalUpsert<TModel extends Model.Any, TOptions, TServices> {
|
|
26
|
+
(input: TModel["insert"]["Type"], options: TOptions & {
|
|
27
|
+
readonly updateWhere: UpsertFilter<TModel>;
|
|
28
|
+
}): Effect.Effect<UpsertResult<TModel["Type"]>, SqlError | Schema.SchemaError, TServices | TModel["fields"][keyof TModel["fields"]]["EncodingServices"]>;
|
|
29
|
+
(input: TModel["insert"]["Type"], options: TOptions & {
|
|
30
|
+
readonly updateWhere?: never;
|
|
31
|
+
}): Effect.Effect<TModel["Type"], SqlError | Schema.SchemaError, TServices>;
|
|
32
|
+
}
|
|
33
|
+
export interface ConditionalUpsertMany<TModel extends Model.Any, TOptions, TServices> {
|
|
34
|
+
(inputs: readonly TModel["insert"]["Type"][], options: TOptions & {
|
|
35
|
+
readonly updateWhere: UpsertFilter<TModel>;
|
|
36
|
+
}): Effect.Effect<UpsertResult<TModel["Type"]>[], SqlError | Schema.SchemaError, TServices | TModel["fields"][keyof TModel["fields"]]["EncodingServices"]>;
|
|
37
|
+
(inputs: readonly TModel["insert"]["Type"][], options: TOptions & {
|
|
38
|
+
readonly updateWhere?: never;
|
|
39
|
+
}): Effect.Effect<TModel["Type"][], SqlError | Schema.SchemaError, TServices>;
|
|
40
|
+
}
|
|
41
|
+
export declare function makeConditionalUpsert(model: Model.Any, sql: SqlClient.SqlClient, options: {
|
|
42
|
+
readonly tableName: string;
|
|
43
|
+
readonly spanPrefix: string;
|
|
44
|
+
readonly changes: RepositoryChanges;
|
|
45
|
+
readonly conflictColumns: readonly string[];
|
|
46
|
+
readonly conflictWhere?: Readonly<Record<string, unknown>>;
|
|
47
|
+
readonly idColumns: readonly string[];
|
|
48
|
+
}): (inputs: readonly unknown[], settings: {
|
|
49
|
+
readonly updateColumns: readonly string[];
|
|
50
|
+
readonly updateWhere: Readonly<Record<string, unknown>>;
|
|
51
|
+
}) => Effect.Effect<({
|
|
52
|
+
readonly _tag: "Unchanged";
|
|
53
|
+
readonly row?: never;
|
|
54
|
+
} | {
|
|
55
|
+
readonly _tag: "Inserted" | "Updated";
|
|
56
|
+
readonly row: unknown;
|
|
57
|
+
})[], Schema.SchemaError | SqlError, unknown>;
|
|
58
|
+
export {};
|
|
59
|
+
//# sourceMappingURL=conditionalUpsert.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conditionalUpsert.d.ts","sourceRoot":"","sources":["../src/conditionalUpsert.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { makeConflictClause } from "#makeConflictClause.ts";
|
|
3
|
+
export function makeConditionalUpsert(model, sql, options) {
|
|
4
|
+
const encode = Schema.encodeEffect(model.insert);
|
|
5
|
+
const record = Schema.decodeUnknownEffect(Schema.Record(Schema.String, Schema.Unknown));
|
|
6
|
+
const decode = Schema.decodeUnknownEffect(model);
|
|
7
|
+
const clause = makeConflictClause(model, sql, options);
|
|
8
|
+
return (inputs, settings) => Effect.gen(function* () {
|
|
9
|
+
const statements = yield* Effect.forEach(inputs, (input) => Effect.gen(function* () {
|
|
10
|
+
const row = yield* record(yield* encode(input));
|
|
11
|
+
const suffix = yield* clause(row, settings.updateColumns, settings.updateWhere);
|
|
12
|
+
return sql `insert into ${sql(options.tableName)} ${sql.insert(row)} ${suffix} returning *, (xmax = 0) as ${sql("effectSqlInserted")}`;
|
|
13
|
+
}));
|
|
14
|
+
const changedRows = [];
|
|
15
|
+
const results = yield* Effect.forEach(statements, (statement) => Effect.gen(function* () {
|
|
16
|
+
const rows = yield* statement;
|
|
17
|
+
changedRows.push(...rows);
|
|
18
|
+
const row = rows[0];
|
|
19
|
+
if (row === undefined) {
|
|
20
|
+
return { _tag: "Unchanged" };
|
|
21
|
+
}
|
|
22
|
+
return { _tag: row.effectSqlInserted ? "Inserted" : "Updated", row: yield* decode(row) };
|
|
23
|
+
}));
|
|
24
|
+
yield* options.changes.record(changedRows);
|
|
25
|
+
return results;
|
|
26
|
+
}).pipe(options.changes.write, Effect.withSpan(`${options.spanPrefix}.conditionalUpsert`));
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=conditionalUpsert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conditionalUpsert.js","sourceRoot":"","sources":["../src/conditionalUpsert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAiD5D,MAAM,UAAU,qBAAqB,CACpC,KAAgB,EAChB,GAAwB,EACxB,OAOC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACxF,MAAM,MAAM,GAAG,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IACvD,OAAO,CACN,MAA0B,EAC1B,QAAgH,EAC/G,EAAE,CACH,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAC1D,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACnB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;YAChF,OAAO,GAAG,CAAA,eAAe,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,+BAA+B,GAAG,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACvI,CAAC,CAAC,CACF,CAAC;QACF,MAAM,WAAW,GAAwC,EAAE,CAAC;QAC5D,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,SAAS,EAAE,EAAE,CAC/D,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACnB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC;YAC9B,WAAW,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;YAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACvB,OAAO,EAAE,IAAI,EAAE,WAAW,EAAW,CAAC;YACvC,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAW,CAAC;QACnG,CAAC,CAAC,CACF,CAAC;QACF,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC3C,OAAO,OAAO,CAAC;IAChB,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,UAAU,oBAAoB,CAAC,CAAC,CAAC;AAC7F,CAAC"}
|