@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,134 +0,0 @@
1
- import { dropRight, get, groupBy, set } from "lodash-es";
2
- import hash from "object-hash";
3
- import { BaseConfiguration } from "src/schema/types/base/BaseConfiguration";
4
-
5
- import { Connection } from "../Connection";
6
- import { OrmError } from "../errors";
7
- import { logger } from "../logger";
8
- import { ensureArray } from "../util/ensureArray";
9
- import { buildFind } from "./find/buildFind";
10
- import { findToSql } from "./find/findToSql";
11
- import { getIncludedManyToManyRelations } from "./find/getIncludedManyToManyRelations";
12
- import { getIncludedOneToManyRelations } from "./find/getIncludedOneToManyRelations";
13
- import { BaseFindParams } from "./find/types/BaseFindParams";
14
- import { rowToObject } from "./util/rowToObject";
15
-
16
- export const findMany = async (
17
- conn: Connection,
18
- config: BaseConfiguration,
19
- m: string,
20
- query: BaseFindParams,
21
- ) => {
22
- const builder = buildFind(config, m, query);
23
- const statement = findToSql(config, builder);
24
- logger.info({
25
- message: "Executing query",
26
- sql: statement.text,
27
- values: statement.values,
28
- });
29
-
30
- if (process.env.ORM_VERBOSE_LOGGING) {
31
- console.log(statement.text);
32
- console.log(statement.values);
33
- }
34
-
35
- const results = await conn
36
- .query(statement)
37
- .then((result) => result.rows.map(rowToObject(builder.columns)));
38
-
39
- const fetchIncludedOneToManyRelations = getIncludedOneToManyRelations(
40
- config,
41
- m,
42
- query,
43
- ).map(({ model, relation, query, path }) => {
44
- const pk = config.models[model].primaryKey;
45
- const fk = ensureArray(relation.foreignKey);
46
- const lateralBy = fk.map((c, index) => ({
47
- column: c,
48
- values: results.map((result) =>
49
- get(result, [...dropRight(path, 1), pk[index]]),
50
- ),
51
- }));
52
- return findMany(conn, config, relation.model, {
53
- ...query,
54
- for: builder.for,
55
- lateralBy,
56
- }).then((subqueryResults) => {
57
- const lookup = groupBy(subqueryResults, (result) => {
58
- return hash(fk.map((c) => result[c]));
59
- });
60
- for (const result of results) {
61
- const parent =
62
- path.length === 1
63
- ? result
64
- : get(result, dropRight(path, 1));
65
- if (parent !== undefined) {
66
- const key = hash(pk.map((c) => get(parent, c)));
67
- set(result, path, lookup[key] ?? []);
68
- }
69
- }
70
- });
71
- });
72
-
73
- const fetchIncludedManyToManyRelations = getIncludedManyToManyRelations(
74
- config,
75
- m,
76
- query,
77
- ).map(({ model, relation, query, path }) => {
78
- const joinFrom = Object.entries(config.relations[model]).find(
79
- ([, rel]) => rel.type === "1:N" && rel.model === relation.through,
80
- )?.[0];
81
-
82
- const joinTo = Object.entries(config.relations[relation.through]).find(
83
- ([, rel]) => rel.type === "N:1" && rel.model === relation.model,
84
- )?.[0];
85
-
86
- if (joinFrom === undefined || joinTo === undefined) {
87
- throw new OrmError("Both sides of a N:N relation must be defined", {
88
- data: { joinFrom, joinTo, query },
89
- });
90
- }
91
-
92
- const pk = config.models[model].primaryKey;
93
- const fk = ensureArray(relation.foreignKey);
94
- const lateralBy = fk.map((c, index) => ({
95
- column: c,
96
- values: results.map((result) =>
97
- get(result, [...dropRight(path, 1), pk[index]]),
98
- ),
99
- }));
100
-
101
- return findMany(conn, config, relation.through, {
102
- select: ensureArray(relation.foreignKey),
103
- include: { [joinTo]: query },
104
- for: builder.for,
105
- lateralBy,
106
- }).then((subqueryResults) => {
107
- const lookup = groupBy(subqueryResults, (result) => {
108
- return hash(fk.map((c) => result[c]));
109
- });
110
- for (const result of results) {
111
- const parent =
112
- path.length === 1
113
- ? result
114
- : get(result, dropRight(path, 1));
115
-
116
- if (parent !== undefined) {
117
- const key = hash(pk.map((c) => get(parent, c)));
118
- set(
119
- result,
120
- path,
121
- (lookup[key] ?? []).map((r) => r[joinTo] ?? []),
122
- );
123
- }
124
- }
125
- });
126
- });
127
-
128
- await Promise.all([
129
- ...fetchIncludedOneToManyRelations,
130
- ...fetchIncludedManyToManyRelations,
131
- ]);
132
-
133
- return results;
134
- };
@@ -1,30 +0,0 @@
1
- import { BaseConfiguration } from "src/schema/types/base/BaseConfiguration";
2
-
3
- import { Connection } from "../Connection";
4
- import { OrmError } from "../errors";
5
- import { BaseFindParams } from "./find/types/BaseFindParams";
6
- import { findMany } from "./findMany";
7
-
8
- export const findOne = async (
9
- conn: Connection,
10
- config: BaseConfiguration,
11
- m: string,
12
- query: BaseFindParams,
13
- ) => {
14
- const results = await findMany(conn, config, m, { ...query, limit: 2 });
15
-
16
- if (results.length === 0) {
17
- throw new OrmError("FindOne found zero records", {
18
- model: [m, config.models[m]],
19
- data: query,
20
- });
21
- }
22
- if (results.length > 1) {
23
- throw new OrmError("FindOne found too many records", {
24
- model: [m, config.models[m]],
25
- data: query,
26
- });
27
- }
28
-
29
- return results[0];
30
- };
@@ -1,53 +0,0 @@
1
- import { BaseConfiguration } from "../../schema/types/base/BaseConfiguration";
2
- import { BaseOrm } from "../../schema/types/base/BaseOrm";
3
- import { BaseDeleteParams } from "../delete/types/BaseDeleteParams";
4
- import { BaseUpdateParams } from "../update/types/BaseUpdateParams";
5
- import { ValuesMiddleware } from "./ValuesMiddleware";
6
- import { WhereMiddleware } from "./WhereMiddleware";
7
-
8
- export type Middleware = {
9
- where?: WhereMiddleware;
10
- values?: ValuesMiddleware;
11
- find?: {
12
- where?: WhereMiddleware;
13
- };
14
- create?: {
15
- values?: ValuesMiddleware;
16
- };
17
- update?: {
18
- set?: ValuesMiddleware;
19
- where?: WhereMiddleware;
20
- };
21
- count?: {
22
- where?: WhereMiddleware;
23
- };
24
- delete?: {
25
- where?: WhereMiddleware;
26
- deleteOne?: (
27
- params: BaseDeleteParams,
28
- meta: {
29
- config: BaseConfiguration;
30
- model: string;
31
- deleteOne: (
32
- params: BaseDeleteParams,
33
- ) => ReturnType<BaseOrm["deleteOne"]>;
34
- updateOne: (
35
- params: BaseUpdateParams,
36
- ) => ReturnType<BaseOrm["updateOne"]>;
37
- },
38
- ) => unknown;
39
- deleteMany?: (
40
- params: BaseDeleteParams,
41
- meta: {
42
- config: BaseConfiguration;
43
- model: string;
44
- deleteMany: (
45
- params: BaseDeleteParams,
46
- ) => ReturnType<BaseOrm["deleteOne"]>;
47
- updateMany: (
48
- params: BaseUpdateParams,
49
- ) => ReturnType<BaseOrm["updateOne"]>;
50
- },
51
- ) => unknown;
52
- };
53
- };
@@ -1,9 +0,0 @@
1
- import { BaseConfiguration } from "../../schema/types/base/BaseConfiguration";
2
-
3
- export type ValuesMiddleware = (
4
- values: Record<string, unknown>,
5
- meta: {
6
- model: string;
7
- config: BaseConfiguration;
8
- },
9
- ) => Record<string, unknown>;
@@ -1,16 +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 { WhereClause } from "../clauses/WhereClause";
5
-
6
- export type WhereMiddleware = (
7
- where:
8
- | WhereClause<LooseModelDefinitions, ModelName<LooseModelDefinitions>>
9
- | undefined,
10
- meta: {
11
- model: string;
12
- config: BaseConfiguration;
13
- },
14
- ) =>
15
- | WhereClause<LooseModelDefinitions, ModelName<LooseModelDefinitions>>
16
- | undefined;
@@ -1,76 +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 { BaseUpdateParams } from "./types/BaseUpdateParams";
9
-
10
- export type UpdateBuilder = {
11
- tableIndex: number;
12
- table: { table: string; model: string; alias: string; schema: string };
13
- where: WhereClause<LooseModelDefinitions, ModelName<LooseModelDefinitions>>;
14
- set: { name: string; value: unknown }[];
15
- returning: { name: string; path: string; alias: string }[];
16
- };
17
-
18
- export const buildUpdate = (
19
- config: BaseConfiguration,
20
- m: string,
21
- params: BaseUpdateParams,
22
- _tableIndex = 0,
23
- ): UpdateBuilder => {
24
- const builder: UpdateBuilder = {
25
- tableIndex: _tableIndex,
26
- table: {
27
- table: config.models[m].table,
28
- schema: config.models[m].schema,
29
- model: m,
30
- alias: tableAlias(_tableIndex++),
31
- },
32
- where: config.middleware.update?.where
33
- ? config.middleware.update.where(params.where, {
34
- config,
35
- model: m,
36
- })!
37
- : params.where!,
38
- set: [],
39
- returning: [],
40
- };
41
- let colIndex = 0;
42
- const model = config.models[m];
43
- const set = config.middleware.update?.set
44
- ? config.middleware.update.set(params.set, {
45
- config,
46
- model: m,
47
- })
48
- : params.set;
49
-
50
- if (set.length === 0) {
51
- throw new OrmError("No updates provided for update operation", {
52
- data: { m, model, params },
53
- });
54
- }
55
-
56
- if (Object.keys(builder.where).length === 0) {
57
- throw new OrmError("No where clause provided for update operation", {
58
- data: { m, model, params },
59
- });
60
- }
61
-
62
- for (const [k, v] of Object.entries(set)) {
63
- builder.set.push({
64
- name: model.columns[k]["name"],
65
- value: v,
66
- });
67
- }
68
- for (const f of params.returning ?? []) {
69
- builder.returning.push({
70
- name: model.columns[f]["name"],
71
- path: f,
72
- alias: `${builder.table.alias}_${colIndex++}`,
73
- });
74
- }
75
- return builder;
76
- };
@@ -1,118 +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("updateOne", () => {
9
- test("it updates a single record in the database", async () => {
10
- await db.transact(
11
- async (db) => {
12
- const { users } = await seed(db, {
13
- users: [
14
- {
15
- username: "Stewart House",
16
- tenants: [{ name: "Popova Park", posts: 3 }],
17
- },
18
- ],
19
- });
20
-
21
- const user = users["Stewart House"];
22
-
23
- const updated = await db.updateOne("user", {
24
- set: { username: "Stewart Home" },
25
- where: { username: "Stewart House" },
26
- returning: ["id", "username"],
27
- });
28
-
29
- expect(updated.id).toEqual(user.id);
30
- expect(updated.username).toEqual("Stewart Home");
31
-
32
- const results = await db.findMany("user", {
33
- select: ["id", "username"],
34
- where: { username: { [$like]: "Stewart %" } },
35
- });
36
-
37
- expect(results).toEqual([updated]);
38
- },
39
- { rollback: true },
40
- );
41
- });
42
-
43
- test("if no records are updated, it throws an error and rolls back to before the update", async () => {
44
- await db.transact(
45
- async (db) => {
46
- const { users } = await seed(db, {
47
- users: [
48
- {
49
- username: "Stewart House",
50
- tenants: [{ name: "Popova Park", posts: 3 }],
51
- },
52
- ],
53
- });
54
-
55
- const user = users["Stewart House"];
56
-
57
- await expect(
58
- db.updateOne("user", {
59
- set: { username: "Stewart Home" },
60
- where: { username: "Stewart Wrong" },
61
- returning: ["id", "username"],
62
- }),
63
- ).rejects.toEqual(new OrmError("No rows updated"));
64
-
65
- const result = await db.findOne("user", {
66
- select: ["id", "username"],
67
- where: { username: "Stewart House" },
68
- });
69
-
70
- expect(result).toEqual(user);
71
- },
72
- { rollback: true },
73
- );
74
- });
75
-
76
- test("if multiple records are updated, it throws an error and rolls back to before the update", async () => {
77
- await db.transact(
78
- async (db) => {
79
- await seed(db, {
80
- users: [
81
- {
82
- username: "Stewart House",
83
- tenants: [{ name: "Popova Park", posts: 3 }],
84
- },
85
- {
86
- username: "Stewart Home",
87
- tenants: [{ name: "Popova Park", posts: 3 }],
88
- },
89
- ],
90
- });
91
-
92
- await expect(
93
- db.updateOne("user", {
94
- set: { joinedAt: new Date("2021-01-04") },
95
- where: { username: { [$like]: "Stewart %" } },
96
- returning: ["id", "username"],
97
- }),
98
- ).rejects.toEqual(
99
- new OrmError(
100
- "More than one updated row for updateOne, rolling back",
101
- ),
102
- );
103
-
104
- const result = await db.findMany("user", {
105
- select: ["id", "username", "joinedAt"],
106
- where: { username: { [$like]: "Stewart %" } },
107
- orderBy: ["username"],
108
- });
109
-
110
- expect(result.map((u) => u.joinedAt)).not.toEqual([
111
- new Date("2021-01-04"),
112
- new Date("2021-01-04"),
113
- ]);
114
- },
115
- { rollback: true },
116
- );
117
- });
118
- });
@@ -1,10 +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 BaseUpdateParams = {
7
- set: Record<string, unknown | null>;
8
- where: WhereClause<LooseModelDefinitions, ModelName<LooseModelDefinitions>>;
9
- returning?: NonEmptyArray<string>;
10
- };
@@ -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 { UpdateParams } from "./UpdateParams";
6
-
7
- export type UpdateManyResult<
8
- Models extends LooseModelDefinitions,
9
- M extends ModelName<Models>,
10
- P extends UpdateParams<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 { UpdateParams } from "./UpdateParams";
6
-
7
- export type UpdateOneResult<
8
- Models extends LooseModelDefinitions,
9
- M extends ModelName<Models>,
10
- P extends UpdateParams<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,14 +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
- import { UpdateValues } from "./UpdateValues";
6
-
7
- export type UpdateParams<
8
- Models extends LooseModelDefinitions,
9
- M extends ModelName<Models>,
10
- > = {
11
- set: UpdateValues<Models, M>;
12
- where: WhereClause<Models, M>;
13
- returning?: ReturningClause<Models[M]>;
14
- };
@@ -1,12 +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 { Simplify } from "../../../types/util/Simplify";
6
-
7
- export type UpdateValues<
8
- Models extends LooseModelDefinitions,
9
- M extends ModelName<Models>,
10
- > = Simplify<{
11
- [C in ColumnName<Models[M]>]?: ColumnType<Models, M, C>;
12
- }>;
@@ -1,23 +0,0 @@
1
- import { BaseConfiguration } from "src/schema/types/base/BaseConfiguration";
2
- import { ZodSchema, z } from "zod";
3
-
4
- import { BaseUpdateParams } from "./types/BaseUpdateParams";
5
-
6
- export const updateResultSchema = (
7
- config: BaseConfiguration,
8
- m: string,
9
- params: BaseUpdateParams,
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,43 +0,0 @@
1
- import pgfmt from "pg-format";
2
-
3
- import { BaseConfiguration } from "../../schema/types/base/BaseConfiguration";
4
- import { SQLStatement, sql } from "../../sql";
5
- import { buildWhereClauses } from "../clauses/where/buildWhereClauses";
6
- import { UpdateBuilder } from "./buildUpdate";
7
-
8
- export const updateToSql = (
9
- config: BaseConfiguration,
10
- m: string,
11
- builder: UpdateBuilder,
12
- ): SQLStatement => {
13
- const { table, where, set, returning } = builder;
14
-
15
- const frag = sql`UPDATE %I.%I AS %I\nSET`.withIdentifiers(
16
- table.schema,
17
- table.table,
18
- table.alias,
19
- );
20
-
21
- const fields = set.map((field) => {
22
- return sql`\n %I = ${field.value}`.withIdentifiers(field.name);
23
- });
24
-
25
- frag.push(sql.splat(fields, ",\n"));
26
-
27
- frag.push("\nWHERE\n ");
28
- frag.push(buildWhereClauses(config, table, where));
29
-
30
- if (returning.length > 0) {
31
- frag.push("\nRETURNING\n");
32
- frag.push(
33
- returning
34
- .map((r) =>
35
- pgfmt(` %I.%I as %I`, table.alias, r.name, r.alias),
36
- )
37
- .join(",\n"),
38
- );
39
- }
40
- frag.push(";\n");
41
-
42
- return frag;
43
- };
@@ -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 { buildUpdate } from "./update/buildUpdate";
6
- import { BaseUpdateParams } from "./update/types/BaseUpdateParams";
7
- import { updateToSql } from "./update/updateToSql";
8
- import { rowToObject } from "./util/rowToObject";
9
-
10
- export const updateMany = async (
11
- conn: Connection,
12
- config: BaseConfiguration,
13
- m: string,
14
- params: BaseUpdateParams,
15
- ) => {
16
- const builder = buildUpdate(config, m, params);
17
- const statement = updateToSql(config, m, builder);
18
- logger.info({
19
- message: "Executing update",
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,33 +0,0 @@
1
- import { BaseConfiguration } from "src/schema/types/base/BaseConfiguration";
2
-
3
- import { Connection } from "../Connection";
4
- import { OrmError } from "../errors";
5
- import { BaseUpdateParams } from "./update/types/BaseUpdateParams";
6
- import { updateMany } from "./updateMany";
7
-
8
- export const updateOne = async (
9
- conn: Connection,
10
- config: BaseConfiguration,
11
- m: string,
12
- params: BaseUpdateParams,
13
- ) => {
14
- return await conn.transact(async (conn) => {
15
- const results = await updateMany(conn, config, m, params);
16
-
17
- const updatedCount =
18
- typeof results === "number" ? results : results?.length ?? 0;
19
-
20
- if (updatedCount === 0) {
21
- throw new OrmError("No rows updated", { data: { m, params } });
22
- }
23
-
24
- if (updatedCount > 1) {
25
- throw new OrmError(
26
- "More than one updated row for updateOne, rolling back",
27
- { data: { m, params, updatedCount } },
28
- );
29
- }
30
-
31
- return typeof results === "number" ? results : results[0];
32
- });
33
- };