@abedmurrar/objection 0.0.0-stage → 4.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +105 -2
  3. package/lib/index.mjs +6 -0
  4. package/lib/initialize.js +11 -0
  5. package/lib/model/AjvValidator.js +278 -0
  6. package/lib/model/Model.js +772 -0
  7. package/lib/model/ModifierNotFoundError.js +10 -0
  8. package/lib/model/NotFoundError.js +19 -0
  9. package/lib/model/RelationDoesNotExistError.js +11 -0
  10. package/lib/model/ValidationError.js +46 -0
  11. package/lib/model/Validator.js +20 -0
  12. package/lib/model/getModel.js +7 -0
  13. package/lib/model/graph/ModelGraph.js +60 -0
  14. package/lib/model/graph/ModelGraphBuilder.js +188 -0
  15. package/lib/model/graph/ModelGraphEdge.js +40 -0
  16. package/lib/model/graph/ModelGraphNode.js +201 -0
  17. package/lib/model/inheritModel.js +19 -0
  18. package/lib/model/modelBindKnex.js +69 -0
  19. package/lib/model/modelClone.js +102 -0
  20. package/lib/model/modelColPropMap.js +24 -0
  21. package/lib/model/modelConcurrency.js +24 -0
  22. package/lib/model/modelId.js +57 -0
  23. package/lib/model/modelJsonAttributes.js +72 -0
  24. package/lib/model/modelParseRelations.js +83 -0
  25. package/lib/model/modelQueryProps.js +116 -0
  26. package/lib/model/modelSet.js +116 -0
  27. package/lib/model/modelTableMetadata.js +71 -0
  28. package/lib/model/modelToJson.js +157 -0
  29. package/lib/model/modelUtils.js +40 -0
  30. package/lib/model/modelValidate.js +40 -0
  31. package/lib/model/modelValues.js +113 -0
  32. package/lib/model/modelVisitor.js +34 -0
  33. package/lib/objection.js +89 -0
  34. package/lib/queryBuilder/FunctionBuilder.js +291 -0
  35. package/lib/queryBuilder/InternalOptions.js +24 -0
  36. package/lib/queryBuilder/JoinBuilder.js +124 -0
  37. package/lib/queryBuilder/QueryBuilder.js +1136 -0
  38. package/lib/queryBuilder/QueryBuilderBase.js +666 -0
  39. package/lib/queryBuilder/QueryBuilderContext.js +20 -0
  40. package/lib/queryBuilder/QueryBuilderContextBase.js +26 -0
  41. package/lib/queryBuilder/QueryBuilderOperationSupport.js +484 -0
  42. package/lib/queryBuilder/QueryBuilderUserContext.js +25 -0
  43. package/lib/queryBuilder/RawBuilder.js +78 -0
  44. package/lib/queryBuilder/ReferenceBuilder.js +246 -0
  45. package/lib/queryBuilder/RelationExpression.js +373 -0
  46. package/lib/queryBuilder/StaticHookArguments.js +122 -0
  47. package/lib/queryBuilder/ValueBuilder.js +115 -0
  48. package/lib/queryBuilder/expressions.js +121 -0
  49. package/lib/queryBuilder/functions/mysql.js +762 -0
  50. package/lib/queryBuilder/graph/GraphAction.js +54 -0
  51. package/lib/queryBuilder/graph/GraphData.js +12 -0
  52. package/lib/queryBuilder/graph/GraphFetcher.js +155 -0
  53. package/lib/queryBuilder/graph/GraphNodeDbExistence.js +146 -0
  54. package/lib/queryBuilder/graph/GraphOperation.js +21 -0
  55. package/lib/queryBuilder/graph/GraphOptions.js +165 -0
  56. package/lib/queryBuilder/graph/GraphUpsert.js +231 -0
  57. package/lib/queryBuilder/graph/delete/GraphDelete.js +15 -0
  58. package/lib/queryBuilder/graph/delete/GraphDeleteAction.js +56 -0
  59. package/lib/queryBuilder/graph/insert/GraphInsert.js +116 -0
  60. package/lib/queryBuilder/graph/insert/GraphInsertAction.js +183 -0
  61. package/lib/queryBuilder/graph/insert/JoinRowGraphInsertAction.js +70 -0
  62. package/lib/queryBuilder/graph/patch/GraphPatch.js +15 -0
  63. package/lib/queryBuilder/graph/patch/GraphPatchAction.js +205 -0
  64. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsert.js +26 -0
  65. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsertAction.js +96 -0
  66. package/lib/queryBuilder/join/JoinResultColumn.js +19 -0
  67. package/lib/queryBuilder/join/JoinResultParser.js +106 -0
  68. package/lib/queryBuilder/join/RelationJoiner.js +258 -0
  69. package/lib/queryBuilder/join/TableNode.js +136 -0
  70. package/lib/queryBuilder/join/TableTree.js +69 -0
  71. package/lib/queryBuilder/join/utils.js +19 -0
  72. package/lib/queryBuilder/operations/DelegateOperation.js +101 -0
  73. package/lib/queryBuilder/operations/DeleteOperation.js +47 -0
  74. package/lib/queryBuilder/operations/FindByIdOperation.js +29 -0
  75. package/lib/queryBuilder/operations/FindByIdsOperation.js +23 -0
  76. package/lib/queryBuilder/operations/FindOperation.js +147 -0
  77. package/lib/queryBuilder/operations/FirstOperation.js +22 -0
  78. package/lib/queryBuilder/operations/FromOperation.js +91 -0
  79. package/lib/queryBuilder/operations/InsertAndFetchOperation.js +38 -0
  80. package/lib/queryBuilder/operations/InsertGraphAndFetchOperation.js +35 -0
  81. package/lib/queryBuilder/operations/InsertGraphOperation.js +87 -0
  82. package/lib/queryBuilder/operations/InsertOperation.js +173 -0
  83. package/lib/queryBuilder/operations/InstanceDeleteOperation.js +37 -0
  84. package/lib/queryBuilder/operations/InstanceFindOperation.js +17 -0
  85. package/lib/queryBuilder/operations/InstanceInsertOperation.js +20 -0
  86. package/lib/queryBuilder/operations/InstanceUpdateOperation.js +45 -0
  87. package/lib/queryBuilder/operations/JoinRelatedOperation.js +83 -0
  88. package/lib/queryBuilder/operations/KnexOperation.js +11 -0
  89. package/lib/queryBuilder/operations/MergeOperation.js +43 -0
  90. package/lib/queryBuilder/operations/ObjectionToKnexConvertingOperation.js +173 -0
  91. package/lib/queryBuilder/operations/OnBuildKnexOperation.js +23 -0
  92. package/lib/queryBuilder/operations/OnBuildOperation.js +23 -0
  93. package/lib/queryBuilder/operations/OnErrorOperation.js +23 -0
  94. package/lib/queryBuilder/operations/QueryBuilderOperation.js +258 -0
  95. package/lib/queryBuilder/operations/RangeOperation.js +37 -0
  96. package/lib/queryBuilder/operations/RelateOperation.js +20 -0
  97. package/lib/queryBuilder/operations/ReturningOperation.js +24 -0
  98. package/lib/queryBuilder/operations/RunAfterOperation.js +23 -0
  99. package/lib/queryBuilder/operations/RunBeforeOperation.js +23 -0
  100. package/lib/queryBuilder/operations/UnrelateOperation.js +18 -0
  101. package/lib/queryBuilder/operations/UpdateAndFetchOperation.js +63 -0
  102. package/lib/queryBuilder/operations/UpdateOperation.js +130 -0
  103. package/lib/queryBuilder/operations/UpsertGraphAndFetchOperation.js +35 -0
  104. package/lib/queryBuilder/operations/UpsertGraphOperation.js +47 -0
  105. package/lib/queryBuilder/operations/WhereCompositeOperation.js +48 -0
  106. package/lib/queryBuilder/operations/WhereInOperation.js +46 -0
  107. package/lib/queryBuilder/operations/eager/EagerOperation.js +46 -0
  108. package/lib/queryBuilder/operations/eager/JoinEagerOperation.js +41 -0
  109. package/lib/queryBuilder/operations/eager/NaiveEagerOperation.js +10 -0
  110. package/lib/queryBuilder/operations/eager/WhereInEagerOperation.js +227 -0
  111. package/lib/queryBuilder/operations/jsonApi/WhereJsonHasOperation.js +29 -0
  112. package/lib/queryBuilder/operations/jsonApi/WhereJsonNotObjectOperation.js +37 -0
  113. package/lib/queryBuilder/operations/jsonApi/WhereJsonOperation.js +30 -0
  114. package/lib/queryBuilder/operations/jsonApi/WhereJsonOverlapsOperation.js +33 -0
  115. package/lib/queryBuilder/operations/jsonApi/mysqlJsonApi.js +155 -0
  116. package/lib/queryBuilder/operations/jsonApi/postgresJsonApi.js +135 -0
  117. package/lib/queryBuilder/operations/select/SelectOperation.js +50 -0
  118. package/lib/queryBuilder/operations/select/Selection.js +112 -0
  119. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeMsSqlOperation.js +84 -0
  120. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeOperation.js +90 -0
  121. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeSqliteOperation.js +95 -0
  122. package/lib/queryBuilder/parsers/jsonFieldExpressionParser.js +787 -0
  123. package/lib/queryBuilder/parsers/relationExpressionParser.js +930 -0
  124. package/lib/queryBuilder/transformations/CompositeQueryTransformation.js +17 -0
  125. package/lib/queryBuilder/transformations/QueryTransformation.js +9 -0
  126. package/lib/queryBuilder/transformations/WrapMysqlModifySubqueryTransformation.js +57 -0
  127. package/lib/queryBuilder/transformations/index.js +9 -0
  128. package/lib/queryBuilder/whereScopes.js +199 -0
  129. package/lib/relations/Relation.js +317 -0
  130. package/lib/relations/RelationDeleteOperation.js +23 -0
  131. package/lib/relations/RelationFindOperation.js +116 -0
  132. package/lib/relations/RelationInsertOperation.js +25 -0
  133. package/lib/relations/RelationOwner.js +199 -0
  134. package/lib/relations/RelationProperty.js +207 -0
  135. package/lib/relations/RelationUpdateOperation.js +23 -0
  136. package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +18 -0
  137. package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +33 -0
  138. package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +39 -0
  139. package/lib/relations/belongsToOne/BelongsToOneRelation.js +45 -0
  140. package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +46 -0
  141. package/lib/relations/hasMany/HasManyInsertOperation.js +45 -0
  142. package/lib/relations/hasMany/HasManyRelateOperation.js +48 -0
  143. package/lib/relations/hasMany/HasManyRelation.js +41 -0
  144. package/lib/relations/hasMany/HasManyUnrelateOperation.js +26 -0
  145. package/lib/relations/hasOne/HasOneRelation.js +10 -0
  146. package/lib/relations/hasOneThrough/HasOneThroughRelation.js +10 -0
  147. package/lib/relations/manyToMany/ManyToManyModifyMixin.js +82 -0
  148. package/lib/relations/manyToMany/ManyToManyRelation.js +405 -0
  149. package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +29 -0
  150. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +8 -0
  151. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +20 -0
  152. package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +8 -0
  153. package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +82 -0
  154. package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +40 -0
  155. package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +64 -0
  156. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +11 -0
  157. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +27 -0
  158. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +11 -0
  159. package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +8 -0
  160. package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +65 -0
  161. package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +8 -0
  162. package/lib/transaction.js +66 -0
  163. package/lib/utils/assert.js +19 -0
  164. package/lib/utils/buildUtils.js +19 -0
  165. package/lib/utils/classUtils.js +9 -0
  166. package/lib/utils/cloneDeep.js +365 -0
  167. package/lib/utils/createModifier.js +37 -0
  168. package/lib/utils/deprecate.js +11 -0
  169. package/lib/utils/identifierMapping.js +188 -0
  170. package/lib/utils/internalPropUtils.js +7 -0
  171. package/lib/utils/knexUtils.js +81 -0
  172. package/lib/utils/mixin.js +18 -0
  173. package/lib/utils/mysqlJsonPath.js +70 -0
  174. package/lib/utils/normalizeIds.js +127 -0
  175. package/lib/utils/objectUtils.js +314 -0
  176. package/lib/utils/parseFieldExpression.js +73 -0
  177. package/lib/utils/postgresJsonPath.js +96 -0
  178. package/lib/utils/promiseUtils/after.js +14 -0
  179. package/lib/utils/promiseUtils/afterReturn.js +14 -0
  180. package/lib/utils/promiseUtils/index.js +15 -0
  181. package/lib/utils/promiseUtils/isPromise.js +8 -0
  182. package/lib/utils/promiseUtils/map.js +96 -0
  183. package/lib/utils/promiseUtils/mapAfterAllReturn.js +23 -0
  184. package/lib/utils/promiseUtils/try.js +19 -0
  185. package/lib/utils/resolveModel.js +104 -0
  186. package/lib/utils/tmpColumnUtils.js +7 -0
  187. package/package.json +113 -4
  188. package/typings/objection/index.d.mts +362 -0
  189. package/typings/objection/index.d.ts +4131 -0
  190. package/typings/objection/relation-expression.d.ts +237 -0
@@ -0,0 +1,50 @@
1
+ 'use strict';
2
+ const { flatten } = require('../../../utils/objectUtils');
3
+ const { Selection } = require('./Selection');
4
+ const { ObjectionToKnexConvertingOperation } = require('../ObjectionToKnexConvertingOperation');
5
+ const COUNT_REGEX = /count/i;
6
+ class SelectOperation extends ObjectionToKnexConvertingOperation {
7
+ constructor(name, opt) {
8
+ super(name, opt);
9
+ this.selections = [];
10
+ }
11
+ onAdd(builder, args) {
12
+ const selections = flatten(args);
13
+ // Don't add an empty selection. Empty list is accepted for `count`, `countDistinct`
14
+ // etc. because knex apparently supports it.
15
+ if (selections.length === 0 && !COUNT_REGEX.test(this.name)) {
16
+ return false;
17
+ }
18
+ const ret = super.onAdd(builder, selections);
19
+ for (const selection of selections) {
20
+ const selectionInstance = Selection.create(selection);
21
+ if (selectionInstance) {
22
+ this.selections.push(selectionInstance);
23
+ }
24
+ }
25
+ return ret;
26
+ }
27
+ onBuildKnex(knexBuilder, builder) {
28
+ return knexBuilder[this.name].apply(knexBuilder, this.getKnexArgs(builder));
29
+ }
30
+ findSelection(builder, selectionToFind) {
31
+ const selectionInstanceToFind = Selection.create(selectionToFind);
32
+ if (!selectionInstanceToFind) {
33
+ return null;
34
+ }
35
+ for (const selection of this.selections) {
36
+ if (Selection.doesSelect(builder, selection, selectionInstanceToFind)) {
37
+ return selection;
38
+ }
39
+ }
40
+ return null;
41
+ }
42
+ clone() {
43
+ const clone = super.clone();
44
+ clone.selections = this.selections.slice();
45
+ return clone;
46
+ }
47
+ }
48
+ module.exports = {
49
+ SelectOperation,
50
+ };
@@ -0,0 +1,112 @@
1
+ 'use strict';
2
+ const { isString, isObject } = require('../../../utils/objectUtils');
3
+ const ALIAS_REGEX = /\s+as\s+/i;
4
+ class Selection {
5
+ constructor(table, column, alias) {
6
+ this.table = table;
7
+ this.column = column;
8
+ this.alias = alias;
9
+ }
10
+ get name() {
11
+ return this.alias || this.column;
12
+ }
13
+ static create(selection) {
14
+ if (isObject(selection)) {
15
+ if (selection.isObjectionSelection) {
16
+ return selection;
17
+ }
18
+ else if (selection.isObjectionReferenceBuilder) {
19
+ return createSelectionFromReference(selection);
20
+ }
21
+ else if (selection.isObjectionRawBuilder) {
22
+ return createSelectionFromRaw(selection);
23
+ }
24
+ else {
25
+ return null;
26
+ }
27
+ }
28
+ else if (isString(selection)) {
29
+ return createSelectionFromString(selection);
30
+ }
31
+ else {
32
+ return null;
33
+ }
34
+ }
35
+ /**
36
+ * Returns true if `selectionInBuilder` causes `selectionToTest` to be selected.
37
+ *
38
+ * Examples that return true:
39
+ *
40
+ * doesSelect(Person.query(), '*', 'name')
41
+ * doesSelect(Person.query(), 'Person.*', 'name')
42
+ * doesSelect(Person.query(), 'name', 'name')
43
+ * doesSelect(Person.query(), 'name', 'Person.name')
44
+ */
45
+ static doesSelect(builder, selectionInBuilder, selectionToTest) {
46
+ selectionInBuilder = Selection.create(selectionInBuilder);
47
+ selectionToTest = Selection.create(selectionToTest);
48
+ if (selectionInBuilder.column === '*') {
49
+ if (selectionInBuilder.table) {
50
+ if (selectionToTest.column === '*') {
51
+ return selectionToTest.table === selectionInBuilder.table;
52
+ }
53
+ else {
54
+ return (selectionToTest.table === null || selectionToTest.table === selectionInBuilder.table);
55
+ }
56
+ }
57
+ else {
58
+ return true;
59
+ }
60
+ }
61
+ else {
62
+ const selectionInBuilderTable = selectionInBuilder.table || builder.tableRef();
63
+ if (selectionToTest.column === '*') {
64
+ return false;
65
+ }
66
+ else {
67
+ return (selectionToTest.column === selectionInBuilder.column &&
68
+ (selectionToTest.table === null || selectionToTest.table === selectionInBuilderTable));
69
+ }
70
+ }
71
+ }
72
+ }
73
+ Object.defineProperties(Selection.prototype, {
74
+ isObjectionSelection: {
75
+ enumerable: false,
76
+ writable: false,
77
+ value: true,
78
+ },
79
+ });
80
+ function createSelectionFromReference(ref) {
81
+ return new Selection(ref.tableName, ref.column, ref.alias);
82
+ }
83
+ function createSelectionFromRaw(raw) {
84
+ if (raw.alias) {
85
+ return new Selection(null, null, raw.alias);
86
+ }
87
+ else {
88
+ return null;
89
+ }
90
+ }
91
+ function createSelectionFromString(selection) {
92
+ let table = null;
93
+ let column = null;
94
+ let alias = null;
95
+ if (ALIAS_REGEX.test(selection)) {
96
+ const parts = selection.split(ALIAS_REGEX);
97
+ selection = parts[0].trim();
98
+ alias = parts[1].trim();
99
+ }
100
+ const dotIdx = selection.lastIndexOf('.');
101
+ if (dotIdx !== -1) {
102
+ table = selection.substr(0, dotIdx);
103
+ column = selection.substr(dotIdx + 1);
104
+ }
105
+ else {
106
+ column = selection;
107
+ }
108
+ return new Selection(table, column, alias);
109
+ }
110
+ module.exports = {
111
+ Selection,
112
+ };
@@ -0,0 +1,84 @@
1
+ 'use strict';
2
+ const { ObjectionToKnexConvertingOperation } = require('../ObjectionToKnexConvertingOperation');
3
+ const { flatten, zipObject, isString } = require('../../../utils/objectUtils');
4
+ const { getTempColumn } = require('../../../utils/tmpColumnUtils');
5
+ class WhereInCompositeMsSqlOperation extends ObjectionToKnexConvertingOperation {
6
+ constructor(name, opt) {
7
+ super(name, opt);
8
+ this.prefix = this.opt.prefix || null;
9
+ }
10
+ onBuildKnex(knexBuilder, builder) {
11
+ const args = this.getKnexArgs(builder);
12
+ return this.build(builder.knex(), knexBuilder, args[0], args[1]);
13
+ }
14
+ build(knex, knexBuilder, columns, values) {
15
+ const isCompositeKey = Array.isArray(columns) && columns.length > 1;
16
+ if (isCompositeKey) {
17
+ return this.buildComposite(knex, knexBuilder, columns, values);
18
+ }
19
+ else {
20
+ return this.buildNonComposite(knexBuilder, columns, values);
21
+ }
22
+ }
23
+ buildComposite(knex, knexBuilder, columns, values) {
24
+ const helperColumns = columns.map((_, index) => getTempColumn(index));
25
+ if (Array.isArray(values)) {
26
+ return this.buildCompositeValue(knex, knexBuilder, columns, helperColumns, values);
27
+ }
28
+ else {
29
+ return this.buildCompositeSubquery(knex, knexBuilder, columns, helperColumns, values.as(knex.raw(`V(${helperColumns.map((_) => '??')})`, helperColumns)));
30
+ }
31
+ }
32
+ buildCompositeValue(knex, knexBuilder, columns, helperColumns, values) {
33
+ return this.buildCompositeSubquery(knex, knexBuilder, columns, helperColumns, knex.raw(`(VALUES ${values
34
+ .map((value) => `(${value.map((_) => '?').join(',')})`)
35
+ .join(',')}) AS V(${helperColumns.map((_) => '??').join(',')})`, flatten(values).concat(helperColumns)));
36
+ }
37
+ buildCompositeSubquery(knex, knexBuilder, columns, helperColumns, subQuery) {
38
+ const wrapperQuery = knex.from(subQuery).where(zipObject(helperColumns, columns.map((column) => knex.raw('??', column))));
39
+ if (this.prefix === 'not') {
40
+ return knexBuilder.whereNotExists(wrapperQuery);
41
+ }
42
+ else {
43
+ return knexBuilder.whereExists(wrapperQuery);
44
+ }
45
+ }
46
+ buildNonComposite(knexBuilder, columns, values) {
47
+ const col = isString(columns) ? columns : columns[0];
48
+ if (Array.isArray(values)) {
49
+ values = pickNonNull(values, []);
50
+ }
51
+ else {
52
+ values = [values];
53
+ }
54
+ return this.whereIn(knexBuilder, col, values);
55
+ }
56
+ whereIn(knexBuilder, col, val) {
57
+ if (this.prefix === 'not') {
58
+ return knexBuilder.whereNotIn(col, val);
59
+ }
60
+ else {
61
+ return knexBuilder.whereIn(col, val);
62
+ }
63
+ }
64
+ clone() {
65
+ const clone = super.clone();
66
+ clone.prefix = this.prefix;
67
+ return clone;
68
+ }
69
+ }
70
+ function pickNonNull(values, output) {
71
+ for (let i = 0, l = values.length; i < l; ++i) {
72
+ const val = values[i];
73
+ if (Array.isArray(val)) {
74
+ pickNonNull(val, output);
75
+ }
76
+ else if (val !== null && val !== undefined) {
77
+ output.push(val);
78
+ }
79
+ }
80
+ return output;
81
+ }
82
+ module.exports = {
83
+ WhereInCompositeMsSqlOperation,
84
+ };
@@ -0,0 +1,90 @@
1
+ 'use strict';
2
+ const { ObjectionToKnexConvertingOperation } = require('../ObjectionToKnexConvertingOperation');
3
+ const { isObject, asSingle } = require('../../../utils/objectUtils');
4
+ const { isKnexQueryBuilder } = require('../../../utils/knexUtils');
5
+ class WhereInCompositeOperation extends ObjectionToKnexConvertingOperation {
6
+ constructor(name, opt) {
7
+ super(name, opt);
8
+ this.prefix = this.opt.prefix || null;
9
+ }
10
+ onBuildKnex(knexBuilder, builder) {
11
+ const whereInArgs = buildWhereInArgs(builder.knex(), ...this.getKnexArgs(builder));
12
+ if (this.prefix === 'not') {
13
+ return knexBuilder.whereNotIn(...whereInArgs);
14
+ }
15
+ else {
16
+ return knexBuilder.whereIn(...whereInArgs);
17
+ }
18
+ }
19
+ clone() {
20
+ const clone = super.clone();
21
+ clone.prefix = this.prefix;
22
+ return clone;
23
+ }
24
+ }
25
+ function buildWhereInArgs(knex, columns, values) {
26
+ if (isCompositeKey(columns)) {
27
+ return buildCompositeArgs(knex, columns, values);
28
+ }
29
+ else {
30
+ return buildNonCompositeArgs(columns, values);
31
+ }
32
+ }
33
+ function isCompositeKey(columns) {
34
+ return Array.isArray(columns) && columns.length > 1;
35
+ }
36
+ function buildCompositeArgs(knex, columns, values) {
37
+ if (Array.isArray(values)) {
38
+ return buildCompositeValueArgs(columns, values);
39
+ }
40
+ else {
41
+ return buildCompositeSubqueryArgs(knex, columns, values);
42
+ }
43
+ }
44
+ function buildCompositeValueArgs(columns, values) {
45
+ if (!Array.isArray(values[0])) {
46
+ return [columns, [values]];
47
+ }
48
+ else {
49
+ return [columns, values];
50
+ }
51
+ }
52
+ function buildCompositeSubqueryArgs(knex, columns, subquery) {
53
+ const sql = `(${columns
54
+ .map((col) => {
55
+ // On older versions of knex, raw doesn't work
56
+ // with `??`. We use `?` for those.
57
+ if (isObject(col)) {
58
+ return '?';
59
+ }
60
+ else {
61
+ return '??';
62
+ }
63
+ })
64
+ .join(',')})`;
65
+ return [knex.raw(sql, columns), subquery];
66
+ }
67
+ function buildNonCompositeArgs(columns, values) {
68
+ if (Array.isArray(values)) {
69
+ values = pickNonNull(values, []);
70
+ }
71
+ else if (!isKnexQueryBuilder(values)) {
72
+ values = [values];
73
+ }
74
+ return [asSingle(columns), values];
75
+ }
76
+ function pickNonNull(values, output) {
77
+ for (let i = 0, l = values.length; i < l; ++i) {
78
+ const val = values[i];
79
+ if (Array.isArray(val)) {
80
+ pickNonNull(val, output);
81
+ }
82
+ else if (val !== null && val !== undefined) {
83
+ output.push(val);
84
+ }
85
+ }
86
+ return output;
87
+ }
88
+ module.exports = {
89
+ WhereInCompositeOperation,
90
+ };
@@ -0,0 +1,95 @@
1
+ 'use strict';
2
+ const { ObjectionToKnexConvertingOperation } = require('../ObjectionToKnexConvertingOperation');
3
+ const { isKnexQueryBuilder } = require('../../../utils/knexUtils');
4
+ const { asSingle } = require('../../../utils/objectUtils');
5
+ class WhereInCompositeSqliteOperation extends ObjectionToKnexConvertingOperation {
6
+ constructor(name, opt) {
7
+ super(name, opt);
8
+ this.prefix = this.opt.prefix || null;
9
+ }
10
+ onBuildKnex(knexBuilder, builder) {
11
+ const { method, args } = buildWhereArgs(...this.getKnexArgs(builder));
12
+ if (method === 'where') {
13
+ if (this.prefix === 'not') {
14
+ return knexBuilder.whereNot(...args);
15
+ }
16
+ else {
17
+ return knexBuilder.where(...args);
18
+ }
19
+ }
20
+ else {
21
+ if (this.prefix === 'not') {
22
+ return knexBuilder.whereNotIn(...args);
23
+ }
24
+ else {
25
+ return knexBuilder.whereIn(...args);
26
+ }
27
+ }
28
+ }
29
+ clone() {
30
+ const clone = super.clone();
31
+ clone.prefix = this.prefix;
32
+ return clone;
33
+ }
34
+ }
35
+ function buildWhereArgs(columns, values) {
36
+ if (isCompositeKey(columns)) {
37
+ return buildCompositeArgs(columns, values);
38
+ }
39
+ else {
40
+ return buildNonCompositeArgs(columns, values);
41
+ }
42
+ }
43
+ function isCompositeKey(columns) {
44
+ return Array.isArray(columns) && columns.length > 1;
45
+ }
46
+ function buildCompositeArgs(columns, values) {
47
+ if (!Array.isArray(values)) {
48
+ // If the `values` is not an array of values but a function or a subquery
49
+ // we have no way to implement this method.
50
+ throw new Error(`sqlite doesn't support multi-column where in clauses`);
51
+ }
52
+ // Sqlite doesn't support the `where in` syntax for multiple columns but
53
+ // we can emulate it using grouped `or` clauses.
54
+ return {
55
+ method: 'where',
56
+ args: [
57
+ (builder) => {
58
+ values.forEach((val) => {
59
+ builder.orWhere((builder) => {
60
+ columns.forEach((col, idx) => {
61
+ builder.andWhere(col, val[idx]);
62
+ });
63
+ });
64
+ });
65
+ },
66
+ ],
67
+ };
68
+ }
69
+ function buildNonCompositeArgs(columns, values) {
70
+ if (Array.isArray(values)) {
71
+ values = pickNonNull(values, []);
72
+ }
73
+ else if (!isKnexQueryBuilder(values)) {
74
+ values = [values];
75
+ }
76
+ return {
77
+ method: 'whereIn',
78
+ args: [asSingle(columns), values],
79
+ };
80
+ }
81
+ function pickNonNull(values, output) {
82
+ for (let i = 0, l = values.length; i < l; ++i) {
83
+ const val = values[i];
84
+ if (Array.isArray(val)) {
85
+ pickNonNull(val, output);
86
+ }
87
+ else if (val !== null && val !== undefined) {
88
+ output.push(val);
89
+ }
90
+ }
91
+ return output;
92
+ }
93
+ module.exports = {
94
+ WhereInCompositeSqliteOperation,
95
+ };