@casekit/orm 0.0.1-alpha.12 → 0.0.1-alpha.13

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 (227) hide show
  1. package/package.json +13 -3
  2. package/.env +0 -2
  3. package/.eslintrc.cjs +0 -69
  4. package/.github/actions/ci-setup/action.yml +0 -19
  5. package/.github/dependabot.yml +0 -12
  6. package/.github/workflows/ci.yml +0 -119
  7. package/.github/workflows/dependabot.yml +0 -26
  8. package/.github/workflows/semgrep.yml +0 -24
  9. package/.prettierrc.cjs +0 -11
  10. package/.vscode/tasks.json +0 -28
  11. package/codecov.yml +0 -7
  12. package/lib/orm.query.test.d.ts +0 -2
  13. package/lib/orm.query.test.d.ts.map +0 -1
  14. package/lib/orm.query.test.js +0 -22
  15. package/lib/orm.query.test.js.map +0 -1
  16. package/src/Connection.ts +0 -65
  17. package/src/errors.ts +0 -18
  18. package/src/index.ts +0 -16
  19. package/src/logger.ts +0 -3
  20. package/src/migrate/commands/implode.ts +0 -46
  21. package/src/migrate/index.ts +0 -1
  22. package/src/migrate/migrator.ts +0 -24
  23. package/src/migrate/sql/createExtensionsSql.test.ts +0 -26
  24. package/src/migrate/sql/createExtensionsSql.ts +0 -16
  25. package/src/migrate/sql/createForeignKeyConstraintSql.test.ts +0 -50
  26. package/src/migrate/sql/createForeignKeyConstraintSql.ts +0 -44
  27. package/src/migrate/sql/createSchemasSql.test.ts +0 -81
  28. package/src/migrate/sql/createSchemasSql.ts +0 -15
  29. package/src/migrate/sql/createTableSql.properties.ts +0 -38
  30. package/src/migrate/sql/createTableSql.test.ts +0 -74
  31. package/src/migrate/sql/createTableSql.ts +0 -53
  32. package/src/migrate/sql/createUniqueConstraintSql.ts +0 -27
  33. package/src/migrate/sql/dropSchemasSql.ts +0 -15
  34. package/src/migrate/sql/dropTableSql.ts +0 -13
  35. package/src/orm.query.test.ts +0 -28
  36. package/src/orm.ts +0 -370
  37. package/src/pull/index.ts +0 -1
  38. package/src/pull/introspect/getForeignKeys.ts +0 -64
  39. package/src/pull/introspect/getPrimaryKeys.ts +0 -26
  40. package/src/pull/introspect/getTables.ts +0 -51
  41. package/src/pull/introspect/getUniqueConstraints.ts +0 -39
  42. package/src/pull/parse/parseCreateUniqueIndexStatement.test.ts +0 -14
  43. package/src/pull/parse/parseCreateUniqueIndexStatement.ts +0 -19
  44. package/src/pull/pull.ts +0 -78
  45. package/src/pull/render/renderModel.test.ts +0 -144
  46. package/src/pull/render/renderModel.ts +0 -141
  47. package/src/pull/render/renderModelsIndex.ts +0 -24
  48. package/src/pull/render/renderRelations.ts +0 -77
  49. package/src/pull/render/renderRelationsIndex.ts +0 -24
  50. package/src/pull/types/ColumnMeta.ts +0 -10
  51. package/src/pull/types/ForeignKey.ts +0 -6
  52. package/src/pull/types/PrimaryKey.ts +0 -6
  53. package/src/pull/types/UniqueConstraint.ts +0 -8
  54. package/src/pull/util/format.ts +0 -17
  55. package/src/pull/util/quote.ts +0 -7
  56. package/src/pull/util/unquote.ts +0 -9
  57. package/src/queries/clauses/IncludeClause.ts +0 -39
  58. package/src/queries/clauses/LateralByClause.ts +0 -4
  59. package/src/queries/clauses/ReturningClause.ts +0 -7
  60. package/src/queries/clauses/SelectClause.ts +0 -7
  61. package/src/queries/clauses/WhereClause.ts +0 -16
  62. package/src/queries/clauses/helpers/OptionalColumn.ts +0 -18
  63. package/src/queries/clauses/helpers/OptionalParams.ts +0 -14
  64. package/src/queries/clauses/helpers/RequiredColumn.ts +0 -8
  65. package/src/queries/clauses/helpers/RequiredParams.ts +0 -14
  66. package/src/queries/clauses/include/IncludedRelationModel.ts +0 -13
  67. package/src/queries/clauses/include/IncludedRelationName.ts +0 -11
  68. package/src/queries/clauses/include/IncludedRelationQuery.ts +0 -20
  69. package/src/queries/clauses/where/buildWhereClause.ts +0 -121
  70. package/src/queries/clauses/where/buildWhereClauses.test.ts +0 -145
  71. package/src/queries/clauses/where/buildWhereClauses.ts +0 -45
  72. package/src/queries/clauses/where/operators.ts +0 -13
  73. package/src/queries/clauses/where/types/WhereClauseValue.ts +0 -39
  74. package/src/queries/count/buildCount.ts +0 -77
  75. package/src/queries/count/countToSql.ts +0 -66
  76. package/src/queries/count/tests/count.test.ts +0 -35
  77. package/src/queries/count/types/BaseCountParams.ts +0 -11
  78. package/src/queries/count/types/CountBuilder.ts +0 -45
  79. package/src/queries/count/types/CountParams.ts +0 -27
  80. package/src/queries/count.ts +0 -33
  81. package/src/queries/create/buildCreate.ts +0 -67
  82. package/src/queries/create/createResultSchema.ts +0 -24
  83. package/src/queries/create/createToSql.ts +0 -44
  84. package/src/queries/create/tests/createMany.varied-keys.test.ts +0 -28
  85. package/src/queries/create/tests/createOne.test-d.ts +0 -116
  86. package/src/queries/create/tests/createOne.test.ts +0 -197
  87. package/src/queries/create/types/BaseCreateManyParams.ts +0 -7
  88. package/src/queries/create/types/BaseCreateOneParams.ts +0 -7
  89. package/src/queries/create/types/CreateManyParams.ts +0 -15
  90. package/src/queries/create/types/CreateManyResult.ts +0 -17
  91. package/src/queries/create/types/CreateOneParams.ts +0 -22
  92. package/src/queries/create/types/CreateOneResult.ts +0 -17
  93. package/src/queries/createMany.ts +0 -38
  94. package/src/queries/createOne.ts +0 -27
  95. package/src/queries/delete/buildDelete.ts +0 -56
  96. package/src/queries/delete/deleteResultSchema.ts +0 -23
  97. package/src/queries/delete/deleteToSql.ts +0 -48
  98. package/src/queries/delete/tests/deleteOne.test.ts +0 -108
  99. package/src/queries/delete/types/BaseDeleteParams.ts +0 -9
  100. package/src/queries/delete/types/DeleteManyResult.ts +0 -16
  101. package/src/queries/delete/types/DeleteOneResult.ts +0 -16
  102. package/src/queries/delete/types/DeleteParams.ts +0 -12
  103. package/src/queries/deleteMany.ts +0 -33
  104. package/src/queries/deleteOne.ts +0 -32
  105. package/src/queries/find/buildFind.ts +0 -138
  106. package/src/queries/find/findResultSchema.ts +0 -32
  107. package/src/queries/find/findToSql.test.ts +0 -123
  108. package/src/queries/find/findToSql.ts +0 -141
  109. package/src/queries/find/getIncludedManyToManyRelations.ts +0 -49
  110. package/src/queries/find/getIncludedOneToManyRelations.ts +0 -44
  111. package/src/queries/find/tests/findMany.include.test.ts +0 -107
  112. package/src/queries/find/tests/findMany.limit.test-d.ts +0 -75
  113. package/src/queries/find/tests/findMany.limit.test.ts +0 -176
  114. package/src/queries/find/tests/findMany.nullable-relations.test.ts +0 -127
  115. package/src/queries/find/tests/findMany.orderBy.test-d.ts +0 -84
  116. package/src/queries/find/tests/findMany.orderBy.test.ts +0 -184
  117. package/src/queries/find/tests/findMany.select.test-d.ts +0 -117
  118. package/src/queries/find/tests/findMany.select.test.ts +0 -188
  119. package/src/queries/find/tests/findMany.too-deep.test-d.ts +0 -154
  120. package/src/queries/find/tests/findMany.where.test-d.ts +0 -85
  121. package/src/queries/find/tests/findMany.where.test.ts +0 -76
  122. package/src/queries/find/tests/middleware.find.where.test.ts +0 -467
  123. package/src/queries/find/types/BaseFindParams.ts +0 -18
  124. package/src/queries/find/types/FindBuilder.ts +0 -73
  125. package/src/queries/find/types/FindManyParams.ts +0 -24
  126. package/src/queries/find/types/FindManyResult.ts +0 -13
  127. package/src/queries/find/types/FindOneParams.ts +0 -17
  128. package/src/queries/find/types/FindOneResult.ts +0 -50
  129. package/src/queries/findMany.ts +0 -134
  130. package/src/queries/findOne.ts +0 -30
  131. package/src/queries/middleware/Middleware.ts +0 -53
  132. package/src/queries/middleware/ValuesMiddleware.ts +0 -9
  133. package/src/queries/middleware/WhereMiddleware.ts +0 -16
  134. package/src/queries/update/buildUpdate.ts +0 -76
  135. package/src/queries/update/tests/updateOne.test.ts +0 -118
  136. package/src/queries/update/types/BaseUpdateParams.ts +0 -10
  137. package/src/queries/update/types/UpdateManyResult.ts +0 -16
  138. package/src/queries/update/types/UpdateOneResult.ts +0 -16
  139. package/src/queries/update/types/UpdateParams.ts +0 -14
  140. package/src/queries/update/types/UpdateValues.ts +0 -12
  141. package/src/queries/update/updateResultSchema.ts +0 -23
  142. package/src/queries/update/updateToSql.ts +0 -43
  143. package/src/queries/updateMany.ts +0 -33
  144. package/src/queries/updateOne.ts +0 -33
  145. package/src/queries/util/hasConditions.test.ts +0 -36
  146. package/src/queries/util/hasConditions.ts +0 -14
  147. package/src/queries/util/rowToObject.test.ts +0 -76
  148. package/src/queries/util/rowToObject.ts +0 -13
  149. package/src/queries/util/tableAlias.test.ts +0 -20
  150. package/src/queries/util/tableAlias.ts +0 -10
  151. package/src/schema/populate/composeMiddleware.ts +0 -51
  152. package/src/schema/populate/populateConfiguration.ts +0 -48
  153. package/src/schema/populate/populateModel.ts +0 -98
  154. package/src/schema/populate/suggestedColumnSchema.ts +0 -62
  155. package/src/schema/types/base/BaseColumn.ts +0 -10
  156. package/src/schema/types/base/BaseConfiguration.ts +0 -14
  157. package/src/schema/types/base/BaseModel.ts +0 -12
  158. package/src/schema/types/base/BaseModels.ts +0 -3
  159. package/src/schema/types/base/BaseOrm.ts +0 -8
  160. package/src/schema/types/base/BaseRelation.ts +0 -19
  161. package/src/schema/types/base/BaseRelations.ts +0 -3
  162. package/src/schema/types/constraints/ForeignKey.ts +0 -13
  163. package/src/schema/types/constraints/UniqueConstraint.ts +0 -9
  164. package/src/schema/types/helpers/ColumnName.ts +0 -6
  165. package/src/schema/types/helpers/ColumnType.ts +0 -23
  166. package/src/schema/types/helpers/Columns.ts +0 -3
  167. package/src/schema/types/helpers/HasDefault.ts +0 -11
  168. package/src/schema/types/helpers/IsNullable.ts +0 -7
  169. package/src/schema/types/helpers/IsProvided.ts +0 -8
  170. package/src/schema/types/helpers/IsSerial.ts +0 -10
  171. package/src/schema/types/helpers/ModelName.ts +0 -6
  172. package/src/schema/types/loose/LooseColumnDefinition.ts +0 -80
  173. package/src/schema/types/loose/LooseModelDefinition.ts +0 -47
  174. package/src/schema/types/loose/LooseModelDefinitions.ts +0 -3
  175. package/src/schema/types/loose/LooseRelationDefinition.ts +0 -10
  176. package/src/schema/types/loose/LooseRelationsDefinition.ts +0 -8
  177. package/src/schema/types/loose/LooseRelationsDefinitions.ts +0 -7
  178. package/src/schema/types/postgres/DataType.ts +0 -65
  179. package/src/schema/types/relations/ManyToManyRelation.ts +0 -15
  180. package/src/schema/types/relations/ManyToOneRelation.ts +0 -14
  181. package/src/schema/types/relations/OneToManyRelation.ts +0 -12
  182. package/src/schema/types/strict/ColumnDefinition.ts +0 -81
  183. package/src/schema/types/strict/ModelDefinition.ts +0 -47
  184. package/src/schema/types/strict/ModelDefinitions.ts +0 -3
  185. package/src/schema/types/strict/RelationDefinition.ts +0 -13
  186. package/src/schema/types/strict/RelationsDefinition.ts +0 -8
  187. package/src/schema/types/strict/RelationsDefinitions.ts +0 -7
  188. package/src/schema/validate/validateConfiguration.ts +0 -9
  189. package/src/schema/validate/validateModel.ts +0 -32
  190. package/src/sql/SQLStatement.test.ts +0 -112
  191. package/src/sql/SQLStatement.ts +0 -86
  192. package/src/sql/index.ts +0 -2
  193. package/src/sql/sql.ts +0 -47
  194. package/src/test/db/index.ts +0 -27
  195. package/src/test/db/models/foo.model.ts +0 -24
  196. package/src/test/db/models/foo.relations.ts +0 -4
  197. package/src/test/db/models/post.model.ts +0 -34
  198. package/src/test/db/models/post.relations.ts +0 -21
  199. package/src/test/db/models/tenant.model.ts +0 -14
  200. package/src/test/db/models/tenant.relations.ts +0 -22
  201. package/src/test/db/models/tenantUser.model.ts +0 -23
  202. package/src/test/db/models/tenantUser.relations.ts +0 -15
  203. package/src/test/db/models/user.model.ts +0 -29
  204. package/src/test/db/models/user.relations.ts +0 -38
  205. package/src/test/db/models.ts +0 -15
  206. package/src/test/db/relations.ts +0 -13
  207. package/src/test/gen/column.ts +0 -39
  208. package/src/test/gen/index.ts +0 -2
  209. package/src/test/gen/model.ts +0 -58
  210. package/src/test/gen/sqldate.ts +0 -8
  211. package/src/test/globalSetup.ts +0 -6
  212. package/src/test/seed/index.ts +0 -75
  213. package/src/test/util/withRollback.ts +0 -18
  214. package/src/test/util/withTransaction.ts +0 -19
  215. package/src/types/ColumnName.ts +0 -6
  216. package/src/types/ColumnType.ts +0 -20
  217. package/src/types/Configuration.ts +0 -21
  218. package/src/types/ModelType.ts +0 -20
  219. package/src/types/util/DeepRequired.ts +0 -7
  220. package/src/types/util/DisallowExtraKeys.ts +0 -5
  221. package/src/types/util/NonEmptyArray.ts +0 -1
  222. package/src/types/util/Simplify.ts +0 -8
  223. package/src/util/ensureArray.ts +0 -4
  224. package/src/util/interleave.test.ts +0 -35
  225. package/src/util/interleave.ts +0 -8
  226. package/tsconfig.json +0 -18
  227. package/vitest.config.ts +0 -15
@@ -1,56 +0,0 @@
1
- import { BaseConfiguration } from "src/schema/types/base/BaseConfiguration";
2
-
3
- import { OrmError } from "../../errors";
4
- import { ModelName } from "../../schema/types/helpers/ModelName";
5
- import { LooseModelDefinitions } from "../../schema/types/loose/LooseModelDefinitions";
6
- import { WhereClause } from "../clauses/WhereClause";
7
- import { tableAlias } from "../util/tableAlias";
8
- import { BaseDeleteParams } from "./types/BaseDeleteParams";
9
-
10
- export type DeleteBuilder = {
11
- tableIndex: number;
12
- table: { table: string; model: string; alias: string; schema: string };
13
- where: WhereClause<LooseModelDefinitions, ModelName<LooseModelDefinitions>>;
14
- returning: { name: string; path: string; alias: string }[];
15
- };
16
-
17
- export const buildDelete = (
18
- config: BaseConfiguration,
19
- m: string,
20
- params: BaseDeleteParams,
21
- _tableIndex = 0,
22
- ): DeleteBuilder => {
23
- const builder: DeleteBuilder = {
24
- tableIndex: _tableIndex,
25
- table: {
26
- table: config.models[m].table,
27
- schema: config.models[m].schema,
28
- model: m,
29
- alias: tableAlias(_tableIndex++),
30
- },
31
- where: config.middleware.delete?.where
32
- ? config.middleware.delete.where(params.where, {
33
- config,
34
- model: m,
35
- })!
36
- : params.where,
37
- returning: [],
38
- };
39
- let colIndex = 0;
40
- const model = config.models[m];
41
-
42
- if (Object.keys(builder.where).length === 0) {
43
- throw new OrmError("No where clause provided for delete operation", {
44
- data: { m, model, params },
45
- });
46
- }
47
-
48
- for (const f of params.returning ?? []) {
49
- builder.returning.push({
50
- name: model.columns[f]["name"],
51
- path: f,
52
- alias: `${builder.table.alias}_${colIndex++}`,
53
- });
54
- }
55
- return builder;
56
- };
@@ -1,23 +0,0 @@
1
- import { BaseConfiguration } from "src/schema/types/base/BaseConfiguration";
2
- import { ZodSchema, z } from "zod";
3
-
4
- import { BaseDeleteParams } from "./types/BaseDeleteParams";
5
-
6
- export const deleteResultSchema = (
7
- config: BaseConfiguration,
8
- m: string,
9
- params: BaseDeleteParams,
10
- ) => {
11
- if (!params.returning) return z.number();
12
-
13
- const obj: Record<string, ZodSchema<unknown>> = {};
14
-
15
- params.returning?.forEach((s) => {
16
- const col = config.models[m].columns[s];
17
- obj[s] = col.nullable
18
- ? col.zodSchema.nullish().transform((x) => x ?? null)
19
- : col.zodSchema;
20
- });
21
-
22
- return z.object(obj);
23
- };
@@ -1,48 +0,0 @@
1
- import pgfmt from "pg-format";
2
-
3
- import { OrmError } from "../../errors";
4
- import { BaseConfiguration } from "../../schema/types/base/BaseConfiguration";
5
- import { SQLStatement, sql } from "../../sql";
6
- import { buildWhereClauses } from "../clauses/where/buildWhereClauses";
7
- import { hasConditions } from "../util/hasConditions";
8
- import { DeleteBuilder } from "./buildDelete";
9
-
10
- export const deleteToSql = (
11
- config: BaseConfiguration,
12
- m: string,
13
- builder: DeleteBuilder,
14
- ): SQLStatement => {
15
- const { table, where, returning } = builder;
16
-
17
- const frag = sql`DELETE FROM %I.%I AS %I`.withIdentifiers(
18
- table.schema,
19
- table.table,
20
- table.alias,
21
- );
22
-
23
- if (!hasConditions(where)) {
24
- throw new OrmError(`No where clause provided for delete`, {
25
- data: {
26
- table,
27
- where,
28
- returning,
29
- },
30
- });
31
- }
32
- frag.push("\nWHERE\n ");
33
- frag.push(buildWhereClauses(config, table, where));
34
-
35
- if (returning.length > 0) {
36
- frag.push("\nRETURNING\n");
37
- frag.push(
38
- returning
39
- .map((r) =>
40
- pgfmt(` %I.%I as %I`, table.alias, r.name, r.alias),
41
- )
42
- .join(",\n"),
43
- );
44
- }
45
- frag.push(";\n");
46
-
47
- return frag;
48
- };
@@ -1,108 +0,0 @@
1
- import { describe, expect, test } from "vitest";
2
-
3
- import { OrmError } from "../../../errors";
4
- import { db } from "../../../test/db";
5
- import { seed } from "../../../test/seed";
6
- import { $like } from "../../clauses/where/operators";
7
-
8
- describe("deleteOne", () => {
9
- test("it deletes a single record in the database", async () => {
10
- await db.transact(
11
- async (db) => {
12
- const { posts } = await seed(db, {
13
- users: [
14
- {
15
- username: "Stewart House",
16
- tenants: [{ name: "Popova Park", posts: 3 }],
17
- },
18
- ],
19
- });
20
-
21
- const deleted = await db.deleteOne("post", {
22
- where: { title: "Post a" },
23
- returning: ["id"],
24
- });
25
-
26
- expect(deleted.id).toEqual(
27
- posts.find((p) => p.title === "Post a")?.id,
28
- );
29
-
30
- const results = await db.findMany("post", {
31
- select: ["id", "title"],
32
- include: {
33
- author: {
34
- select: ["id", "username"],
35
- where: { username: { [$like]: "Stewart %" } },
36
- },
37
- },
38
- });
39
-
40
- expect(results.map((p) => p.title)).toEqual([
41
- "Post b",
42
- "Post c",
43
- ]);
44
- },
45
- { rollback: true },
46
- );
47
- });
48
-
49
- test("if no records are deleted, it throws an error and rolls back to before the delete", async () => {
50
- await db.transact(
51
- async (db) => {
52
- await seed(db, {
53
- users: [
54
- {
55
- username: "Stewart House",
56
- tenants: [{ name: "Popova Park", posts: 3 }],
57
- },
58
- ],
59
- });
60
-
61
- await expect(
62
- db.deleteOne("post", {
63
- where: { title: "Wrong" },
64
- returning: ["id"],
65
- }),
66
- ).rejects.toEqual(new OrmError("No rows deleted"));
67
- },
68
- { rollback: true },
69
- );
70
- });
71
-
72
- test("if multiple records are deleted, it throws an error and rolls back to before the delete", async () => {
73
- await db.transact(
74
- async (db) => {
75
- await seed(db, {
76
- users: [
77
- {
78
- username: "Stewart House",
79
- tenants: [{ name: "Popova Park", posts: 3 }],
80
- },
81
- {
82
- username: "Stewart Home",
83
- tenants: [{ name: "Popova Park", posts: 3 }],
84
- },
85
- ],
86
- });
87
-
88
- await expect(
89
- db.deleteOne("post", {
90
- where: { title: { [$like]: "Post%" } },
91
- returning: ["id"],
92
- }),
93
- ).rejects.toEqual(
94
- new OrmError(
95
- "More than one deleted row for deleteOne, rolling back",
96
- ),
97
- );
98
-
99
- const result = await db.findMany("post", {
100
- select: ["id"],
101
- });
102
-
103
- expect(result.length).toEqual(6);
104
- },
105
- { rollback: true },
106
- );
107
- });
108
- });
@@ -1,9 +0,0 @@
1
- import { ModelName } from "../../../schema/types/helpers/ModelName";
2
- import { LooseModelDefinitions } from "../../../schema/types/loose/LooseModelDefinitions";
3
- import { NonEmptyArray } from "../../../types/util/NonEmptyArray";
4
- import { WhereClause } from "../../clauses/WhereClause";
5
-
6
- export type BaseDeleteParams = {
7
- where: WhereClause<LooseModelDefinitions, ModelName<LooseModelDefinitions>>;
8
- returning?: NonEmptyArray<string>;
9
- };
@@ -1,16 +0,0 @@
1
- import { ColumnType } from "../../../schema/types/helpers/ColumnType";
2
- import { ModelName } from "../../../schema/types/helpers/ModelName";
3
- import { LooseModelDefinitions } from "../../../schema/types/loose/LooseModelDefinitions";
4
- import { ReturningClause } from "../../clauses/ReturningClause";
5
- import { DeleteParams } from "./DeleteParams";
6
-
7
- export type DeleteManyResult<
8
- Models extends LooseModelDefinitions,
9
- M extends ModelName<Models>,
10
- P extends DeleteParams<Models, M>,
11
- > =
12
- P["returning"] extends ReturningClause<Models[M]>
13
- ? Readonly<{
14
- [C in P["returning"][number]]: ColumnType<Models, M, C>;
15
- }>[]
16
- : number;
@@ -1,16 +0,0 @@
1
- import { ColumnType } from "../../../schema/types/helpers/ColumnType";
2
- import { ModelName } from "../../../schema/types/helpers/ModelName";
3
- import { LooseModelDefinitions } from "../../../schema/types/loose/LooseModelDefinitions";
4
- import { ReturningClause } from "../../clauses/ReturningClause";
5
- import { DeleteParams } from "./DeleteParams";
6
-
7
- export type DeleteOneResult<
8
- Models extends LooseModelDefinitions,
9
- M extends ModelName<Models>,
10
- P extends DeleteParams<Models, M>,
11
- > =
12
- P["returning"] extends ReturningClause<Models[M]>
13
- ? Readonly<{
14
- [C in P["returning"][number]]: ColumnType<Models, M, C>;
15
- }>
16
- : number;
@@ -1,12 +0,0 @@
1
- import { ModelName } from "../../../schema/types/helpers/ModelName";
2
- import { LooseModelDefinitions } from "../../../schema/types/loose/LooseModelDefinitions";
3
- import { ReturningClause } from "../../clauses/ReturningClause";
4
- import { WhereClause } from "../../clauses/WhereClause";
5
-
6
- export type DeleteParams<
7
- Models extends LooseModelDefinitions,
8
- M extends ModelName<Models>,
9
- > = {
10
- where: WhereClause<Models, M>;
11
- returning?: ReturningClause<Models[M]>;
12
- };
@@ -1,33 +0,0 @@
1
- import { BaseConfiguration } from "src/schema/types/base/BaseConfiguration";
2
-
3
- import { Connection } from "../Connection";
4
- import { logger } from "../logger";
5
- import { buildDelete } from "./delete/buildDelete";
6
- import { deleteToSql } from "./delete/deleteToSql";
7
- import { BaseDeleteParams } from "./delete/types/BaseDeleteParams";
8
- import { rowToObject } from "./util/rowToObject";
9
-
10
- export const deleteMany = async (
11
- conn: Connection,
12
- config: BaseConfiguration,
13
- m: string,
14
- params: BaseDeleteParams,
15
- ) => {
16
- const builder = buildDelete(config, m, params);
17
- const statement = deleteToSql(config, m, builder);
18
- logger.info({
19
- message: "Executing delete",
20
- sql: statement.text,
21
- values: statement.values,
22
- });
23
-
24
- if (process.env.ORM_VERBOSE_LOGGING) {
25
- console.log(statement.text);
26
- console.log(statement.values);
27
- }
28
-
29
- const result = await conn.query(statement);
30
- return params.returning
31
- ? result.rows.map(rowToObject(builder.returning))
32
- : result.rowCount ?? 0;
33
- };
@@ -1,32 +0,0 @@
1
- import { BaseConfiguration } from "src/schema/types/base/BaseConfiguration";
2
-
3
- import { Connection } from "../Connection";
4
- import { OrmError } from "../errors";
5
- import { BaseDeleteParams } from "./delete/types/BaseDeleteParams";
6
- import { deleteMany } from "./deleteMany";
7
-
8
- export const deleteOne = async (
9
- conn: Connection,
10
- config: BaseConfiguration,
11
- m: string,
12
- params: BaseDeleteParams,
13
- ) => {
14
- return await conn.transact(async (conn) => {
15
- const results = await deleteMany(conn, config, m, params);
16
- const deletedCount =
17
- typeof results === "number" ? results : results?.length ?? 0;
18
-
19
- if (deletedCount === 0) {
20
- throw new OrmError("No rows deleted", { data: { m, params } });
21
- }
22
-
23
- if (deletedCount > 1) {
24
- throw new OrmError(
25
- "More than one deleted row for deleteOne, rolling back",
26
- { data: { m, params, deletedCount } },
27
- );
28
- }
29
-
30
- return typeof results === "number" ? results : results[0];
31
- });
32
- };
@@ -1,138 +0,0 @@
1
- import { max, min, uniq } from "lodash-es";
2
- import { BaseConfiguration } from "src/schema/types/base/BaseConfiguration";
3
-
4
- import { ensureArray } from "../../util/ensureArray";
5
- import { tableAlias } from "../util/tableAlias";
6
- import { BaseFindParams } from "./types/BaseFindParams";
7
- import { FindBuilder } from "./types/FindBuilder";
8
-
9
- export const buildFind = (
10
- config: BaseConfiguration,
11
- m: string,
12
- query: BaseFindParams,
13
- path: string[] = [],
14
- _tableIndex = 0,
15
- ): FindBuilder => {
16
- const builder: FindBuilder = {
17
- columns: [],
18
- table: {
19
- table: config.models[m]["table"],
20
- model: m,
21
- schema: config.models[m]["schema"],
22
- alias: tableAlias(_tableIndex++),
23
- where: config.middleware.find?.where
24
- ? config.middleware.find.where(query.where, {
25
- config,
26
- model: m,
27
- })
28
- : query.where,
29
- joins: [],
30
- },
31
- orderBy: [],
32
- for: query.for,
33
- tableIndex: _tableIndex,
34
- };
35
-
36
- const model = config.models[m];
37
-
38
- const alias = builder.table.alias;
39
- let colIndex = 0;
40
-
41
- // make sure we always select the model's primary key,
42
- // and if necessary the foreign key for a lateral join
43
- // - we'll strip them out later
44
- const select = uniq([
45
- ...query.select,
46
- ...model.primaryKey,
47
- ...(query.lateralBy ?? []).map(({ column }) => column),
48
- ]);
49
-
50
- for (const f of select) {
51
- builder.columns.push({
52
- table: alias,
53
- name: model.columns[f]["name"],
54
- alias: `${alias}_${colIndex++}`,
55
- path: [...path, f],
56
- });
57
- }
58
-
59
- for (const [r, subquery] of Object.entries(query.include ?? {})) {
60
- const relation = config.relations[m][r];
61
- const joinedModel = config.models[relation.model];
62
- if (relation.type === "N:1") {
63
- const joinBuilder = buildFind(
64
- config,
65
- relation.model,
66
- subquery!,
67
- [...path, r],
68
- builder.tableIndex++,
69
- );
70
- const joinedTable = joinBuilder.table;
71
- builder.table.joins.push(
72
- {
73
- from: {
74
- schema: config.models[m].schema,
75
- table: config.models[m].table,
76
- alias,
77
- model: m,
78
- columns: ensureArray(relation.foreignKey).map(
79
- (c) => model.columns[c].name,
80
- ),
81
- },
82
- to: {
83
- schema: joinedModel.schema,
84
- table: joinedTable.table,
85
- alias: joinedTable.alias,
86
- model: relation.model,
87
- columns: joinedModel.primaryKey.map(
88
- (c) => joinedModel.columns[c].name,
89
- ),
90
- },
91
- type: relation.optional ? "left" : "inner",
92
- where: joinedTable.where,
93
- },
94
- ...joinedTable.joins,
95
- );
96
- // this is admittedly a bit weird,
97
- // we wouldn't expect N:1 relations to specify
98
- // ordering, skipping, and limiting, and typescript
99
- // prevents users from doing this, but
100
- // we rely on them being present as part of the N:N
101
- // implementation
102
- builder.columns.push(...joinBuilder.columns);
103
- builder.orderBy.push(...joinBuilder.orderBy);
104
- builder.limit = min([builder.limit, joinBuilder.limit]);
105
- builder.offset = max([builder.offset, joinBuilder.offset]);
106
- }
107
- }
108
-
109
- if (query.lateralBy) {
110
- builder.lateralBy = {
111
- groupTable: tableAlias(builder.tableIndex++),
112
- itemTable: tableAlias(builder.tableIndex++),
113
- columns: query.lateralBy.map(({ column, values }) => ({
114
- column: model.columns[column].name,
115
- type: model.columns[column].type,
116
- values,
117
- })),
118
- };
119
- }
120
-
121
- if (query.orderBy) {
122
- builder.orderBy = query.orderBy.map((o) => ({
123
- table: alias,
124
- column: Array.isArray(o) ? o[0] : o,
125
- direction: Array.isArray(o) ? o[1] : "asc",
126
- }));
127
- }
128
-
129
- if (query.limit) {
130
- builder.limit = query.limit;
131
- }
132
-
133
- if (query.offset) {
134
- builder.offset = query.offset;
135
- }
136
-
137
- return builder;
138
- };
@@ -1,32 +0,0 @@
1
- import { BaseConfiguration } from "src/schema/types/base/BaseConfiguration";
2
- import { ZodSchema, z } from "zod";
3
-
4
- import { BaseFindParams } from "./types/BaseFindParams";
5
-
6
- export const findResultSchema = (
7
- config: BaseConfiguration,
8
- m: string,
9
- query: BaseFindParams,
10
- ) => {
11
- const obj: Record<string, ZodSchema<unknown>> = {};
12
-
13
- query.select.forEach((field) => {
14
- const col = config.models[m].columns[field];
15
- obj[field] = col.nullable
16
- ? col.zodSchema.nullish().transform((x) => x ?? null)
17
- : col.zodSchema;
18
- });
19
-
20
- for (const [field, subquery] of Object.entries(query.include || {})) {
21
- const relation = config.relations[m][field];
22
- const schema = findResultSchema(config, relation.model, subquery!);
23
- obj[field] =
24
- relation.type === "N:1"
25
- ? relation.optional
26
- ? schema.nullish().transform((x) => x ?? null)
27
- : schema
28
- : z.array(schema);
29
- }
30
-
31
- return z.object(obj);
32
- };
@@ -1,123 +0,0 @@
1
- import { unindent } from "@casekit/unindent";
2
-
3
- import * as uuid from "uuid";
4
- import { describe, expect, test } from "vitest";
5
-
6
- import { FindMany, db } from "../../test/db";
7
- import { $and, $ilike, $lte } from "../clauses/where/operators";
8
- import { buildFind } from "./buildFind";
9
- import { findToSql } from "./findToSql";
10
-
11
- describe("findToSql", () => {
12
- test("it builds a valid query for simple selects", async () => {
13
- const builder = buildFind(db.config, "post", {
14
- select: ["id", "title"],
15
- });
16
- const statement = findToSql(db.config, builder);
17
- expect(statement.text).toEqual(unindent`
18
- SELECT
19
- a.id AS a_0,
20
- a.title AS a_1
21
- FROM casekit.post a
22
- WHERE 1 = 1
23
- `);
24
- });
25
-
26
- test("it builds a valid query for included N:1 relations", async () => {
27
- const builder = buildFind(db.config, "post", {
28
- select: ["id", "title"],
29
- include: {
30
- author: { select: ["username"] },
31
- },
32
- } as FindMany<"post">);
33
-
34
- const statement = findToSql(db.config, builder);
35
- expect(statement.text).toEqual(unindent`
36
- SELECT
37
- a.id AS a_0,
38
- a.title AS a_1,
39
- b.username AS b_0,
40
- b.id AS b_1
41
- FROM casekit.post a
42
- JOIN casekit."user" b
43
- ON a.created_by_id = b.id
44
- WHERE 1 = 1
45
- `);
46
- });
47
-
48
- test("it builds a valid lateral query for 1:N relations", async () => {
49
- const builder = buildFind(db.config, "post", {
50
- select: ["id", "title"],
51
- include: {
52
- author: { select: ["username"] },
53
- },
54
- lateralBy: [{ column: "id", values: [uuid.v4()] }],
55
- } as FindMany<"post">);
56
-
57
- const statement = findToSql(db.config, builder);
58
- expect(statement.text).toEqual(unindent`
59
- SELECT d.* FROM (
60
- SELECT UNNEST(ARRAY[$1]::uuid[]) AS id) c
61
- JOIN LATERAL (
62
- SELECT
63
- a.id AS a_0,
64
- a.title AS a_1,
65
- b.username AS b_0,
66
- b.id AS b_1
67
- FROM casekit.post a
68
- JOIN casekit."user" b
69
- ON a.created_by_id = b.id
70
- WHERE 1 = 1
71
- AND a.id = c.id
72
- ) d ON TRUE
73
- `);
74
- });
75
-
76
- test("it allows specifying where clauses on both the top level table and N:1 relations", async () => {
77
- const id1 = uuid.v4();
78
- const id2 = uuid.v4();
79
- const builder = buildFind(db.config, "post", {
80
- select: ["id", "title"],
81
- where: { title: { [$ilike]: "%cats%" } },
82
- include: {
83
- author: {
84
- select: ["username"],
85
- where: {
86
- [$and]: [
87
- { username: "Russell" },
88
- { joinedAt: { [$lte]: new Date(2024, 6, 4) } },
89
- ],
90
- },
91
- },
92
- },
93
- lateralBy: [{ column: "id", values: [id1, id2] }],
94
- } as FindMany<"post">);
95
-
96
- const statement = findToSql(db.config, builder);
97
- expect(statement.text).toEqual(unindent`
98
- SELECT d.* FROM (
99
- SELECT UNNEST(ARRAY[$1, $2]::uuid[]) AS id) c
100
- JOIN LATERAL (
101
- SELECT
102
- a.id AS a_0,
103
- a.title AS a_1,
104
- b.username AS b_0,
105
- b.id AS b_1
106
- FROM casekit.post a
107
- JOIN casekit."user" b
108
- ON a.created_by_id = b.id
109
- AND (((b.username = $3) AND (b.created_at <= $4)))
110
- WHERE 1 = 1
111
- AND (a.title ILIKE $5)
112
- AND a.id = c.id
113
- ) d ON TRUE
114
- `);
115
- expect(statement.values).toEqual([
116
- id1,
117
- id2,
118
- "Russell",
119
- new Date(2024, 6, 4),
120
- "%cats%",
121
- ]);
122
- });
123
- });