@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,20 +0,0 @@
1
- import { ModelName } from "../../../schema/types/helpers/ModelName";
2
- import { LooseModelDefinitions } from "../../../schema/types/loose/LooseModelDefinitions";
3
- import { LooseRelationsDefinitions } from "../../../schema/types/loose/LooseRelationsDefinitions";
4
- import { FindManyParams } from "../../find/types/FindManyParams";
5
- import { IncludedRelationModel } from "./IncludedRelationModel";
6
-
7
- export type IncludedRelationQuery<
8
- Models extends LooseModelDefinitions,
9
- Relations extends LooseRelationsDefinitions<Models>,
10
- M extends ModelName<Models>,
11
- R extends keyof Q["include"] & keyof Relations[M],
12
- Q extends FindManyParams<Models, Relations, M>,
13
- > =
14
- Q["include"][R] extends FindManyParams<
15
- Models,
16
- Relations,
17
- IncludedRelationModel<Models, Relations, M, R>
18
- >
19
- ? Q["include"][R]
20
- : never;
@@ -1,121 +0,0 @@
1
- import { OrmError } from "../../../errors";
2
- import { SQLStatement, sql } from "../../../sql";
3
- import {
4
- $eq,
5
- $gt,
6
- $gte,
7
- $ilike,
8
- $in,
9
- $is,
10
- $like,
11
- $lt,
12
- $lte,
13
- $ne,
14
- $not,
15
- } from "./operators";
16
-
17
- export const buildWhereClause = (
18
- table: string,
19
- column: string,
20
- v: unknown,
21
- ): SQLStatement => {
22
- if (v === null) {
23
- return sql`%I.%I IS NULL`.withIdentifiers(table, column);
24
- } else if (
25
- typeof v === "string" ||
26
- typeof v === "number" ||
27
- typeof v === "boolean" ||
28
- v instanceof Date ||
29
- Object.getOwnPropertySymbols(v).length === 0
30
- ) {
31
- return sql`%I.%I = ${v}`.withIdentifiers(table, column);
32
- } else {
33
- const clauses = Object.getOwnPropertySymbols(v).map(
34
- (op): SQLStatement => {
35
- const v2 = (v as Record<symbol, unknown>)[op];
36
- switch (op) {
37
- case $eq:
38
- return sql`%I.%I = ${v2}`.withIdentifiers(
39
- table,
40
- column,
41
- );
42
- case $gt:
43
- return sql`%I.%I > ${v2}`.withIdentifiers(
44
- table,
45
- column,
46
- );
47
- case $gte:
48
- return sql`%I.%I >= ${v2}`.withIdentifiers(
49
- table,
50
- column,
51
- );
52
- case $ilike:
53
- return sql`%I.%I ILIKE ${v2}`.withIdentifiers(
54
- table,
55
- column,
56
- );
57
- case $in:
58
- if (!Array.isArray(v2)) {
59
- throw new OrmError(
60
- "Non-array passed to IN clause",
61
- { data: { table, column, v, v2 } },
62
- );
63
- } else if (v2.length === 0) {
64
- return sql`%I.%I IN (NULL)`.withIdentifiers(
65
- table,
66
- column,
67
- );
68
- } else {
69
- const values = v2.map((v) => sql`${v}`);
70
- return sql`%I.%I IN (${sql.splat(values)})`.withIdentifiers(
71
- table,
72
- column,
73
- );
74
- }
75
- case $is:
76
- return sql`%I.%I IS ${v2}`.withIdentifiers(
77
- table,
78
- column,
79
- );
80
- case $like:
81
- return sql`%I.%I LIKE ${v2}`.withIdentifiers(
82
- table,
83
- column,
84
- );
85
- case $lt:
86
- return sql`%I.%I < ${v2}`.withIdentifiers(
87
- table,
88
- column,
89
- );
90
- case $lte:
91
- return sql`%I.%I <= ${v2}`.withIdentifiers(
92
- table,
93
- column,
94
- );
95
- case $ne:
96
- return sql`%I.%I != ${v2}`.withIdentifiers(
97
- table,
98
- column,
99
- );
100
- case $not:
101
- if (v2 !== null) {
102
- throw new OrmError(
103
- "Unexpected value other than NULL in NOT clause: " +
104
- v2,
105
- );
106
- }
107
- return sql`%I.%I IS NOT NULL`.withIdentifiers(
108
- table,
109
- column,
110
- );
111
- default:
112
- throw new OrmError("Unexpected symbol in query", {
113
- data: { table, column, op, v },
114
- });
115
- }
116
- },
117
- );
118
-
119
- return sql.splat(clauses, " AND ");
120
- }
121
- };
@@ -1,145 +0,0 @@
1
- import { describe, expect, test } from "vitest";
2
-
3
- import { ModelName } from "../../../schema/types/helpers/ModelName";
4
- import { LooseModelDefinitions } from "../../../schema/types/loose/LooseModelDefinitions";
5
- import { db } from "../../../test/db";
6
- import { WhereClause } from "../types/../WhereClause";
7
- import { buildWhereClauses } from "./buildWhereClauses";
8
- import {
9
- $and,
10
- $eq,
11
- $gt,
12
- $gte,
13
- $ilike,
14
- $in,
15
- $is,
16
- $like,
17
- $lt,
18
- $lte,
19
- $ne,
20
- $not,
21
- $or,
22
- } from "./operators";
23
-
24
- /**
25
- * NB. The dollars in the resulting SQL render as `undefined` in the test output,
26
- * but do generate (and test!) the SQL correctly. This is due to a limitation
27
- * of vitest.each that I haven't figured a way round yet.
28
- */
29
- describe("buildWhereClauses", () => {
30
- test.each([
31
- [{ id: 3 }, "(a.id = $1)", [3]],
32
- [{ id: { [$eq]: 3 } }, "(a.id = $1)", [3]],
33
- [{ a: "foo" }, "(a.a = $1)", ["foo"]],
34
- [
35
- { timestamp: { [$gt]: new Date(2024, 1, 1) } },
36
- `(a.timestamp > $1)`,
37
- [new Date(2024, 1, 1)],
38
- ],
39
- [
40
- { timestamp: { [$gte]: new Date(2024, 1, 3) } },
41
- "(a.timestamp >= $1)",
42
- [new Date(2024, 1, 3)],
43
- ],
44
- [{ bigint: { [$lt]: 47 } }, "(a.bigint < $1)", [47]],
45
- [
46
- { timestamp: { [$lte]: new Date(2024, 1, 3) } },
47
- "(a.timestamp <= $1)",
48
- [new Date(2024, 1, 3)],
49
- ],
50
-
51
- [{ id: 3, text: "foo" }, "(a.id = $1 AND a.text = $2)", [3, "foo"]],
52
- [
53
- { id: 3, text: { [$like]: "foo%" } },
54
- "(a.id = $1 AND a.text LIKE $2)",
55
- [3, "foo%"],
56
- ],
57
- [
58
- { id: 3, text: { [$ilike]: "foo%" } },
59
- "(a.id = $1 AND a.text ILIKE $2)",
60
- [3, "foo%"],
61
- ],
62
- [
63
- { id: 3, text: { [$ne]: "Russell" } },
64
- "(a.id = $1 AND a.text != $2)",
65
- [3, "Russell"],
66
- ],
67
- [
68
- { id: 3, text: { [$not]: null } },
69
- "(a.id = $1 AND a.text IS NOT NULL)",
70
- [3],
71
- ],
72
- [
73
- { id: 3, text: { [$is]: true } },
74
- "(a.id = $1 AND a.text IS $2)",
75
- [3, true],
76
- ],
77
- [
78
- { [$and]: [{ id: 3 }, { text: "foo" }] },
79
- "(((a.id = $1) AND (a.text = $2)))",
80
- [3, "foo"],
81
- ],
82
- [
83
- { [$or]: [{ id: 3 }, { text: "foo" }] },
84
- "(((a.id = $1) OR (a.text = $2)))",
85
- [3, "foo"],
86
- ],
87
- [
88
- { [$not]: { [$or]: [{ text: "foo" }, { text: "bar" }] } },
89
- "(NOT (((a.text = $1) OR (a.text = $2))))",
90
- ["foo", "bar"],
91
- ],
92
- [
93
- { text: { [$in]: ["cat", "dog", "fish"] } },
94
- "(a.text IN ($1, $2, $3))",
95
- ["cat", "dog", "fish"],
96
- ],
97
- [{ text: { [$in]: [] } }, "(a.text IN (NULL))", []],
98
- [
99
- {
100
- [$not]: {
101
- [$and]: [
102
- { text: "foo" },
103
- {
104
- [$or]: [
105
- {
106
- [$and]: [
107
- { text: 1, renamedColumn: 2 },
108
- { renamedColumn: 3 },
109
- ],
110
- },
111
- { [$or]: [{ text: 3 }, { renamedColumn: 5 }] },
112
- { renamedColumn: 333 },
113
- ],
114
- },
115
- ],
116
- },
117
- },
118
- "(NOT (((a.text = $1) AND (((((a.text = $2 AND a.original_name = $3) AND (a.original_name = $4))) OR (((a.text = $5) OR (a.original_name = $6))) OR (a.original_name = $7))))))",
119
- ["foo", 1, 2, 3, 3, 5, 333],
120
- ],
121
- [
122
- { [$or]: [{ text: 1, renamedColumn: 2 }, { text: 3 }] },
123
- "(((a.text = $1 AND a.original_name = $2) OR (a.text = $3)))",
124
- [1, 2, 3],
125
- ],
126
- ])(
127
- "Where clause of %s returns SQL %s with variables %s",
128
- (
129
- where: WhereClause<
130
- LooseModelDefinitions,
131
- ModelName<LooseModelDefinitions>
132
- >,
133
- sql: string,
134
- values: unknown[],
135
- ) => {
136
- const clause = buildWhereClauses(
137
- db.config,
138
- { table: "foo", schema: "casekit", model: "foo", alias: "a" },
139
- where,
140
- );
141
- expect(clause.text).toEqual(sql);
142
- expect(clause.values).toEqual(values);
143
- },
144
- );
145
- });
@@ -1,45 +0,0 @@
1
- import { BaseConfiguration } from "../../../schema/types/base/BaseConfiguration";
2
- import { ModelName } from "../../../schema/types/helpers/ModelName";
3
- import { LooseModelDefinitions } from "../../../schema/types/loose/LooseModelDefinitions";
4
- import { SQLStatement, sql } from "../../../sql";
5
- import { WhereClause } from "../WhereClause";
6
- import { buildWhereClause } from "./buildWhereClause";
7
- import { $and, $not, $or } from "./operators";
8
-
9
- export const buildWhereClauses = (
10
- config: BaseConfiguration,
11
- table: { table: string; schema: string; alias: string; model: string },
12
- where: WhereClause<LooseModelDefinitions, ModelName<LooseModelDefinitions>>,
13
- ): SQLStatement => {
14
- const clauses: SQLStatement[] = [];
15
- Object.entries(where).forEach(([column, value]) => {
16
- clauses.push(
17
- buildWhereClause(
18
- table.alias,
19
- config.models[table.model]["columns"][column]["name"],
20
- value,
21
- ),
22
- );
23
- });
24
-
25
- if (where[$and]) {
26
- const subclauses = where[$and].map((condition) => {
27
- return buildWhereClauses(config, table, condition);
28
- });
29
- clauses.push(sql`(${sql.splat(subclauses, " AND ")})`);
30
- }
31
-
32
- if (where[$or]) {
33
- const subclauses = where[$or].map((condition) => {
34
- return buildWhereClauses(config, table, condition);
35
- });
36
- clauses.push(sql`(${sql.splat(subclauses, " OR ")})`);
37
- }
38
-
39
- if (where[$not]) {
40
- const subclauses = buildWhereClauses(config, table, where[$not]);
41
- clauses.push(sql`NOT ${subclauses}`);
42
- }
43
-
44
- return sql`(${sql.splat(clauses, " AND ")})`;
45
- };
@@ -1,13 +0,0 @@
1
- export const $and = Symbol("and");
2
- export const $eq = Symbol("eq");
3
- export const $gt = Symbol("gt");
4
- export const $gte = Symbol("gte");
5
- export const $ilike = Symbol("ilike");
6
- export const $in = Symbol("in");
7
- export const $is = Symbol("is");
8
- export const $like = Symbol("like");
9
- export const $lt = Symbol("lt");
10
- export const $lte = Symbol("lte");
11
- export const $ne = Symbol("ne");
12
- export const $not = Symbol("not");
13
- export const $or = Symbol("or");
@@ -1,39 +0,0 @@
1
- import { ColumnName } from "../../../../schema/types/helpers/ColumnName";
2
- import { ColumnType } from "../../../../schema/types/helpers/ColumnType";
3
- import { ModelName } from "../../../../schema/types/helpers/ModelName";
4
- import { LooseModelDefinitions } from "../../../../schema/types/loose/LooseModelDefinitions";
5
- import {
6
- $eq,
7
- $gt,
8
- $gte,
9
- $ilike,
10
- $in,
11
- $is,
12
- $like,
13
- $lt,
14
- $lte,
15
- $ne,
16
- $not,
17
- } from "../operators";
18
-
19
- export type WhereClauseValue<
20
- Models extends LooseModelDefinitions,
21
- M extends ModelName<Models>,
22
- C extends ColumnName<Models[M]>,
23
- T = ColumnType<Models, M, C>,
24
- > =
25
- | ColumnType<Models, M, C>
26
- | null
27
- | {
28
- [$eq]?: T;
29
- [$ne]?: T;
30
- [$not]?: null;
31
- [$is]?: null | true | false | { [$not]: true | false };
32
- [$gt]?: T;
33
- [$gte]?: T;
34
- [$lt]?: T;
35
- [$lte]?: T;
36
- [$in]?: T[];
37
- [$like]?: string;
38
- [$ilike]?: string;
39
- };
@@ -1,77 +0,0 @@
1
- import { BaseConfiguration } from "src/schema/types/base/BaseConfiguration";
2
-
3
- import { ensureArray } from "../../util/ensureArray";
4
- import { tableAlias } from "../util/tableAlias";
5
- import { BaseCountParams } from "./types/BaseCountParams";
6
- import { CountBuilder } from "./types/CountBuilder";
7
-
8
- export const buildCount = (
9
- config: BaseConfiguration,
10
- m: string,
11
- query: BaseCountParams,
12
- path: string[] = [],
13
- _tableIndex = 0,
14
- ): CountBuilder => {
15
- const builder: CountBuilder = {
16
- table: {
17
- table: config.models[m]["table"],
18
- model: m,
19
- schema: config.models[m]["schema"],
20
- alias: tableAlias(_tableIndex++),
21
- joins: [],
22
- where: config.middleware.count?.where
23
- ? config.middleware.count.where(query.where, {
24
- config,
25
- model: m,
26
- })
27
- : query.where,
28
- },
29
- tableIndex: _tableIndex,
30
- };
31
-
32
- const model = config.models[m];
33
-
34
- const alias = builder.table.alias;
35
-
36
- for (const [r, subquery] of Object.entries(query.include ?? {})) {
37
- const relation = config.relations[m][r];
38
- const joinedModel = config.models[relation.model];
39
- if (relation.type === "N:1") {
40
- const joinBuilder = buildCount(
41
- config,
42
- relation.model,
43
- subquery!,
44
- [...path, r],
45
- builder.tableIndex++,
46
- );
47
- const joinedTable = joinBuilder.table;
48
- builder.table.joins.push(
49
- {
50
- from: {
51
- schema: config.models[m].schema,
52
- table: config.models[m].table,
53
- alias,
54
- model: m,
55
- columns: ensureArray(relation.foreignKey).map(
56
- (c) => model.columns[c].name,
57
- ),
58
- },
59
- to: {
60
- schema: joinedModel.schema,
61
- table: joinedTable.table,
62
- alias: joinedTable.alias,
63
- model: relation.model,
64
- columns: joinedModel.primaryKey.map(
65
- (c) => joinedModel.columns[c].name,
66
- ),
67
- },
68
- where: joinedTable.where,
69
- type: relation.optional ? "left" : "inner",
70
- },
71
- ...joinedTable.joins,
72
- );
73
- }
74
- }
75
-
76
- return builder;
77
- };
@@ -1,66 +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 { CountBuilder } from "./types/CountBuilder";
9
-
10
- export const countToSql = (
11
- config: BaseConfiguration,
12
- builder: CountBuilder,
13
- ): SQLStatement => {
14
- const table = builder.table;
15
-
16
- const frag = sql`SELECT count(1) as "count"`;
17
-
18
- frag.push(pgfmt(`\nFROM %I.%I %I`, table.schema, table.table, table.alias));
19
-
20
- for (const join of table.joins ?? []) {
21
- if (join.from.columns.length !== join.to.columns.length) {
22
- throw new OrmError(
23
- "Number of foreign keys doesn't match number of primary keys in join",
24
- { data: builder },
25
- );
26
- }
27
-
28
- frag.push(join.type === "left" ? "\nLEFT JOIN" : "\nJOIN");
29
- frag.push(
30
- pgfmt(
31
- "\n %I.%I %I\n ON ",
32
- join.to.schema,
33
- join.to.table,
34
- join.to.alias,
35
- ),
36
- );
37
- frag.push(
38
- join.from.columns
39
- .map((from, i) =>
40
- pgfmt(
41
- "%I.%I = %I.%I",
42
- join.from.alias,
43
- from,
44
- join.to.alias,
45
- join.to.columns[i],
46
- ),
47
- )
48
- .join(" AND "),
49
- );
50
- if (hasConditions(join.where)) {
51
- frag.push(
52
- sql`\n AND ${buildWhereClauses(config, join.to, join.where)}`,
53
- );
54
- }
55
- }
56
-
57
- frag.push(sql`\nWHERE 1 = 1`);
58
-
59
- if (hasConditions(table.where)) {
60
- frag.push(
61
- sql`\n AND ${buildWhereClauses(config, table, table.where)}`,
62
- );
63
- }
64
-
65
- return frag;
66
- };
@@ -1,35 +0,0 @@
1
- import { describe, expect, test } from "vitest";
2
-
3
- import { db } from "../../../test/db";
4
- import { seed } from "../../../test/seed";
5
-
6
- describe("count", () => {
7
- test("it counts the number of rows a query would return", async () => {
8
- await db.transact(
9
- async (db) => {
10
- await seed(db, {
11
- users: [
12
- {
13
- username: "Russell",
14
- tenants: [{ name: "WFMA", posts: 3 }],
15
- },
16
- {
17
- username: "Stewart Home",
18
- tenants: [{ name: "Popova Park", posts: 2 }],
19
- },
20
- ],
21
- });
22
- const result = await db.count("post", {
23
- include: {
24
- author: {
25
- where: { username: "Stewart Home" },
26
- },
27
- },
28
- });
29
-
30
- expect(result).toBe(2);
31
- },
32
- { rollback: true },
33
- );
34
- });
35
- });
@@ -1,11 +0,0 @@
1
- import { ModelName } from "../../../schema/types/helpers/ModelName";
2
- import { LooseModelDefinitions } from "../../../schema/types/loose/LooseModelDefinitions";
3
- import { WhereClause } from "../../clauses/WhereClause";
4
-
5
- export type BaseCountParams = {
6
- include?: Partial<Record<string, BaseCountParams>>;
7
- where?: WhereClause<
8
- LooseModelDefinitions,
9
- ModelName<LooseModelDefinitions>
10
- >;
11
- };
@@ -1,45 +0,0 @@
1
- import { ModelName } from "../../../schema/types/helpers/ModelName";
2
- import { LooseModelDefinitions } from "../../../schema/types/loose/LooseModelDefinitions";
3
- import { WhereClause } from "../../clauses/WhereClause";
4
-
5
- export type CountBuilder = {
6
- tableIndex: number;
7
-
8
- table: {
9
- table: string;
10
- model: string;
11
- schema: string;
12
- alias: string;
13
- joins: Join[];
14
- conditions?: WhereClause<
15
- LooseModelDefinitions,
16
- ModelName<LooseModelDefinitions>
17
- >;
18
- where?: WhereClause<
19
- LooseModelDefinitions,
20
- ModelName<LooseModelDefinitions>
21
- >;
22
- };
23
- };
24
-
25
- export type Join = {
26
- from: {
27
- schema: string;
28
- table: string;
29
- alias: string;
30
- model: string;
31
- columns: string[];
32
- };
33
- to: {
34
- schema: string;
35
- table: string;
36
- alias: string;
37
- model: string;
38
- columns: string[];
39
- };
40
- where?: WhereClause<
41
- LooseModelDefinitions,
42
- ModelName<LooseModelDefinitions>
43
- >;
44
- type?: "inner" | "left";
45
- };
@@ -1,27 +0,0 @@
1
- import { ModelName } from "../../../schema/types/helpers/ModelName";
2
- import { LooseModelDefinitions } from "../../../schema/types/loose/LooseModelDefinitions";
3
- import { LooseRelationsDefinitions } from "../../../schema/types/loose/LooseRelationsDefinitions";
4
- import { WhereClause } from "../../clauses/WhereClause";
5
-
6
- export type IncludeHasOneRelationsClause<
7
- Models extends LooseModelDefinitions,
8
- Relations extends LooseRelationsDefinitions<Models>,
9
- M extends ModelName<Models>,
10
- > = {
11
- [R in Extract<keyof Relations[M], string>]?: Relations[M][R] extends {
12
- model: ModelName<Models>;
13
- }
14
- ? Relations[M][R] extends { type: "N:1" }
15
- ? CountParams<Models, Relations, Relations[M][R]["model"]>
16
- : never
17
- : never;
18
- };
19
-
20
- export type CountParams<
21
- Models extends LooseModelDefinitions,
22
- Relations extends LooseRelationsDefinitions<Models>,
23
- M extends ModelName<Models>,
24
- > = {
25
- where?: WhereClause<Models, M>;
26
- include?: IncludeHasOneRelationsClause<Models, Relations, M>;
27
- };
@@ -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 { buildCount } from "./count/buildCount";
6
- import { countToSql } from "./count/countToSql";
7
- import { BaseCountParams } from "./count/types/BaseCountParams";
8
-
9
- export const count = async (
10
- conn: Connection,
11
- config: BaseConfiguration,
12
- m: string,
13
- query: BaseCountParams,
14
- ) => {
15
- const builder = buildCount(config, m, query);
16
- const statement = countToSql(config, builder);
17
- logger.info({
18
- message: "Executing query",
19
- sql: statement.text,
20
- values: statement.values,
21
- });
22
-
23
- if (process.env.ORM_VERBOSE_LOGGING) {
24
- console.log(statement.text);
25
- console.log(statement.values);
26
- }
27
-
28
- const result = await conn
29
- .query(statement)
30
- .then((result) => result.rows[0].count);
31
-
32
- return result;
33
- };