xansql 1.0.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.
- package/Types/fields/Array.d.ts +7 -0
- package/Types/fields/Array.js +6 -0
- package/Types/fields/Array.js.map +1 -0
- package/Types/fields/Array.mjs +6 -0
- package/Types/fields/Array.mjs.map +1 -0
- package/Types/fields/Boolean.d.ts +8 -0
- package/Types/fields/Boolean.js +11 -0
- package/Types/fields/Boolean.js.map +1 -0
- package/Types/fields/Boolean.mjs +11 -0
- package/Types/fields/Boolean.mjs.map +1 -0
- package/Types/fields/Date.d.ts +10 -0
- package/Types/fields/Date.js +22 -0
- package/Types/fields/Date.js.map +1 -0
- package/Types/fields/Date.mjs +22 -0
- package/Types/fields/Date.mjs.map +1 -0
- package/Types/fields/Enum.d.ts +8 -0
- package/Types/fields/Enum.js +10 -0
- package/Types/fields/Enum.js.map +1 -0
- package/Types/fields/Enum.mjs +10 -0
- package/Types/fields/Enum.mjs.map +1 -0
- package/Types/fields/File.d.ts +7 -0
- package/Types/fields/File.js +6 -0
- package/Types/fields/File.js.map +1 -0
- package/Types/fields/File.mjs +6 -0
- package/Types/fields/File.mjs.map +1 -0
- package/Types/fields/IDField.d.ts +6 -0
- package/Types/fields/IDField.js +2 -0
- package/Types/fields/IDField.js.map +1 -0
- package/Types/fields/IDField.mjs +2 -0
- package/Types/fields/IDField.mjs.map +1 -0
- package/Types/fields/Number.d.ts +8 -0
- package/Types/fields/Number.js +11 -0
- package/Types/fields/Number.js.map +1 -0
- package/Types/fields/Number.mjs +11 -0
- package/Types/fields/Number.mjs.map +1 -0
- package/Types/fields/Object.d.ts +8 -0
- package/Types/fields/Object.js +11 -0
- package/Types/fields/Object.js.map +1 -0
- package/Types/fields/Object.mjs +11 -0
- package/Types/fields/Object.mjs.map +1 -0
- package/Types/fields/Record.d.ts +8 -0
- package/Types/fields/Record.js +11 -0
- package/Types/fields/Record.js.map +1 -0
- package/Types/fields/Record.mjs +11 -0
- package/Types/fields/Record.mjs.map +1 -0
- package/Types/fields/Schema.d.ts +16 -0
- package/Types/fields/Schema.js +34 -0
- package/Types/fields/Schema.js.map +1 -0
- package/Types/fields/Schema.mjs +34 -0
- package/Types/fields/Schema.mjs.map +1 -0
- package/Types/fields/String.d.ts +10 -0
- package/Types/fields/String.js +20 -0
- package/Types/fields/String.js.map +1 -0
- package/Types/fields/String.mjs +20 -0
- package/Types/fields/String.mjs.map +1 -0
- package/Types/fields/Tuple.d.ts +8 -0
- package/Types/fields/Tuple.js +11 -0
- package/Types/fields/Tuple.js.map +1 -0
- package/Types/fields/Tuple.mjs +11 -0
- package/Types/fields/Tuple.mjs.map +1 -0
- package/Types/fields/Union.d.ts +8 -0
- package/Types/fields/Union.js +11 -0
- package/Types/fields/Union.js.map +1 -0
- package/Types/fields/Union.mjs +11 -0
- package/Types/fields/Union.mjs.map +1 -0
- package/Types/index.d.ts +56 -0
- package/Types/index.js +129 -0
- package/Types/index.js.map +1 -0
- package/Types/index.mjs +129 -0
- package/Types/index.mjs.map +1 -0
- package/Types/types.d.ts +20 -0
- package/core/ExcuteMeta.d.ts +11 -0
- package/core/ExcuteMeta.js +22 -0
- package/core/ExcuteMeta.js.map +1 -0
- package/core/ExcuteMeta.mjs +22 -0
- package/core/ExcuteMeta.mjs.map +1 -0
- package/core/Xansql.d.ts +46 -0
- package/core/Xansql.js +132 -0
- package/core/Xansql.js.map +1 -0
- package/core/Xansql.mjs +132 -0
- package/core/Xansql.mjs.map +1 -0
- package/core/XansqlError.js +11 -0
- package/core/XansqlError.js.map +1 -0
- package/core/XansqlError.mjs +11 -0
- package/core/XansqlError.mjs.map +1 -0
- package/core/XansqlResult.d.ts +12 -0
- package/core/XansqlResult.js +32 -0
- package/core/XansqlResult.js.map +1 -0
- package/core/XansqlResult.mjs +32 -0
- package/core/XansqlResult.mjs.map +1 -0
- package/core/classes/EventManager.d.ts +72 -0
- package/core/classes/EventManager.js +21 -0
- package/core/classes/EventManager.js.map +1 -0
- package/core/classes/EventManager.mjs +21 -0
- package/core/classes/EventManager.mjs.map +1 -0
- package/core/classes/ForeignInfo.js +51 -0
- package/core/classes/ForeignInfo.js.map +1 -0
- package/core/classes/ForeignInfo.mjs +51 -0
- package/core/classes/ForeignInfo.mjs.map +1 -0
- package/core/classes/Migration/ForeingMigration.d.ts +12 -0
- package/core/classes/Migration/ForeingMigration.js +52 -0
- package/core/classes/Migration/ForeingMigration.js.map +1 -0
- package/core/classes/Migration/ForeingMigration.mjs +52 -0
- package/core/classes/Migration/ForeingMigration.mjs.map +1 -0
- package/core/classes/Migration/IndexMigration.d.ts +12 -0
- package/core/classes/Migration/IndexMigration.js +49 -0
- package/core/classes/Migration/IndexMigration.js.map +1 -0
- package/core/classes/Migration/IndexMigration.mjs +49 -0
- package/core/classes/Migration/IndexMigration.mjs.map +1 -0
- package/core/classes/Migration/TableMigration.d.ts +33 -0
- package/core/classes/Migration/TableMigration.js +215 -0
- package/core/classes/Migration/TableMigration.js.map +1 -0
- package/core/classes/Migration/TableMigration.mjs +215 -0
- package/core/classes/Migration/TableMigration.mjs.map +1 -0
- package/core/classes/Migration/index.d.ts +12 -0
- package/core/classes/Migration/index.js +189 -0
- package/core/classes/Migration/index.js.map +1 -0
- package/core/classes/Migration/index.mjs +189 -0
- package/core/classes/Migration/index.mjs.map +1 -0
- package/core/classes/ModelFormatter.js +166 -0
- package/core/classes/ModelFormatter.js.map +1 -0
- package/core/classes/ModelFormatter.mjs +166 -0
- package/core/classes/ModelFormatter.mjs.map +1 -0
- package/core/classes/TypesGenerator.d.ts +13 -0
- package/core/classes/TypesGenerator.js +170 -0
- package/core/classes/TypesGenerator.js.map +1 -0
- package/core/classes/TypesGenerator.mjs +170 -0
- package/core/classes/TypesGenerator.mjs.map +1 -0
- package/core/classes/XansqlConfig.js +33 -0
- package/core/classes/XansqlConfig.js.map +1 -0
- package/core/classes/XansqlConfig.mjs +33 -0
- package/core/classes/XansqlConfig.mjs.map +1 -0
- package/core/classes/XansqlFetch.js +304 -0
- package/core/classes/XansqlFetch.js.map +1 -0
- package/core/classes/XansqlFetch.mjs +304 -0
- package/core/classes/XansqlFetch.mjs.map +1 -0
- package/core/classes/XansqlTransaction.d.ts +13 -0
- package/core/classes/XansqlTransaction.js +46 -0
- package/core/classes/XansqlTransaction.js.map +1 -0
- package/core/classes/XansqlTransaction.mjs +46 -0
- package/core/classes/XansqlTransaction.mjs.map +1 -0
- package/core/type.d.ts +117 -0
- package/index.d.ts +3 -0
- package/index.js +1 -0
- package/index.js.map +1 -0
- package/index.mjs +1 -0
- package/index.mjs.map +1 -0
- package/model/Args/RelationExcuteArgs.js +5 -0
- package/model/Args/RelationExcuteArgs.js.map +1 -0
- package/model/Args/RelationExcuteArgs.mjs +5 -0
- package/model/Args/RelationExcuteArgs.mjs.map +1 -0
- package/model/Args/WhereArgs.js +226 -0
- package/model/Args/WhereArgs.js.map +1 -0
- package/model/Args/WhereArgs.mjs +226 -0
- package/model/Args/WhereArgs.mjs.map +1 -0
- package/model/Base.d.ts +26 -0
- package/model/Base.js +64 -0
- package/model/Base.js.map +1 -0
- package/model/Base.mjs +64 -0
- package/model/Base.mjs.map +1 -0
- package/model/Executer/Aggregate/SelectArgs.js +59 -0
- package/model/Executer/Aggregate/SelectArgs.js.map +1 -0
- package/model/Executer/Aggregate/SelectArgs.mjs +59 -0
- package/model/Executer/Aggregate/SelectArgs.mjs.map +1 -0
- package/model/Executer/Aggregate/index.js +59 -0
- package/model/Executer/Aggregate/index.js.map +1 -0
- package/model/Executer/Aggregate/index.mjs +59 -0
- package/model/Executer/Aggregate/index.mjs.map +1 -0
- package/model/Executer/Create/CreateDataArgs.js +145 -0
- package/model/Executer/Create/CreateDataArgs.js.map +1 -0
- package/model/Executer/Create/CreateDataArgs.mjs +145 -0
- package/model/Executer/Create/CreateDataArgs.mjs.map +1 -0
- package/model/Executer/Create/index.js +101 -0
- package/model/Executer/Create/index.js.map +1 -0
- package/model/Executer/Create/index.mjs +101 -0
- package/model/Executer/Create/index.mjs.map +1 -0
- package/model/Executer/Delete/index.js +112 -0
- package/model/Executer/Delete/index.js.map +1 -0
- package/model/Executer/Delete/index.mjs +112 -0
- package/model/Executer/Delete/index.mjs.map +1 -0
- package/model/Executer/Find/DistinctArgs.js +32 -0
- package/model/Executer/Find/DistinctArgs.js.map +1 -0
- package/model/Executer/Find/DistinctArgs.mjs +32 -0
- package/model/Executer/Find/DistinctArgs.mjs.map +1 -0
- package/model/Executer/Find/LimitArgs.js +31 -0
- package/model/Executer/Find/LimitArgs.js.map +1 -0
- package/model/Executer/Find/LimitArgs.mjs +31 -0
- package/model/Executer/Find/LimitArgs.mjs.map +1 -0
- package/model/Executer/Find/OrderByArgs.js +29 -0
- package/model/Executer/Find/OrderByArgs.js.map +1 -0
- package/model/Executer/Find/OrderByArgs.mjs +29 -0
- package/model/Executer/Find/OrderByArgs.mjs.map +1 -0
- package/model/Executer/Find/SelectArgs.js +119 -0
- package/model/Executer/Find/SelectArgs.js.map +1 -0
- package/model/Executer/Find/SelectArgs.mjs +119 -0
- package/model/Executer/Find/SelectArgs.mjs.map +1 -0
- package/model/Executer/Find/index.js +338 -0
- package/model/Executer/Find/index.js.map +1 -0
- package/model/Executer/Find/index.mjs +338 -0
- package/model/Executer/Find/index.mjs.map +1 -0
- package/model/Executer/Update/UpdateDataArgs.js +124 -0
- package/model/Executer/Update/UpdateDataArgs.js.map +1 -0
- package/model/Executer/Update/UpdateDataArgs.mjs +124 -0
- package/model/Executer/Update/UpdateDataArgs.mjs.map +1 -0
- package/model/Executer/Update/index.js +207 -0
- package/model/Executer/Update/index.js.map +1 -0
- package/model/Executer/Update/index.mjs +207 -0
- package/model/Executer/Update/index.mjs.map +1 -0
- package/model/include/ValueFormatter.js +99 -0
- package/model/include/ValueFormatter.js.map +1 -0
- package/model/include/ValueFormatter.mjs +99 -0
- package/model/include/ValueFormatter.mjs.map +1 -0
- package/model/index.d.ts +29 -0
- package/model/index.js +236 -0
- package/model/index.js.map +1 -0
- package/model/index.mjs +236 -0
- package/model/index.mjs.map +1 -0
- package/model/type.d.ts +106 -0
- package/package.json +32 -0
- package/readme.md +359 -0
- package/utils/chunker.js +53 -0
- package/utils/chunker.js.map +1 -0
- package/utils/chunker.mjs +53 -0
- package/utils/chunker.mjs.map +1 -0
- package/utils/index.js +49 -0
- package/utils/index.js.map +1 -0
- package/utils/index.mjs +49 -0
- package/utils/index.mjs.map +1 -0
- package/utils/sha256.js +66 -0
- package/utils/sha256.js.map +1 -0
- package/utils/sha256.mjs +66 -0
- package/utils/sha256.mjs.map +1 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var DistinctArgs=require('./DistinctArgs.js'),LimitArgs=require('./LimitArgs.js'),OrderByArgs=require('./OrderByArgs.js'),WhereArgs=require('../../Args/WhereArgs.js'),ValueFormatter=require('../../include/ValueFormatter.js'),Enum=require('../../../Types/fields/Enum.js'),Array=require('../../../Types/fields/Array.js'),Object$1=require('../../../Types/fields/Object.js'),Record=require('../../../Types/fields/Record.js'),Tuple=require('../../../Types/fields/Tuple.js'),Union=require('../../../Types/fields/Union.js'),ForeignInfo=require('../../../core/classes/ForeignInfo.js'),File=require('../../../Types/fields/File.js'),XansqlError=require('../../../core/XansqlError.js');class SelectArgs {
|
|
2
|
+
constructor(model, args) {
|
|
3
|
+
/**
|
|
4
|
+
* Get Columns
|
|
5
|
+
* @description Returns the columns to be selected
|
|
6
|
+
* @returns {string[]} Array of column names
|
|
7
|
+
*/
|
|
8
|
+
this.columns = [];
|
|
9
|
+
/**
|
|
10
|
+
* Get Formatable Columns
|
|
11
|
+
*/
|
|
12
|
+
this.formatable_columns = [];
|
|
13
|
+
/**
|
|
14
|
+
* Get SQL
|
|
15
|
+
* @description Returns the SQL string for the selected columns
|
|
16
|
+
* @returns {string} SQL string for selected columns
|
|
17
|
+
* @example
|
|
18
|
+
* const sql = selectArgs.sql; // returns "table.column1, table.column2, ..."
|
|
19
|
+
*/
|
|
20
|
+
this.relations = {};
|
|
21
|
+
/**
|
|
22
|
+
* Get Relations
|
|
23
|
+
* @description Returns the relations to be selected
|
|
24
|
+
* @returns {SelectArgsRelations} Object containing relation information
|
|
25
|
+
* @example
|
|
26
|
+
* const relations = selectArgs.relations; // returns { column: { args: FindArgsType, foreign: ForeignInfoType }, ... }
|
|
27
|
+
*/
|
|
28
|
+
this.sql = '';
|
|
29
|
+
this.model = model;
|
|
30
|
+
for (let column in args) {
|
|
31
|
+
if (!(column in this.model.schema)) {
|
|
32
|
+
throw new XansqlError.default({
|
|
33
|
+
message: `Column ${column} not found in model ${model.table} for select`,
|
|
34
|
+
model: model.table,
|
|
35
|
+
column: column
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
let field = model.schema[column];
|
|
39
|
+
let value = args[column];
|
|
40
|
+
if (ForeignInfo.default.is(field)) {
|
|
41
|
+
const relArgs = value === true ? { select: {} } : value;
|
|
42
|
+
if (ForeignInfo.default.isSchema(field)) {
|
|
43
|
+
this.columns.push(column);
|
|
44
|
+
}
|
|
45
|
+
const foreign = ForeignInfo.default.get(model, column);
|
|
46
|
+
const FModel = model.xansql.getModel(foreign.table);
|
|
47
|
+
// ====== Prepare select args for relation ======
|
|
48
|
+
let fargs = {};
|
|
49
|
+
const Select = new SelectArgs(FModel, relArgs.select || {});
|
|
50
|
+
// ====== Prevent circular reference ======
|
|
51
|
+
for (let rcol in Select.relations) {
|
|
52
|
+
if (Select.relations[rcol].foreign.table === model.table) {
|
|
53
|
+
throw new XansqlError.default({
|
|
54
|
+
message: `Circular reference detected in relation ${column} of model ${model.table}`,
|
|
55
|
+
model: model.table,
|
|
56
|
+
column: column
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// ====== Make sure main column of relation is selected ======
|
|
61
|
+
let columns = Select.columns;
|
|
62
|
+
if (!columns.includes(foreign.relation.main)) {
|
|
63
|
+
columns.unshift(foreign.relation.main);
|
|
64
|
+
}
|
|
65
|
+
let sql = Select.sql;
|
|
66
|
+
let relcol = `${foreign.table}.${foreign.relation.main}`;
|
|
67
|
+
sql = sql.includes(relcol) ? sql : `${sql}, ${relcol}`;
|
|
68
|
+
fargs.select = {
|
|
69
|
+
sql,
|
|
70
|
+
columns,
|
|
71
|
+
formatable_columns: Select.formatable_columns,
|
|
72
|
+
relations: Select.relations,
|
|
73
|
+
};
|
|
74
|
+
// ==== Where =====
|
|
75
|
+
const Where = new WhereArgs.default(FModel, relArgs.where || {});
|
|
76
|
+
fargs.where = Where.wheres.join(" AND ");
|
|
77
|
+
// ===== OrderBy =====
|
|
78
|
+
fargs.orderBy = (new OrderByArgs.default(FModel, relArgs.orderBy || {})).sql;
|
|
79
|
+
// ===== Limit =====
|
|
80
|
+
fargs.limit = new LimitArgs.default(FModel, relArgs.limit || {});
|
|
81
|
+
// ===== Distinct =====
|
|
82
|
+
if (relArgs.distinct) {
|
|
83
|
+
const distinct = new DistinctArgs.default(FModel, relArgs.distinct || [], Where, relArgs.orderBy);
|
|
84
|
+
if (distinct.sql) {
|
|
85
|
+
fargs.where += fargs.where ? ` AND ${distinct.sql}` : `WHERE ${distinct.sql}`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// ===== Aggregate =====
|
|
89
|
+
if (relArgs.aggregate && Object.keys(relArgs.aggregate).length) {
|
|
90
|
+
fargs.aggregate = relArgs.aggregate;
|
|
91
|
+
}
|
|
92
|
+
this.relations[column] = {
|
|
93
|
+
args: fargs,
|
|
94
|
+
foreign
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
if (ValueFormatter.default.iof(model, column, File.default, Enum.default, Array.default, Object$1.default, Record.default, Tuple.default, Union.default)) {
|
|
99
|
+
this.formatable_columns.push(column);
|
|
100
|
+
}
|
|
101
|
+
this.columns.push(column);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// if no columns are selected, select all columns
|
|
105
|
+
if (this.columns.length === 0) {
|
|
106
|
+
for (let column in model.schema) {
|
|
107
|
+
let field = model.schema[column];
|
|
108
|
+
if (!ForeignInfo.default.is(field)) {
|
|
109
|
+
this.columns.push(column);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// always include ID column
|
|
114
|
+
if (!this.columns.includes(model.IDColumn)) {
|
|
115
|
+
this.columns.unshift(model.IDColumn);
|
|
116
|
+
}
|
|
117
|
+
this.sql = this.columns.map(col => `${this.model.table}.${col}`).join(', ');
|
|
118
|
+
}
|
|
119
|
+
}exports.default=SelectArgs;//# sourceMappingURL=SelectArgs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectArgs.js","sources":["../../../../src/model/Executer/Find/SelectArgs.ts"],"sourcesContent":["import Model from \"../..\";\nimport { FindArgsAggregate, FindArgsType, SelectArgsType } from \"../../type\";\nimport DistinctArgs from \"./DistinctArgs\";\nimport LimitArgs from \"./LimitArgs\";\nimport OrderByArgs from \"./OrderByArgs\";\nimport WhereArgs from \"../../Args/WhereArgs\";\nimport ValueFormatter from \"../../include/ValueFormatter\";\nimport XqlEnum from \"../../../Types/fields/Enum\";\nimport XqlArray from \"../../../Types/fields/Array\";\nimport XqlObject from \"../../../Types/fields/Object\";\nimport XqlRecord from \"../../../Types/fields/Record\";\nimport XqlTuple from \"../../../Types/fields/Tuple\";\nimport XqlUnion from \"../../../Types/fields/Union\";\nimport Foreign, { ForeignInfoType } from \"../../../core/classes/ForeignInfo\";\nimport XqlFile from \"../../../Types/fields/File\";\nimport XansqlError from \"../../../core/XansqlError\";\n\nexport type SelectArgsRelationInfo = {\n args: {\n select: {\n sql: string,\n columns: string[],\n formatable_columns: string[],\n relations?: SelectArgsRelations,\n },\n where: string,\n limit: Required<LimitArgs>,\n orderBy: string\n aggregate: FindArgsAggregate,\n },\n foreign: ForeignInfoType\n}\n\ntype SelectArgsRelations = {\n [column: string]: SelectArgsRelationInfo\n}\n\nclass SelectArgs {\n private model: Model\n\n /**\n * Get Columns\n * @description Returns the columns to be selected\n * @returns {string[]} Array of column names\n */\n readonly columns: string[] = []\n\n\n /**\n * Get Formatable Columns\n */\n readonly formatable_columns: string[] = []\n\n /**\n * Get SQL\n * @description Returns the SQL string for the selected columns\n * @returns {string} SQL string for selected columns\n * @example\n * const sql = selectArgs.sql; // returns \"table.column1, table.column2, ...\"\n */\n readonly relations: SelectArgsRelations = {}\n\n\n /**\n * Get Relations\n * @description Returns the relations to be selected\n * @returns {SelectArgsRelations} Object containing relation information\n * @example\n * const relations = selectArgs.relations; // returns { column: { args: FindArgsType, foreign: ForeignInfoType }, ... }\n */\n readonly sql: string = ''\n\n\n constructor(model: Model, args: SelectArgsType) {\n this.model = model\n\n for (let column in args) {\n if (!(column in this.model.schema)) {\n throw new XansqlError({\n message: `Column ${column} not found in model ${model.table} for select`,\n model: model.table,\n column: column\n });\n }\n\n let field = model.schema[column]\n let value: boolean | FindArgsType = args[column]\n\n if (Foreign.is(field)) {\n\n const relArgs = value === true ? { select: {} } : value as FindArgsType\n\n if (Foreign.isSchema(field)) {\n this.columns.push(column)\n }\n\n const foreign = Foreign.get(model, column)\n const FModel = model.xansql.getModel(foreign.table)\n\n\n // ====== Prepare select args for relation ======\n let fargs: any = {}\n const Select = new SelectArgs(FModel, relArgs.select || {})\n\n // ====== Prevent circular reference ======\n for (let rcol in Select.relations) {\n if (Select.relations[rcol].foreign.table === model.table) {\n throw new XansqlError({\n message: `Circular reference detected in relation ${column} of model ${model.table}`,\n model: model.table,\n column: column\n });\n }\n }\n\n // ====== Make sure main column of relation is selected ======\n\n let columns = Select.columns\n if (!columns.includes(foreign.relation.main)) {\n columns.unshift(foreign.relation.main)\n }\n let sql = Select.sql\n let relcol = `${foreign.table}.${foreign.relation.main}`\n sql = sql.includes(relcol) ? sql : `${sql}, ${relcol}`\n\n fargs.select = {\n sql,\n columns,\n formatable_columns: Select.formatable_columns,\n relations: Select.relations,\n }\n\n // ==== Where =====\n const Where = new WhereArgs(FModel, relArgs.where || {})\n fargs.where = Where.wheres.join(\" AND \")\n\n // ===== OrderBy =====\n fargs.orderBy = (new OrderByArgs(FModel, relArgs.orderBy || {})).sql\n\n // ===== Limit =====\n fargs.limit = new LimitArgs(FModel, relArgs.limit || {})\n\n // ===== Distinct =====\n if (relArgs.distinct) {\n const distinct = new DistinctArgs(FModel, relArgs.distinct || [], Where, relArgs.orderBy)\n if (distinct.sql) {\n fargs.where += fargs.where ? ` AND ${distinct.sql}` : `WHERE ${distinct.sql}`\n }\n }\n\n // ===== Aggregate =====\n if (relArgs.aggregate && Object.keys(relArgs.aggregate).length) {\n fargs.aggregate = relArgs.aggregate\n }\n\n this.relations[column] = {\n args: fargs,\n foreign\n }\n\n } else {\n if (ValueFormatter.iof(model, column, XqlFile, XqlEnum, XqlArray, XqlObject, XqlRecord, XqlTuple, XqlUnion)) {\n this.formatable_columns.push(column)\n }\n this.columns.push(column)\n }\n }\n\n // if no columns are selected, select all columns\n if (this.columns.length === 0) {\n for (let column in model.schema) {\n let field = model.schema[column]\n if (!Foreign.is(field)) {\n this.columns.push(column)\n }\n }\n }\n\n // always include ID column\n if (!this.columns.includes(model.IDColumn)) {\n this.columns.unshift(model.IDColumn)\n }\n\n this.sql = this.columns.map(col => `${this.model.table}.${col}`).join(', ')\n }\n\n\n}\n\nexport default SelectArgs"],"names":["XansqlError","Foreign","WhereArgs","OrderByArgs","LimitArgs","DistinctArgs","ValueFormatter","XqlFile","XqlEnum","XqlArray","XqlObject","XqlRecord","XqlTuple","XqlUnion"],"mappings":"yuBAqCA,MAAM,UAAU,CAAA;IAoCb,WAAA,CAAY,KAAY,EAAE,IAAoB,EAAA;AAjC9C;;;;AAIG;QACM,IAAA,CAAA,OAAO,GAAa,EAAE;AAG/B;;AAEG;QACM,IAAA,CAAA,kBAAkB,GAAa,EAAE;AAE1C;;;;;;AAMG;QACM,IAAA,CAAA,SAAS,GAAwB,EAAE;AAG5C;;;;;;AAMG;QACM,IAAA,CAAA,GAAG,GAAW,EAAE;AAItB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAElB,QAAA,KAAK,IAAI,MAAM,IAAI,IAAI,EAAE;YACtB,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;gBACjC,MAAM,IAAIA,mBAAW,CAAC;AACnB,oBAAA,OAAO,EAAE,CAAA,OAAA,EAAU,MAAM,uBAAuB,KAAK,CAAC,KAAK,CAAA,WAAA,CAAa;oBACxE,KAAK,EAAE,KAAK,CAAC,KAAK;AAClB,oBAAA,MAAM,EAAE;AACV,iBAAA,CAAC;YACL;YAEA,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;AAChC,YAAA,IAAI,KAAK,GAA2B,IAAI,CAAC,MAAM,CAAC;AAEhD,YAAA,IAAIC,mBAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;AAEpB,gBAAA,MAAM,OAAO,GAAG,KAAK,KAAK,IAAI,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,KAAqB;AAEvE,gBAAA,IAAIA,mBAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AAC1B,oBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC5B;gBAEA,MAAM,OAAO,GAAGA,mBAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC;AAC1C,gBAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC;;gBAInD,IAAI,KAAK,GAAQ,EAAE;AACnB,gBAAA,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;;AAG3D,gBAAA,KAAK,IAAI,IAAI,IAAI,MAAM,CAAC,SAAS,EAAE;AAChC,oBAAA,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,EAAE;wBACvD,MAAM,IAAID,mBAAW,CAAC;AACnB,4BAAA,OAAO,EAAE,CAAA,wCAAA,EAA2C,MAAM,aAAa,KAAK,CAAC,KAAK,CAAA,CAAE;4BACpF,KAAK,EAAE,KAAK,CAAC,KAAK;AAClB,4BAAA,MAAM,EAAE;AACV,yBAAA,CAAC;oBACL;gBACH;;AAIA,gBAAA,IAAI,OAAO,GAAG,MAAM,CAAC,OAAO;AAC5B,gBAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;oBAC3C,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;gBACzC;AACA,gBAAA,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG;AACpB,gBAAA,IAAI,MAAM,GAAG,CAAA,EAAG,OAAO,CAAC,KAAK,CAAA,CAAA,EAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;AACxD,gBAAA,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,CAAA,EAAG,GAAG,CAAA,EAAA,EAAK,MAAM,EAAE;gBAEtD,KAAK,CAAC,MAAM,GAAG;oBACZ,GAAG;oBACH,OAAO;oBACP,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;oBAC7C,SAAS,EAAE,MAAM,CAAC,SAAS;iBAC7B;;AAGD,gBAAA,MAAM,KAAK,GAAG,IAAIE,iBAAS,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;gBACxD,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;;AAGxC,gBAAA,KAAK,CAAC,OAAO,GAAG,CAAC,IAAIC,mBAAW,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,GAAG;;AAGpE,gBAAA,KAAK,CAAC,KAAK,GAAG,IAAIC,iBAAS,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;;AAGxD,gBAAA,IAAI,OAAO,CAAC,QAAQ,EAAE;AACnB,oBAAA,MAAM,QAAQ,GAAG,IAAIC,oBAAY,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC;AACzF,oBAAA,IAAI,QAAQ,CAAC,GAAG,EAAE;wBACf,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,GAAG,CAAA,KAAA,EAAQ,QAAQ,CAAC,GAAG,CAAA,CAAE,GAAG,SAAS,QAAQ,CAAC,GAAG,CAAA,CAAE;oBAChF;gBACH;;AAGA,gBAAA,IAAI,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE;AAC7D,oBAAA,KAAK,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS;gBACtC;AAEA,gBAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG;AACtB,oBAAA,IAAI,EAAE,KAAK;oBACX;iBACF;YAEJ;iBAAO;gBACJ,IAAIC,sBAAc,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAEC,YAAO,EAAEC,YAAO,EAAEC,aAAQ,EAAEC,gBAAS,EAAEC,cAAS,EAAEC,aAAQ,EAAEC,aAAQ,CAAC,EAAE;AAC1G,oBAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC;gBACvC;AACA,gBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;YAC5B;QACH;;QAGA,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;AAC5B,YAAA,KAAK,IAAI,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE;gBAC9B,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;gBAChC,IAAI,CAACZ,mBAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;AACrB,oBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC5B;YACH;QACH;;AAGA,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE;YACzC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;QACvC;AAEA,QAAA,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA,EAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAC9E;AAGF"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import DistinctArgs from'./DistinctArgs.mjs';import LimitArgs from'./LimitArgs.mjs';import OrderByArgs from'./OrderByArgs.mjs';import WhereArgs from'../../Args/WhereArgs.mjs';import ValueFormatter from'../../include/ValueFormatter.mjs';import XqlEnum from'../../../Types/fields/Enum.mjs';import XqlArray from'../../../Types/fields/Array.mjs';import XqlObject from'../../../Types/fields/Object.mjs';import XqlRecord from'../../../Types/fields/Record.mjs';import XqlTuple from'../../../Types/fields/Tuple.mjs';import XqlUnion from'../../../Types/fields/Union.mjs';import Foreign from'../../../core/classes/ForeignInfo.mjs';import XqlFile from'../../../Types/fields/File.mjs';import XansqlError from'../../../core/XansqlError.mjs';class SelectArgs {
|
|
2
|
+
constructor(model, args) {
|
|
3
|
+
/**
|
|
4
|
+
* Get Columns
|
|
5
|
+
* @description Returns the columns to be selected
|
|
6
|
+
* @returns {string[]} Array of column names
|
|
7
|
+
*/
|
|
8
|
+
this.columns = [];
|
|
9
|
+
/**
|
|
10
|
+
* Get Formatable Columns
|
|
11
|
+
*/
|
|
12
|
+
this.formatable_columns = [];
|
|
13
|
+
/**
|
|
14
|
+
* Get SQL
|
|
15
|
+
* @description Returns the SQL string for the selected columns
|
|
16
|
+
* @returns {string} SQL string for selected columns
|
|
17
|
+
* @example
|
|
18
|
+
* const sql = selectArgs.sql; // returns "table.column1, table.column2, ..."
|
|
19
|
+
*/
|
|
20
|
+
this.relations = {};
|
|
21
|
+
/**
|
|
22
|
+
* Get Relations
|
|
23
|
+
* @description Returns the relations to be selected
|
|
24
|
+
* @returns {SelectArgsRelations} Object containing relation information
|
|
25
|
+
* @example
|
|
26
|
+
* const relations = selectArgs.relations; // returns { column: { args: FindArgsType, foreign: ForeignInfoType }, ... }
|
|
27
|
+
*/
|
|
28
|
+
this.sql = '';
|
|
29
|
+
this.model = model;
|
|
30
|
+
for (let column in args) {
|
|
31
|
+
if (!(column in this.model.schema)) {
|
|
32
|
+
throw new XansqlError({
|
|
33
|
+
message: `Column ${column} not found in model ${model.table} for select`,
|
|
34
|
+
model: model.table,
|
|
35
|
+
column: column
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
let field = model.schema[column];
|
|
39
|
+
let value = args[column];
|
|
40
|
+
if (Foreign.is(field)) {
|
|
41
|
+
const relArgs = value === true ? { select: {} } : value;
|
|
42
|
+
if (Foreign.isSchema(field)) {
|
|
43
|
+
this.columns.push(column);
|
|
44
|
+
}
|
|
45
|
+
const foreign = Foreign.get(model, column);
|
|
46
|
+
const FModel = model.xansql.getModel(foreign.table);
|
|
47
|
+
// ====== Prepare select args for relation ======
|
|
48
|
+
let fargs = {};
|
|
49
|
+
const Select = new SelectArgs(FModel, relArgs.select || {});
|
|
50
|
+
// ====== Prevent circular reference ======
|
|
51
|
+
for (let rcol in Select.relations) {
|
|
52
|
+
if (Select.relations[rcol].foreign.table === model.table) {
|
|
53
|
+
throw new XansqlError({
|
|
54
|
+
message: `Circular reference detected in relation ${column} of model ${model.table}`,
|
|
55
|
+
model: model.table,
|
|
56
|
+
column: column
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// ====== Make sure main column of relation is selected ======
|
|
61
|
+
let columns = Select.columns;
|
|
62
|
+
if (!columns.includes(foreign.relation.main)) {
|
|
63
|
+
columns.unshift(foreign.relation.main);
|
|
64
|
+
}
|
|
65
|
+
let sql = Select.sql;
|
|
66
|
+
let relcol = `${foreign.table}.${foreign.relation.main}`;
|
|
67
|
+
sql = sql.includes(relcol) ? sql : `${sql}, ${relcol}`;
|
|
68
|
+
fargs.select = {
|
|
69
|
+
sql,
|
|
70
|
+
columns,
|
|
71
|
+
formatable_columns: Select.formatable_columns,
|
|
72
|
+
relations: Select.relations,
|
|
73
|
+
};
|
|
74
|
+
// ==== Where =====
|
|
75
|
+
const Where = new WhereArgs(FModel, relArgs.where || {});
|
|
76
|
+
fargs.where = Where.wheres.join(" AND ");
|
|
77
|
+
// ===== OrderBy =====
|
|
78
|
+
fargs.orderBy = (new OrderByArgs(FModel, relArgs.orderBy || {})).sql;
|
|
79
|
+
// ===== Limit =====
|
|
80
|
+
fargs.limit = new LimitArgs(FModel, relArgs.limit || {});
|
|
81
|
+
// ===== Distinct =====
|
|
82
|
+
if (relArgs.distinct) {
|
|
83
|
+
const distinct = new DistinctArgs(FModel, relArgs.distinct || [], Where, relArgs.orderBy);
|
|
84
|
+
if (distinct.sql) {
|
|
85
|
+
fargs.where += fargs.where ? ` AND ${distinct.sql}` : `WHERE ${distinct.sql}`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// ===== Aggregate =====
|
|
89
|
+
if (relArgs.aggregate && Object.keys(relArgs.aggregate).length) {
|
|
90
|
+
fargs.aggregate = relArgs.aggregate;
|
|
91
|
+
}
|
|
92
|
+
this.relations[column] = {
|
|
93
|
+
args: fargs,
|
|
94
|
+
foreign
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
if (ValueFormatter.iof(model, column, XqlFile, XqlEnum, XqlArray, XqlObject, XqlRecord, XqlTuple, XqlUnion)) {
|
|
99
|
+
this.formatable_columns.push(column);
|
|
100
|
+
}
|
|
101
|
+
this.columns.push(column);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// if no columns are selected, select all columns
|
|
105
|
+
if (this.columns.length === 0) {
|
|
106
|
+
for (let column in model.schema) {
|
|
107
|
+
let field = model.schema[column];
|
|
108
|
+
if (!Foreign.is(field)) {
|
|
109
|
+
this.columns.push(column);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// always include ID column
|
|
114
|
+
if (!this.columns.includes(model.IDColumn)) {
|
|
115
|
+
this.columns.unshift(model.IDColumn);
|
|
116
|
+
}
|
|
117
|
+
this.sql = this.columns.map(col => `${this.model.table}.${col}`).join(', ');
|
|
118
|
+
}
|
|
119
|
+
}export{SelectArgs as default};//# sourceMappingURL=SelectArgs.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectArgs.mjs","sources":["../../../../src/model/Executer/Find/SelectArgs.ts"],"sourcesContent":["import Model from \"../..\";\nimport { FindArgsAggregate, FindArgsType, SelectArgsType } from \"../../type\";\nimport DistinctArgs from \"./DistinctArgs\";\nimport LimitArgs from \"./LimitArgs\";\nimport OrderByArgs from \"./OrderByArgs\";\nimport WhereArgs from \"../../Args/WhereArgs\";\nimport ValueFormatter from \"../../include/ValueFormatter\";\nimport XqlEnum from \"../../../Types/fields/Enum\";\nimport XqlArray from \"../../../Types/fields/Array\";\nimport XqlObject from \"../../../Types/fields/Object\";\nimport XqlRecord from \"../../../Types/fields/Record\";\nimport XqlTuple from \"../../../Types/fields/Tuple\";\nimport XqlUnion from \"../../../Types/fields/Union\";\nimport Foreign, { ForeignInfoType } from \"../../../core/classes/ForeignInfo\";\nimport XqlFile from \"../../../Types/fields/File\";\nimport XansqlError from \"../../../core/XansqlError\";\n\nexport type SelectArgsRelationInfo = {\n args: {\n select: {\n sql: string,\n columns: string[],\n formatable_columns: string[],\n relations?: SelectArgsRelations,\n },\n where: string,\n limit: Required<LimitArgs>,\n orderBy: string\n aggregate: FindArgsAggregate,\n },\n foreign: ForeignInfoType\n}\n\ntype SelectArgsRelations = {\n [column: string]: SelectArgsRelationInfo\n}\n\nclass SelectArgs {\n private model: Model\n\n /**\n * Get Columns\n * @description Returns the columns to be selected\n * @returns {string[]} Array of column names\n */\n readonly columns: string[] = []\n\n\n /**\n * Get Formatable Columns\n */\n readonly formatable_columns: string[] = []\n\n /**\n * Get SQL\n * @description Returns the SQL string for the selected columns\n * @returns {string} SQL string for selected columns\n * @example\n * const sql = selectArgs.sql; // returns \"table.column1, table.column2, ...\"\n */\n readonly relations: SelectArgsRelations = {}\n\n\n /**\n * Get Relations\n * @description Returns the relations to be selected\n * @returns {SelectArgsRelations} Object containing relation information\n * @example\n * const relations = selectArgs.relations; // returns { column: { args: FindArgsType, foreign: ForeignInfoType }, ... }\n */\n readonly sql: string = ''\n\n\n constructor(model: Model, args: SelectArgsType) {\n this.model = model\n\n for (let column in args) {\n if (!(column in this.model.schema)) {\n throw new XansqlError({\n message: `Column ${column} not found in model ${model.table} for select`,\n model: model.table,\n column: column\n });\n }\n\n let field = model.schema[column]\n let value: boolean | FindArgsType = args[column]\n\n if (Foreign.is(field)) {\n\n const relArgs = value === true ? { select: {} } : value as FindArgsType\n\n if (Foreign.isSchema(field)) {\n this.columns.push(column)\n }\n\n const foreign = Foreign.get(model, column)\n const FModel = model.xansql.getModel(foreign.table)\n\n\n // ====== Prepare select args for relation ======\n let fargs: any = {}\n const Select = new SelectArgs(FModel, relArgs.select || {})\n\n // ====== Prevent circular reference ======\n for (let rcol in Select.relations) {\n if (Select.relations[rcol].foreign.table === model.table) {\n throw new XansqlError({\n message: `Circular reference detected in relation ${column} of model ${model.table}`,\n model: model.table,\n column: column\n });\n }\n }\n\n // ====== Make sure main column of relation is selected ======\n\n let columns = Select.columns\n if (!columns.includes(foreign.relation.main)) {\n columns.unshift(foreign.relation.main)\n }\n let sql = Select.sql\n let relcol = `${foreign.table}.${foreign.relation.main}`\n sql = sql.includes(relcol) ? sql : `${sql}, ${relcol}`\n\n fargs.select = {\n sql,\n columns,\n formatable_columns: Select.formatable_columns,\n relations: Select.relations,\n }\n\n // ==== Where =====\n const Where = new WhereArgs(FModel, relArgs.where || {})\n fargs.where = Where.wheres.join(\" AND \")\n\n // ===== OrderBy =====\n fargs.orderBy = (new OrderByArgs(FModel, relArgs.orderBy || {})).sql\n\n // ===== Limit =====\n fargs.limit = new LimitArgs(FModel, relArgs.limit || {})\n\n // ===== Distinct =====\n if (relArgs.distinct) {\n const distinct = new DistinctArgs(FModel, relArgs.distinct || [], Where, relArgs.orderBy)\n if (distinct.sql) {\n fargs.where += fargs.where ? ` AND ${distinct.sql}` : `WHERE ${distinct.sql}`\n }\n }\n\n // ===== Aggregate =====\n if (relArgs.aggregate && Object.keys(relArgs.aggregate).length) {\n fargs.aggregate = relArgs.aggregate\n }\n\n this.relations[column] = {\n args: fargs,\n foreign\n }\n\n } else {\n if (ValueFormatter.iof(model, column, XqlFile, XqlEnum, XqlArray, XqlObject, XqlRecord, XqlTuple, XqlUnion)) {\n this.formatable_columns.push(column)\n }\n this.columns.push(column)\n }\n }\n\n // if no columns are selected, select all columns\n if (this.columns.length === 0) {\n for (let column in model.schema) {\n let field = model.schema[column]\n if (!Foreign.is(field)) {\n this.columns.push(column)\n }\n }\n }\n\n // always include ID column\n if (!this.columns.includes(model.IDColumn)) {\n this.columns.unshift(model.IDColumn)\n }\n\n this.sql = this.columns.map(col => `${this.model.table}.${col}`).join(', ')\n }\n\n\n}\n\nexport default SelectArgs"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var ForeignInfo=require('../../../core/classes/ForeignInfo.js'),ExcuteMeta=require('../../../core/ExcuteMeta.js'),XansqlError=require('../../../core/XansqlError.js'),chunker=require('../../../utils/chunker.js'),RelationExcuteArgs=require('../../Args/RelationExcuteArgs.js'),WhereArgs=require('../../Args/WhereArgs.js'),index=require('../Aggregate/index.js'),DistinctArgs=require('./DistinctArgs.js'),LimitArgs=require('./LimitArgs.js'),OrderByArgs=require('./OrderByArgs.js'),SelectArgs=require('./SelectArgs.js');class FindExecuter {
|
|
2
|
+
constructor(model, transformer = null) {
|
|
3
|
+
this.transformer = null;
|
|
4
|
+
this.model = model;
|
|
5
|
+
this.transformer = transformer;
|
|
6
|
+
}
|
|
7
|
+
async execute(args) {
|
|
8
|
+
const xansql = this.model.xansql;
|
|
9
|
+
const model = this.model;
|
|
10
|
+
const Select = new SelectArgs.default(model, args.select || {});
|
|
11
|
+
const Where = new WhereArgs.default(model, args.where || {});
|
|
12
|
+
const Limit = new LimitArgs.default(model, args.limit || {});
|
|
13
|
+
const OrderBy = new OrderByArgs.default(model, args.orderBy || {});
|
|
14
|
+
const Distinct = new DistinctArgs.default(model, args.distinct || [], Where, args.orderBy);
|
|
15
|
+
const isRelation = args instanceof RelationExcuteArgs.default;
|
|
16
|
+
let where_sql = Where.sql;
|
|
17
|
+
if (Distinct.sql) {
|
|
18
|
+
where_sql = where_sql ? `${where_sql} AND ${Distinct.sql}` : `WHERE ${Distinct.sql}`;
|
|
19
|
+
}
|
|
20
|
+
// batch execution with limit and offset
|
|
21
|
+
let results = [];
|
|
22
|
+
if (!Limit.sql) {
|
|
23
|
+
let executeId = undefined;
|
|
24
|
+
if (typeof window !== "undefined") {
|
|
25
|
+
executeId = ExcuteMeta.default.set({
|
|
26
|
+
model,
|
|
27
|
+
action: "SELECT",
|
|
28
|
+
modelType: isRelation ? "child" : "main",
|
|
29
|
+
args
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
const sql = `SELECT ${Select.sql} FROM ${model.table} ${where_sql}${OrderBy.sql}`.trim();
|
|
33
|
+
const executed = await xansql.execute(sql, executeId);
|
|
34
|
+
if (executed === null || executed === void 0 ? void 0 : executed.results) {
|
|
35
|
+
results = results.concat(executed.results);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
for (let { take, skip } of chunker.chunkNumbers(Limit.take)) {
|
|
40
|
+
let executeId = undefined;
|
|
41
|
+
if (typeof window !== "undefined") {
|
|
42
|
+
executeId = ExcuteMeta.default.set({
|
|
43
|
+
model,
|
|
44
|
+
action: "SELECT",
|
|
45
|
+
modelType: isRelation ? "child" : "main",
|
|
46
|
+
args
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
const batchLimitArgs = new LimitArgs.default(model, { take, skip: Limit.skip + skip });
|
|
50
|
+
const sql = `SELECT ${Select.sql} FROM ${model.table} ${where_sql}${OrderBy.sql}${batchLimitArgs.sql}`.trim();
|
|
51
|
+
const executed = await xansql.execute(sql, executeId);
|
|
52
|
+
if (executed === null || executed === void 0 ? void 0 : executed.results) {
|
|
53
|
+
results = results.concat(executed.results);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (results === null || results === void 0 ? void 0 : results.length) {
|
|
58
|
+
const is = Select.formatable_columns.length
|
|
59
|
+
|| Object.keys(Select.relations).length
|
|
60
|
+
|| Object.keys(args.aggregate || {}).length;
|
|
61
|
+
if (!is)
|
|
62
|
+
return results;
|
|
63
|
+
const freses = {};
|
|
64
|
+
let idsList = {};
|
|
65
|
+
for (let column in Select.relations) {
|
|
66
|
+
const relation = Select.relations[column];
|
|
67
|
+
const ids = idsList[column] || [];
|
|
68
|
+
const foreign = relation.foreign;
|
|
69
|
+
if (!idsList[column]) {
|
|
70
|
+
for (let r of results) {
|
|
71
|
+
let id = r[foreign.relation.target];
|
|
72
|
+
if (typeof id === "number" && !ids.includes(id)) {
|
|
73
|
+
ids.push(id);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
idsList[column] = ids;
|
|
77
|
+
}
|
|
78
|
+
const fres = await this.executeRelation(relation, ids);
|
|
79
|
+
freses[column] = fres;
|
|
80
|
+
}
|
|
81
|
+
const agg_reses = {};
|
|
82
|
+
if (Object.keys(args.aggregate || {}).length) {
|
|
83
|
+
const agg_results = await this.aggregate(model, args.aggregate || {}, results);
|
|
84
|
+
for (let col in agg_results) {
|
|
85
|
+
agg_reses[col] = agg_results[col];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
for (let { chunk } of chunker.chunkArray(results)) {
|
|
89
|
+
for (let row of chunk) {
|
|
90
|
+
// handle formattable columns
|
|
91
|
+
this.formatFormadableColumns(row, Select.formatable_columns);
|
|
92
|
+
row = (this === null || this === void 0 ? void 0 : this.transformer) ? await this.transformer(row) : row;
|
|
93
|
+
// handle aggregate
|
|
94
|
+
if (Object.keys(agg_reses).length) {
|
|
95
|
+
for (let col in agg_reses) {
|
|
96
|
+
const aggres = agg_reses[col];
|
|
97
|
+
if (!row.aggregate) {
|
|
98
|
+
row.aggregate = {};
|
|
99
|
+
}
|
|
100
|
+
row.aggregate[col] = aggres.results.find((ar) => {
|
|
101
|
+
let is = ar[aggres.foreign.relation.main] === row[aggres.foreign.relation.target];
|
|
102
|
+
if (is)
|
|
103
|
+
delete ar[aggres.foreign.relation.main];
|
|
104
|
+
return is;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// handle relations
|
|
109
|
+
if (Object.keys(freses).length) {
|
|
110
|
+
for (let col in freses) {
|
|
111
|
+
const fres = freses[col];
|
|
112
|
+
const relation = Select.relations[col];
|
|
113
|
+
if (ForeignInfo.default.isArray(model.schema[col])) {
|
|
114
|
+
row[col] = fres.filter((fr) => {
|
|
115
|
+
let is = fr[relation.foreign.relation.main] === row[relation.foreign.relation.target];
|
|
116
|
+
if (is)
|
|
117
|
+
delete fr[relation.foreign.relation.main];
|
|
118
|
+
return is;
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
row[col] = fres.find((fr) => fr[relation.foreign.relation.main] === row[relation.foreign.relation.target]) || null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return results;
|
|
130
|
+
}
|
|
131
|
+
async executeRelation(relation, ids) {
|
|
132
|
+
var _a;
|
|
133
|
+
let xansql = this.model.xansql;
|
|
134
|
+
let foreign = relation.foreign;
|
|
135
|
+
const table = foreign.table;
|
|
136
|
+
let FModel = xansql.getModel(table);
|
|
137
|
+
const field = FModel.schema[foreign.column];
|
|
138
|
+
let args = relation.args;
|
|
139
|
+
const chunkedIds = chunker.chunkArray(ids, 150);
|
|
140
|
+
let fres = [];
|
|
141
|
+
for (let { chunk } of chunkedIds) {
|
|
142
|
+
let sql = '';
|
|
143
|
+
const limit = args.limit;
|
|
144
|
+
let where_sql = args.where;
|
|
145
|
+
let insql = `${foreign.relation.main} IN (${chunk.join(",")})`;
|
|
146
|
+
where_sql += where_sql ? ` AND ${insql}` : `WHERE ${insql}`;
|
|
147
|
+
if (!ForeignInfo.default.isSchema(field)) {
|
|
148
|
+
sql = `SELECT ${args.select.sql} FROM ${table} ${where_sql} ${args.orderBy} ${limit.sql}`.trim();
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
if (!limit.sql) {
|
|
152
|
+
sql = `SELECT ${args.select.sql} FROM ${table} ${where_sql} ${args.orderBy}`.trim();
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
sql = `
|
|
156
|
+
SELECT ${args.select.sql} FROM (
|
|
157
|
+
SELECT
|
|
158
|
+
${args.select.sql},
|
|
159
|
+
ROW_NUMBER() OVER (PARTITION BY ${table}.${foreign.relation.main} ${args.orderBy}) AS ${table}_rank
|
|
160
|
+
FROM ${table}
|
|
161
|
+
${where_sql}
|
|
162
|
+
) AS ${table}
|
|
163
|
+
WHERE ${table}_rank > ${limit.skip} AND ${table}_rank <= ${limit.take + limit.skip};
|
|
164
|
+
`;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
let executeId = undefined;
|
|
168
|
+
if (typeof window !== "undefined") {
|
|
169
|
+
executeId = ExcuteMeta.default.set({
|
|
170
|
+
model: FModel,
|
|
171
|
+
action: "SELECT",
|
|
172
|
+
modelType: "child",
|
|
173
|
+
args
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
const res = (await xansql.execute(sql, executeId)).results;
|
|
177
|
+
if (res) {
|
|
178
|
+
fres = fres.concat(res);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// let insql = `${foreign.relation.main} IN (${ids.join(",")})`
|
|
182
|
+
// where_sql += where_sql ? ` AND ${insql}` : `WHERE ${insql}`
|
|
183
|
+
// if (!Foreign.isSchema(field)) {
|
|
184
|
+
// sql = `SELECT ${args.select.sql} FROM ${table} ${where_sql} ${args.orderBy} ${limit.sql}`.trim()
|
|
185
|
+
// } else {
|
|
186
|
+
// sql = `
|
|
187
|
+
// SELECT ${args.select.sql} FROM (
|
|
188
|
+
// SELECT
|
|
189
|
+
// ${args.select.sql},
|
|
190
|
+
// ROW_NUMBER() OVER (PARTITION BY ${table}.${foreign.relation.main} ${args.orderBy}) AS ${table}_rank
|
|
191
|
+
// FROM ${table}
|
|
192
|
+
// ${where_sql}
|
|
193
|
+
// ) AS ${table}
|
|
194
|
+
// WHERE ${table}_rank > ${limit.skip} AND ${table}_rank <= ${limit.take + limit.skip};
|
|
195
|
+
// `
|
|
196
|
+
// }
|
|
197
|
+
// const res = (await FModel.execute(sql)).results
|
|
198
|
+
// fres = fres.concat(res)
|
|
199
|
+
if (fres.length) {
|
|
200
|
+
const is = args.select.formatable_columns.length
|
|
201
|
+
|| Object.keys(args.select.relations || {}).length
|
|
202
|
+
|| Object.keys(args.aggregate || {}).length;
|
|
203
|
+
if (!is)
|
|
204
|
+
return fres;
|
|
205
|
+
const nested_freses = {};
|
|
206
|
+
const idsList = {};
|
|
207
|
+
// handle nested relations
|
|
208
|
+
for (let col in args.select.relations) {
|
|
209
|
+
const rel = args.select.relations[col];
|
|
210
|
+
const ids = idsList[col] || [];
|
|
211
|
+
const foreign = rel.foreign;
|
|
212
|
+
if (!idsList[col]) {
|
|
213
|
+
for (let r of fres) {
|
|
214
|
+
let id = r[foreign.relation.target];
|
|
215
|
+
if (typeof id === "number" && !ids.includes(id)) {
|
|
216
|
+
ids.push(id);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
idsList[col] = ids;
|
|
220
|
+
}
|
|
221
|
+
const nested_fres = await this.executeRelation(rel, ids);
|
|
222
|
+
nested_freses[col] = nested_fres;
|
|
223
|
+
}
|
|
224
|
+
// handle aggregate
|
|
225
|
+
const agg_reses = {};
|
|
226
|
+
if (Object.keys(args.aggregate || {}).length) {
|
|
227
|
+
const agg_results = await this.aggregate(FModel, args.aggregate || {}, fres);
|
|
228
|
+
for (let col in agg_results) {
|
|
229
|
+
agg_reses[col] = agg_results[col];
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
for (let { chunk } of chunker.chunkArray(fres)) {
|
|
233
|
+
for (let row of chunk) {
|
|
234
|
+
// handle formattable columns
|
|
235
|
+
this.formatFormadableColumns(row, args.select.formatable_columns);
|
|
236
|
+
row = (this === null || this === void 0 ? void 0 : this.transformer) ? await this.transformer(row) : row;
|
|
237
|
+
// handle aggregate
|
|
238
|
+
if (Object.keys(agg_reses).length) {
|
|
239
|
+
for (let col in agg_reses) {
|
|
240
|
+
const aggres = agg_reses[col];
|
|
241
|
+
if (!row.aggregate) {
|
|
242
|
+
row.aggregate = {};
|
|
243
|
+
}
|
|
244
|
+
row.aggregate[col] = aggres.results.find((ar) => {
|
|
245
|
+
let is = ar[aggres.foreign.relation.target] === row[aggres.foreign.relation.main];
|
|
246
|
+
if (is)
|
|
247
|
+
delete ar[aggres.foreign.relation.main];
|
|
248
|
+
return is;
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
// handle nested relations
|
|
253
|
+
if (Object.keys(nested_freses).length) {
|
|
254
|
+
for (let col in nested_freses) {
|
|
255
|
+
const nested_fres = nested_freses[col];
|
|
256
|
+
const rel = (_a = args.select.relations) === null || _a === void 0 ? void 0 : _a[col];
|
|
257
|
+
if (ForeignInfo.default.isArray(FModel.schema[col])) {
|
|
258
|
+
row[col] = nested_fres.filter((fr) => {
|
|
259
|
+
let is = fr[rel.foreign.relation.main] === row[rel.foreign.relation.target];
|
|
260
|
+
if (is)
|
|
261
|
+
delete fr[rel.foreign.relation.main];
|
|
262
|
+
return is;
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
row[col] = nested_fres.find((fr) => fr[rel.foreign.relation.main] === row[rel.foreign.relation.target]) || null;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return fres;
|
|
274
|
+
}
|
|
275
|
+
formatFormadableColumns(row, columns) {
|
|
276
|
+
for (let col of columns) {
|
|
277
|
+
try {
|
|
278
|
+
row[col] = JSON.parse(row[col]);
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
row[col] = row[col];
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
async aggregate(model, aggregate, results) {
|
|
286
|
+
const xansql = model.xansql;
|
|
287
|
+
const agg_results = {};
|
|
288
|
+
for (let col in aggregate) {
|
|
289
|
+
if (!(col in model.schema)) {
|
|
290
|
+
throw new XansqlError.default({
|
|
291
|
+
message: `Column ${col} not found in model ${model.table} for aggregate`,
|
|
292
|
+
model: model.table,
|
|
293
|
+
column: col
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
const foreign = ForeignInfo.default.get(model, col);
|
|
297
|
+
if (!foreign) {
|
|
298
|
+
throw new XansqlError.default({
|
|
299
|
+
message: `Column ${col} is not a foreign column in ${model.table}, cannot aggregate on it.`,
|
|
300
|
+
model: model.table,
|
|
301
|
+
column: col
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
if (!ForeignInfo.default.isArray(model.schema[col])) {
|
|
305
|
+
throw new XansqlError.default({
|
|
306
|
+
message: `Column ${col} is not a relation column in ${model.table}, cannot aggregate on it.`,
|
|
307
|
+
model: model.table,
|
|
308
|
+
column: col
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
const FModel = xansql.getModel(foreign.table);
|
|
312
|
+
let ids = [];
|
|
313
|
+
for (let r of results) {
|
|
314
|
+
let id = r[foreign.relation.target];
|
|
315
|
+
if (typeof id === "number" && !ids.includes(id)) {
|
|
316
|
+
ids.push(id);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
if (ids.length === 0)
|
|
320
|
+
continue;
|
|
321
|
+
const AggExecuter = new index.default(FModel, false);
|
|
322
|
+
const aggRes = await AggExecuter.execute({
|
|
323
|
+
where: {
|
|
324
|
+
[foreign.relation.main]: {
|
|
325
|
+
in: ids
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
groupBy: [foreign.relation.main],
|
|
329
|
+
select: aggregate[col]
|
|
330
|
+
});
|
|
331
|
+
agg_results[col] = {
|
|
332
|
+
results: aggRes,
|
|
333
|
+
foreign
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
return agg_results;
|
|
337
|
+
}
|
|
338
|
+
}exports.default=FindExecuter;//# sourceMappingURL=index.js.map
|