@technicity/data-service-generator 0.10.0-next.0 → 0.10.0-next.1
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/dist/generation/generate.js +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -3
- package/dist/runtime/RuntimeKSQL.d.ts +1 -1
- package/dist/runtime/RuntimeKSQL.js +11 -13
- package/dist/runtime/RuntimeMSSQL.d.ts +14 -18
- package/dist/runtime/RuntimeMSSQL.js +43 -48
- package/dist/runtime/RuntimeMySQL.d.ts +12 -10
- package/dist/runtime/RuntimeMySQL.js +84 -46
- package/dist/runtime/lib/MSSQL.d.ts +13 -0
- package/dist/runtime/lib/MSSQL.js +73 -0
- package/dist/runtime/lib/SDKBadWhereError.d.ts +4 -0
- package/dist/runtime/lib/SDKBadWhereError.js +10 -0
- package/dist/runtime/lib/SDKNotFoundError.d.ts +4 -0
- package/dist/runtime/lib/SDKNotFoundError.js +10 -0
- package/dist/runtime/lib/getDateTimeStringMySQL.d.ts +1 -0
- package/dist/runtime/lib/getDateTimeStringMySQL.js +8 -0
- package/dist/runtime/lib/getSqlAst.js +2 -2
- package/dist/runtime/lib/getWhere.d.ts +0 -17
- package/dist/runtime/lib/getWhere.js +4 -228
- package/dist/runtime/lib/shared.d.ts +13 -22
- package/dist/runtime/lib/shared.js +787 -16
- package/dist/runtime/lib/stringifyWhere.d.ts +18 -0
- package/dist/runtime/lib/stringifyWhere.js +228 -0
- package/dist/runtime/lib/typeCastMSSQL.js +1 -1
- package/package.json +1 -1
- package/dist/runtime/Runtime.d.ts +0 -23
- package/dist/runtime/Runtime.js +0 -29
- package/dist/runtime/lib/create.d.ts +0 -12
- package/dist/runtime/lib/create.js +0 -175
- package/dist/runtime/lib/delete.d.ts +0 -5
- package/dist/runtime/lib/delete.js +0 -43
- package/dist/runtime/lib/error.d.ts +0 -9
- package/dist/runtime/lib/error.js +0 -22
- package/dist/runtime/lib/getData.d.ts +0 -4
- package/dist/runtime/lib/getData.js +0 -227
- package/dist/runtime/lib/prepareWhere.d.ts +0 -2
- package/dist/runtime/lib/prepareWhere.js +0 -158
- package/dist/runtime/lib/resolve.d.ts +0 -10
- package/dist/runtime/lib/resolve.js +0 -66
- package/dist/runtime/lib/update.d.ts +0 -4
- package/dist/runtime/lib/update.js +0 -143
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IOrderBy, IDialect } from "../IRuntime";
|
|
2
|
+
declare type IWhere = {
|
|
3
|
+
[k: string]: any;
|
|
4
|
+
};
|
|
5
|
+
declare type IArgs = {
|
|
6
|
+
[k: string]: any;
|
|
7
|
+
};
|
|
8
|
+
export declare function stringifyWhere(input: {
|
|
9
|
+
where: IWhere;
|
|
10
|
+
table: string;
|
|
11
|
+
dialect: IDialect;
|
|
12
|
+
args: IArgs;
|
|
13
|
+
orderBy?: IOrderBy | undefined;
|
|
14
|
+
rowWithMatchingCursor?: any;
|
|
15
|
+
}): string;
|
|
16
|
+
export declare function getEscapeId(dialect: IDialect): any;
|
|
17
|
+
export declare function getEscape(dialect: IDialect): any;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getEscape = exports.getEscapeId = exports.stringifyWhere = void 0;
|
|
4
|
+
const _ = require("lodash/fp");
|
|
5
|
+
const MySqlString = require("sqlstring");
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
const TSqlString = require("tsqlstring");
|
|
8
|
+
function stringifyWhere(input) {
|
|
9
|
+
const { where, table, dialect, args, orderBy, rowWithMatchingCursor } = input;
|
|
10
|
+
const escapeId = getEscapeId(dialect);
|
|
11
|
+
const escape = getEscape(dialect);
|
|
12
|
+
let result = _stringifyWhere(where, table, escapeId, escape, "");
|
|
13
|
+
const paginationWhere = stringifyPaginationWhere({
|
|
14
|
+
table,
|
|
15
|
+
args,
|
|
16
|
+
orderBy,
|
|
17
|
+
escapeId,
|
|
18
|
+
escape,
|
|
19
|
+
rowWithMatchingCursor,
|
|
20
|
+
});
|
|
21
|
+
if (paginationWhere) {
|
|
22
|
+
result =
|
|
23
|
+
result.length === 0
|
|
24
|
+
? paginationWhere
|
|
25
|
+
: result + " AND " + paginationWhere;
|
|
26
|
+
}
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
exports.stringifyWhere = stringifyWhere;
|
|
30
|
+
function _stringifyWhere(where, table, escapeId, escape, result) {
|
|
31
|
+
if (Object.prototype.hasOwnProperty.call(where, "$and")) {
|
|
32
|
+
if (Object.keys(where).length !== 1) {
|
|
33
|
+
throw new Error("Must have 1 key: " + JSON.stringify(where, null, 2));
|
|
34
|
+
}
|
|
35
|
+
const _xs = where.$and.filter((x) => x != null);
|
|
36
|
+
if (_xs.length === 0) {
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
const xs = _xs
|
|
40
|
+
.map((x) => _stringifyWhere(x, table, escapeId, escape, result))
|
|
41
|
+
.filter(Boolean);
|
|
42
|
+
if (xs.length === 0) {
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
return `(${xs.join(" AND ")})`;
|
|
46
|
+
}
|
|
47
|
+
if (Object.prototype.hasOwnProperty.call(where, "$or")) {
|
|
48
|
+
if (Object.keys(where).length !== 1) {
|
|
49
|
+
throw new Error("Must have 1 key: " + JSON.stringify(where, null, 2));
|
|
50
|
+
}
|
|
51
|
+
const _xs = where.$or.filter((x) => x != null);
|
|
52
|
+
if (_xs.length === 0) {
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
const xs = _xs
|
|
56
|
+
.map((x) => _stringifyWhere(x, table, escapeId, escape, result))
|
|
57
|
+
.filter(Boolean);
|
|
58
|
+
if (xs.length === 0) {
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
return `(${xs.join(" OR ")})`;
|
|
62
|
+
}
|
|
63
|
+
function printValue(v) {
|
|
64
|
+
if (v === true) {
|
|
65
|
+
v = 1;
|
|
66
|
+
}
|
|
67
|
+
if (v === false) {
|
|
68
|
+
v = 0;
|
|
69
|
+
}
|
|
70
|
+
return escape(v);
|
|
71
|
+
}
|
|
72
|
+
return Object.keys(where)
|
|
73
|
+
.map((k) => {
|
|
74
|
+
let v = where[k];
|
|
75
|
+
if (v === void 0) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
// Can't do this, since we need this function to be sync
|
|
79
|
+
// if (relationMap[k] !== null) {
|
|
80
|
+
// const relationData = await getRelationData(k, v, relationMap);
|
|
81
|
+
// k = relationData.k;
|
|
82
|
+
// v = relationData.v;
|
|
83
|
+
// }
|
|
84
|
+
if (v === null) {
|
|
85
|
+
return `${table}.${escapeId(k)} IS NULL`;
|
|
86
|
+
}
|
|
87
|
+
if (typeof v === "string" ||
|
|
88
|
+
typeof v === "number" ||
|
|
89
|
+
typeof v === "boolean") {
|
|
90
|
+
return `${table}.${escapeId(k)} = ${printValue(v)}`;
|
|
91
|
+
}
|
|
92
|
+
if (_.isPlainObject(v)) {
|
|
93
|
+
const keys = Object.keys(v);
|
|
94
|
+
if (keys.length !== 1) {
|
|
95
|
+
throw new Error("Must have 1 key: " + JSON.stringify(v, null, 2));
|
|
96
|
+
}
|
|
97
|
+
const operator = keys[0];
|
|
98
|
+
const operand = v[operator];
|
|
99
|
+
if (operator === "$ne") {
|
|
100
|
+
return `${table}.${escapeId(k)} ${getOperatorNeq(v)} ${printValue(operand)}`;
|
|
101
|
+
}
|
|
102
|
+
if (operator === "$gt") {
|
|
103
|
+
return `${table}.${escapeId(k)} > ${printValue(operand)}`;
|
|
104
|
+
}
|
|
105
|
+
if (operator === "$gte") {
|
|
106
|
+
return `${table}.${escapeId(k)} >= ${printValue(operand)}`;
|
|
107
|
+
}
|
|
108
|
+
if (operator === "$lt") {
|
|
109
|
+
return `${table}.${escapeId(k)} < ${printValue(operand)}`;
|
|
110
|
+
}
|
|
111
|
+
if (operator === "$lte") {
|
|
112
|
+
return `${table}.${escapeId(k)} <= ${printValue(operand)}`;
|
|
113
|
+
}
|
|
114
|
+
if (operator === "$like") {
|
|
115
|
+
return `${table}.${escapeId(k)} LIKE ${printValue(operand)}`;
|
|
116
|
+
}
|
|
117
|
+
if (operator === "$nlike") {
|
|
118
|
+
return `${table}.${escapeId(k)} NOT LIKE ${printValue(operand)}`;
|
|
119
|
+
}
|
|
120
|
+
if (operator === "$in") {
|
|
121
|
+
if (operand.length === 0) {
|
|
122
|
+
// Would do "FALSE" instead, as it's more readable, but it
|
|
123
|
+
// causes a RequestError in MSSQL.
|
|
124
|
+
return "(1=0)";
|
|
125
|
+
}
|
|
126
|
+
return `${table}.${escapeId(k)} IN (${operand
|
|
127
|
+
.map((x) => printValue(x))
|
|
128
|
+
.join(",")})`;
|
|
129
|
+
}
|
|
130
|
+
if (operator === "$nin") {
|
|
131
|
+
if (operand.length === 0) {
|
|
132
|
+
// Would do "TRUE" instead, as it's more readable, but it
|
|
133
|
+
// causes a RequestError in MSSQL.
|
|
134
|
+
return "(1=1)";
|
|
135
|
+
}
|
|
136
|
+
return `${table}.${escapeId(k)} NOT IN (${operand
|
|
137
|
+
.map((x) => printValue(x))
|
|
138
|
+
.join(",")})`;
|
|
139
|
+
}
|
|
140
|
+
if (operator === "$btwn") {
|
|
141
|
+
if (operand.length !== 2) {
|
|
142
|
+
throw new Error("Expected length of 2, got: " + operand.length);
|
|
143
|
+
}
|
|
144
|
+
return `${table}.${escapeId(k)} BETWEEN ${printValue(operand[0])} AND ${printValue(operand[1])}`;
|
|
145
|
+
}
|
|
146
|
+
if (operator === "$nbtwn") {
|
|
147
|
+
if (operand.length !== 2) {
|
|
148
|
+
throw new Error("Expected length of 2, got: " + operand.length);
|
|
149
|
+
}
|
|
150
|
+
return `${table}.${escapeId(k)} NOT BETWEEN ${printValue(operand[0])} AND ${printValue(operand[1])}`;
|
|
151
|
+
}
|
|
152
|
+
throw new Error("Invalid operator: " + operator);
|
|
153
|
+
}
|
|
154
|
+
throw new Error("Invalid value: " + v);
|
|
155
|
+
})
|
|
156
|
+
.filter((x) => x != null)
|
|
157
|
+
.join(" AND ");
|
|
158
|
+
}
|
|
159
|
+
const valuesThatUseIsOrIsNot = new Set([null]);
|
|
160
|
+
function getOperatorNeq(value) {
|
|
161
|
+
return valuesThatUseIsOrIsNot.has(value) ? "IS NOT" : "!=";
|
|
162
|
+
}
|
|
163
|
+
// async function getRelationData(k: string, v: any, relationMap: IRelationMap) {
|
|
164
|
+
// // TODO
|
|
165
|
+
// return { k, v };
|
|
166
|
+
// }
|
|
167
|
+
function stringifyPaginationWhere(input) {
|
|
168
|
+
const { table, args, orderBy, escapeId, escape, rowWithMatchingCursor } = input;
|
|
169
|
+
if (args?.$paginate?.after == null && args?.$paginate?.before == null) {
|
|
170
|
+
return "";
|
|
171
|
+
}
|
|
172
|
+
if (rowWithMatchingCursor == null) {
|
|
173
|
+
return "";
|
|
174
|
+
}
|
|
175
|
+
// orderBy should never be null because of getOrderBy, but add a check.
|
|
176
|
+
if (orderBy == null) {
|
|
177
|
+
throw new Error("orderBy cannot be null when paginating");
|
|
178
|
+
}
|
|
179
|
+
function getCompOp(dir) {
|
|
180
|
+
return dir === "asc" ? ">" : "<";
|
|
181
|
+
}
|
|
182
|
+
function printValue(v) {
|
|
183
|
+
if (v === true) {
|
|
184
|
+
v = 1;
|
|
185
|
+
}
|
|
186
|
+
if (v === false) {
|
|
187
|
+
v = 0;
|
|
188
|
+
}
|
|
189
|
+
return escape(v);
|
|
190
|
+
}
|
|
191
|
+
// https://gist.github.com/pcattori/2bb645d587e45c9fdbcabf5cef7a7106
|
|
192
|
+
const cond = orderBy
|
|
193
|
+
.map(({ column, direction }, i) => {
|
|
194
|
+
let a = orderBy.slice(0, i).map(({ column: col2 }) => {
|
|
195
|
+
const field = `${table}.${escapeId(col2)}`;
|
|
196
|
+
const op = "=";
|
|
197
|
+
const v = printValue(rowWithMatchingCursor[col2]);
|
|
198
|
+
return `${field} ${op} ${v}`;
|
|
199
|
+
});
|
|
200
|
+
const field = `${table}.${escapeId(column)}`;
|
|
201
|
+
const op = getCompOp(direction);
|
|
202
|
+
const v = printValue(rowWithMatchingCursor[column]);
|
|
203
|
+
a.push(`${field} ${op} ${v}`);
|
|
204
|
+
return "(" + a.join(" AND ") + ")";
|
|
205
|
+
})
|
|
206
|
+
.join(" OR ");
|
|
207
|
+
return "(" + cond + ")";
|
|
208
|
+
}
|
|
209
|
+
function getEscapeId(dialect) {
|
|
210
|
+
if (dialect === "mysql") {
|
|
211
|
+
return MySqlString.escapeId.bind(MySqlString);
|
|
212
|
+
}
|
|
213
|
+
if (dialect === "mssql") {
|
|
214
|
+
return TSqlString.escapeId.bind(TSqlString);
|
|
215
|
+
}
|
|
216
|
+
throw new Error("Unsupported dialect: " + dialect);
|
|
217
|
+
}
|
|
218
|
+
exports.getEscapeId = getEscapeId;
|
|
219
|
+
function getEscape(dialect) {
|
|
220
|
+
if (dialect === "mysql") {
|
|
221
|
+
return MySqlString.escape.bind(MySqlString);
|
|
222
|
+
}
|
|
223
|
+
if (dialect === "mssql") {
|
|
224
|
+
return TSqlString.escape.bind(TSqlString);
|
|
225
|
+
}
|
|
226
|
+
throw new Error("Unsupported dialect: " + dialect);
|
|
227
|
+
}
|
|
228
|
+
exports.getEscape = getEscape;
|
|
@@ -5,7 +5,7 @@ const mssql = require("mssql");
|
|
|
5
5
|
// TODO: see https://github.com/tediousjs/node-mssql/pull/1171
|
|
6
6
|
function typeCastMSSQL(customTypeCast) {
|
|
7
7
|
return function (result, meta) {
|
|
8
|
-
|
|
8
|
+
let typeCasts = {};
|
|
9
9
|
for (let k in meta) {
|
|
10
10
|
const v = meta[k];
|
|
11
11
|
if (typeof customTypeCast === "function") {
|
package/package.json
CHANGED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import Cache from './Cache';
|
|
2
|
-
import { IArtifacts, IRuntime, TMiddleware, TResolveParams } from './IRuntime';
|
|
3
|
-
import { MiddlewareHandler } from './lib/resolve';
|
|
4
|
-
declare abstract class Runtime implements IRuntime {
|
|
5
|
-
protected abstract $dialect: "mysql" | "mssql";
|
|
6
|
-
protected $clientCache?: Cache;
|
|
7
|
-
protected $middlewareHandler: MiddlewareHandler<TMiddleware>;
|
|
8
|
-
constructor(otherOpts: {
|
|
9
|
-
redisHost?: string;
|
|
10
|
-
}, clientOpts?: {
|
|
11
|
-
[k: string]: any;
|
|
12
|
-
});
|
|
13
|
-
protected abstract formatQuery(q: string, values: any[]): string;
|
|
14
|
-
protected abstract beginTransaction(): Promise<any>;
|
|
15
|
-
protected abstract dbCall(q: string): Promise<any>;
|
|
16
|
-
abstract $shutdown(): Promise<void>;
|
|
17
|
-
$queryRaw(sql: string, values?: any[]): Promise<any>;
|
|
18
|
-
resolve(input: TResolveParams): Promise<any>;
|
|
19
|
-
$use(middleware: TMiddleware): Promise<void>;
|
|
20
|
-
$prepareWhere(artifacts: IArtifacts, table: string, data: any): Promise<{}>;
|
|
21
|
-
$whereNeedsProcessing(where: any): boolean;
|
|
22
|
-
}
|
|
23
|
-
export default Runtime;
|
package/dist/runtime/Runtime.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const Cache_1 = require("./Cache");
|
|
4
|
-
const prepareWhere_1 = require("./lib/prepareWhere");
|
|
5
|
-
const resolve_1 = require("./lib/resolve");
|
|
6
|
-
class Runtime {
|
|
7
|
-
constructor(otherOpts, clientOpts) {
|
|
8
|
-
this.$middlewareHandler = new resolve_1.MiddlewareHandler();
|
|
9
|
-
const debugCache = clientOpts?.debug?.includes("Cache");
|
|
10
|
-
if (otherOpts.redisHost)
|
|
11
|
-
this.$clientCache = new Cache_1.default(otherOpts.redisHost, debugCache);
|
|
12
|
-
}
|
|
13
|
-
async $queryRaw(sql, values) {
|
|
14
|
-
return this.dbCall(this.formatQuery(sql, values ?? []));
|
|
15
|
-
}
|
|
16
|
-
async resolve(input) {
|
|
17
|
-
return (0, resolve_1.resolve)(input, this.dbCall.bind(this), this.formatQuery.bind(this), this.beginTransaction.bind(this), this.$dialect, this.$middlewareHandler, input.context ?? {}, this.$clientCache);
|
|
18
|
-
}
|
|
19
|
-
async $use(middleware) {
|
|
20
|
-
this.$middlewareHandler.register(middleware);
|
|
21
|
-
}
|
|
22
|
-
async $prepareWhere(artifacts, table, data) {
|
|
23
|
-
return (0, prepareWhere_1.prepareWhere)(artifacts, table, data, this.dbCall.bind(this), this.formatQuery.bind(this));
|
|
24
|
-
}
|
|
25
|
-
$whereNeedsProcessing(where) {
|
|
26
|
-
return JSON.stringify(where).includes("Uuid");
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
exports.default = Runtime;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { IDialect, TBeginTransaction, TContext, TDbCall, TFormatQuery, TResolveParams } from '../IRuntime';
|
|
2
|
-
export declare function create(input: TResolveParams, dbCall: TDbCall, formatQuery: TFormatQuery, beginTransaction: TBeginTransaction, dialect: IDialect, context: TContext): Promise<any>;
|
|
3
|
-
declare type TRunCreateTreeSQL = (table: string, referencedKey: string | null, referencedKeyValue: number | string | null, columns: string[][], values: any[][], dbCall: TDbCall, formatQuery: TFormatQuery) => Promise<any[]>;
|
|
4
|
-
export declare function runCreateTree(tree: TCreateTree, referencedKeyValue: number | string | null, runCreateTreeSQL: TRunCreateTreeSQL, dbCall: TDbCall, formatQuery: TFormatQuery, dialect: IDialect): Promise<any[]>;
|
|
5
|
-
declare type TCreateTree = {
|
|
6
|
-
table: string;
|
|
7
|
-
referencedKey: string | null;
|
|
8
|
-
columns: string[][];
|
|
9
|
-
values: any[][];
|
|
10
|
-
children: TCreateTree[][];
|
|
11
|
-
};
|
|
12
|
-
export {};
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.runCreateTree = exports.create = void 0;
|
|
4
|
-
const uuid_1 = require("uuid");
|
|
5
|
-
const getData_1 = require("./getData");
|
|
6
|
-
const shared_1 = require("./shared");
|
|
7
|
-
async function create(input, dbCall, formatQuery, beginTransaction, dialect, context) {
|
|
8
|
-
async function _create() {
|
|
9
|
-
// Shallow clone, as we're going to mutate later
|
|
10
|
-
let data = { ...input.data };
|
|
11
|
-
const tableArtifacts = input.artifacts[input.resource];
|
|
12
|
-
// Top-level only
|
|
13
|
-
if ((0, shared_1.hasMappedFields)(input.artifacts, input.resource, data)) {
|
|
14
|
-
await (0, shared_1.mapMappedFields)(tableArtifacts, data, dbCall, formatQuery);
|
|
15
|
-
}
|
|
16
|
-
const hasChildren = Object.keys(data).some((k) => {
|
|
17
|
-
const oneToManyRelation = tableArtifacts.relationFields[k];
|
|
18
|
-
if (oneToManyRelation == null) {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
if (oneToManyRelation.type === "one-to-many__many-to-one" &&
|
|
22
|
-
oneToManyRelation.kind === "one-to-many") {
|
|
23
|
-
return true;
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
if (hasChildren) {
|
|
27
|
-
const { dbCall: dbCallTransaction, commit } = await beginTransaction();
|
|
28
|
-
const id = await runCreateTree(getCreateTree([data], input.resource, null, context?.specialCaseUuidColumn, dialect, input.artifacts), null, dialect === "mssql" ? runCreateTreeMSSQL : runCreateTreeMySQL, dbCallTransaction, formatQuery, dialect).then((xs) => xs[0]);
|
|
29
|
-
await commit();
|
|
30
|
-
return id;
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
data = processCreateData(data, tableArtifacts, dialect, context?.specialCaseUuidColumn);
|
|
34
|
-
if (dialect === "mysql") {
|
|
35
|
-
const inserted = await dbCall(formatQuery("INSERT INTO ?? SET ?", [input.resource, data]));
|
|
36
|
-
return inserted.insertId;
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
const columns = Object.keys(data);
|
|
40
|
-
const values = Object.values(data);
|
|
41
|
-
const inserted = await dbCall(formatQuery(`INSERT INTO ?? (??) VALUES (?) SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]`, [input.resource, columns, values]));
|
|
42
|
-
return inserted[0]["SCOPE_IDENTITY"];
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
const id = await _create();
|
|
47
|
-
return (0, getData_1.getData)({ ...input, args: { $where: { id } } }, dbCall, formatQuery, dialect);
|
|
48
|
-
}
|
|
49
|
-
exports.create = create;
|
|
50
|
-
function processCreateData(data, tableArtifacts, dialect, specialCaseUuidColumn) {
|
|
51
|
-
const out = { ...data };
|
|
52
|
-
if (dialect === "mysql" && tableArtifacts.dateTimeFieldsCount > 0) {
|
|
53
|
-
for (let k in tableArtifacts.dateTimeFields) {
|
|
54
|
-
if (out[k] != null) {
|
|
55
|
-
out[k] = (0, shared_1.getDateTimeStringMySQL)(out[k]);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
// Delete keys with value of undefined
|
|
60
|
-
for (let k in out) {
|
|
61
|
-
if (out[k] === void 0) {
|
|
62
|
-
delete out[k];
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
const scalarFieldSet = new Set(tableArtifacts.scalarFields);
|
|
66
|
-
if (specialCaseUuidColumn &&
|
|
67
|
-
scalarFieldSet.has("uuid") &&
|
|
68
|
-
!Object.prototype.hasOwnProperty.call(out, "uuid")) {
|
|
69
|
-
out["uuid"] = (0, uuid_1.v4)();
|
|
70
|
-
}
|
|
71
|
-
return out;
|
|
72
|
-
}
|
|
73
|
-
async function runCreateTree(tree, referencedKeyValue, runCreateTreeSQL, dbCall, formatQuery, dialect) {
|
|
74
|
-
const ids = await runCreateTreeSQL(tree.table, tree.referencedKey, referencedKeyValue, tree.columns, tree.values, dbCall, formatQuery);
|
|
75
|
-
if (tree.children?.length > 0) {
|
|
76
|
-
// https://github.com/tediousjs/node-mssql/issues/302
|
|
77
|
-
if (dialect === "mssql") {
|
|
78
|
-
const idIndexes = Array(ids.length)
|
|
79
|
-
.fill(null)
|
|
80
|
-
.map((_, i) => i);
|
|
81
|
-
for (let i of idIndexes) {
|
|
82
|
-
for (let c of tree.children[i]) {
|
|
83
|
-
await runCreateTree(c, ids[i], runCreateTreeSQL, dbCall, formatQuery, dialect);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
await Promise.all(ids.flatMap((id, i) => tree.children[i].map((c) => runCreateTree(c, id, runCreateTreeSQL, dbCall, formatQuery, dialect))));
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return ids;
|
|
92
|
-
}
|
|
93
|
-
exports.runCreateTree = runCreateTree;
|
|
94
|
-
function getCreateTree(data, table, referencedKey, specialCaseUuidColumn, dialect, artifacts) {
|
|
95
|
-
const tableArtifacts = artifacts[table];
|
|
96
|
-
const scalarFieldSet = new Set(tableArtifacts.scalarFields);
|
|
97
|
-
const out = {
|
|
98
|
-
table,
|
|
99
|
-
referencedKey,
|
|
100
|
-
columns: [],
|
|
101
|
-
values: [],
|
|
102
|
-
children: [],
|
|
103
|
-
};
|
|
104
|
-
for (let i = 0; i < data.length; i++) {
|
|
105
|
-
let d = data[i];
|
|
106
|
-
if (Object.keys(d).length === 0) {
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
d = processCreateData(d, tableArtifacts, dialect, specialCaseUuidColumn);
|
|
110
|
-
out.columns[i] = [];
|
|
111
|
-
out.values[i] = [];
|
|
112
|
-
out.children[i] = [];
|
|
113
|
-
for (let k in d) {
|
|
114
|
-
if (scalarFieldSet.has(k)) {
|
|
115
|
-
out.columns[i].push(k);
|
|
116
|
-
const v = d[k];
|
|
117
|
-
out.values[i].push(v);
|
|
118
|
-
continue;
|
|
119
|
-
}
|
|
120
|
-
const oneToManyRelation = tableArtifacts.relationFields[k];
|
|
121
|
-
if (oneToManyRelation == null ||
|
|
122
|
-
oneToManyRelation.type !== "one-to-many__many-to-one" ||
|
|
123
|
-
oneToManyRelation.kind !== "one-to-many") {
|
|
124
|
-
continue;
|
|
125
|
-
}
|
|
126
|
-
if (!Array.isArray(d[k]?.$create)) {
|
|
127
|
-
throw new Error("Invalid data: " + k);
|
|
128
|
-
}
|
|
129
|
-
out.children[i].push(getCreateTree(d[k].$create, oneToManyRelation.table, oneToManyRelation.relation.referencedKey, specialCaseUuidColumn, dialect, artifacts));
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return out;
|
|
133
|
-
}
|
|
134
|
-
const runCreateTreeMySQL = async (table, referencedKey, referencedKeyValue, columns, values, dbCall, formatQuery) => {
|
|
135
|
-
let allColumns = columns;
|
|
136
|
-
if (typeof referencedKey === "string") {
|
|
137
|
-
allColumns = allColumns.slice().map((xs) => xs.concat(referencedKey));
|
|
138
|
-
}
|
|
139
|
-
let allValues = values;
|
|
140
|
-
if (referencedKeyValue != null) {
|
|
141
|
-
allValues = allValues.slice().map((xs) => xs.concat(referencedKeyValue));
|
|
142
|
-
}
|
|
143
|
-
return Promise.all(allColumns.map((cs, i) => dbCall(formatQuery(`INSERT INTO ?? (??) VALUES (?)`, [table, cs, allValues[i]])).then((x) => x.insertId)));
|
|
144
|
-
};
|
|
145
|
-
// This doesn't use bulk inserts because:
|
|
146
|
-
// 1. columns aren't necessarily uniform
|
|
147
|
-
// 2. We don't want to do backflips to get all the inserted IDs
|
|
148
|
-
const runCreateTreeMSSQL = async (table, referencedKey, referencedKeyValue, columns, values, dbCall, formatQuery) => {
|
|
149
|
-
let allColumns = columns;
|
|
150
|
-
if (typeof referencedKey === "string") {
|
|
151
|
-
allColumns = allColumns.slice().map((xs) => xs.concat(referencedKey));
|
|
152
|
-
}
|
|
153
|
-
let allValues = values;
|
|
154
|
-
if (referencedKeyValue != null) {
|
|
155
|
-
allValues = allValues.slice().map((xs) => xs.concat(referencedKeyValue));
|
|
156
|
-
}
|
|
157
|
-
// https://github.com/tediousjs/node-mssql/issues/302
|
|
158
|
-
// return Promise.all(
|
|
159
|
-
// allColumns.map((cs, i) =>
|
|
160
|
-
// dbCall(
|
|
161
|
-
// formatQuery(
|
|
162
|
-
// `INSERT INTO ?? (??) VALUES (?) SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]`,
|
|
163
|
-
// [table, cs, allValues[i]]
|
|
164
|
-
// )
|
|
165
|
-
// ).then((xs) => xs[0]["SCOPE_IDENTITY"])
|
|
166
|
-
// )
|
|
167
|
-
// );
|
|
168
|
-
const out = [];
|
|
169
|
-
let i = 0;
|
|
170
|
-
for (let cs of allColumns) {
|
|
171
|
-
out.push(await dbCall(formatQuery(`INSERT INTO ?? (??) VALUES (?) SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]`, [table, cs, allValues[i]])).then((xs) => xs[0]["SCOPE_IDENTITY"]));
|
|
172
|
-
i += 1;
|
|
173
|
-
}
|
|
174
|
-
return out;
|
|
175
|
-
};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { IDialect, TDbCall, TFormatQuery } from '../IRuntime';
|
|
2
|
-
import type { TResolveParams } from "../IRuntime";
|
|
3
|
-
import Cache from '../Cache';
|
|
4
|
-
export declare function deleteOne(input: TResolveParams, dbCall: TDbCall, formatQuery: TFormatQuery, dialect: IDialect, cache?: Cache): Promise<boolean>;
|
|
5
|
-
export declare function deleteMany(input: TResolveParams, dbCall: TDbCall, formatQuery: TFormatQuery, dialect: IDialect, cache?: Cache): Promise<boolean>;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.deleteMany = exports.deleteOne = void 0;
|
|
4
|
-
const error_1 = require("./error");
|
|
5
|
-
const getWhere_1 = require("./getWhere");
|
|
6
|
-
async function deleteOne(input, dbCall, formatQuery, dialect, cache) {
|
|
7
|
-
const _findOne = Object.entries(input.args.$where)[0];
|
|
8
|
-
const findOne = { key: _findOne[0], value: _findOne[1] };
|
|
9
|
-
const current = await dbCall(formatQuery("SELECT * FROM ?? WHERE ?? = ?", [
|
|
10
|
-
input.resource,
|
|
11
|
-
findOne.key,
|
|
12
|
-
findOne.value,
|
|
13
|
-
])).then((xs) => xs[0]);
|
|
14
|
-
if (current == null) {
|
|
15
|
-
throw new error_1.SDKNotFoundError();
|
|
16
|
-
}
|
|
17
|
-
if (cache && current.uuid)
|
|
18
|
-
cache.purge(current.uuid);
|
|
19
|
-
await dbCall(formatQuery("DELETE FROM ?? WHERE ?? = ?", [
|
|
20
|
-
input.resource,
|
|
21
|
-
findOne.key,
|
|
22
|
-
findOne.value,
|
|
23
|
-
]));
|
|
24
|
-
return true;
|
|
25
|
-
}
|
|
26
|
-
exports.deleteOne = deleteOne;
|
|
27
|
-
async function deleteMany(input, dbCall, formatQuery, dialect, cache) {
|
|
28
|
-
const escapeId = (0, getWhere_1.getEscapeId)(dialect);
|
|
29
|
-
const where = (0, getWhere_1.getWhere)(escapeId(input.resource), input.args, dialect);
|
|
30
|
-
if (where == null)
|
|
31
|
-
throw new Error("Null where");
|
|
32
|
-
if (cache)
|
|
33
|
-
try {
|
|
34
|
-
const query = formatQuery(`SELECT uuid FROM ?? WHERE ${where}`, [input.resource]);
|
|
35
|
-
const matches = await dbCall(query);
|
|
36
|
-
const uuids = matches.map((x) => x.uuid);
|
|
37
|
-
cache.purge(...uuids);
|
|
38
|
-
}
|
|
39
|
-
catch (err) { }
|
|
40
|
-
await dbCall(formatQuery(`DELETE FROM ?? WHERE ${where}`, [input.resource]));
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
exports.deleteMany = deleteMany;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export declare class CustomError extends Error {
|
|
2
|
-
constructor(message: string);
|
|
3
|
-
}
|
|
4
|
-
export declare class SDKBadWhereError extends CustomError {
|
|
5
|
-
constructor(message?: string);
|
|
6
|
-
}
|
|
7
|
-
export declare class SDKNotFoundError extends CustomError {
|
|
8
|
-
constructor();
|
|
9
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SDKNotFoundError = exports.SDKBadWhereError = exports.CustomError = void 0;
|
|
4
|
-
class CustomError extends Error {
|
|
5
|
-
constructor(message) {
|
|
6
|
-
super(message);
|
|
7
|
-
this.name = this.constructor.name;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
exports.CustomError = CustomError;
|
|
11
|
-
class SDKBadWhereError extends CustomError {
|
|
12
|
-
constructor(message) {
|
|
13
|
-
super(message || "Invalid $where");
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
exports.SDKBadWhereError = SDKBadWhereError;
|
|
17
|
-
class SDKNotFoundError extends CustomError {
|
|
18
|
-
constructor() {
|
|
19
|
-
super("Not found");
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
exports.SDKNotFoundError = SDKNotFoundError;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import Cache from '../Cache';
|
|
2
|
-
import { IDialect, TDbCall, TFormatQuery, TResolveParams } from '../IRuntime';
|
|
3
|
-
export declare function getCacheableData(input: TResolveParams, dbCall: TDbCall, formatQuery: TFormatQuery, dialect: IDialect, cache: Cache): Promise<any>;
|
|
4
|
-
export declare function getData(input: TResolveParams, dbCall: TDbCall, formatQuery: TFormatQuery, dialect: IDialect): Promise<any>;
|