@shivaedev/sql 0.29.0 → 0.31.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +101 -1
  3. package/dist/applyLowMemoryPostgres.d.ts +7 -0
  4. package/dist/applyLowMemoryPostgres.d.ts.map +1 -0
  5. package/dist/applyLowMemoryPostgres.js +24 -0
  6. package/dist/applyLowMemoryPostgres.js.map +1 -0
  7. package/dist/batchedDelete.d.ts +33 -0
  8. package/dist/batchedDelete.d.ts.map +1 -0
  9. package/dist/batchedDelete.js +64 -0
  10. package/dist/batchedDelete.js.map +1 -0
  11. package/dist/compositeRepository.d.ts +14 -13
  12. package/dist/compositeRepository.d.ts.map +1 -1
  13. package/dist/compositeRepository.js.map +1 -1
  14. package/dist/jsonb.d.ts +3 -0
  15. package/dist/jsonb.d.ts.map +1 -0
  16. package/dist/jsonb.js +9 -0
  17. package/dist/jsonb.js.map +1 -0
  18. package/dist/repository.d.ts.map +1 -1
  19. package/dist/repository.js +19 -17
  20. package/dist/repository.js.map +1 -1
  21. package/dist/repositoryChanges.d.ts +1 -0
  22. package/dist/repositoryChanges.d.ts.map +1 -1
  23. package/dist/repositoryChanges.js +9 -1
  24. package/dist/repositoryChanges.js.map +1 -1
  25. package/dist/repositoryUpdate.d.ts +31 -0
  26. package/dist/repositoryUpdate.d.ts.map +1 -0
  27. package/dist/repositoryUpdate.js +16 -0
  28. package/dist/repositoryUpdate.js.map +1 -0
  29. package/dist/repositoryWrites.d.ts +5 -2
  30. package/dist/repositoryWrites.d.ts.map +1 -1
  31. package/dist/repositoryWrites.js +19 -4
  32. package/dist/repositoryWrites.js.map +1 -1
  33. package/dist/tryPurgeLock.d.ts +4 -0
  34. package/dist/tryPurgeLock.d.ts.map +1 -0
  35. package/dist/tryPurgeLock.js +15 -0
  36. package/dist/tryPurgeLock.js.map +1 -0
  37. package/dist/versionedRepository.d.ts +3 -2
  38. package/dist/versionedRepository.d.ts.map +1 -1
  39. package/dist/versionedRepository.js.map +1 -1
  40. package/package.json +4 -4
  41. package/src/applyLowMemoryPostgres.ts +28 -0
  42. package/src/batchedDelete.ts +93 -0
  43. package/src/compositeRepository.ts +25 -34
  44. package/src/jsonb.ts +12 -0
  45. package/src/repository.ts +19 -17
  46. package/src/repositoryChanges.ts +9 -1
  47. package/src/repositoryUpdate.ts +65 -0
  48. package/src/repositoryWrites.ts +19 -4
  49. package/src/tryPurgeLock.ts +18 -0
  50. package/src/versionedRepository.ts +3 -2
@@ -0,0 +1,31 @@
1
+ import type { Brand, Cause } from "effect";
2
+ import { Effect, Schema } from "effect";
3
+ import type { Model } from "effect/schema";
4
+ import type { SqlError } from "effect/sql/SqlError";
5
+ type WithoutOverride<A> = A extends infer TValue & Brand.Brand<"Override"> ? TValue : A;
6
+ export type UpdateInput<TModel extends Model.Any> = {
7
+ readonly [TKey in keyof TModel["update"]["Type"]]: WithoutOverride<TModel["update"]["Type"][TKey]>;
8
+ };
9
+ type Column<TModel extends Model.Any, TId extends PropertyKey> = Exclude<Extract<keyof UpdateInput<TModel>, string>, TId>;
10
+ type Selected<TModel extends Model.Any, TId extends PropertyKey, TColumn extends PropertyKey> = Required<Pick<UpdateInput<TModel>, Extract<TId | TColumn, keyof UpdateInput<TModel>>>>;
11
+ interface Columns<TColumn> {
12
+ readonly columns: readonly [TColumn, ...TColumn[]];
13
+ }
14
+ type WriteResult<TModel extends Model.Any, A, E = never> = Effect.Effect<A, SqlError | Schema.SchemaError | E, TModel["update"]["EncodingServices"] | TModel["DecodingServices"]>;
15
+ export interface Update<TModel extends Model.Any, TId extends PropertyKey> {
16
+ <TColumn extends Column<TModel, TId>>(input: Selected<TModel, TId, TColumn>, options: Columns<TColumn> & {
17
+ readonly onMissing: "fail";
18
+ }): WriteResult<TModel, TModel["Type"], Cause.NoSuchElementError>;
19
+ <TColumn extends Column<TModel, TId>>(input: Selected<TModel, TId, TColumn>, options: Columns<TColumn>): WriteResult<TModel, TModel["Type"]>;
20
+ (input: UpdateInput<TModel>, options: {
21
+ readonly onMissing: "fail";
22
+ }): WriteResult<TModel, TModel["Type"], Cause.NoSuchElementError>;
23
+ (input: UpdateInput<TModel>): WriteResult<TModel, TModel["Type"]>;
24
+ }
25
+ export interface UpdateVoid<TModel extends Model.Any, TId extends PropertyKey> {
26
+ <TColumn extends Column<TModel, TId>>(input: Selected<TModel, TId, TColumn>, options: Columns<TColumn>): Effect.Effect<void, SqlError | Schema.SchemaError, TModel["update"]["EncodingServices"]>;
27
+ (input: UpdateInput<TModel>): Effect.Effect<void, SqlError | Schema.SchemaError, TModel["update"]["EncodingServices"]>;
28
+ }
29
+ export declare const selectedUpdate: (model: Model.Any, columns: readonly string[], idColumns: readonly string[], input: Readonly<Record<string, unknown>>) => Effect.Effect<Schema.Constraint, Schema.SchemaError, never>;
30
+ export {};
31
+ //# sourceMappingURL=repositoryUpdate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repositoryUpdate.d.ts","sourceRoot":"","sources":["../src/repositoryUpdate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { Effect, Schema, SchemaAST, SchemaIssue } from "effect";
2
+ export const selectedUpdate = Effect.fnUntraced(function* (model, columns, idColumns, input) {
3
+ const ast = model.update.ast;
4
+ const fields = SchemaAST.isObjects(ast) ? ast.propertySignatures : [];
5
+ const writable = new Set(fields.map((field) => String(field.name)));
6
+ const invalid = columns.find((column) => idColumns.includes(column) || !writable.has(column));
7
+ if (columns.length === 0 || invalid !== undefined) {
8
+ return yield* Effect.fail(new Schema.SchemaError(new SchemaIssue.Pointer([invalid ?? ""], new SchemaIssue.UnexpectedKey(ast, invalid ?? ""))));
9
+ }
10
+ const missing = [...idColumns, ...columns].find((column) => !Object.hasOwn(input, column));
11
+ if (missing !== undefined) {
12
+ return yield* Effect.fail(new Schema.SchemaError(new SchemaIssue.Pointer([missing], new SchemaIssue.MissingKey(undefined))));
13
+ }
14
+ return Schema.make(new SchemaAST.Objects(fields.filter((field) => [...idColumns, ...columns].includes(String(field.name))), []));
15
+ });
16
+ //# sourceMappingURL=repositoryUpdate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repositoryUpdate.js","sourceRoot":"","sources":["../src/repositoryUpdate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAwChE,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EACxD,KAAgB,EAChB,OAA0B,EAC1B,SAA4B,EAC5B,KAAwC;IAExC,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC;IAC7B,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;IACtE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9F,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACnD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,IAAI,WAAW,CAAC,aAAa,CAAC,GAAG,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChJ,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,GAAG,SAAS,EAAE,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3F,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,WAAW,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9H,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CACjB,IAAI,SAAS,CAAC,OAAO,CACpB,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,GAAG,SAAS,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EACjF,EAAE,CACF,CACD,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -11,8 +11,11 @@ export declare function repositoryWrites(model: Model.Any, sql: SqlClient.SqlCli
11
11
  insert: (input: unknown) => Effect.Effect<unknown, Schema.SchemaError | import("effect/sql/SqlError").SqlError, unknown>;
12
12
  insertVoid: (input: unknown) => Effect.Effect<void, Schema.SchemaError | import("effect/sql/SqlError").SqlError, unknown>;
13
13
  update: (input: unknown, settings?: {
14
- readonly onMissing: "fail";
14
+ readonly onMissing?: "fail";
15
+ readonly columns?: readonly string[];
16
+ }) => Effect.Effect<unknown, import("effect/Cause").NoSuchElementError | Schema.SchemaError | import("effect/sql/SqlError").SqlError, unknown>;
17
+ updateVoid: (input: unknown, settings?: {
18
+ readonly columns: readonly string[];
15
19
  }) => Effect.Effect<unknown, import("effect/Cause").NoSuchElementError | Schema.SchemaError | import("effect/sql/SqlError").SqlError, unknown>;
16
- updateVoid: (input: unknown) => Effect.Effect<void, Schema.SchemaError | import("effect/sql/SqlError").SqlError, unknown>;
17
20
  };
18
21
  //# sourceMappingURL=repositoryWrites.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"repositoryWrites.d.ts","sourceRoot":"","sources":["../src/repositoryWrites.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,YAAY,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,KAAK,CAAC,GAAG,EAChB,GAAG,EAAE,SAAS,CAAC,SAAS,EACxB,OAAO,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EAC3G,OAAO,EAAE,iBAAiB;IAmDzB,MAAM,OAAO,OAAO;IACpB,MAAM,UAAU,OAAO;IAEvB,UAAU,UAAU,OAAO;IAC3B,MAAM,UAAU,OAAO,aAAa;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAIlE,UAAU,UAAU,OAAO;EAE5B"}
1
+ {"version":3,"file":"repositoryWrites.d.ts","sourceRoot":"","sources":["../src/repositoryWrites.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,YAAY,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAIhE,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,KAAK,CAAC,GAAG,EAChB,GAAG,EAAE,SAAS,CAAC,SAAS,EACxB,OAAO,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EAC3G,OAAO,EAAE,iBAAiB;IA4DzB,MAAM,OAAO,OAAO;IACpB,MAAM,UAAU,OAAO;IAEvB,UAAU,UAAU,OAAO;IAC3B,MAAM,UAAU,OAAO,aAAa;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE;IAMzG,UAAU,UAAU,OAAO,aAAa;QAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE;EAKhF"}
@@ -1,6 +1,7 @@
1
1
  import { Effect, Schema } from "effect";
2
2
  import { SqlSchema } from "effect/sql";
3
3
  import { makeFilter } from "./repositoryFilter.js";
4
+ import { selectedUpdate } from "./repositoryUpdate.js";
4
5
  export function repositoryWrites(model, sql, options, changes) {
5
6
  const { idColumns, tableName, spanPrefix } = options;
6
7
  const { where } = makeFilter(model, sql);
@@ -21,6 +22,15 @@ export function repositoryWrites(model, sql, options, changes) {
21
22
  const insertVoid = SqlSchema.void({ execute: insert, Request: model.insert });
22
23
  const updateRow = SqlSchema.findOne({ execute: update, Request: model.update, Result: model });
23
24
  const updateVoid = SqlSchema.void({ execute: update, Request: model.update });
25
+ function selected(input, columns, returning) {
26
+ return Effect.gen(function* () {
27
+ const row = yield* record(input);
28
+ const Request = yield* selectedUpdate(model, columns, idColumns, row);
29
+ return yield* returning
30
+ ? SqlSchema.findOne({ execute: update, Request, Result: model })(row)
31
+ : SqlSchema.void({ execute: update, Request })(row);
32
+ });
33
+ }
24
34
  const idColumn = idColumns[0] ?? "";
25
35
  const key = model.fields[idColumn];
26
36
  if (key === undefined) {
@@ -40,10 +50,15 @@ export function repositoryWrites(model, sql, options, changes) {
40
50
  delete: (id) => changes.write(remove(id)).pipe(Effect.withSpan(`${spanPrefix}.delete`)),
41
51
  insert: (input) => changes.write(insertRow(input).pipe(Effect.catchTag("NoSuchElementError", Effect.die))).pipe(Effect.withSpan(`${spanPrefix}.insert`)),
42
52
  insertVoid: (input) => changes.write(insertVoid(input)).pipe(Effect.withSpan(`${spanPrefix}.insertVoid`)),
43
- update: (input, settings) => changes
44
- .write(settings?.onMissing === "fail" ? updateRow(input) : updateRow(input).pipe(Effect.catchTag("NoSuchElementError", Effect.die)))
45
- .pipe(Effect.withSpan(`${spanPrefix}.update`)),
46
- updateVoid: (input) => changes.write(updateVoid(input)).pipe(Effect.withSpan(`${spanPrefix}.updateVoid`)),
53
+ update: (input, settings) => {
54
+ const result = settings?.columns === undefined ? updateRow(input) : selected(input, settings.columns, true);
55
+ return changes
56
+ .write(settings?.onMissing === "fail" ? result : result.pipe(Effect.catchTag("NoSuchElementError", Effect.die)))
57
+ .pipe(Effect.withSpan(`${spanPrefix}.update`));
58
+ },
59
+ updateVoid: (input, settings) => changes
60
+ .write(settings === undefined ? updateVoid(input) : selected(input, settings.columns, false))
61
+ .pipe(Effect.withSpan(`${spanPrefix}.updateVoid`)),
47
62
  };
48
63
  }
49
64
  //# sourceMappingURL=repositoryWrites.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"repositoryWrites.js","sourceRoot":"","sources":["../src/repositoryWrites.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EAAkB,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,MAAM,UAAU,gBAAgB,CAC/B,KAAgB,EAChB,GAAwB,EACxB,OAA2G,EAC3G,OAA0B;IAE1B,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IACrD,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACxF,MAAM,YAAY,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACnG,SAAS,SAAS,CAAC,KAAwC;QAC1D,OAAO,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAA,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACnF,CAAC;IACD,SAAS,MAAM,CAAC,KAAc;QAC7B,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAC5C,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC;YAC7B,CAAC,CAAC,GAAG,CAAA,eAAe,GAAG,CAAC,SAAS,CAAC,6BAA6B,OAAO,CAAC,SAAS,EAAE,EAAE;YACpF,CAAC,CAAC,GAAG,CAAA,eAAe,GAAG,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,OAAO,CAAC,SAAS,EAAE,EAAE,CACxF,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAClC,CAAC;IACH,CAAC;IACD,SAAS,MAAM,CAAC,KAAc;QAC7B,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAC5C,GAAG,CAAA,UAAU,GAAG,CAAC,SAAS,CAAC,QAAQ,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,UAAU,SAAS,CAAC,GAAG,CAAC,cAAc,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAC5H,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAC1B,CACD,CAAC;IACH,CAAC;IACD,MAAM,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/F,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9E,MAAM,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/F,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9E,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACjD,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC;QAClC,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,CACf,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CACtD,GAAG,CAAA,eAAe,GAAG,CAAC,SAAS,CAAC,UAAU,SAAS,CAAC,OAAO,CAAC,cAAc,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAChI;QACF,OAAO,EAAE,GAAG;KACZ,CAAC,CAAC;IACH,SAAS,MAAM,CAAC,KAAc;QAC7B,OAAO,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC;YAC5C,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC;YACpB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAC/C,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAC9C,GAAG,CAAA,eAAe,GAAG,CAAC,SAAS,CAAC,UAAU,MAAM,cAAc,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CACnI,CACD,CAAC;IACL,CAAC;IACD,OAAO;QACN,MAAM,EAAE,CAAC,EAAW,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,UAAU,SAAS,CAAC,CAAC;QAChG,MAAM,EAAE,CAAC,KAAc,EAAE,EAAE,CAC1B,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,UAAU,SAAS,CAAC,CAAC;QACtI,UAAU,EAAE,CAAC,KAAc,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,UAAU,aAAa,CAAC,CAAC;QAClH,MAAM,EAAE,CAAC,KAAc,EAAE,QAAyC,EAAE,EAAE,CACrE,OAAO;aACL,KAAK,CAAC,QAAQ,EAAE,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;aACnI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,UAAU,SAAS,CAAC,CAAC;QAChD,UAAU,EAAE,CAAC,KAAc,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,UAAU,aAAa,CAAC,CAAC;KAClH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"repositoryWrites.js","sourceRoot":"","sources":["../src/repositoryWrites.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Effect } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+ export declare const tryPurgeLock: (tableName: string) => Effect.Effect<boolean, import("effect/sql/SqlError").SqlError, import("effect/Scope").Scope | SqlClient.SqlClient>;
4
+ //# sourceMappingURL=tryPurgeLock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tryPurgeLock.d.ts","sourceRoot":"","sources":["../src/tryPurgeLock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,eAAO,MAAM,YAAY,2IAavB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { Effect } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+ export const tryPurgeLock = Effect.fnUntraced(function* (tableName) {
4
+ const sql = yield* SqlClient.SqlClient;
5
+ const [identifier] = sql `${sql(tableName)}`.compile();
6
+ const key = sql `hashtextextended('@shivaedev/sql/deleteBatched:' || ${identifier}::regclass::oid::text, 0)`;
7
+ const connection = yield* sql.reserve;
8
+ function execute(statement) {
9
+ const [text, parameters] = statement.compile();
10
+ return connection.execute(text, parameters, undefined);
11
+ }
12
+ const [lock] = yield* Effect.acquireRelease(execute(sql `select pg_try_advisory_lock(${key}) as acquired`), (rows) => rows[0]?.acquired === true ? Effect.orDie(execute(sql `select pg_advisory_unlock(${key})`)) : Effect.void);
13
+ return lock?.acquired === true;
14
+ });
15
+ //# sourceMappingURL=tryPurgeLock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tryPurgeLock.js","sourceRoot":"","sources":["../src/tryPurgeLock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,SAAiB;IACzE,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC;IACvC,MAAM,CAAC,UAAU,CAAC,GAAG,GAAG,CAAA,GAAG,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC;IACtD,MAAM,GAAG,GAAG,GAAG,CAAA,uDAAuD,UAAU,2BAA2B,CAAC;IAC5G,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;IACtC,SAAS,OAAO,CAAC,SAAuD;QACvE,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;QAC/C,OAAO,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,CAAA,+BAA+B,GAAG,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CACnH,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAA,6BAA6B,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CACxG,CAAC;IACF,OAAO,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;AAChC,CAAC,CAAC,CAAC"}
@@ -4,6 +4,7 @@ import type { SqlClient, SqlModel } from "effect/sql";
4
4
  import type { SqlError } from "effect/sql/SqlError";
5
5
  import type { PrimaryKey, Repository } from "#compositeRepository.ts";
6
6
  import type { OptimisticConcurrencyError } from "#repository.ts";
7
+ import type { UpdateInput } from "#repositoryUpdate.ts";
7
8
  import { type VersionedOptions } from "#versionedStatements.ts";
8
9
  import type { RepositoryChanges } from "./repositoryChanges.ts";
9
10
  export type IdColumn<TModel extends Model.Any> = keyof TModel["Type"] & keyof TModel["update"]["Type"] & keyof TModel["fields"];
@@ -19,8 +20,8 @@ export interface VersionedWrites<TModel extends Model.Any, TId extends PrimaryKe
19
20
  readonly delete: (id: TId extends readonly IdColumn<TModel>[] ? Pick<TModel["Type"], TId[number]> : TModel["fields"][Extract<TId, IdColumn<TModel>>]["Type"], expectedVersion: number) => Effect.Effect<void, WriteError, TModel["fields"][KeyColumn<TModel, TId>]["EncodingServices"]>;
20
21
  readonly insert: Repository<TModel, TId>["insert"];
21
22
  readonly insertVoid: Repository<TModel, TId>["insertVoid"];
22
- readonly update: (input: TModel["update"]["Type"]) => Effect.Effect<TModel["Type"], WriteError, TModel["update"]["EncodingServices"] | TModel["DecodingServices"]>;
23
- readonly updateVoid: (input: TModel["update"]["Type"]) => Effect.Effect<void, WriteError, TModel["update"]["EncodingServices"]>;
23
+ readonly update: (input: UpdateInput<TModel>) => Effect.Effect<TModel["Type"], WriteError, TModel["update"]["EncodingServices"] | TModel["DecodingServices"]>;
24
+ readonly updateVoid: (input: UpdateInput<TModel>) => Effect.Effect<void, WriteError, TModel["update"]["EncodingServices"]>;
24
25
  }
25
26
  export declare function makeVersionedWrites(model: Model.Any, sql: SqlClient.SqlClient, options: VersionedOptions & {
26
27
  readonly changes: RepositoryChanges;
@@ -1 +1 @@
1
- {"version":3,"file":"versionedRepository.d.ts","sourceRoot":"","sources":["../src/versionedRepository.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"versionedRepository.d.ts","sourceRoot":"","sources":["../src/versionedRepository.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"versionedRepository.js","sourceRoot":"","sources":["../src/versionedRepository.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"versionedRepository.js","sourceRoot":"","sources":["../src/versionedRepository.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shivaedev/sql",
3
- "version": "0.29.0",
3
+ "version": "0.31.0",
4
4
  "description": "Schema-derived repositories over native Effect SQL",
5
5
  "keywords": [
6
6
  "effect"
@@ -50,9 +50,9 @@
50
50
  "@effect/platform-node": "4.0.6",
51
51
  "@effect/sql-pg": "4.0.6",
52
52
  "@effect/sql-sqlite-node": "4.0.6",
53
- "@shivaedev/quality": "0.52.0",
54
- "@shivaedev/test-sql": "0.15.2",
55
- "@shivaedev/test-story": "0.31.2",
53
+ "@shivaedev/quality": "0.54.0",
54
+ "@shivaedev/test-sql": "0.16.0",
55
+ "@shivaedev/test-story": "0.32.0",
56
56
  "@types/node": "24.19.2",
57
57
  "effect": "4.0.6",
58
58
  "typescript": "7.0.2",
@@ -0,0 +1,28 @@
1
+ import { Effect } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+
4
+ export interface LowMemoryPostgresOptions {
5
+ readonly pointInTimeRecovery: boolean;
6
+ }
7
+
8
+ export const applyLowMemoryPostgres = Effect.fn("Sql.applyLowMemoryPostgres")(function* ({ pointInTimeRecovery }: LowMemoryPostgresOptions) {
9
+ const sql = yield* SqlClient.SqlClient;
10
+ const settings = {
11
+ "autovacuum_max_workers": "2",
12
+ "autovacuum_work_mem": "32MB",
13
+ "hash_mem_multiplier": "1",
14
+ "idle_in_transaction_session_timeout": "10min",
15
+ "idle_session_timeout": "0",
16
+ jit: "off",
17
+ "max_connections": "50",
18
+ "max_parallel_workers_per_gather": "0",
19
+ "shared_buffers": "32MB",
20
+ "wal_buffers": "4MB",
21
+ "wal_compression": "zstd",
22
+ ...(pointInTimeRecovery ? { "archive_timeout": "300" } : { "archive_mode": "off" }),
23
+ };
24
+ for (const [name, value] of Object.entries(settings)) {
25
+ yield* sql.unsafe(`ALTER SYSTEM SET ${name} = '${value}'`);
26
+ }
27
+ yield* sql`select pg_reload_conf()`;
28
+ });
@@ -0,0 +1,93 @@
1
+ import { Data, type Duration, Effect, Option, Schema } from "effect";
2
+ import type { Model } from "effect/schema";
3
+ import { SqlClient, SqlSchema } 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
+ import { type FindManyFilter, makeFilter } from "#repositoryFilter.ts";
8
+ import { tryPurgeLock } from "#tryPurgeLock.ts";
9
+
10
+ export interface BatchedDeleteOptions<TModel extends Model.Any> {
11
+ readonly batchSize: number;
12
+ readonly maxRows: number;
13
+ readonly pause: Duration.Input;
14
+ readonly where: FindManyFilter<TModel>;
15
+ }
16
+
17
+ export class BatchedDeleteUnavailable extends Data.TaggedError("BatchedDeleteUnavailable")<{
18
+ readonly reason: "transaction" | "dialect";
19
+ }> {}
20
+
21
+ export interface BatchedDelete<TModel extends Model.Any> {
22
+ readonly deleteBatched: (
23
+ options: BatchedDeleteOptions<TModel>,
24
+ ) => Effect.Effect<number, SqlError | Schema.SchemaError | BatchedDeleteUnavailable, TModel["fields"][keyof TModel["fields"]]["EncodingServices"]>;
25
+ }
26
+
27
+ const Positive = Schema.Number.check(Schema.isInt(), Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(Number.MAX_SAFE_INTEGER));
28
+ const Nonnegative = Schema.Number.check(Schema.isInt(), Schema.isGreaterThanOrEqualTo(0), Schema.isLessThanOrEqualTo(Number.MAX_SAFE_INTEGER));
29
+ const Limits = Schema.Struct({ batchSize: Positive, maxRows: Nonnegative });
30
+
31
+ export const makeBatchedDelete = Effect.fnUntraced(function* (
32
+ model: Model.Any,
33
+ { tableName, spanPrefix }: { readonly tableName: string; readonly spanPrefix: string },
34
+ changes: RepositoryChanges,
35
+ ) {
36
+ const sql = yield* SqlClient.SqlClient;
37
+ const { where } = makeFilter(model, sql);
38
+ const available = Effect.gen(function* () {
39
+ if (sql.driver !== "pg") {
40
+ return yield* new BatchedDeleteUnavailable({ reason: "dialect" });
41
+ }
42
+ if (Option.isSome(yield* Effect.serviceOption(sql.transactionService))) {
43
+ return yield* new BatchedDeleteUnavailable({ reason: "transaction" });
44
+ }
45
+ });
46
+ function deleteBatch(predicate: Fragment, limit: number) {
47
+ const count = SqlSchema.findOne({
48
+ execute: (batchLimit) => sql`with removed as (
49
+ delete from ${sql(tableName)} where (tableoid, ctid) in (
50
+ select tableoid, ctid from ${sql(tableName)} where ${predicate} limit ${batchLimit} for update skip locked
51
+ ) returning 1
52
+ ) select count(*)::text as count from removed`,
53
+ Request: Schema.Number,
54
+ Result: Schema.Struct({ count: Schema.NumberFromString }),
55
+ });
56
+ return changes.write(
57
+ Effect.gen(function* () {
58
+ const result = yield* count(limit).pipe(Effect.catchTag("NoSuchElementError", Effect.die));
59
+ yield* changes.recordTable(result.count);
60
+ return result.count;
61
+ }),
62
+ );
63
+ }
64
+
65
+ const runBatches = Effect.fnUntraced(function* (options: BatchedDeleteOptions<Model.Any>, predicate: Fragment) {
66
+ const { batchSize, maxRows } = options;
67
+ let removed = 0;
68
+ while (removed < maxRows) {
69
+ const limit = Math.min(batchSize, maxRows - removed);
70
+ const count = yield* deleteBatch(predicate, limit);
71
+ removed += count;
72
+ if (count < limit || removed === maxRows) {
73
+ break;
74
+ }
75
+ yield* Effect.sleep(options.pause);
76
+ }
77
+ return removed;
78
+ });
79
+
80
+ return (options: BatchedDeleteOptions<Model.Any>) =>
81
+ Effect.gen(function* () {
82
+ yield* available;
83
+ const { maxRows } = yield* Schema.decodeUnknownEffect(Limits)(options);
84
+ const predicate = yield* where(options.where, true, true);
85
+ if (maxRows === 0) {
86
+ return 0;
87
+ }
88
+ if (!(yield* tryPurgeLock(tableName).pipe(Effect.provideService(SqlClient.SqlClient, sql)))) {
89
+ return 0;
90
+ }
91
+ return yield* runBatches(options, predicate);
92
+ }).pipe(Effect.scoped, Effect.withSpan(`${spanPrefix}.deleteBatched`));
93
+ });
@@ -3,8 +3,10 @@ import { Effect, Schema } from "effect";
3
3
  import type { Model } from "effect/schema";
4
4
  import { type SqlClient, SqlSchema } from "effect/sql";
5
5
  import type { SqlError } from "effect/sql/SqlError";
6
+ import type { BatchedDelete } from "#batchedDelete.ts";
6
7
  import type { RepositoryChanges } from "#repositoryChanges.ts";
7
8
  import type { RepositoryListFilter } from "#repositoryFilter.ts";
9
+ import type { Update, UpdateVoid } from "#repositoryUpdate.ts";
8
10
  import { repositoryWrites } from "#repositoryWrites.ts";
9
11
  import type { IdColumn, NativeRepository } from "#versionedRepository.ts";
10
12
 
@@ -14,41 +16,30 @@ type DeleteWhere<TModel extends Model.Any> = (
14
16
  where: RepositoryListFilter<TModel>,
15
17
  ) => Effect.Effect<void, SqlError | Schema.SchemaError, TModel["fields"][keyof TModel["fields"]]["EncodingServices"]>;
16
18
 
17
- interface Update<TModel extends Model.Any> {
18
- (
19
- input: TModel["update"]["Type"],
20
- options: { readonly onMissing: "fail" },
21
- ): Effect.Effect<
22
- TModel["Type"],
23
- SqlError | Schema.SchemaError | Cause.NoSuchElementError,
24
- TModel["update"]["EncodingServices"] | TModel["DecodingServices"]
25
- >;
26
- (
27
- input: TModel["update"]["Type"],
28
- ): Effect.Effect<TModel["Type"], SqlError | Schema.SchemaError, TModel["update"]["EncodingServices"] | TModel["DecodingServices"]>;
29
- }
30
-
31
- export type Repository<TModel extends Model.Any, TId extends PrimaryKey<TModel>> = [TId] extends [IdColumn<TModel>]
32
- ? Omit<NativeRepository<TModel, Extract<TId, IdColumn<TModel>>>, "delete" | "update"> & {
33
- readonly delete: NativeRepository<TModel, Extract<TId, IdColumn<TModel>>>["delete"] & DeleteWhere<TModel>;
34
- readonly update: Update<TModel>;
35
- }
36
- : TId extends CompositeKey<TModel>
37
- ? Omit<NativeRepository<TModel, TId[number]>, "findById" | "delete" | "update"> & {
38
- readonly update: Update<TModel>;
39
- readonly findById: (
40
- id: Pick<TModel["Type"], TId[number]>,
41
- ) => Effect.Effect<
42
- TModel["Type"],
43
- SqlError | Schema.SchemaError | Cause.NoSuchElementError,
44
- TModel["DecodingServices"] | TModel["fields"][TId[number]]["EncodingServices"]
45
- >;
46
- readonly delete: ((
47
- id: Pick<TModel["Type"], TId[number]>,
48
- ) => Effect.Effect<void, SqlError | Schema.SchemaError, TModel["fields"][TId[number]]["EncodingServices"]>) &
49
- DeleteWhere<TModel>;
19
+ export type Repository<TModel extends Model.Any, TId extends PrimaryKey<TModel>> = BatchedDelete<TModel> &
20
+ ([TId] extends [IdColumn<TModel>]
21
+ ? Omit<NativeRepository<TModel, Extract<TId, IdColumn<TModel>>>, "delete" | "update" | "updateVoid"> & {
22
+ readonly delete: NativeRepository<TModel, Extract<TId, IdColumn<TModel>>>["delete"] & DeleteWhere<TModel>;
23
+ readonly update: Update<TModel, TId extends readonly PropertyKey[] ? TId[number] : Extract<TId, PropertyKey>>;
24
+ readonly updateVoid: UpdateVoid<TModel, TId extends readonly PropertyKey[] ? TId[number] : Extract<TId, PropertyKey>>;
50
25
  }
51
- : never;
26
+ : TId extends CompositeKey<TModel>
27
+ ? Omit<NativeRepository<TModel, TId[number]>, "findById" | "delete" | "update" | "updateVoid"> & {
28
+ readonly update: Update<TModel, TId extends readonly PropertyKey[] ? TId[number] : Extract<TId, PropertyKey>>;
29
+ readonly updateVoid: UpdateVoid<TModel, TId extends readonly PropertyKey[] ? TId[number] : Extract<TId, PropertyKey>>;
30
+ readonly findById: (
31
+ id: Pick<TModel["Type"], TId[number]>,
32
+ ) => Effect.Effect<
33
+ TModel["Type"],
34
+ SqlError | Schema.SchemaError | Cause.NoSuchElementError,
35
+ TModel["DecodingServices"] | TModel["fields"][TId[number]]["EncodingServices"]
36
+ >;
37
+ readonly delete: ((
38
+ id: Pick<TModel["Type"], TId[number]>,
39
+ ) => Effect.Effect<void, SqlError | Schema.SchemaError, TModel["fields"][TId[number]]["EncodingServices"]>) &
40
+ DeleteWhere<TModel>;
41
+ }
42
+ : never);
52
43
 
53
44
  export function makeCompositeCrud(
54
45
  model: Model.Any,
package/src/jsonb.ts ADDED
@@ -0,0 +1,12 @@
1
+ import * as PgTypes from "@effect/sql-pg/PgTypes";
2
+ import { Schema, SchemaGetter } from "effect";
3
+
4
+ export function jsonb<TSchema extends Schema.Top>(schema: TSchema) {
5
+ return Schema.Unknown.pipe(
6
+ Schema.decodeTo(Schema.Unknown, {
7
+ decode: SchemaGetter.transform((value) => (PgTypes.isParameter(value) ? value.value : value)),
8
+ encode: SchemaGetter.transform(PgTypes.jsonb),
9
+ }),
10
+ Schema.decodeTo(schema),
11
+ );
12
+ }
package/src/repository.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Data, Effect, type Schema } from "effect";
2
2
  import type { Model } from "effect/schema";
3
3
  import { SqlClient } from "effect/sql";
4
+ import { makeBatchedDelete } from "#batchedDelete.ts";
4
5
  import { type BatchWrites, makeInsertMany } from "#batchWrites.ts";
5
6
  import { makeCompositeCrud, type PrimaryKey, type Repository } from "#compositeRepository.ts";
6
7
  import { type ConflictColumns, type ConflictWrites, makeConflictWrites } from "#conflictWrites.ts";
@@ -120,28 +121,29 @@ export function makeRepository<TModel extends Model.Any, TId extends IdColumn<TM
120
121
  const composite = typeof options.idColumn === "object";
121
122
  const idColumns = (composite ? options.idColumn : [options.idColumn]).map(String);
122
123
  const changes = yield* repositoryChanges(sql, options.tableName, idColumns, model.fields);
123
- const crud = makeCompositeCrud(model, sql, { ...options, columns: idColumns }, changes);
124
+ const crud = {
125
+ ...makeCompositeCrud(model, sql, { ...options, columns: idColumns }, changes),
126
+ deleteBatched: yield* makeBatchedDelete(model, options, changes),
127
+ };
124
128
  const queries = makeQueries(model, sql, options);
125
- return options.versionColumn === undefined
126
- ? {
127
- ...crud,
128
- insertFromSelect: makeInsertFromSelect(model, sql, { ...options, changes }, "insertFromSelect"),
129
- insertMany: makeInsertMany(model, sql, { ...options, changes }, "insertMany"),
130
- ...(options.conflictColumns === undefined
131
- ? {}
132
- : makeConflictWrites(model, sql, { ...options, changes, conflictColumns: options.conflictColumns, idColumns })),
133
- ...queries,
134
- }
135
- : {
136
- ...crud,
137
- ...makeVersionedWrites(model, sql, {
129
+ return {
130
+ ...crud,
131
+ ...queries,
132
+ ...(options.versionColumn === undefined
133
+ ? {
134
+ insertFromSelect: makeInsertFromSelect(model, sql, { ...options, changes }, "insertFromSelect"),
135
+ insertMany: makeInsertMany(model, sql, { ...options, changes }, "insertMany"),
136
+ ...(options.conflictColumns === undefined
137
+ ? {}
138
+ : makeConflictWrites(model, sql, { ...options, changes, conflictColumns: options.conflictColumns, idColumns })),
139
+ }
140
+ : makeVersionedWrites(model, sql, {
138
141
  ...options,
139
142
  changes,
140
143
  conflict: (id, expectedVersion, reason) => new OptimisticConcurrencyError({ expectedVersion, id, reason, tableName: options.tableName }),
141
144
  idColumns,
142
145
  versionColumn: options.versionColumn,
143
- }),
144
- ...queries,
145
- };
146
+ })),
147
+ };
146
148
  })();
147
149
  }
@@ -66,5 +66,13 @@ export const repositoryChanges = Effect.fnUntraced(function* (
66
66
  function write<A, E, R>(effect: Effect.Effect<A, E, R>) {
67
67
  return provide(transact(effect, { onSqlError: (error) => error }));
68
68
  }
69
- return { record, returning, write };
69
+ const recordTable = Effect.fnUntraced(function* (rows: number) {
70
+ if (rows === 0) {
71
+ return;
72
+ }
73
+ const declarations = yield* ChangeDeclarations;
74
+ yield* declarations.declare(table, [table], rows);
75
+ yield* provide(invalidateOnCommit([table]));
76
+ });
77
+ return { record, recordTable, returning, write };
70
78
  });
@@ -0,0 +1,65 @@
1
+ import type { Brand, Cause } from "effect";
2
+ import { Effect, Schema, SchemaAST, SchemaIssue } from "effect";
3
+ import type { Model } from "effect/schema";
4
+ import type { SqlError } from "effect/sql/SqlError";
5
+
6
+ type WithoutOverride<A> = A extends infer TValue & Brand.Brand<"Override"> ? TValue : A;
7
+ export type UpdateInput<TModel extends Model.Any> = {
8
+ readonly [TKey in keyof TModel["update"]["Type"]]: WithoutOverride<TModel["update"]["Type"][TKey]>;
9
+ };
10
+
11
+ type Column<TModel extends Model.Any, TId extends PropertyKey> = Exclude<Extract<keyof UpdateInput<TModel>, string>, TId>;
12
+ type Selected<TModel extends Model.Any, TId extends PropertyKey, TColumn extends PropertyKey> = Required<
13
+ Pick<UpdateInput<TModel>, Extract<TId | TColumn, keyof UpdateInput<TModel>>>
14
+ >;
15
+ interface Columns<TColumn> {
16
+ readonly columns: readonly [TColumn, ...TColumn[]];
17
+ }
18
+ type WriteResult<TModel extends Model.Any, A, E = never> = Effect.Effect<
19
+ A,
20
+ SqlError | Schema.SchemaError | E,
21
+ TModel["update"]["EncodingServices"] | TModel["DecodingServices"]
22
+ >;
23
+
24
+ export interface Update<TModel extends Model.Any, TId extends PropertyKey> {
25
+ <TColumn extends Column<TModel, TId>>(
26
+ input: Selected<TModel, TId, TColumn>,
27
+ options: Columns<TColumn> & { readonly onMissing: "fail" },
28
+ ): WriteResult<TModel, TModel["Type"], Cause.NoSuchElementError>;
29
+ <TColumn extends Column<TModel, TId>>(input: Selected<TModel, TId, TColumn>, options: Columns<TColumn>): WriteResult<TModel, TModel["Type"]>;
30
+ (input: UpdateInput<TModel>, options: { readonly onMissing: "fail" }): WriteResult<TModel, TModel["Type"], Cause.NoSuchElementError>;
31
+ (input: UpdateInput<TModel>): WriteResult<TModel, TModel["Type"]>;
32
+ }
33
+
34
+ export interface UpdateVoid<TModel extends Model.Any, TId extends PropertyKey> {
35
+ <TColumn extends Column<TModel, TId>>(
36
+ input: Selected<TModel, TId, TColumn>,
37
+ options: Columns<TColumn>,
38
+ ): Effect.Effect<void, SqlError | Schema.SchemaError, TModel["update"]["EncodingServices"]>;
39
+ (input: UpdateInput<TModel>): Effect.Effect<void, SqlError | Schema.SchemaError, TModel["update"]["EncodingServices"]>;
40
+ }
41
+
42
+ export const selectedUpdate = Effect.fnUntraced(function* (
43
+ model: Model.Any,
44
+ columns: readonly string[],
45
+ idColumns: readonly string[],
46
+ input: Readonly<Record<string, unknown>>,
47
+ ) {
48
+ const ast = model.update.ast;
49
+ const fields = SchemaAST.isObjects(ast) ? ast.propertySignatures : [];
50
+ const writable = new Set(fields.map((field) => String(field.name)));
51
+ const invalid = columns.find((column) => idColumns.includes(column) || !writable.has(column));
52
+ if (columns.length === 0 || invalid !== undefined) {
53
+ return yield* Effect.fail(new Schema.SchemaError(new SchemaIssue.Pointer([invalid ?? ""], new SchemaIssue.UnexpectedKey(ast, invalid ?? ""))));
54
+ }
55
+ const missing = [...idColumns, ...columns].find((column) => !Object.hasOwn(input, column));
56
+ if (missing !== undefined) {
57
+ return yield* Effect.fail(new Schema.SchemaError(new SchemaIssue.Pointer([missing], new SchemaIssue.MissingKey(undefined))));
58
+ }
59
+ return Schema.make(
60
+ new SchemaAST.Objects(
61
+ fields.filter((field) => [...idColumns, ...columns].includes(String(field.name))),
62
+ [],
63
+ ),
64
+ );
65
+ });