@bunyad/orm 0.2.0-beta.2 → 0.2.0-beta.4
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.
- package/README.md +0 -1
- package/dist/model-query.d.ts +3 -2
- package/dist/model-query.js +178 -220
- package/dist/model.d.ts +2 -2
- package/dist/model.js +4 -4
- package/dist/test-drivers.js +3 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -81,7 +81,6 @@ Pick one and install it next to `@bunyad/database`: `better-sqlite3`, `pg` or `m
|
|
|
81
81
|
|
|
82
82
|
- Express on Node: [`docs/examples/orm-node-express`](https://github.com/bunyadjs/framework/tree/main/docs/examples/orm-node-express)
|
|
83
83
|
- Next.js (server-only, one shared pool): [`docs/examples/orm-node-next`](https://github.com/bunyadjs/framework/tree/main/docs/examples/orm-node-next)
|
|
84
|
-
- NestJS: `@bunyad/nestjs` (`BunyadOrmModule`), in the monorepo and not published yet.
|
|
85
84
|
|
|
86
85
|
## Status
|
|
87
86
|
|
package/dist/model-query.d.ts
CHANGED
|
@@ -217,9 +217,10 @@ export declare class ModelQuery<T extends Model = Model, TResult extends "model"
|
|
|
217
217
|
distinct(value?: boolean): this;
|
|
218
218
|
orderBy(column: ColumnHint<T>, direction?: "asc" | "desc"): this;
|
|
219
219
|
orderByDesc(column: ColumnHint<T>): this;
|
|
220
|
-
orderByRaw(sql
|
|
220
|
+
/** `orderByRaw($sql, $bindings)`. */
|
|
221
|
+
orderByRaw(sql: string, bindings?: unknown[]): this;
|
|
221
222
|
/** Alias for `orderByRaw`. */
|
|
222
|
-
orderBySql(sql: string): this;
|
|
223
|
+
orderBySql(sql: string, bindings?: unknown[]): this;
|
|
223
224
|
reorder(column?: string, direction?: "asc" | "desc"): this;
|
|
224
225
|
inRandomOrder(): this;
|
|
225
226
|
latest(column?: string): this;
|
package/dist/model-query.js
CHANGED
|
@@ -39,6 +39,120 @@ function mqMut(arr) {
|
|
|
39
39
|
function mqMutObj(obj) {
|
|
40
40
|
return obj === MQ_EMPTY_OBJ ? {} : obj;
|
|
41
41
|
}
|
|
42
|
+
/** Creation order of where conditions, shared across every kind (plain, IN, null, …). */
|
|
43
|
+
let mqWhereSeq = 0;
|
|
44
|
+
function nextWhereSeq() {
|
|
45
|
+
return ++mqWhereSeq;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Apply every kind of where condition onto a QueryBuilder in the order the caller
|
|
49
|
+
* wrote them, so `whereIn(...).orWhereNull(...)` stays `IN … OR NULL`. Conditions
|
|
50
|
+
* without a sequence number keep the old per-kind order.
|
|
51
|
+
*/
|
|
52
|
+
function applyWhereLists(q, lists) {
|
|
53
|
+
const steps = [];
|
|
54
|
+
for (const w of lists.wheres ?? []) {
|
|
55
|
+
steps.push({
|
|
56
|
+
seq: w.seq ?? 0,
|
|
57
|
+
run: (q) => {
|
|
58
|
+
if (w.op === "__null__") {
|
|
59
|
+
return w.boolean === "or" ? q.orWhereNull(w.column) : q.whereNull(w.column);
|
|
60
|
+
}
|
|
61
|
+
if (w.op === "__notnull__") {
|
|
62
|
+
return w.boolean === "or"
|
|
63
|
+
? q.orWhereNotNull(w.column)
|
|
64
|
+
: q.whereNotNull(w.column);
|
|
65
|
+
}
|
|
66
|
+
return w.boolean === "or"
|
|
67
|
+
? q.orWhere(w.column, w.op, w.value)
|
|
68
|
+
: q.where(w.column, w.op, w.value);
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
for (const w of lists.whereIns ?? []) {
|
|
73
|
+
steps.push({
|
|
74
|
+
seq: w.seq ?? 0,
|
|
75
|
+
run: (q) => w.boolean === "or"
|
|
76
|
+
? w.not
|
|
77
|
+
? q.orWhereNotIn(w.column, w.values)
|
|
78
|
+
: q.orWhereIn(w.column, w.values)
|
|
79
|
+
: w.not
|
|
80
|
+
? q.whereNotIn(w.column, w.values)
|
|
81
|
+
: q.whereIn(w.column, w.values),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
for (const w of lists.whereNulls ?? []) {
|
|
85
|
+
steps.push({
|
|
86
|
+
seq: w.seq ?? 0,
|
|
87
|
+
run: (q) => w.boolean === "or"
|
|
88
|
+
? w.not
|
|
89
|
+
? q.orWhereNotNull(w.column)
|
|
90
|
+
: q.orWhereNull(w.column)
|
|
91
|
+
: w.not
|
|
92
|
+
? q.whereNotNull(w.column)
|
|
93
|
+
: q.whereNull(w.column),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
for (const w of lists.whereBetweens ?? []) {
|
|
97
|
+
steps.push({
|
|
98
|
+
seq: w.seq ?? 0,
|
|
99
|
+
run: (q) => w.boolean === "or"
|
|
100
|
+
? w.not
|
|
101
|
+
? q.orWhereNotBetween(w.column, w.values)
|
|
102
|
+
: q.orWhereBetween(w.column, w.values)
|
|
103
|
+
: w.not
|
|
104
|
+
? q.whereNotBetween(w.column, w.values)
|
|
105
|
+
: q.whereBetween(w.column, w.values),
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
for (const w of lists.whereColumns ?? []) {
|
|
109
|
+
steps.push({
|
|
110
|
+
seq: w.seq ?? 0,
|
|
111
|
+
run: (q) => w.boolean === "or"
|
|
112
|
+
? q.orWhereColumn(w.first, w.op, w.second)
|
|
113
|
+
: q.whereColumn(w.first, w.op, w.second),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
for (const w of lists.whereRaws ?? []) {
|
|
117
|
+
steps.push({
|
|
118
|
+
seq: w.seq ?? 0,
|
|
119
|
+
run: (q) => w.boolean === "or"
|
|
120
|
+
? q.orWhereRaw(w.sql, w.bindings)
|
|
121
|
+
: q.whereRaw(w.sql, w.bindings),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
for (const w of lists.whereLikes ?? []) {
|
|
125
|
+
steps.push({
|
|
126
|
+
seq: w.seq ?? 0,
|
|
127
|
+
run: (q) => w.boolean === "or"
|
|
128
|
+
? w.not
|
|
129
|
+
? q.orWhereNotLike(w.column, w.value, w.caseSensitive)
|
|
130
|
+
: q.orWhereLike(w.column, w.value, w.caseSensitive)
|
|
131
|
+
: w.not
|
|
132
|
+
? q.whereNotLike(w.column, w.value, w.caseSensitive)
|
|
133
|
+
: q.whereLike(w.column, w.value, w.caseSensitive),
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
for (const w of lists.dateWheres ?? []) {
|
|
137
|
+
steps.push({
|
|
138
|
+
seq: w.seq ?? 0,
|
|
139
|
+
run: (q) => {
|
|
140
|
+
if (w.kind === "date")
|
|
141
|
+
return q.whereDate(w.column, w.op, w.value);
|
|
142
|
+
if (w.kind === "year")
|
|
143
|
+
return q.whereYear(w.column, w.op, Number(w.value));
|
|
144
|
+
if (w.kind === "month")
|
|
145
|
+
return q.whereMonth(w.column, w.op, Number(w.value));
|
|
146
|
+
return q.whereDay(w.column, w.op, Number(w.value));
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
// Array.prototype.sort is stable: equal (or missing) sequence numbers keep list order.
|
|
151
|
+
steps.sort((a, b) => a.seq - b.seq);
|
|
152
|
+
for (const step of steps)
|
|
153
|
+
q = step.run(q);
|
|
154
|
+
return q;
|
|
155
|
+
}
|
|
42
156
|
/** Compiled simple-SELECT SQL keyed by constraint fingerprint (per model). */
|
|
43
157
|
const simpleSelectSqlCache = new WeakMap();
|
|
44
158
|
/** Compiled parent+EXISTS SELECT SQL (whereHas fast path). */
|
|
@@ -753,7 +867,7 @@ export class ModelQuery {
|
|
|
753
867
|
return this;
|
|
754
868
|
}
|
|
755
869
|
if (value === undefined) {
|
|
756
|
-
(this.#wheres = mqMut(this.#wheres)).push({
|
|
870
|
+
(this.#wheres = mqMut(this.#wheres)).push({ seq: nextWhereSeq(),
|
|
757
871
|
column: columnOrCallback,
|
|
758
872
|
op: "=",
|
|
759
873
|
value: opOrValue,
|
|
@@ -775,7 +889,7 @@ export class ModelQuery {
|
|
|
775
889
|
op !== "NOT LIKE") {
|
|
776
890
|
this.#simple = false;
|
|
777
891
|
}
|
|
778
|
-
(this.#wheres = mqMut(this.#wheres)).push({
|
|
892
|
+
(this.#wheres = mqMut(this.#wheres)).push({ seq: nextWhereSeq(),
|
|
779
893
|
column: columnOrCallback,
|
|
780
894
|
op,
|
|
781
895
|
value,
|
|
@@ -795,7 +909,7 @@ export class ModelQuery {
|
|
|
795
909
|
return this;
|
|
796
910
|
}
|
|
797
911
|
if (value === undefined) {
|
|
798
|
-
(this.#wheres = mqMut(this.#wheres)).push({
|
|
912
|
+
(this.#wheres = mqMut(this.#wheres)).push({ seq: nextWhereSeq(),
|
|
799
913
|
column: columnOrCallback,
|
|
800
914
|
op: "=",
|
|
801
915
|
value: opOrValue,
|
|
@@ -817,7 +931,7 @@ export class ModelQuery {
|
|
|
817
931
|
op !== "NOT LIKE") {
|
|
818
932
|
this.#simple = false;
|
|
819
933
|
}
|
|
820
|
-
(this.#wheres = mqMut(this.#wheres)).push({
|
|
934
|
+
(this.#wheres = mqMut(this.#wheres)).push({ seq: nextWhereSeq(),
|
|
821
935
|
column: columnOrCallback,
|
|
822
936
|
op,
|
|
823
937
|
value,
|
|
@@ -828,26 +942,26 @@ export class ModelQuery {
|
|
|
828
942
|
}
|
|
829
943
|
whereIn(column, values) {
|
|
830
944
|
this.#simple = false;
|
|
831
|
-
(this.#whereIns = mqMut(this.#whereIns)).push({ column, values, not: false, boolean: "and" });
|
|
945
|
+
(this.#whereIns = mqMut(this.#whereIns)).push({ seq: nextWhereSeq(), column, values, not: false, boolean: "and" });
|
|
832
946
|
return this;
|
|
833
947
|
}
|
|
834
948
|
orWhereIn(column, values) {
|
|
835
949
|
this.#simple = false;
|
|
836
|
-
(this.#whereIns = mqMut(this.#whereIns)).push({ column, values, not: false, boolean: "or" });
|
|
950
|
+
(this.#whereIns = mqMut(this.#whereIns)).push({ seq: nextWhereSeq(), column, values, not: false, boolean: "or" });
|
|
837
951
|
return this;
|
|
838
952
|
}
|
|
839
953
|
whereNotIn(column, values) {
|
|
840
954
|
this.#simple = false;
|
|
841
|
-
(this.#whereIns = mqMut(this.#whereIns)).push({ column, values, not: true, boolean: "and" });
|
|
955
|
+
(this.#whereIns = mqMut(this.#whereIns)).push({ seq: nextWhereSeq(), column, values, not: true, boolean: "and" });
|
|
842
956
|
return this;
|
|
843
957
|
}
|
|
844
958
|
orWhereNotIn(column, values) {
|
|
845
959
|
this.#simple = false;
|
|
846
|
-
(this.#whereIns = mqMut(this.#whereIns)).push({ column, values, not: true, boolean: "or" });
|
|
960
|
+
(this.#whereIns = mqMut(this.#whereIns)).push({ seq: nextWhereSeq(), column, values, not: true, boolean: "or" });
|
|
847
961
|
return this;
|
|
848
962
|
}
|
|
849
963
|
whereNull(column) {
|
|
850
|
-
(this.#wheres = mqMut(this.#wheres)).push({
|
|
964
|
+
(this.#wheres = mqMut(this.#wheres)).push({ seq: nextWhereSeq(),
|
|
851
965
|
column,
|
|
852
966
|
op: "__null__",
|
|
853
967
|
value: null,
|
|
@@ -856,7 +970,7 @@ export class ModelQuery {
|
|
|
856
970
|
return this;
|
|
857
971
|
}
|
|
858
972
|
orWhereNull(column) {
|
|
859
|
-
(this.#wheres = mqMut(this.#wheres)).push({
|
|
973
|
+
(this.#wheres = mqMut(this.#wheres)).push({ seq: nextWhereSeq(),
|
|
860
974
|
column,
|
|
861
975
|
op: "__null__",
|
|
862
976
|
value: null,
|
|
@@ -865,7 +979,7 @@ export class ModelQuery {
|
|
|
865
979
|
return this;
|
|
866
980
|
}
|
|
867
981
|
whereNotNull(column) {
|
|
868
|
-
(this.#wheres = mqMut(this.#wheres)).push({
|
|
982
|
+
(this.#wheres = mqMut(this.#wheres)).push({ seq: nextWhereSeq(),
|
|
869
983
|
column,
|
|
870
984
|
op: "__notnull__",
|
|
871
985
|
value: null,
|
|
@@ -874,7 +988,7 @@ export class ModelQuery {
|
|
|
874
988
|
return this;
|
|
875
989
|
}
|
|
876
990
|
orWhereNotNull(column) {
|
|
877
|
-
(this.#wheres = mqMut(this.#wheres)).push({
|
|
991
|
+
(this.#wheres = mqMut(this.#wheres)).push({ seq: nextWhereSeq(),
|
|
878
992
|
column,
|
|
879
993
|
op: "__notnull__",
|
|
880
994
|
value: null,
|
|
@@ -884,7 +998,7 @@ export class ModelQuery {
|
|
|
884
998
|
}
|
|
885
999
|
whereBetween(column, values) {
|
|
886
1000
|
this.#simple = false;
|
|
887
|
-
(this.#whereBetweens = mqMut(this.#whereBetweens)).push({
|
|
1001
|
+
(this.#whereBetweens = mqMut(this.#whereBetweens)).push({ seq: nextWhereSeq(),
|
|
888
1002
|
column,
|
|
889
1003
|
values,
|
|
890
1004
|
not: false,
|
|
@@ -894,7 +1008,7 @@ export class ModelQuery {
|
|
|
894
1008
|
}
|
|
895
1009
|
orWhereBetween(column, values) {
|
|
896
1010
|
this.#simple = false;
|
|
897
|
-
(this.#whereBetweens = mqMut(this.#whereBetweens)).push({
|
|
1011
|
+
(this.#whereBetweens = mqMut(this.#whereBetweens)).push({ seq: nextWhereSeq(),
|
|
898
1012
|
column,
|
|
899
1013
|
values,
|
|
900
1014
|
not: false,
|
|
@@ -904,7 +1018,7 @@ export class ModelQuery {
|
|
|
904
1018
|
}
|
|
905
1019
|
whereNotBetween(column, values) {
|
|
906
1020
|
this.#simple = false;
|
|
907
|
-
(this.#whereBetweens = mqMut(this.#whereBetweens)).push({
|
|
1021
|
+
(this.#whereBetweens = mqMut(this.#whereBetweens)).push({ seq: nextWhereSeq(),
|
|
908
1022
|
column,
|
|
909
1023
|
values,
|
|
910
1024
|
not: true,
|
|
@@ -914,7 +1028,7 @@ export class ModelQuery {
|
|
|
914
1028
|
}
|
|
915
1029
|
orWhereNotBetween(column, values) {
|
|
916
1030
|
this.#simple = false;
|
|
917
|
-
(this.#whereBetweens = mqMut(this.#whereBetweens)).push({
|
|
1031
|
+
(this.#whereBetweens = mqMut(this.#whereBetweens)).push({ seq: nextWhereSeq(),
|
|
918
1032
|
column,
|
|
919
1033
|
values,
|
|
920
1034
|
not: true,
|
|
@@ -925,7 +1039,7 @@ export class ModelQuery {
|
|
|
925
1039
|
whereColumn(first, opOrSecond, second) {
|
|
926
1040
|
if (second === undefined) {
|
|
927
1041
|
this.#simple = false;
|
|
928
|
-
(this.#whereColumns = mqMut(this.#whereColumns)).push({
|
|
1042
|
+
(this.#whereColumns = mqMut(this.#whereColumns)).push({ seq: nextWhereSeq(),
|
|
929
1043
|
first,
|
|
930
1044
|
op: "=",
|
|
931
1045
|
second: opOrSecond,
|
|
@@ -934,7 +1048,7 @@ export class ModelQuery {
|
|
|
934
1048
|
}
|
|
935
1049
|
else {
|
|
936
1050
|
this.#simple = false;
|
|
937
|
-
(this.#whereColumns = mqMut(this.#whereColumns)).push({
|
|
1051
|
+
(this.#whereColumns = mqMut(this.#whereColumns)).push({ seq: nextWhereSeq(),
|
|
938
1052
|
first,
|
|
939
1053
|
op: opOrSecond,
|
|
940
1054
|
second,
|
|
@@ -946,7 +1060,7 @@ export class ModelQuery {
|
|
|
946
1060
|
orWhereColumn(first, opOrSecond, second) {
|
|
947
1061
|
if (second === undefined) {
|
|
948
1062
|
this.#simple = false;
|
|
949
|
-
(this.#whereColumns = mqMut(this.#whereColumns)).push({
|
|
1063
|
+
(this.#whereColumns = mqMut(this.#whereColumns)).push({ seq: nextWhereSeq(),
|
|
950
1064
|
first,
|
|
951
1065
|
op: "=",
|
|
952
1066
|
second: opOrSecond,
|
|
@@ -955,7 +1069,7 @@ export class ModelQuery {
|
|
|
955
1069
|
}
|
|
956
1070
|
else {
|
|
957
1071
|
this.#simple = false;
|
|
958
|
-
(this.#whereColumns = mqMut(this.#whereColumns)).push({
|
|
1072
|
+
(this.#whereColumns = mqMut(this.#whereColumns)).push({ seq: nextWhereSeq(),
|
|
959
1073
|
first,
|
|
960
1074
|
op: opOrSecond,
|
|
961
1075
|
second,
|
|
@@ -966,17 +1080,17 @@ export class ModelQuery {
|
|
|
966
1080
|
}
|
|
967
1081
|
whereRaw(sql, bindings = []) {
|
|
968
1082
|
this.#simple = false;
|
|
969
|
-
(this.#whereRaws = mqMut(this.#whereRaws)).push({ sql, bindings, boolean: "and" });
|
|
1083
|
+
(this.#whereRaws = mqMut(this.#whereRaws)).push({ seq: nextWhereSeq(), sql, bindings, boolean: "and" });
|
|
970
1084
|
return this;
|
|
971
1085
|
}
|
|
972
1086
|
orWhereRaw(sql, bindings = []) {
|
|
973
1087
|
this.#simple = false;
|
|
974
|
-
(this.#whereRaws = mqMut(this.#whereRaws)).push({ sql, bindings, boolean: "or" });
|
|
1088
|
+
(this.#whereRaws = mqMut(this.#whereRaws)).push({ seq: nextWhereSeq(), sql, bindings, boolean: "or" });
|
|
975
1089
|
return this;
|
|
976
1090
|
}
|
|
977
1091
|
whereLike(column, value, caseSensitive = false) {
|
|
978
1092
|
this.#simple = false;
|
|
979
|
-
(this.#whereLikes = mqMut(this.#whereLikes)).push({
|
|
1093
|
+
(this.#whereLikes = mqMut(this.#whereLikes)).push({ seq: nextWhereSeq(),
|
|
980
1094
|
column,
|
|
981
1095
|
value,
|
|
982
1096
|
not: false,
|
|
@@ -987,7 +1101,7 @@ export class ModelQuery {
|
|
|
987
1101
|
}
|
|
988
1102
|
orWhereLike(column, value, caseSensitive = false) {
|
|
989
1103
|
this.#simple = false;
|
|
990
|
-
(this.#whereLikes = mqMut(this.#whereLikes)).push({
|
|
1104
|
+
(this.#whereLikes = mqMut(this.#whereLikes)).push({ seq: nextWhereSeq(),
|
|
991
1105
|
column,
|
|
992
1106
|
value,
|
|
993
1107
|
not: false,
|
|
@@ -998,7 +1112,7 @@ export class ModelQuery {
|
|
|
998
1112
|
}
|
|
999
1113
|
whereNotLike(column, value, caseSensitive = false) {
|
|
1000
1114
|
this.#simple = false;
|
|
1001
|
-
(this.#whereLikes = mqMut(this.#whereLikes)).push({
|
|
1115
|
+
(this.#whereLikes = mqMut(this.#whereLikes)).push({ seq: nextWhereSeq(),
|
|
1002
1116
|
column,
|
|
1003
1117
|
value,
|
|
1004
1118
|
not: true,
|
|
@@ -1009,7 +1123,7 @@ export class ModelQuery {
|
|
|
1009
1123
|
}
|
|
1010
1124
|
orWhereNotLike(column, value, caseSensitive = false) {
|
|
1011
1125
|
this.#simple = false;
|
|
1012
|
-
(this.#whereLikes = mqMut(this.#whereLikes)).push({
|
|
1126
|
+
(this.#whereLikes = mqMut(this.#whereLikes)).push({ seq: nextWhereSeq(),
|
|
1013
1127
|
column,
|
|
1014
1128
|
value,
|
|
1015
1129
|
not: true,
|
|
@@ -1022,12 +1136,12 @@ export class ModelQuery {
|
|
|
1022
1136
|
const op = value === undefined ? "=" : String(opOrValue);
|
|
1023
1137
|
const raw = (value === undefined ? opOrValue : value);
|
|
1024
1138
|
this.#simple = false;
|
|
1025
|
-
(this.#dateWheres = mqMut(this.#dateWheres)).push({ column, op, value: raw, kind: "date" });
|
|
1139
|
+
(this.#dateWheres = mqMut(this.#dateWheres)).push({ seq: nextWhereSeq(), column, op, value: raw, kind: "date" });
|
|
1026
1140
|
return this;
|
|
1027
1141
|
}
|
|
1028
1142
|
whereYear(column, value) {
|
|
1029
1143
|
this.#simple = false;
|
|
1030
|
-
(this.#dateWheres = mqMut(this.#dateWheres)).push({
|
|
1144
|
+
(this.#dateWheres = mqMut(this.#dateWheres)).push({ seq: nextWhereSeq(),
|
|
1031
1145
|
column,
|
|
1032
1146
|
op: "=",
|
|
1033
1147
|
value: String(value),
|
|
@@ -1037,7 +1151,7 @@ export class ModelQuery {
|
|
|
1037
1151
|
}
|
|
1038
1152
|
whereMonth(column, value) {
|
|
1039
1153
|
this.#simple = false;
|
|
1040
|
-
(this.#dateWheres = mqMut(this.#dateWheres)).push({
|
|
1154
|
+
(this.#dateWheres = mqMut(this.#dateWheres)).push({ seq: nextWhereSeq(),
|
|
1041
1155
|
column,
|
|
1042
1156
|
op: "=",
|
|
1043
1157
|
value: String(value),
|
|
@@ -1047,7 +1161,7 @@ export class ModelQuery {
|
|
|
1047
1161
|
}
|
|
1048
1162
|
whereDay(column, value) {
|
|
1049
1163
|
this.#simple = false;
|
|
1050
|
-
(this.#dateWheres = mqMut(this.#dateWheres)).push({
|
|
1164
|
+
(this.#dateWheres = mqMut(this.#dateWheres)).push({ seq: nextWhereSeq(),
|
|
1051
1165
|
column,
|
|
1052
1166
|
op: "=",
|
|
1053
1167
|
value: String(value),
|
|
@@ -1083,14 +1197,15 @@ export class ModelQuery {
|
|
|
1083
1197
|
orderByDesc(column) {
|
|
1084
1198
|
return this.orderBy(column, "desc");
|
|
1085
1199
|
}
|
|
1086
|
-
orderByRaw(sql)
|
|
1200
|
+
/** `orderByRaw($sql, $bindings)`. */
|
|
1201
|
+
orderByRaw(sql, bindings = []) {
|
|
1087
1202
|
this.#simple = false;
|
|
1088
|
-
(this.#orders = mqMut(this.#orders)).push({ raw: sql });
|
|
1203
|
+
(this.#orders = mqMut(this.#orders)).push(bindings.length > 0 ? { raw: sql, bindings } : { raw: sql });
|
|
1089
1204
|
return this;
|
|
1090
1205
|
}
|
|
1091
1206
|
/** Alias for `orderByRaw`. */
|
|
1092
|
-
orderBySql(sql) {
|
|
1093
|
-
return this.orderByRaw(sql);
|
|
1207
|
+
orderBySql(sql, bindings = []) {
|
|
1208
|
+
return this.orderByRaw(sql, bindings);
|
|
1094
1209
|
}
|
|
1095
1210
|
reorder(column, direction = "asc") {
|
|
1096
1211
|
this.#orders = [];
|
|
@@ -1541,6 +1656,13 @@ export class ModelQuery {
|
|
|
1541
1656
|
#canHasExistsSelect() {
|
|
1542
1657
|
if (this.#hasConstraints.length === 0)
|
|
1543
1658
|
return false;
|
|
1659
|
+
// This path compiles its own statement and has no place for values bound in an ORDER BY.
|
|
1660
|
+
for (const o of this.#orders) {
|
|
1661
|
+
if ("raw" in o && o.raw === "__inRandomOrder__")
|
|
1662
|
+
continue;
|
|
1663
|
+
if ("bindings" in o && o.bindings !== undefined && o.bindings.length > 0)
|
|
1664
|
+
return false;
|
|
1665
|
+
}
|
|
1544
1666
|
for (const c of this.#hasConstraints) {
|
|
1545
1667
|
if (c.existsSql === undefined)
|
|
1546
1668
|
return false;
|
|
@@ -1713,7 +1835,7 @@ export class ModelQuery {
|
|
|
1713
1835
|
q =
|
|
1714
1836
|
o.raw === "__inRandomOrder__"
|
|
1715
1837
|
? q.inRandomOrder()
|
|
1716
|
-
: q.orderByRaw(o.raw);
|
|
1838
|
+
: q.orderByRaw(o.raw, o.bindings ?? []);
|
|
1717
1839
|
}
|
|
1718
1840
|
else
|
|
1719
1841
|
q = q.orderBy(o.column, o.direction);
|
|
@@ -1846,90 +1968,16 @@ export class ModelQuery {
|
|
|
1846
1968
|
}
|
|
1847
1969
|
/** Apply this query's wheres onto a QueryBuilder (exists subqueries). */
|
|
1848
1970
|
applyConstraintsTo(q) {
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
: q.whereNotNull(w.column);
|
|
1860
|
-
continue;
|
|
1861
|
-
}
|
|
1862
|
-
q =
|
|
1863
|
-
w.boolean === "or"
|
|
1864
|
-
? q.orWhere(w.column, w.op, w.value)
|
|
1865
|
-
: q.where(w.column, w.op, w.value);
|
|
1866
|
-
}
|
|
1867
|
-
for (const w of this.#whereIns) {
|
|
1868
|
-
if (w.boolean === "or") {
|
|
1869
|
-
q = w.not
|
|
1870
|
-
? q.orWhereNotIn(w.column, w.values)
|
|
1871
|
-
: q.orWhereIn(w.column, w.values);
|
|
1872
|
-
}
|
|
1873
|
-
else {
|
|
1874
|
-
q = w.not
|
|
1875
|
-
? q.whereNotIn(w.column, w.values)
|
|
1876
|
-
: q.whereIn(w.column, w.values);
|
|
1877
|
-
}
|
|
1878
|
-
}
|
|
1879
|
-
for (const w of this.#whereNulls) {
|
|
1880
|
-
if (w.boolean === "or") {
|
|
1881
|
-
q = w.not ? q.orWhereNotNull(w.column) : q.orWhereNull(w.column);
|
|
1882
|
-
}
|
|
1883
|
-
else {
|
|
1884
|
-
q = w.not ? q.whereNotNull(w.column) : q.whereNull(w.column);
|
|
1885
|
-
}
|
|
1886
|
-
}
|
|
1887
|
-
for (const w of this.#whereBetweens) {
|
|
1888
|
-
if (w.boolean === "or") {
|
|
1889
|
-
q = w.not
|
|
1890
|
-
? q.orWhereNotBetween(w.column, w.values)
|
|
1891
|
-
: q.orWhereBetween(w.column, w.values);
|
|
1892
|
-
}
|
|
1893
|
-
else {
|
|
1894
|
-
q = w.not
|
|
1895
|
-
? q.whereNotBetween(w.column, w.values)
|
|
1896
|
-
: q.whereBetween(w.column, w.values);
|
|
1897
|
-
}
|
|
1898
|
-
}
|
|
1899
|
-
for (const w of this.#whereColumns) {
|
|
1900
|
-
q =
|
|
1901
|
-
w.boolean === "or"
|
|
1902
|
-
? q.orWhereColumn(w.first, w.op, w.second)
|
|
1903
|
-
: q.whereColumn(w.first, w.op, w.second);
|
|
1904
|
-
}
|
|
1905
|
-
for (const w of this.#whereRaws) {
|
|
1906
|
-
q =
|
|
1907
|
-
w.boolean === "or"
|
|
1908
|
-
? q.orWhereRaw(w.sql, w.bindings)
|
|
1909
|
-
: q.whereRaw(w.sql, w.bindings);
|
|
1910
|
-
}
|
|
1911
|
-
for (const w of this.#whereLikes) {
|
|
1912
|
-
if (w.boolean === "or") {
|
|
1913
|
-
q = w.not
|
|
1914
|
-
? q.orWhereNotLike(w.column, w.value, w.caseSensitive)
|
|
1915
|
-
: q.orWhereLike(w.column, w.value, w.caseSensitive);
|
|
1916
|
-
}
|
|
1917
|
-
else {
|
|
1918
|
-
q = w.not
|
|
1919
|
-
? q.whereNotLike(w.column, w.value, w.caseSensitive)
|
|
1920
|
-
: q.whereLike(w.column, w.value, w.caseSensitive);
|
|
1921
|
-
}
|
|
1922
|
-
}
|
|
1923
|
-
for (const w of this.#dateWheres) {
|
|
1924
|
-
if (w.kind === "date")
|
|
1925
|
-
q = q.whereDate(w.column, w.op, w.value);
|
|
1926
|
-
else if (w.kind === "year")
|
|
1927
|
-
q = q.whereYear(w.column, w.op, Number(w.value));
|
|
1928
|
-
else if (w.kind === "month")
|
|
1929
|
-
q = q.whereMonth(w.column, w.op, Number(w.value));
|
|
1930
|
-
else
|
|
1931
|
-
q = q.whereDay(w.column, w.op, Number(w.value));
|
|
1932
|
-
}
|
|
1971
|
+
q = applyWhereLists(q, {
|
|
1972
|
+
wheres: this.#wheres,
|
|
1973
|
+
whereIns: this.#whereIns,
|
|
1974
|
+
whereNulls: this.#whereNulls,
|
|
1975
|
+
whereBetweens: this.#whereBetweens,
|
|
1976
|
+
whereColumns: this.#whereColumns,
|
|
1977
|
+
whereRaws: this.#whereRaws,
|
|
1978
|
+
whereLikes: this.#whereLikes,
|
|
1979
|
+
dateWheres: this.#dateWheres,
|
|
1980
|
+
});
|
|
1933
1981
|
for (const constraint of this.#hasConstraints) {
|
|
1934
1982
|
q = this.#applyHasConstraint(q, constraint);
|
|
1935
1983
|
}
|
|
@@ -2154,106 +2202,16 @@ export class ModelQuery {
|
|
|
2154
2202
|
return () => { };
|
|
2155
2203
|
}
|
|
2156
2204
|
return (q) => {
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
? q.orWhereNotNull(w.column)
|
|
2168
|
-
: q.whereNotNull(w.column);
|
|
2169
|
-
continue;
|
|
2170
|
-
}
|
|
2171
|
-
q =
|
|
2172
|
-
w.boolean === "or"
|
|
2173
|
-
? q.orWhere(w.column, w.op, w.value)
|
|
2174
|
-
: q.where(w.column, w.op, w.value);
|
|
2175
|
-
}
|
|
2176
|
-
}
|
|
2177
|
-
if (whereIns) {
|
|
2178
|
-
for (const w of whereIns) {
|
|
2179
|
-
if (w.boolean === "or") {
|
|
2180
|
-
q = w.not
|
|
2181
|
-
? q.orWhereNotIn(w.column, w.values)
|
|
2182
|
-
: q.orWhereIn(w.column, w.values);
|
|
2183
|
-
}
|
|
2184
|
-
else {
|
|
2185
|
-
q = w.not
|
|
2186
|
-
? q.whereNotIn(w.column, w.values)
|
|
2187
|
-
: q.whereIn(w.column, w.values);
|
|
2188
|
-
}
|
|
2189
|
-
}
|
|
2190
|
-
}
|
|
2191
|
-
if (whereNulls) {
|
|
2192
|
-
for (const w of whereNulls) {
|
|
2193
|
-
if (w.boolean === "or") {
|
|
2194
|
-
q = w.not ? q.orWhereNotNull(w.column) : q.orWhereNull(w.column);
|
|
2195
|
-
}
|
|
2196
|
-
else {
|
|
2197
|
-
q = w.not ? q.whereNotNull(w.column) : q.whereNull(w.column);
|
|
2198
|
-
}
|
|
2199
|
-
}
|
|
2200
|
-
}
|
|
2201
|
-
if (whereBetweens) {
|
|
2202
|
-
for (const w of whereBetweens) {
|
|
2203
|
-
if (w.boolean === "or") {
|
|
2204
|
-
q = w.not
|
|
2205
|
-
? q.orWhereNotBetween(w.column, w.values)
|
|
2206
|
-
: q.orWhereBetween(w.column, w.values);
|
|
2207
|
-
}
|
|
2208
|
-
else {
|
|
2209
|
-
q = w.not
|
|
2210
|
-
? q.whereNotBetween(w.column, w.values)
|
|
2211
|
-
: q.whereBetween(w.column, w.values);
|
|
2212
|
-
}
|
|
2213
|
-
}
|
|
2214
|
-
}
|
|
2215
|
-
if (whereColumns) {
|
|
2216
|
-
for (const w of whereColumns) {
|
|
2217
|
-
q =
|
|
2218
|
-
w.boolean === "or"
|
|
2219
|
-
? q.orWhereColumn(w.first, w.op, w.second)
|
|
2220
|
-
: q.whereColumn(w.first, w.op, w.second);
|
|
2221
|
-
}
|
|
2222
|
-
}
|
|
2223
|
-
if (whereRaws) {
|
|
2224
|
-
for (const w of whereRaws) {
|
|
2225
|
-
q =
|
|
2226
|
-
w.boolean === "or"
|
|
2227
|
-
? q.orWhereRaw(w.sql, w.bindings)
|
|
2228
|
-
: q.whereRaw(w.sql, w.bindings);
|
|
2229
|
-
}
|
|
2230
|
-
}
|
|
2231
|
-
if (whereLikes) {
|
|
2232
|
-
for (const w of whereLikes) {
|
|
2233
|
-
if (w.boolean === "or") {
|
|
2234
|
-
q = w.not
|
|
2235
|
-
? q.orWhereNotLike(w.column, w.value, w.caseSensitive)
|
|
2236
|
-
: q.orWhereLike(w.column, w.value, w.caseSensitive);
|
|
2237
|
-
}
|
|
2238
|
-
else {
|
|
2239
|
-
q = w.not
|
|
2240
|
-
? q.whereNotLike(w.column, w.value, w.caseSensitive)
|
|
2241
|
-
: q.whereLike(w.column, w.value, w.caseSensitive);
|
|
2242
|
-
}
|
|
2243
|
-
}
|
|
2244
|
-
}
|
|
2245
|
-
if (dateWheres) {
|
|
2246
|
-
for (const w of dateWheres) {
|
|
2247
|
-
if (w.kind === "date")
|
|
2248
|
-
q = q.whereDate(w.column, w.op, w.value);
|
|
2249
|
-
else if (w.kind === "year")
|
|
2250
|
-
q = q.whereYear(w.column, w.op, Number(w.value));
|
|
2251
|
-
else if (w.kind === "month")
|
|
2252
|
-
q = q.whereMonth(w.column, w.op, Number(w.value));
|
|
2253
|
-
else
|
|
2254
|
-
q = q.whereDay(w.column, w.op, Number(w.value));
|
|
2255
|
-
}
|
|
2256
|
-
}
|
|
2205
|
+
applyWhereLists(q, {
|
|
2206
|
+
wheres,
|
|
2207
|
+
whereIns,
|
|
2208
|
+
whereNulls,
|
|
2209
|
+
whereBetweens,
|
|
2210
|
+
whereColumns,
|
|
2211
|
+
whereRaws,
|
|
2212
|
+
whereLikes,
|
|
2213
|
+
dateWheres,
|
|
2214
|
+
});
|
|
2257
2215
|
};
|
|
2258
2216
|
}
|
|
2259
2217
|
/**
|
|
@@ -2279,7 +2237,7 @@ export class ModelQuery {
|
|
|
2279
2237
|
});
|
|
2280
2238
|
if (usesSoftDeletes(meta.related)) {
|
|
2281
2239
|
const delCol = deletedAtColumn(meta.related);
|
|
2282
|
-
(this.#wheres = mqMut(this.#wheres)).push({
|
|
2240
|
+
(this.#wheres = mqMut(this.#wheres)).push({ seq: nextWhereSeq(),
|
|
2283
2241
|
column: `${relatedAlias}.${delCol}`,
|
|
2284
2242
|
op: "__null__",
|
|
2285
2243
|
value: null,
|
package/dist/model.d.ts
CHANGED
|
@@ -398,9 +398,9 @@ export declare class Model {
|
|
|
398
398
|
static whereNotNull<T extends typeof Model>(this: T, column: ColumnHint<InstanceType<T>>): ModelQuery<InstanceType<T>>;
|
|
399
399
|
static orderBy<T extends typeof Model>(this: T, column: ColumnHint<InstanceType<T>>, direction?: "asc" | "desc"): ModelQuery<InstanceType<T>>;
|
|
400
400
|
static orderByDesc<T extends typeof Model>(this: T, column: ColumnHint<InstanceType<T>>): ModelQuery<InstanceType<T>>;
|
|
401
|
-
static orderByRaw<T extends typeof Model>(this: T,
|
|
401
|
+
static orderByRaw<T extends typeof Model>(this: T, ...args: Parameters<ModelQuery<InstanceType<T>>["orderByRaw"]>): ModelQuery<InstanceType<T>>;
|
|
402
402
|
/** Alias for `orderByRaw`. */
|
|
403
|
-
static orderBySql<T extends typeof Model>(this: T,
|
|
403
|
+
static orderBySql<T extends typeof Model>(this: T, ...args: Parameters<ModelQuery<InstanceType<T>>["orderByRaw"]>): ModelQuery<InstanceType<T>>;
|
|
404
404
|
static latest<T extends typeof Model>(this: T, column?: string): ModelQuery<InstanceType<T>>;
|
|
405
405
|
static oldest<T extends typeof Model>(this: T, column?: string): ModelQuery<InstanceType<T>>;
|
|
406
406
|
static limit<T extends typeof Model>(this: T, value: number): ModelQuery<InstanceType<T>>;
|
package/dist/model.js
CHANGED
|
@@ -1525,13 +1525,13 @@ export class Model {
|
|
|
1525
1525
|
static orderByDesc(column) {
|
|
1526
1526
|
return this.orderBy(column, "desc");
|
|
1527
1527
|
}
|
|
1528
|
-
static orderByRaw(
|
|
1528
|
+
static orderByRaw(...args) {
|
|
1529
1529
|
this.bootIfNotBooted();
|
|
1530
|
-
return this.newQuery().orderByRaw(
|
|
1530
|
+
return this.newQuery().orderByRaw(...args);
|
|
1531
1531
|
}
|
|
1532
1532
|
/** Alias for `orderByRaw`. */
|
|
1533
|
-
static orderBySql(
|
|
1534
|
-
return this.orderByRaw(
|
|
1533
|
+
static orderBySql(...args) {
|
|
1534
|
+
return this.orderByRaw(...args);
|
|
1535
1535
|
}
|
|
1536
1536
|
static latest(column = "created_at") {
|
|
1537
1537
|
this.bootIfNotBooted();
|
package/dist/test-drivers.js
CHANGED
|
@@ -32,7 +32,9 @@ export async function testDrivers() {
|
|
|
32
32
|
}
|
|
33
33
|
const my = Bun.env.BUNYAD_TEST_MYSQL_URL;
|
|
34
34
|
if (my && /^mysql:\/\//i.test(my)) {
|
|
35
|
-
|
|
35
|
+
// Every test file opens its own connection and none closes it, so keep each pool small:
|
|
36
|
+
// with the default of 10 the run exhausts MySQL's 151 connections and later tests fail.
|
|
37
|
+
const connection = connectMysql({ url: my, tls: { rejectUnauthorized: false }, max: 2 });
|
|
36
38
|
if (await reachable(connection))
|
|
37
39
|
drivers.push({ name: "mysql", connection });
|
|
38
40
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bunyad/orm",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.4",
|
|
4
4
|
"description": "Active-record ORM for Bunyad: models, relations, casts, scopes, events, factories.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Shah Khalid",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@bunyad/common": "^0.2.0-beta.
|
|
40
|
-
"@bunyad/database": "^0.2.0-beta.
|
|
39
|
+
"@bunyad/common": "^0.2.0-beta.4",
|
|
40
|
+
"@bunyad/database": "^0.2.0-beta.4"
|
|
41
41
|
},
|
|
42
42
|
"publishConfig": {
|
|
43
43
|
"access": "public"
|