@ronin/compiler 0.14.9 → 0.14.10
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 +2 -21
- package/dist/index.d.ts +0 -2
- package/dist/index.js +36 -47
- package/package.json +1 -1
package/README.md
CHANGED
@@ -70,7 +70,7 @@ executed and their results can be formatted by the compiler as well:
|
|
70
70
|
|
71
71
|
```typescript
|
72
72
|
// Passing `rawResults` (rows being arrays of values) provided by the database (ideal)
|
73
|
-
const results: Array<Result> = transaction.formatResults(rawResults);
|
73
|
+
const results: Array<Result> = transaction.formatResults(rawResults, true);
|
74
74
|
|
75
75
|
// Passing `objectResults` (rows being objects) provided by a driver
|
76
76
|
const results: Array<Result> = transaction.formatResults(objectResults, false);
|
@@ -127,26 +127,7 @@ new Transaction(queries, {
|
|
127
127
|
// Instead of returning an array of parameters for every statement (which allows for
|
128
128
|
// preventing SQL injections), all parameters are inlined directly into the SQL strings.
|
129
129
|
// This option should only be used if the generated SQL will be manually verified.
|
130
|
-
inlineParams: true
|
131
|
-
|
132
|
-
// By default, in the generated SQL statements, the compiler does not alias columns if
|
133
|
-
// multiple different tables with the same column names are being joined. Only the table
|
134
|
-
// names themselves are aliased.
|
135
|
-
//
|
136
|
-
// This ensures the cleanest possible SQL statements in conjunction with the default
|
137
|
-
// behavior of SQL databases, where the result of a statement is a list (array) of
|
138
|
-
// values, which are inherently not prone to conflicts.
|
139
|
-
//
|
140
|
-
// If the driver being used instead returns an object for every row, the driver must
|
141
|
-
// ensure the uniqueness of every key in that object, which means prefixing duplicated
|
142
|
-
// column names with the name of the respective table, if multiple tables are joined
|
143
|
-
// (example for an object key: "table_name.column_name").
|
144
|
-
//
|
145
|
-
// Drivers that return objects for rows offer this behavior as an option that is
|
146
|
-
// usually called "expand columns". If the driver being used does not offer such an
|
147
|
-
// option, you can instead activate the option in the compiler, which results in longer
|
148
|
-
// SQL statements because all column names are aliased.
|
149
|
-
expandColumns: true
|
130
|
+
inlineParams: true
|
150
131
|
});
|
151
132
|
```
|
152
133
|
|
package/dist/index.d.ts
CHANGED
@@ -394,8 +394,6 @@ interface TransactionOptions {
|
|
394
394
|
* separating them out into a dedicated `params` array.
|
395
395
|
*/
|
396
396
|
inlineParams?: boolean;
|
397
|
-
/** Alias column names that are duplicated when joining multiple tables. */
|
398
|
-
expandColumns?: boolean;
|
399
397
|
}
|
400
398
|
declare class Transaction {
|
401
399
|
#private;
|
package/dist/index.js
CHANGED
@@ -25,12 +25,13 @@ var CURRENT_TIME_EXPRESSION = {
|
|
25
25
|
};
|
26
26
|
var MOUNTING_PATH_SUFFIX = /(.*?)(\{(\d+)\})?$/;
|
27
27
|
var composeMountingPath = (single, key, mountingPath) => {
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
if (key === "ronin_root") {
|
29
|
+
return mountingPath ? mountingPath.replace(
|
30
|
+
MOUNTING_PATH_SUFFIX,
|
31
|
+
(_, p, __, n) => `${p}{${n ? +n + 1 : 1}}`
|
32
|
+
) : key;
|
33
|
+
}
|
34
|
+
return `${mountingPath ? `${mountingPath}.` : ""}${single ? key : `${key}[0]`}`;
|
34
35
|
};
|
35
36
|
var MODEL_ENTITY_ERROR_CODES = {
|
36
37
|
field: "FIELD_NOT_FOUND",
|
@@ -318,11 +319,12 @@ var handleIncluding = (models, model, statementParams, single, instruction, opti
|
|
318
319
|
let joinType = "LEFT";
|
319
320
|
let relatedTableSelector = `"${relatedModel.table}"`;
|
320
321
|
const subSingle = queryModel !== relatedModel.pluralSlug;
|
321
|
-
const
|
322
|
+
const subMountingPath = composeMountingPath(
|
322
323
|
subSingle,
|
323
324
|
ephemeralFieldSlug,
|
324
325
|
options.mountingPath
|
325
326
|
);
|
327
|
+
const tableAlias = `including_${subMountingPath}`;
|
326
328
|
if (!modifiableQueryInstructions?.with) {
|
327
329
|
joinType = "CROSS";
|
328
330
|
if (subSingle) {
|
@@ -419,12 +421,11 @@ var handleSelecting = (models, model, statementParams, single, instructions, opt
|
|
419
421
|
instructions.selecting
|
420
422
|
).filter((field) => !(field.type === "link" && field.kind === "many")).map((field) => {
|
421
423
|
const newField = { ...field, mountingPath: field.slug };
|
422
|
-
if (options.mountingPath) {
|
424
|
+
if (options.mountingPath && options.mountingPath !== "ronin_root") {
|
423
425
|
newField.mountingPath = `${options.mountingPath.replace(/\{\d+\}/g, "")}.${field.slug}`;
|
424
426
|
}
|
425
427
|
return newField;
|
426
428
|
});
|
427
|
-
if (instructions.selecting) options.expandColumns = true;
|
428
429
|
const joinedSelectedFields = [];
|
429
430
|
const joinedColumns = [];
|
430
431
|
if (instructions.including) {
|
@@ -440,18 +441,13 @@ var handleSelecting = (models, model, statementParams, single, instructions, opt
|
|
440
441
|
const { queryModel, queryInstructions } = splitQuery(symbol2.value);
|
441
442
|
const subQueryModel = getModelBySlug(models, queryModel);
|
442
443
|
isJoining = true;
|
443
|
-
if (queryInstructions?.selecting) options.expandColumns = true;
|
444
444
|
const subSingle = queryModel !== subQueryModel.pluralSlug;
|
445
445
|
if (!model.tableAlias)
|
446
446
|
model.tableAlias = single && !subSingle ? `sub_${model.table}` : model.table;
|
447
|
-
const
|
448
|
-
subSingle,
|
449
|
-
key,
|
450
|
-
options.mountingPath
|
451
|
-
);
|
447
|
+
const subMountingPath = composeMountingPath(subSingle, key, options.mountingPath);
|
452
448
|
const { columns: nestedColumns, selectedFields: nestedSelectedFields } = handleSelecting(
|
453
449
|
models,
|
454
|
-
{ ...subQueryModel, tableAlias },
|
450
|
+
{ ...subQueryModel, tableAlias: `including_${subMountingPath}` },
|
455
451
|
statementParams,
|
456
452
|
subSingle,
|
457
453
|
{
|
@@ -478,11 +474,7 @@ var handleSelecting = (models, model, statementParams, single, instructions, opt
|
|
478
474
|
});
|
479
475
|
}
|
480
476
|
}
|
481
|
-
|
482
|
-
const fieldsToExpand = options.expandColumns ? selectedFields : selectedFields.filter(
|
483
|
-
(loadedField) => typeof loadedField.mountedValue !== "undefined"
|
484
|
-
);
|
485
|
-
const extraColumns = fieldsToExpand.map((selectedField) => {
|
477
|
+
const columns = selectedFields.map((selectedField) => {
|
486
478
|
if (selectedField.mountedValue) {
|
487
479
|
return `${selectedField.mountedValue} as "${selectedField.slug}"`;
|
488
480
|
}
|
@@ -494,11 +486,6 @@ var handleSelecting = (models, model, statementParams, single, instructions, opt
|
|
494
486
|
}
|
495
487
|
return fieldSelector;
|
496
488
|
});
|
497
|
-
if (options.expandColumns) {
|
498
|
-
columns = extraColumns;
|
499
|
-
} else if (extraColumns) {
|
500
|
-
columns.push(...extraColumns);
|
501
|
-
}
|
502
489
|
columns.push(...joinedColumns);
|
503
490
|
selectedFields.push(...joinedSelectedFields);
|
504
491
|
return { columns: columns.join(", "), isJoining, selectedFields };
|
@@ -631,6 +618,15 @@ var compileQueryInput = (defaultQuery, models, statementParams, options) => {
|
|
631
618
|
if (instructions && Object.hasOwn(instructions, "for")) {
|
632
619
|
instructions = handleFor(model, instructions);
|
633
620
|
}
|
621
|
+
if (queryType === "count") {
|
622
|
+
if (!instructions) instructions = {};
|
623
|
+
instructions.selecting = ["amount"];
|
624
|
+
instructions.including = Object.assign(instructions?.including || {}, {
|
625
|
+
amount: {
|
626
|
+
[QUERY_SYMBOLS.EXPRESSION]: "COUNT(*)"
|
627
|
+
}
|
628
|
+
});
|
629
|
+
}
|
634
630
|
const { columns, isJoining, selectedFields } = handleSelecting(
|
635
631
|
models,
|
636
632
|
model,
|
@@ -639,12 +635,12 @@ var compileQueryInput = (defaultQuery, models, statementParams, options) => {
|
|
639
635
|
{
|
640
636
|
selecting: instructions?.selecting,
|
641
637
|
including: instructions?.including
|
642
|
-
}
|
643
|
-
options
|
638
|
+
}
|
644
639
|
);
|
645
640
|
let statement = "";
|
646
641
|
switch (queryType) {
|
647
642
|
case "get":
|
643
|
+
case "count":
|
648
644
|
statement += `SELECT ${columns} FROM `;
|
649
645
|
break;
|
650
646
|
case "set":
|
@@ -656,9 +652,6 @@ var compileQueryInput = (defaultQuery, models, statementParams, options) => {
|
|
656
652
|
case "remove":
|
657
653
|
statement += "DELETE FROM ";
|
658
654
|
break;
|
659
|
-
case "count":
|
660
|
-
statement += `SELECT COUNT(${columns}) FROM `;
|
661
|
-
break;
|
662
655
|
}
|
663
656
|
let isJoiningMultipleRows = false;
|
664
657
|
if (isJoining) {
|
@@ -753,7 +746,7 @@ var compileQueryInput = (defaultQuery, models, statementParams, options) => {
|
|
753
746
|
statement += handleLimitedTo(single, instructions?.limitedTo);
|
754
747
|
}
|
755
748
|
if (["add", "set", "remove"].includes(queryType) && returning) {
|
756
|
-
statement +=
|
749
|
+
statement += `RETURNING ${columns}`;
|
757
750
|
}
|
758
751
|
const mainStatement = {
|
759
752
|
statement: statement.trimEnd(),
|
@@ -1390,13 +1383,9 @@ var composeAssociationModelSlug = (model, field) => convertToCamelCase(`ronin_li
|
|
1390
1383
|
var getFieldSelector = (model, field, fieldPath, writing) => {
|
1391
1384
|
const symbol = model.tableAlias?.startsWith(QUERY_SYMBOLS.FIELD_PARENT) ? `${model.tableAlias.replace(QUERY_SYMBOLS.FIELD_PARENT, "").slice(0, -1)}.` : "";
|
1392
1385
|
const tablePrefix = symbol || (model.tableAlias ? `"${model.tableAlias}".` : "");
|
1393
|
-
if ((field.type === "json" || field.type === "blob") && !writing) {
|
1394
|
-
const
|
1395
|
-
|
1396
|
-
if (dotParts.length > 0) {
|
1397
|
-
const jsonField = dotParts.join(".");
|
1398
|
-
return `json_extract(${columnName}, '$.${jsonField}')`;
|
1399
|
-
}
|
1386
|
+
if ((field.type === "json" || field.type === "blob") && !writing && fieldPath.length > field.slug.length) {
|
1387
|
+
const jsonField = fieldPath.replace(`${field.slug}.`, "");
|
1388
|
+
return `json_extract(${tablePrefix + field.slug}, '$.${jsonField}')`;
|
1400
1389
|
}
|
1401
1390
|
return `${tablePrefix}"${fieldPath}"`;
|
1402
1391
|
};
|
@@ -1988,8 +1977,7 @@ var Transaction = class {
|
|
1988
1977
|
const { dependencies, main, selectedFields } = compileQueryInput(
|
1989
1978
|
query,
|
1990
1979
|
modelsWithPresets,
|
1991
|
-
options?.inlineParams ? null : []
|
1992
|
-
{ expandColumns: options?.expandColumns }
|
1980
|
+
options?.inlineParams ? null : []
|
1993
1981
|
);
|
1994
1982
|
const preDependencies = dependencies.filter(({ after }) => !after);
|
1995
1983
|
const postDependencies = dependencies.map(({ after, ...rest }) => after ? rest : null).filter((item) => item != null);
|
@@ -2083,18 +2071,19 @@ var Transaction = class {
|
|
2083
2071
|
*
|
2084
2072
|
* @param results - A list of results from the database, where each result is an array
|
2085
2073
|
* of rows.
|
2086
|
-
* @param raw - By default, rows are expected to be
|
2087
|
-
*
|
2088
|
-
*
|
2074
|
+
* @param raw - By default, rows are expected to be objects. If the driver being used
|
2075
|
+
* returns rows as arrays of values (which is how SQL databases return rows directly),
|
2076
|
+
* this option should be set to `true`.
|
2089
2077
|
*
|
2090
2078
|
* @returns A list of formatted RONIN results, where each result is either a single
|
2091
2079
|
* RONIN record, an array of RONIN records, or a RONIN count result.
|
2092
2080
|
*/
|
2093
|
-
formatResults(results, raw =
|
2094
|
-
const normalizedResults = raw ? results : results.map((rows) => {
|
2081
|
+
formatResults(results, raw = false) {
|
2082
|
+
const normalizedResults = raw ? results : results.map((rows, index) => {
|
2083
|
+
const { query } = this.#internalStatements[index];
|
2095
2084
|
return rows.map((row) => {
|
2096
2085
|
if (Array.isArray(row)) return row;
|
2097
|
-
if (
|
2086
|
+
if (query.count) return [row.amount];
|
2098
2087
|
return Object.values(row);
|
2099
2088
|
});
|
2100
2089
|
});
|