@snowtop/ent 0.1.0-alpha160-test7 → 0.1.0-alpha161-test1

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 (317) hide show
  1. package/{dist/core → core}/query/assoc_query.d.ts +3 -0
  2. package/{dist/core → core}/query/assoc_query.js +71 -0
  3. package/{dist/core → core}/query/query.d.ts +3 -0
  4. package/{dist/core → core}/query/query.js +20 -6
  5. package/core/query/shared_assoc_test.d.ts +2 -0
  6. package/core/query/shared_assoc_test.js +1089 -0
  7. package/core/query/shared_test.d.ts +21 -0
  8. package/core/query/shared_test.js +736 -0
  9. package/graphql/query/shared_assoc_test.d.ts +1 -0
  10. package/graphql/query/shared_assoc_test.js +203 -0
  11. package/package.json +8 -53
  12. package/{dist/testutils → testutils}/fake_data/test_helpers.js +2 -1
  13. package/dist/package.json +0 -64
  14. package/src/action/action.ts +0 -330
  15. package/src/action/executor.ts +0 -453
  16. package/src/action/experimental_action.ts +0 -277
  17. package/src/action/index.ts +0 -31
  18. package/src/action/operations.ts +0 -967
  19. package/src/action/orchestrator.ts +0 -1527
  20. package/src/action/privacy.ts +0 -37
  21. package/src/action/relative_value.ts +0 -242
  22. package/src/action/transaction.ts +0 -38
  23. package/src/auth/auth.ts +0 -77
  24. package/src/auth/index.ts +0 -8
  25. package/src/core/base.ts +0 -367
  26. package/src/core/clause.ts +0 -1065
  27. package/src/core/config.ts +0 -219
  28. package/src/core/const.ts +0 -5
  29. package/src/core/context.ts +0 -135
  30. package/src/core/convert.ts +0 -106
  31. package/src/core/date.ts +0 -23
  32. package/src/core/db.ts +0 -498
  33. package/src/core/ent.ts +0 -1740
  34. package/src/core/global_schema.ts +0 -49
  35. package/src/core/loaders/assoc_count_loader.ts +0 -99
  36. package/src/core/loaders/assoc_edge_loader.ts +0 -250
  37. package/src/core/loaders/index.ts +0 -12
  38. package/src/core/loaders/loader.ts +0 -66
  39. package/src/core/loaders/object_loader.ts +0 -489
  40. package/src/core/loaders/query_loader.ts +0 -314
  41. package/src/core/loaders/raw_count_loader.ts +0 -175
  42. package/src/core/logger.ts +0 -49
  43. package/src/core/privacy.ts +0 -660
  44. package/src/core/query/assoc_query.ts +0 -240
  45. package/src/core/query/custom_clause_query.ts +0 -174
  46. package/src/core/query/custom_query.ts +0 -302
  47. package/src/core/query/index.ts +0 -9
  48. package/src/core/query/query.ts +0 -674
  49. package/src/core/query_impl.ts +0 -32
  50. package/src/core/viewer.ts +0 -52
  51. package/src/ent.code-workspace +0 -73
  52. package/src/graphql/builtins/connection.ts +0 -25
  53. package/src/graphql/builtins/edge.ts +0 -16
  54. package/src/graphql/builtins/node.ts +0 -12
  55. package/src/graphql/graphql.ts +0 -891
  56. package/src/graphql/graphql_field_helpers.ts +0 -221
  57. package/src/graphql/index.ts +0 -42
  58. package/src/graphql/mutations/union.ts +0 -39
  59. package/src/graphql/node_resolver.ts +0 -122
  60. package/src/graphql/query/connection_type.ts +0 -113
  61. package/src/graphql/query/edge_connection.ts +0 -171
  62. package/src/graphql/query/page_info.ts +0 -34
  63. package/src/graphql/query/shared_edge_connection.ts +0 -287
  64. package/src/graphql/scalars/orderby_direction.ts +0 -13
  65. package/src/graphql/scalars/time.ts +0 -38
  66. package/src/imports/dataz/example1/_auth.ts +0 -51
  67. package/src/imports/dataz/example1/_viewer.ts +0 -35
  68. package/src/imports/index.ts +0 -213
  69. package/src/index.ts +0 -145
  70. package/src/parse_schema/parse.ts +0 -585
  71. package/src/schema/base_schema.ts +0 -224
  72. package/src/schema/field.ts +0 -1087
  73. package/src/schema/index.ts +0 -53
  74. package/src/schema/json_field.ts +0 -94
  75. package/src/schema/schema.ts +0 -1028
  76. package/src/schema/struct_field.ts +0 -234
  77. package/src/schema/union_field.ts +0 -105
  78. package/src/scripts/custom_compiler.ts +0 -331
  79. package/src/scripts/custom_graphql.ts +0 -550
  80. package/src/scripts/migrate_v0.1.ts +0 -41
  81. package/src/scripts/move_types.ts +0 -131
  82. package/src/scripts/read_schema.ts +0 -67
  83. package/src/setupPackage.js +0 -42
  84. package/src/testutils/action/complex_schemas.ts +0 -517
  85. package/src/testutils/builder.ts +0 -422
  86. package/src/testutils/context/test_context.ts +0 -25
  87. package/src/testutils/db/fixture.ts +0 -32
  88. package/src/testutils/db/temp_db.ts +0 -941
  89. package/src/testutils/db/value.ts +0 -294
  90. package/src/testutils/db_mock.ts +0 -351
  91. package/src/testutils/db_time_zone.ts +0 -40
  92. package/src/testutils/ent-graphql-tests/index.ts +0 -653
  93. package/src/testutils/fake_comms.ts +0 -50
  94. package/src/testutils/fake_data/const.ts +0 -64
  95. package/src/testutils/fake_data/events_query.ts +0 -145
  96. package/src/testutils/fake_data/fake_contact.ts +0 -150
  97. package/src/testutils/fake_data/fake_event.ts +0 -150
  98. package/src/testutils/fake_data/fake_tag.ts +0 -139
  99. package/src/testutils/fake_data/fake_user.ts +0 -232
  100. package/src/testutils/fake_data/index.ts +0 -1
  101. package/src/testutils/fake_data/internal.ts +0 -8
  102. package/src/testutils/fake_data/tag_query.ts +0 -56
  103. package/src/testutils/fake_data/test_helpers.ts +0 -388
  104. package/src/testutils/fake_data/user_query.ts +0 -524
  105. package/src/testutils/fake_log.ts +0 -52
  106. package/src/testutils/mock_date.ts +0 -10
  107. package/src/testutils/mock_log.ts +0 -39
  108. package/src/testutils/parse_sql.ts +0 -685
  109. package/src/testutils/test_edge_global_schema.ts +0 -49
  110. package/src/testutils/write.ts +0 -70
  111. package/src/tsc/ast.ts +0 -351
  112. package/src/tsc/compilerOptions.ts +0 -85
  113. package/src/tsc/move_generated.ts +0 -191
  114. package/src/tsc/transform.ts +0 -226
  115. package/src/tsc/transform_action.ts +0 -224
  116. package/src/tsc/transform_ent.ts +0 -66
  117. package/src/tsc/transform_schema.ts +0 -546
  118. package/tsconfig.json +0 -20
  119. /package/{dist/action → action}/action.d.ts +0 -0
  120. /package/{dist/action → action}/action.js +0 -0
  121. /package/{dist/action → action}/executor.d.ts +0 -0
  122. /package/{dist/action → action}/executor.js +0 -0
  123. /package/{dist/action → action}/experimental_action.d.ts +0 -0
  124. /package/{dist/action → action}/experimental_action.js +0 -0
  125. /package/{dist/action → action}/index.d.ts +0 -0
  126. /package/{dist/action → action}/index.js +0 -0
  127. /package/{dist/action → action}/operations.d.ts +0 -0
  128. /package/{dist/action → action}/operations.js +0 -0
  129. /package/{dist/action → action}/orchestrator.d.ts +0 -0
  130. /package/{dist/action → action}/orchestrator.js +0 -0
  131. /package/{dist/action → action}/privacy.d.ts +0 -0
  132. /package/{dist/action → action}/privacy.js +0 -0
  133. /package/{dist/action → action}/relative_value.d.ts +0 -0
  134. /package/{dist/action → action}/relative_value.js +0 -0
  135. /package/{dist/action → action}/transaction.d.ts +0 -0
  136. /package/{dist/action → action}/transaction.js +0 -0
  137. /package/{dist/auth → auth}/auth.d.ts +0 -0
  138. /package/{dist/auth → auth}/auth.js +0 -0
  139. /package/{dist/auth → auth}/index.d.ts +0 -0
  140. /package/{dist/auth → auth}/index.js +0 -0
  141. /package/{dist/core → core}/base.d.ts +0 -0
  142. /package/{dist/core → core}/base.js +0 -0
  143. /package/{dist/core → core}/clause.d.ts +0 -0
  144. /package/{dist/core → core}/clause.js +0 -0
  145. /package/{dist/core → core}/config.d.ts +0 -0
  146. /package/{dist/core → core}/config.js +0 -0
  147. /package/{dist/core → core}/const.d.ts +0 -0
  148. /package/{dist/core → core}/const.js +0 -0
  149. /package/{dist/core → core}/context.d.ts +0 -0
  150. /package/{dist/core → core}/context.js +0 -0
  151. /package/{dist/core → core}/convert.d.ts +0 -0
  152. /package/{dist/core → core}/convert.js +0 -0
  153. /package/{dist/core → core}/date.d.ts +0 -0
  154. /package/{dist/core → core}/date.js +0 -0
  155. /package/{dist/core → core}/db.d.ts +0 -0
  156. /package/{dist/core → core}/db.js +0 -0
  157. /package/{dist/core → core}/ent.d.ts +0 -0
  158. /package/{dist/core → core}/ent.js +0 -0
  159. /package/{dist/core → core}/global_schema.d.ts +0 -0
  160. /package/{dist/core → core}/global_schema.js +0 -0
  161. /package/{dist/core → core}/loaders/assoc_count_loader.d.ts +0 -0
  162. /package/{dist/core → core}/loaders/assoc_count_loader.js +0 -0
  163. /package/{dist/core → core}/loaders/assoc_edge_loader.d.ts +0 -0
  164. /package/{dist/core → core}/loaders/assoc_edge_loader.js +0 -0
  165. /package/{dist/core → core}/loaders/index.d.ts +0 -0
  166. /package/{dist/core → core}/loaders/index.js +0 -0
  167. /package/{dist/core → core}/loaders/loader.d.ts +0 -0
  168. /package/{dist/core → core}/loaders/loader.js +0 -0
  169. /package/{dist/core → core}/loaders/object_loader.d.ts +0 -0
  170. /package/{dist/core → core}/loaders/object_loader.js +0 -0
  171. /package/{dist/core → core}/loaders/query_loader.d.ts +0 -0
  172. /package/{dist/core → core}/loaders/query_loader.js +0 -0
  173. /package/{dist/core → core}/loaders/raw_count_loader.d.ts +0 -0
  174. /package/{dist/core → core}/loaders/raw_count_loader.js +0 -0
  175. /package/{dist/core → core}/logger.d.ts +0 -0
  176. /package/{dist/core → core}/logger.js +0 -0
  177. /package/{dist/core → core}/privacy.d.ts +0 -0
  178. /package/{dist/core → core}/privacy.js +0 -0
  179. /package/{dist/core → core}/query/custom_clause_query.d.ts +0 -0
  180. /package/{dist/core → core}/query/custom_clause_query.js +0 -0
  181. /package/{dist/core → core}/query/custom_query.d.ts +0 -0
  182. /package/{dist/core → core}/query/custom_query.js +0 -0
  183. /package/{dist/core → core}/query/index.d.ts +0 -0
  184. /package/{dist/core → core}/query/index.js +0 -0
  185. /package/{dist/core → core}/query_impl.d.ts +0 -0
  186. /package/{dist/core → core}/query_impl.js +0 -0
  187. /package/{dist/core → core}/viewer.d.ts +0 -0
  188. /package/{dist/core → core}/viewer.js +0 -0
  189. /package/{dist/graphql → graphql}/builtins/connection.d.ts +0 -0
  190. /package/{dist/graphql → graphql}/builtins/connection.js +0 -0
  191. /package/{dist/graphql → graphql}/builtins/edge.d.ts +0 -0
  192. /package/{dist/graphql → graphql}/builtins/edge.js +0 -0
  193. /package/{dist/graphql → graphql}/builtins/node.d.ts +0 -0
  194. /package/{dist/graphql → graphql}/builtins/node.js +0 -0
  195. /package/{dist/graphql → graphql}/graphql.d.ts +0 -0
  196. /package/{dist/graphql → graphql}/graphql.js +0 -0
  197. /package/{dist/graphql → graphql}/graphql_field_helpers.d.ts +0 -0
  198. /package/{dist/graphql → graphql}/graphql_field_helpers.js +0 -0
  199. /package/{dist/graphql → graphql}/index.d.ts +0 -0
  200. /package/{dist/graphql → graphql}/index.js +0 -0
  201. /package/{dist/graphql → graphql}/mutations/union.d.ts +0 -0
  202. /package/{dist/graphql → graphql}/mutations/union.js +0 -0
  203. /package/{dist/graphql → graphql}/node_resolver.d.ts +0 -0
  204. /package/{dist/graphql → graphql}/node_resolver.js +0 -0
  205. /package/{dist/graphql → graphql}/query/connection_type.d.ts +0 -0
  206. /package/{dist/graphql → graphql}/query/connection_type.js +0 -0
  207. /package/{dist/graphql → graphql}/query/edge_connection.d.ts +0 -0
  208. /package/{dist/graphql → graphql}/query/edge_connection.js +0 -0
  209. /package/{dist/graphql → graphql}/query/page_info.d.ts +0 -0
  210. /package/{dist/graphql → graphql}/query/page_info.js +0 -0
  211. /package/{dist/graphql → graphql}/query/shared_edge_connection.d.ts +0 -0
  212. /package/{dist/graphql → graphql}/query/shared_edge_connection.js +0 -0
  213. /package/{dist/graphql → graphql}/scalars/orderby_direction.d.ts +0 -0
  214. /package/{dist/graphql → graphql}/scalars/orderby_direction.js +0 -0
  215. /package/{dist/graphql → graphql}/scalars/time.d.ts +0 -0
  216. /package/{dist/graphql → graphql}/scalars/time.js +0 -0
  217. /package/{dist/imports → imports}/dataz/example1/_auth.d.ts +0 -0
  218. /package/{dist/imports → imports}/dataz/example1/_auth.js +0 -0
  219. /package/{dist/imports → imports}/dataz/example1/_viewer.d.ts +0 -0
  220. /package/{dist/imports → imports}/dataz/example1/_viewer.js +0 -0
  221. /package/{dist/imports → imports}/index.d.ts +0 -0
  222. /package/{dist/imports → imports}/index.js +0 -0
  223. /package/{dist/index.d.ts → index.d.ts} +0 -0
  224. /package/{dist/index.js → index.js} +0 -0
  225. /package/{dist/parse_schema → parse_schema}/parse.d.ts +0 -0
  226. /package/{dist/parse_schema → parse_schema}/parse.js +0 -0
  227. /package/{dist/schema → schema}/base_schema.d.ts +0 -0
  228. /package/{dist/schema → schema}/base_schema.js +0 -0
  229. /package/{dist/schema → schema}/field.d.ts +0 -0
  230. /package/{dist/schema → schema}/field.js +0 -0
  231. /package/{dist/schema → schema}/index.d.ts +0 -0
  232. /package/{dist/schema → schema}/index.js +0 -0
  233. /package/{dist/schema → schema}/json_field.d.ts +0 -0
  234. /package/{dist/schema → schema}/json_field.js +0 -0
  235. /package/{dist/schema → schema}/schema.d.ts +0 -0
  236. /package/{dist/schema → schema}/schema.js +0 -0
  237. /package/{dist/schema → schema}/struct_field.d.ts +0 -0
  238. /package/{dist/schema → schema}/struct_field.js +0 -0
  239. /package/{dist/schema → schema}/union_field.d.ts +0 -0
  240. /package/{dist/schema → schema}/union_field.js +0 -0
  241. /package/{dist/scripts → scripts}/custom_compiler.d.ts +0 -0
  242. /package/{dist/scripts → scripts}/custom_compiler.js +0 -0
  243. /package/{dist/scripts → scripts}/custom_graphql.d.ts +0 -0
  244. /package/{dist/scripts → scripts}/custom_graphql.js +0 -0
  245. /package/{dist/scripts → scripts}/migrate_v0.1.d.ts +0 -0
  246. /package/{dist/scripts → scripts}/migrate_v0.1.js +0 -0
  247. /package/{dist/scripts → scripts}/move_types.d.ts +0 -0
  248. /package/{dist/scripts → scripts}/move_types.js +0 -0
  249. /package/{dist/scripts → scripts}/read_schema.d.ts +0 -0
  250. /package/{dist/scripts → scripts}/read_schema.js +0 -0
  251. /package/{dist/testutils → testutils}/action/complex_schemas.d.ts +0 -0
  252. /package/{dist/testutils → testutils}/action/complex_schemas.js +0 -0
  253. /package/{dist/testutils → testutils}/builder.d.ts +0 -0
  254. /package/{dist/testutils → testutils}/builder.js +0 -0
  255. /package/{dist/testutils → testutils}/context/test_context.d.ts +0 -0
  256. /package/{dist/testutils → testutils}/context/test_context.js +0 -0
  257. /package/{dist/testutils → testutils}/db/fixture.d.ts +0 -0
  258. /package/{dist/testutils → testutils}/db/fixture.js +0 -0
  259. /package/{dist/testutils → testutils}/db/temp_db.d.ts +0 -0
  260. /package/{dist/testutils → testutils}/db/temp_db.js +0 -0
  261. /package/{dist/testutils → testutils}/db/value.d.ts +0 -0
  262. /package/{dist/testutils → testutils}/db/value.js +0 -0
  263. /package/{dist/testutils → testutils}/db_mock.d.ts +0 -0
  264. /package/{dist/testutils → testutils}/db_mock.js +0 -0
  265. /package/{dist/testutils → testutils}/db_time_zone.d.ts +0 -0
  266. /package/{dist/testutils → testutils}/db_time_zone.js +0 -0
  267. /package/{dist/testutils → testutils}/ent-graphql-tests/index.d.ts +0 -0
  268. /package/{dist/testutils → testutils}/ent-graphql-tests/index.js +0 -0
  269. /package/{dist/testutils → testutils}/fake_comms.d.ts +0 -0
  270. /package/{dist/testutils → testutils}/fake_comms.js +0 -0
  271. /package/{dist/testutils → testutils}/fake_data/const.d.ts +0 -0
  272. /package/{dist/testutils → testutils}/fake_data/const.js +0 -0
  273. /package/{dist/testutils → testutils}/fake_data/events_query.d.ts +0 -0
  274. /package/{dist/testutils → testutils}/fake_data/events_query.js +0 -0
  275. /package/{dist/testutils → testutils}/fake_data/fake_contact.d.ts +0 -0
  276. /package/{dist/testutils → testutils}/fake_data/fake_contact.js +0 -0
  277. /package/{dist/testutils → testutils}/fake_data/fake_event.d.ts +0 -0
  278. /package/{dist/testutils → testutils}/fake_data/fake_event.js +0 -0
  279. /package/{dist/testutils → testutils}/fake_data/fake_tag.d.ts +0 -0
  280. /package/{dist/testutils → testutils}/fake_data/fake_tag.js +0 -0
  281. /package/{dist/testutils → testutils}/fake_data/fake_user.d.ts +0 -0
  282. /package/{dist/testutils → testutils}/fake_data/fake_user.js +0 -0
  283. /package/{dist/testutils → testutils}/fake_data/index.d.ts +0 -0
  284. /package/{dist/testutils → testutils}/fake_data/index.js +0 -0
  285. /package/{dist/testutils → testutils}/fake_data/internal.d.ts +0 -0
  286. /package/{dist/testutils → testutils}/fake_data/internal.js +0 -0
  287. /package/{dist/testutils → testutils}/fake_data/tag_query.d.ts +0 -0
  288. /package/{dist/testutils → testutils}/fake_data/tag_query.js +0 -0
  289. /package/{dist/testutils → testutils}/fake_data/test_helpers.d.ts +0 -0
  290. /package/{dist/testutils → testutils}/fake_data/user_query.d.ts +0 -0
  291. /package/{dist/testutils → testutils}/fake_data/user_query.js +0 -0
  292. /package/{dist/testutils → testutils}/fake_log.d.ts +0 -0
  293. /package/{dist/testutils → testutils}/fake_log.js +0 -0
  294. /package/{dist/testutils → testutils}/mock_date.d.ts +0 -0
  295. /package/{dist/testutils → testutils}/mock_date.js +0 -0
  296. /package/{dist/testutils → testutils}/mock_log.d.ts +0 -0
  297. /package/{dist/testutils → testutils}/mock_log.js +0 -0
  298. /package/{dist/testutils → testutils}/parse_sql.d.ts +0 -0
  299. /package/{dist/testutils → testutils}/parse_sql.js +0 -0
  300. /package/{dist/testutils → testutils}/test_edge_global_schema.d.ts +0 -0
  301. /package/{dist/testutils → testutils}/test_edge_global_schema.js +0 -0
  302. /package/{dist/testutils → testutils}/write.d.ts +0 -0
  303. /package/{dist/testutils → testutils}/write.js +0 -0
  304. /package/{dist/tsc → tsc}/ast.d.ts +0 -0
  305. /package/{dist/tsc → tsc}/ast.js +0 -0
  306. /package/{dist/tsc → tsc}/compilerOptions.d.ts +0 -0
  307. /package/{dist/tsc → tsc}/compilerOptions.js +0 -0
  308. /package/{dist/tsc → tsc}/move_generated.d.ts +0 -0
  309. /package/{dist/tsc → tsc}/move_generated.js +0 -0
  310. /package/{dist/tsc → tsc}/transform.d.ts +0 -0
  311. /package/{dist/tsc → tsc}/transform.js +0 -0
  312. /package/{dist/tsc → tsc}/transform_action.d.ts +0 -0
  313. /package/{dist/tsc → tsc}/transform_action.js +0 -0
  314. /package/{dist/tsc → tsc}/transform_ent.d.ts +0 -0
  315. /package/{dist/tsc → tsc}/transform_ent.js +0 -0
  316. /package/{dist/tsc → tsc}/transform_schema.d.ts +0 -0
  317. /package/{dist/tsc → tsc}/transform_schema.js +0 -0
@@ -1,1065 +0,0 @@
1
- import { Data, ID, SelectDataOptions } from "./base";
2
- import DB, { Dialect } from "./db";
3
-
4
- // NOTE: we use ? for sqlite dialect even though it supports $1 like postgres so that it'll be easier to support different dialects down the line
5
-
6
- export interface Clause<T extends Data = Data, K = keyof T> {
7
- clause(idx: number): string;
8
- columns(): K[];
9
- values(): any[];
10
- instanceKey(): string;
11
- // values to log when querying
12
- logValues(): any[];
13
- // to indicate if a composite clause e.g. combining multiple things
14
- // one such reason is to be used by other composite clauses to know if to add parens
15
- // around a clause to ensure order of operations is met
16
- compositeOp?: string; // e.g. AND, OR etc
17
- }
18
-
19
- export interface SensitiveValue {
20
- value(): any;
21
- logValue(): any;
22
- }
23
-
24
- function isSensitive(val: any): val is SensitiveValue {
25
- return (
26
- val !== null &&
27
- typeof val === "object" &&
28
- (val as SensitiveValue).logValue !== undefined
29
- );
30
- }
31
-
32
- function rawValue(val: any) {
33
- if (isSensitive(val)) {
34
- return val.value();
35
- }
36
- return val;
37
- }
38
-
39
- class simpleClause<T extends Data, K = keyof T> implements Clause<T, K> {
40
- constructor(
41
- protected col: K,
42
- private value: any,
43
- private op: string,
44
- private handleNull?: Clause<T, K>,
45
- ) {}
46
-
47
- clause(idx: number): string {
48
- const nullClause = this.nullClause();
49
- if (nullClause) {
50
- return nullClause.clause(idx);
51
- }
52
- if (DB.getDialect() === Dialect.Postgres) {
53
- return `${this.col} ${this.op} $${idx}`;
54
- }
55
- return `${this.col} ${this.op} ?`;
56
- }
57
-
58
- private nullClause() {
59
- if (!this.handleNull || this.value !== null) {
60
- return;
61
- }
62
- return this.handleNull;
63
- }
64
-
65
- columns(): K[] {
66
- return [this.col];
67
- }
68
-
69
- values(): any[] {
70
- const nullClause = this.nullClause();
71
- if (nullClause) {
72
- return nullClause.values();
73
- }
74
- if (isSensitive(this.value)) {
75
- return [this.value.value()];
76
- }
77
- return [this.value];
78
- }
79
-
80
- logValues(): any[] {
81
- const nullClause = this.nullClause();
82
- if (nullClause) {
83
- return nullClause.logValues();
84
- }
85
- if (isSensitive(this.value)) {
86
- return [this.value.logValue()];
87
- }
88
- return [this.value];
89
- }
90
-
91
- instanceKey(): string {
92
- const nullClause = this.nullClause();
93
- if (nullClause) {
94
- return nullClause.instanceKey();
95
- }
96
- return `${this.col}${this.op}${rawValue(this.value)}`;
97
- }
98
- }
99
-
100
- class isNullClause<T extends Data, K = keyof T> implements Clause<T, K> {
101
- constructor(protected col: K) {}
102
-
103
- clause(_idx: number): string {
104
- return `${this.col} IS NULL`;
105
- }
106
-
107
- columns(): K[] {
108
- return [];
109
- }
110
-
111
- values(): any[] {
112
- return [];
113
- }
114
-
115
- logValues(): any[] {
116
- return [];
117
- }
118
-
119
- instanceKey(): string {
120
- return `${this.col} IS NULL`;
121
- }
122
- }
123
-
124
- class isNotNullClause<T extends Data, K = keyof T> implements Clause<T, K> {
125
- constructor(protected col: K) {}
126
-
127
- clause(idx: number): string {
128
- return `${this.col} IS NOT NULL`;
129
- }
130
-
131
- columns(): K[] {
132
- return [];
133
- }
134
-
135
- values(): any[] {
136
- return [];
137
- }
138
-
139
- logValues(): any[] {
140
- return [];
141
- }
142
-
143
- instanceKey(): string {
144
- return `${this.col} IS NOT NULL`;
145
- }
146
- }
147
-
148
- class arraySimpleClause<T extends Data, K = keyof T> implements Clause<T, K> {
149
- constructor(protected col: K, private value: any, private op: string) {}
150
-
151
- clause(idx: number): string {
152
- if (DB.getDialect() === Dialect.Postgres) {
153
- return `$${idx} ${this.op} ANY(${this.col})`;
154
- }
155
- return `${this.col} ${this.op} ?`;
156
- }
157
-
158
- columns(): K[] {
159
- return [this.col];
160
- }
161
-
162
- values(): any[] {
163
- if (isSensitive(this.value)) {
164
- return [this.value.value()];
165
- }
166
- return [this.value];
167
- }
168
-
169
- logValues(): any[] {
170
- if (isSensitive(this.value)) {
171
- return [this.value.logValue()];
172
- }
173
- return [this.value];
174
- }
175
-
176
- instanceKey(): string {
177
- return `${this.col}${this.op}${rawValue(this.value)}`;
178
- }
179
- }
180
-
181
- class postgresArrayOperator<T extends Data, K = keyof T>
182
- implements Clause<T, K>
183
- {
184
- constructor(
185
- protected col: K,
186
- protected value: any,
187
- private op: string,
188
- private not?: boolean,
189
- ) {}
190
-
191
- clause(idx: number): string {
192
- if (DB.getDialect() === Dialect.Postgres) {
193
- if (this.not) {
194
- return `NOT ${this.col} ${this.op} $${idx}`;
195
- }
196
- return `${this.col} ${this.op} $${idx}`;
197
- }
198
- throw new Error(`not supported`);
199
- }
200
-
201
- columns(): K[] {
202
- return [this.col];
203
- }
204
-
205
- values(): any[] {
206
- if (isSensitive(this.value)) {
207
- return [`{${this.value.value()}}`];
208
- }
209
- return [`{${this.value}}`];
210
- }
211
-
212
- logValues(): any[] {
213
- if (isSensitive(this.value)) {
214
- return [`{${this.value.logValue()}}`];
215
- }
216
- return [`{${this.value}}`];
217
- }
218
-
219
- instanceKey(): string {
220
- if (this.not) {
221
- return `NOT:${this.col}${this.op}${rawValue(this.value)}`;
222
- }
223
- return `${this.col}${this.op}${rawValue(this.value)}`;
224
- }
225
- }
226
-
227
- class postgresArrayOperatorList<
228
- T extends Data,
229
- K = keyof T,
230
- > extends postgresArrayOperator<T, K> {
231
- constructor(col: K, value: any[], op: string, not?: boolean) {
232
- super(col, value, op, not);
233
- }
234
-
235
- values(): any[] {
236
- return [
237
- `{${this.value
238
- .map((v: any) => {
239
- if (isSensitive(v)) {
240
- return v.value();
241
- }
242
- return v;
243
- })
244
- .join(", ")}}`,
245
- ];
246
- }
247
-
248
- logValues(): any[] {
249
- return [
250
- `{${this.value
251
- .map((v: any) => {
252
- if (isSensitive(v)) {
253
- return v.logValue();
254
- }
255
- return v;
256
- })
257
- .join(", ")}}`,
258
- ];
259
- }
260
- }
261
-
262
- type InClauseOperator = "IN" | "NOT IN";
263
-
264
- export class inClause<T extends Data, K = keyof T> implements Clause<T, K> {
265
- protected op: InClauseOperator = "IN";
266
-
267
- static getPostgresInClauseValuesThreshold() {
268
- return 70;
269
- }
270
-
271
- constructor(private col: K, private value: any[], private type = "uuid") {}
272
-
273
- clause(idx: number): string {
274
- // do a simple = when only one item
275
- if (this.value.length === 1) {
276
- if (this.op === "IN") {
277
- return new simpleClause(this.col, this.value[0], "=").clause(idx);
278
- } else {
279
- return new simpleClause(this.col, this.value[0], "!=").clause(idx);
280
- }
281
- }
282
-
283
- const postgres = DB.getDialect() === Dialect.Postgres;
284
- const postgresValuesList =
285
- postgres &&
286
- this.value.length >= inClause.getPostgresInClauseValuesThreshold();
287
-
288
- let indices: string[];
289
- if (postgres) {
290
- indices = [];
291
- for (let i = 0; i < this.value.length; i++) {
292
- if (postgresValuesList) {
293
- if (i === 0) {
294
- indices.push(`($${idx}::${this.type})`);
295
- } else {
296
- indices.push(`($${idx})`);
297
- }
298
- } else {
299
- indices.push(`$${idx}`);
300
- }
301
- idx++;
302
- }
303
- } else {
304
- indices = new Array(this.value.length);
305
- indices.fill("?", 0);
306
- }
307
-
308
- let inValue = indices.join(", ");
309
-
310
- // wrap in VALUES list for postgres...
311
- if (postgresValuesList) {
312
- inValue = `VALUES${inValue}`;
313
- }
314
-
315
- return `${this.col} ${this.op} (${inValue})`;
316
- // TODO we need to return idx at end to query builder...
317
- // or anything that's doing a composite query so next clause knows where to start
318
- // or change to a sqlx.Rebind format
319
- // here's what sqlx does: https://play.golang.org/p/vPzvYqeAcP0
320
- }
321
-
322
- columns(): K[] {
323
- return [this.col];
324
- }
325
-
326
- values(): any[] {
327
- const result: any[] = [];
328
- for (let value of this.value) {
329
- result.push(rawValue(value));
330
- }
331
- return result;
332
- }
333
-
334
- logValues(): any[] {
335
- const result: any[] = [];
336
- for (let value of this.value) {
337
- result.push(isSensitive(value) ? value.logValue() : value);
338
- }
339
- return result;
340
- }
341
-
342
- instanceKey(): string {
343
- return `${this.op.toLowerCase()}:${this.col}:${this.values().join(",")}`;
344
- }
345
- }
346
-
347
- export class notInClause<T extends Data, K = keyof T> extends inClause<T, K> {
348
- protected op: InClauseOperator = "NOT IN";
349
- }
350
-
351
- class compositeClause<T extends Data, K = keyof T> implements Clause<T, K> {
352
- compositeOp: string;
353
-
354
- constructor(private clauses: Clause<T, K>[], private sep: string) {
355
- this.compositeOp = this.sep;
356
- }
357
-
358
- clause(idx: number): string {
359
- let clauses: string[] = [];
360
- for (const clause of this.clauses) {
361
- let cls = clause.clause(idx);
362
- // if composite clause and a different op, add parens so that we enforce order of precedence
363
- if (clause.compositeOp && clause.compositeOp !== this.sep) {
364
- cls = `(${cls})`;
365
- }
366
- clauses.push(cls);
367
- idx = idx + clause.values().length;
368
- }
369
- return clauses.join(this.sep);
370
- }
371
-
372
- columns(): K[] {
373
- const ret: K[] = [];
374
- for (const cls of this.clauses) {
375
- ret.push(...cls.columns());
376
- }
377
- return ret;
378
- }
379
-
380
- values(): any[] {
381
- let result = [];
382
- for (const clause of this.clauses) {
383
- result = result.concat(...clause.values());
384
- }
385
- return result;
386
- }
387
-
388
- logValues(): any[] {
389
- let result = [];
390
- for (const clause of this.clauses) {
391
- result = result.concat(...clause.logValues());
392
- }
393
- return result;
394
- }
395
-
396
- instanceKey(): string {
397
- let keys: string[] = [];
398
- this.clauses.forEach((clause) => {
399
- if (clause.compositeOp && clause.compositeOp != this.sep) {
400
- keys.push(`(${clause.instanceKey()})`);
401
- } else {
402
- keys.push(clause.instanceKey());
403
- }
404
- });
405
- return keys.join(this.sep);
406
- }
407
- }
408
-
409
- class tsQueryClause<T extends Data, K = keyof T> implements Clause<T, K> {
410
- constructor(
411
- protected col: K,
412
- protected val: string | TsQuery,
413
- private tsVectorCol?: boolean,
414
- ) {}
415
-
416
- private isTsQuery(val: string | TsQuery): val is TsQuery {
417
- return typeof val !== "string";
418
- }
419
-
420
- protected getInfo() {
421
- if (this.isTsQuery(this.val)) {
422
- return { value: this.val.value, language: this.val.language };
423
- }
424
- return {
425
- language: "english",
426
- value: this.val,
427
- };
428
- }
429
-
430
- clause(idx: number): string {
431
- const { language } = this.getInfo();
432
- if (Dialect.Postgres === DB.getDialect()) {
433
- if (this.tsVectorCol) {
434
- return `to_tsvector(${
435
- this.col
436
- }) @@ ${this.getFunction()}('${language}', $${idx})`;
437
- }
438
- return `${this.col} @@ ${this.getFunction()}('${language}', $${idx})`;
439
- }
440
- // FYI this doesn't actually work for sqlite since different
441
- return `${this.col} @@ ${this.getFunction()}('${language}', ?)`;
442
- }
443
-
444
- columns(): K[] {
445
- return [this.col];
446
- }
447
-
448
- values(): any[] {
449
- const { value } = this.getInfo();
450
- return [value];
451
- }
452
-
453
- logValues(): any[] {
454
- const { value } = this.getInfo();
455
- return [value];
456
- }
457
-
458
- protected getFunction(): string {
459
- return "to_tsquery";
460
- }
461
-
462
- instanceKey(): string {
463
- const { language, value } = this.getInfo();
464
- if (this.tsVectorCol) {
465
- return `to_tsvector(${
466
- this.col
467
- })@@${this.getFunction()}:${language}:${value}`;
468
- }
469
- return `${this.col}@@${this.getFunction()}:${language}:${value}`;
470
- }
471
- }
472
-
473
- class plainToTsQueryClause<T extends Data, K = keyof T> extends tsQueryClause<
474
- T,
475
- K
476
- > {
477
- protected getFunction(): string {
478
- return "plainto_tsquery";
479
- }
480
- }
481
-
482
- class phraseToTsQueryClause<T extends Data, K = keyof T> extends tsQueryClause<
483
- T,
484
- K
485
- > {
486
- protected getFunction(): string {
487
- return "phraseto_tsquery";
488
- }
489
- }
490
-
491
- class websearchTosQueryClause<
492
- T extends Data,
493
- K = keyof T,
494
- > extends tsQueryClause<T, K> {
495
- protected getFunction(): string {
496
- return "websearch_to_tsquery";
497
- }
498
- }
499
-
500
- // postgres array operators
501
- // https://www.postgresql.org/docs/current/functions-array.html
502
-
503
- /**
504
- * creates a clause to determine if the given value is contained in the array stored in the column in the db
505
- * only works with postgres gin indexes
506
- * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
507
- */
508
- export function PostgresArrayContainsValue<T extends Data, K = keyof T>(
509
- col: K,
510
- value: any,
511
- ): Clause<T, K> {
512
- return new postgresArrayOperator(col, value, "@>");
513
- }
514
-
515
- /**
516
- * creates a clause to determine if every item in the list is stored in the array stored in the column in the db
517
- * only works with postgres gin indexes
518
- * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
519
- */
520
- export function PostgresArrayContains<T extends Data, K = keyof T>(
521
- col: K,
522
- value: any[],
523
- ): Clause<T, K> {
524
- return new postgresArrayOperatorList(col, value, "@>");
525
- }
526
-
527
- /**
528
- * creates a clause to determine if the given value is NOT contained in the array stored in the column in the db
529
- * only works with postgres gin indexes
530
- * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
531
- */
532
- export function PostgresArrayNotContainsValue<T extends Data, K = keyof T>(
533
- col: K,
534
- value: any,
535
- ): Clause<T, K> {
536
- return new postgresArrayOperator(col, value, "@>", true);
537
- }
538
-
539
- /**
540
- * creates a clause to determine if every item in the list is NOT stored in the array stored in the column in the db
541
- * only works with postgres gin indexes
542
- * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
543
- */
544
- export function PostgresArrayNotContains<T extends Data, K = keyof T>(
545
- col: K,
546
- value: any[],
547
- ): Clause<T, K> {
548
- return new postgresArrayOperatorList(col, value, "@>", true);
549
- }
550
-
551
- /**
552
- * creates a clause to determine if the arrays overlap, that is, do they have any elements in common
553
- * only works with postgres gin indexes
554
- * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
555
- */
556
- export function PostgresArrayOverlaps<T extends Data, K = keyof T>(
557
- col: K,
558
- value: any[],
559
- ): Clause<T, K> {
560
- return new postgresArrayOperatorList(col, value, "&&");
561
- }
562
-
563
- /**
564
- * creates a clause to determine if the arrays do not overlap, that is, do they have any elements in common
565
- * only works with postgres gin indexes
566
- * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
567
- */
568
- export function PostgresArrayNotOverlaps<T extends Data, K = keyof T>(
569
- col: K,
570
- value: any[],
571
- ): Clause<T, K> {
572
- return new postgresArrayOperatorList(col, value, "&&", true);
573
- }
574
-
575
- /**
576
- * @deprecated use PostgresArrayContainsValue
577
- */
578
- export function ArrayEq<T extends Data, K = keyof T>(
579
- col: K,
580
- value: any,
581
- ): Clause<T, K> {
582
- return new arraySimpleClause(col, value, "=");
583
- }
584
-
585
- /**
586
- * @deprecated use PostgresNotArrayContains
587
- */
588
- export function ArrayNotEq<T extends Data, K = keyof T>(
589
- col: K,
590
- value: any,
591
- ): Clause<T, K> {
592
- return new arraySimpleClause(col, value, "!=");
593
- }
594
-
595
- export function Eq<T extends Data, K = keyof T>(
596
- col: K,
597
- value: any,
598
- ): Clause<T, K> {
599
- return new simpleClause<T, K>(col, value, "=", new isNullClause(col));
600
- }
601
-
602
- export function NotEq<T extends Data, K = keyof T>(
603
- col: K,
604
- value: any,
605
- ): Clause<T, K> {
606
- return new simpleClause<T, K>(col, value, "!=", new isNotNullClause(col));
607
- }
608
-
609
- export function Greater<T extends Data, K = keyof T>(
610
- col: K,
611
- value: any,
612
- ): Clause<T, K> {
613
- return new simpleClause<T, K>(col, value, ">");
614
- }
615
-
616
- export function Less<T extends Data, K = keyof T>(
617
- col: K,
618
- value: any,
619
- ): Clause<T, K> {
620
- return new simpleClause<T, K>(col, value, "<");
621
- }
622
-
623
- export function GreaterEq<T extends Data, K = keyof T>(
624
- col: K,
625
- value: any,
626
- ): Clause<T, K> {
627
- return new simpleClause<T, K>(col, value, ">=");
628
- }
629
-
630
- export function LessEq<T extends Data, K = keyof T>(
631
- col: K,
632
- value: any,
633
- ): Clause<T, K> {
634
- return new simpleClause<T, K>(col, value, "<=");
635
- }
636
-
637
- export function And<T extends Data, K = keyof T>(
638
- ...args: Clause<T, K>[]
639
- ): Clause<T, K> {
640
- return new compositeClause(args, " AND ");
641
- }
642
-
643
- export function AndOptional<T extends Data, K = keyof T>(
644
- ...args: (Clause<T, K> | undefined)[]
645
- ): Clause<T, K> {
646
- // @ts-ignore
647
- let filtered: Clause<T, K>[] = args.filter((v) => v !== undefined);
648
- if (filtered.length === 1) {
649
- return filtered[0];
650
- }
651
- return And(...filtered);
652
- }
653
-
654
- export function Or<T extends Data, K = keyof T>(
655
- ...args: Clause<T, K>[]
656
- ): Clause<T, K> {
657
- return new compositeClause(args, " OR ");
658
- }
659
-
660
- export function OrOptional<T extends Data, K = keyof T>(
661
- ...args: (Clause<T, K> | undefined)[]
662
- ): Clause<T, K> {
663
- // @ts-ignore
664
- let filtered: Clause<T, K>[] = args.filter((v) => v !== undefined);
665
- if (filtered.length === 1) {
666
- return filtered[0];
667
- }
668
- return Or(...filtered);
669
- }
670
-
671
- /**
672
- * @deprecated use UUidIn, TextIn, IntegerIn, or TypeIn
673
- */
674
- export function In<T extends Data, K = keyof T>(
675
- col: K,
676
- ...values: any
677
- ): Clause<T, K>;
678
-
679
- /**
680
- * @deprecated use UUidIn, TextIn, IntegerIn, or TypeIn
681
- */
682
- export function In<T extends Data, K = keyof T>(
683
- col: K,
684
- values: any[],
685
- type?: string,
686
- ): Clause<T, K>;
687
-
688
- export function In<T extends Data, K = keyof T>(...args: any[]): Clause<T, K> {
689
- if (args.length < 2) {
690
- throw new Error(`invalid args passed to In`);
691
- }
692
- // 2nd overload
693
- if (Array.isArray(args[1])) {
694
- return new inClause(args[0], args[1], args[2]);
695
- }
696
- return new inClause(args[0], args.slice(1));
697
- }
698
-
699
- export function UuidIn<T extends Data, K = keyof T>(
700
- col: K,
701
- values: ID[],
702
- ): Clause<T, K> {
703
- return new inClause(col, values, "uuid");
704
- }
705
-
706
- export function IntegerIn<T extends Data, K = keyof T>(
707
- col: K,
708
- values: number[],
709
- ): Clause<T, K> {
710
- return new inClause(col, values, "integer");
711
- }
712
-
713
- export function TextIn<T extends Data, K = keyof T>(
714
- col: K,
715
- values: any[],
716
- ): Clause<T, K> {
717
- return new inClause(col, values, "text");
718
- }
719
-
720
- /*
721
- * if not uuid or text, pass the db type that can be used to cast this query
722
- * if we end up with a large list of ids
723
- */
724
- export function DBTypeIn<T extends Data, K = keyof T>(
725
- col: K,
726
- values: any[],
727
- typ: string,
728
- ): Clause<T, K> {
729
- return new inClause(col, values, typ);
730
- }
731
-
732
- export function UuidNotIn<T extends Data, K = keyof T>(
733
- col: K,
734
- values: ID[],
735
- ): Clause<T, K> {
736
- return new notInClause(col, values, "uuid");
737
- }
738
-
739
- export function IntegerNotIn<T extends Data, K = keyof T>(
740
- col: K,
741
- values: number[],
742
- ): Clause<T, K> {
743
- return new notInClause(col, values, "integer");
744
- }
745
-
746
- export function TextNotIn<T extends Data, K = keyof T>(
747
- col: K,
748
- values: any[],
749
- ): Clause<T, K> {
750
- return new notInClause(col, values, "text");
751
- }
752
-
753
- /*
754
- * if not uuid or text, pass the db type that can be used to cast this query
755
- * if we end up with a large list of ids
756
- */
757
- export function DBTypeNotIn<T extends Data, K = keyof T>(
758
- col: K,
759
- values: any[],
760
- typ: string,
761
- ): Clause<T, K> {
762
- return new notInClause(col, values, typ);
763
- }
764
-
765
- interface TsQuery {
766
- // todo lang ::reconfig
767
- language: "english" | "french" | "german" | "simple";
768
- value: string;
769
- }
770
-
771
- // if string defaults to english
772
- // https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES
773
- // to_tsquery
774
- // plainto_tsquery
775
- // phraseto_tsquery;
776
- // websearch_to_tsquery
777
- export function TsQuery<T extends Data, K = keyof T>(
778
- col: K,
779
- val: string | TsQuery,
780
- ): Clause<T, K> {
781
- return new tsQueryClause(col, val);
782
- }
783
-
784
- export function PlainToTsQuery<T extends Data, K = keyof T>(
785
- col: K,
786
- val: string | TsQuery,
787
- ): Clause<T, K> {
788
- return new plainToTsQueryClause(col, val);
789
- }
790
-
791
- export function PhraseToTsQuery<T extends Data, K = keyof T>(
792
- col: K,
793
- val: string | TsQuery,
794
- ): Clause<T, K> {
795
- return new phraseToTsQueryClause(col, val);
796
- }
797
-
798
- export function WebsearchToTsQuery<T extends Data, K = keyof T>(
799
- col: K,
800
- val: string | TsQuery,
801
- ): Clause<T, K> {
802
- return new websearchTosQueryClause(col, val);
803
- }
804
-
805
- // TsVectorColTsQuery is used when the column is not a tsvector field e.g.
806
- // when there's an index just on the field and is not a combination of multiple fields
807
- export function TsVectorColTsQuery<T extends Data, K = keyof T>(
808
- col: K,
809
- val: string | TsQuery,
810
- ): Clause<T, K> {
811
- return new tsQueryClause(col, val, true);
812
- }
813
-
814
- // TsVectorPlainToTsQuery is used when the column is not a tsvector field e.g.
815
- // when there's an index just on the field and is not a combination of multiple fields
816
- // TODO do these 4 need TsQuery because would be nice to have language?
817
- // it seems to default to the config of the column
818
- export function TsVectorPlainToTsQuery<T extends Data, K = keyof T>(
819
- col: K,
820
- val: string | TsQuery,
821
- ): Clause<T, K> {
822
- return new plainToTsQueryClause(col, val, true);
823
- }
824
-
825
- // TsVectorPhraseToTsQuery is used when the column is not a tsvector field e.g.
826
- // when there's an index just on the field and is not a combination of multiple fields
827
- export function TsVectorPhraseToTsQuery<T extends Data, K = keyof T>(
828
- col: K,
829
- val: string | TsQuery,
830
- ): Clause<T, K> {
831
- return new phraseToTsQueryClause(col, val, true);
832
- }
833
-
834
- // TsVectorWebsearchToTsQuery is used when the column is not a tsvector field e.g.
835
- // when there's an index just on the field and is not a combination of multiple fields
836
- export function TsVectorWebsearchToTsQuery<T extends Data, K = keyof T>(
837
- col: K,
838
- val: string | TsQuery,
839
- ): Clause<T, K> {
840
- return new websearchTosQueryClause(col, val, true);
841
- }
842
-
843
- // TODO would be nice to support this with building blocks but not supporting for now
844
- // AND: foo & bar,
845
- // OR: foo | bar
846
- // followed by: foo <-> bar
847
- // NOT: !foo
848
- // starts_with: theo:*
849
-
850
- // wrap a query in the db with this to ensure that it doesn't show up in the logs
851
- // e.g. if querying for password, SSN, etc
852
- // we'll pass the right fields to query and log something along the lines of `****`
853
- export function sensitiveValue(val: any): SensitiveValue {
854
- return {
855
- value() {
856
- return val;
857
- },
858
- logValue() {
859
- return "*".repeat(`${val}`.length);
860
- },
861
- };
862
- }
863
-
864
- // These don't return Clauses but return helpful things that can be passed to clauses
865
-
866
- // https://www.postgresql.org/docs/12/functions-json.html#FUNCTIONS-JSON-OP-TABLE
867
- // see test in db_clause.test.ts
868
- // unclear best time to use this...
869
- export function JSONObjectFieldKeyASJSON<T extends Data, K = keyof T>(
870
- col: K,
871
- field: string,
872
- ): keyof T {
873
- // type as keyof T to make it easier to use in other queries
874
- return `${col}->'${field}'`;
875
- }
876
-
877
- export function JSONObjectFieldKeyAsText<T extends Data, K = keyof T>(
878
- col: K,
879
- field: string,
880
- ): keyof T {
881
- // type as keyof T to make it easier to use in other queries
882
- return `${col}->>'${field}'`;
883
- }
884
-
885
- // can't get this to work...
886
- // https://www.postgresql.org/docs/12/functions-json.html#FUNCTIONS-JSON-OP-TABLE
887
- // export function ArrayIndexAsText(col: string, index: number) {
888
- // return `${col}->>${index}`;
889
- // }
890
-
891
- type predicate = "==" | ">" | "<" | "!=" | ">=" | "<=";
892
-
893
- class jSONPathValuePredicateClause<T extends Data, K = keyof T>
894
- implements Clause<T, K>
895
- {
896
- constructor(
897
- protected col: K,
898
- protected path: string,
899
- protected value: any,
900
- private pred: predicate,
901
- ) {}
902
-
903
- clause(idx: number): string {
904
- if (DB.getDialect() !== Dialect.Postgres) {
905
- throw new Error(`not supported`);
906
- }
907
- return `${this.col} @@ $${idx}`;
908
- }
909
-
910
- columns(): K[] {
911
- return [this.col];
912
- }
913
-
914
- private wrap(val: any) {
915
- return `${this.path} ${this.pred} ${JSON.stringify(val)}`;
916
- }
917
-
918
- values(): any[] {
919
- if (isSensitive(this.value)) {
920
- return [this.wrap(this.value.value())];
921
- }
922
-
923
- return [this.wrap(this.value)];
924
- }
925
-
926
- logValues(): any[] {
927
- if (isSensitive(this.value)) {
928
- return [this.wrap(this.value.logValue())];
929
- }
930
- return [this.wrap(this.value)];
931
- }
932
-
933
- instanceKey(): string {
934
- return `${this.col}${this.path}${rawValue(this.value)}${this.pred}`;
935
- }
936
- }
937
-
938
- // https://www.postgresql.org/docs/12/functions-json.html#FUNCTIONS-JSON-OP-TABLE
939
- export function JSONPathValuePredicate<T extends Data, K = keyof T>(
940
- dbCol: K,
941
- path: string,
942
- val: any,
943
- pred: predicate,
944
- ): Clause<T, K> {
945
- return new jSONPathValuePredicateClause(dbCol, path, val, pred);
946
- }
947
-
948
- // TODO need a better name for this lol
949
- // this assumes we're doing the same direction twice which isn't necessarily accurate in the future...
950
- class paginationMultipleColumnsSubQueryClause<T extends Data, K = keyof T>
951
- implements Clause<T, K>
952
- {
953
- constructor(
954
- private col: K,
955
- private op: string,
956
- private tableName: string,
957
- private uniqueCol: K,
958
- private val: any,
959
- ) {}
960
-
961
- private buildSimpleQuery(clause: Clause<T, K>, idx: number) {
962
- return `SELECT ${this.col} FROM ${this.tableName} WHERE ${clause.clause(
963
- idx,
964
- )}`;
965
- }
966
-
967
- clause(idx: number): string {
968
- const eq1 = this.buildSimpleQuery(Eq(this.uniqueCol, this.val), idx);
969
- const eq2 = this.buildSimpleQuery(Eq(this.uniqueCol, this.val), idx + 1);
970
- const op = new simpleClause(this.uniqueCol, this.val, this.op).clause(
971
- idx + 2,
972
- );
973
-
974
- // nest in () to make sure it's scoped correctly
975
- return `(${this.col} ${this.op} (${eq1}) OR (${this.col} = (${eq2}) AND ${op}))`;
976
- }
977
-
978
- columns(): K[] {
979
- return [this.col];
980
- }
981
-
982
- values(): any[] {
983
- return [this.val, this.val, this.val];
984
- }
985
-
986
- logValues(): any[] {
987
- const log = isSensitive(this.val) ? this.val.logValue() : this.val;
988
- return [log, log, log];
989
- }
990
-
991
- instanceKey(): string {
992
- return `${this.col}-${this.op}-${this.tableName}-${this.uniqueCol}-${this.val}`;
993
- }
994
- }
995
-
996
- export function PaginationMultipleColsSubQuery<T extends Data, K = keyof T>(
997
- col: K,
998
- op: string,
999
- tableName: string,
1000
- uniqueCol: K,
1001
- val: any,
1002
- ): Clause<T, K> {
1003
- return new paginationMultipleColumnsSubQueryClause(
1004
- col,
1005
- op,
1006
- tableName,
1007
- uniqueCol,
1008
- val,
1009
- );
1010
- }
1011
-
1012
- // These 5 are used on the RHS of an expression
1013
- export function Add<T extends Data, K = keyof T>(
1014
- col: K,
1015
- value: any,
1016
- ): Clause<T, K> {
1017
- return new simpleClause(col, value, "+", new isNullClause(col));
1018
- }
1019
-
1020
- export function Subtract<T extends Data, K = keyof T>(
1021
- col: K,
1022
- value: any,
1023
- ): Clause<T, K> {
1024
- return new simpleClause(col, value, "-", new isNullClause(col));
1025
- }
1026
-
1027
- export function Multiply<T extends Data, K = keyof T>(
1028
- col: K,
1029
- value: any,
1030
- ): Clause<T, K> {
1031
- return new simpleClause(col, value, "*", new isNullClause(col));
1032
- }
1033
-
1034
- export function Divide<T extends Data, K = keyof T>(
1035
- col: K,
1036
- value: any,
1037
- ): Clause<T, K> {
1038
- return new simpleClause(col, value, "/", new isNullClause(col));
1039
- }
1040
-
1041
- export function Modulo<T extends Data, K = keyof T>(
1042
- col: K,
1043
- value: any,
1044
- ): Clause<T, K> {
1045
- return new simpleClause(col, value, "%", new isNullClause(col));
1046
- }
1047
-
1048
- export function getCombinedClause<V extends Data = Data, K = keyof V>(
1049
- options: Omit<SelectDataOptions, "key">,
1050
- cls: Clause<V, K>,
1051
- ): Clause<V, K> {
1052
- if (options.clause) {
1053
- let optionClause: Clause | undefined;
1054
- if (typeof options.clause === "function") {
1055
- optionClause = options.clause();
1056
- } else {
1057
- optionClause = options.clause;
1058
- }
1059
- if (optionClause) {
1060
- // @ts-expect-error different types
1061
- cls = And(cls, optionClause);
1062
- }
1063
- }
1064
- return cls;
1065
- }