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.
Files changed (232) hide show
  1. package/Types/fields/Array.d.ts +7 -0
  2. package/Types/fields/Array.js +6 -0
  3. package/Types/fields/Array.js.map +1 -0
  4. package/Types/fields/Array.mjs +6 -0
  5. package/Types/fields/Array.mjs.map +1 -0
  6. package/Types/fields/Boolean.d.ts +8 -0
  7. package/Types/fields/Boolean.js +11 -0
  8. package/Types/fields/Boolean.js.map +1 -0
  9. package/Types/fields/Boolean.mjs +11 -0
  10. package/Types/fields/Boolean.mjs.map +1 -0
  11. package/Types/fields/Date.d.ts +10 -0
  12. package/Types/fields/Date.js +22 -0
  13. package/Types/fields/Date.js.map +1 -0
  14. package/Types/fields/Date.mjs +22 -0
  15. package/Types/fields/Date.mjs.map +1 -0
  16. package/Types/fields/Enum.d.ts +8 -0
  17. package/Types/fields/Enum.js +10 -0
  18. package/Types/fields/Enum.js.map +1 -0
  19. package/Types/fields/Enum.mjs +10 -0
  20. package/Types/fields/Enum.mjs.map +1 -0
  21. package/Types/fields/File.d.ts +7 -0
  22. package/Types/fields/File.js +6 -0
  23. package/Types/fields/File.js.map +1 -0
  24. package/Types/fields/File.mjs +6 -0
  25. package/Types/fields/File.mjs.map +1 -0
  26. package/Types/fields/IDField.d.ts +6 -0
  27. package/Types/fields/IDField.js +2 -0
  28. package/Types/fields/IDField.js.map +1 -0
  29. package/Types/fields/IDField.mjs +2 -0
  30. package/Types/fields/IDField.mjs.map +1 -0
  31. package/Types/fields/Number.d.ts +8 -0
  32. package/Types/fields/Number.js +11 -0
  33. package/Types/fields/Number.js.map +1 -0
  34. package/Types/fields/Number.mjs +11 -0
  35. package/Types/fields/Number.mjs.map +1 -0
  36. package/Types/fields/Object.d.ts +8 -0
  37. package/Types/fields/Object.js +11 -0
  38. package/Types/fields/Object.js.map +1 -0
  39. package/Types/fields/Object.mjs +11 -0
  40. package/Types/fields/Object.mjs.map +1 -0
  41. package/Types/fields/Record.d.ts +8 -0
  42. package/Types/fields/Record.js +11 -0
  43. package/Types/fields/Record.js.map +1 -0
  44. package/Types/fields/Record.mjs +11 -0
  45. package/Types/fields/Record.mjs.map +1 -0
  46. package/Types/fields/Schema.d.ts +16 -0
  47. package/Types/fields/Schema.js +34 -0
  48. package/Types/fields/Schema.js.map +1 -0
  49. package/Types/fields/Schema.mjs +34 -0
  50. package/Types/fields/Schema.mjs.map +1 -0
  51. package/Types/fields/String.d.ts +10 -0
  52. package/Types/fields/String.js +20 -0
  53. package/Types/fields/String.js.map +1 -0
  54. package/Types/fields/String.mjs +20 -0
  55. package/Types/fields/String.mjs.map +1 -0
  56. package/Types/fields/Tuple.d.ts +8 -0
  57. package/Types/fields/Tuple.js +11 -0
  58. package/Types/fields/Tuple.js.map +1 -0
  59. package/Types/fields/Tuple.mjs +11 -0
  60. package/Types/fields/Tuple.mjs.map +1 -0
  61. package/Types/fields/Union.d.ts +8 -0
  62. package/Types/fields/Union.js +11 -0
  63. package/Types/fields/Union.js.map +1 -0
  64. package/Types/fields/Union.mjs +11 -0
  65. package/Types/fields/Union.mjs.map +1 -0
  66. package/Types/index.d.ts +56 -0
  67. package/Types/index.js +129 -0
  68. package/Types/index.js.map +1 -0
  69. package/Types/index.mjs +129 -0
  70. package/Types/index.mjs.map +1 -0
  71. package/Types/types.d.ts +20 -0
  72. package/core/ExcuteMeta.d.ts +11 -0
  73. package/core/ExcuteMeta.js +22 -0
  74. package/core/ExcuteMeta.js.map +1 -0
  75. package/core/ExcuteMeta.mjs +22 -0
  76. package/core/ExcuteMeta.mjs.map +1 -0
  77. package/core/Xansql.d.ts +46 -0
  78. package/core/Xansql.js +132 -0
  79. package/core/Xansql.js.map +1 -0
  80. package/core/Xansql.mjs +132 -0
  81. package/core/Xansql.mjs.map +1 -0
  82. package/core/XansqlError.js +11 -0
  83. package/core/XansqlError.js.map +1 -0
  84. package/core/XansqlError.mjs +11 -0
  85. package/core/XansqlError.mjs.map +1 -0
  86. package/core/XansqlResult.d.ts +12 -0
  87. package/core/XansqlResult.js +32 -0
  88. package/core/XansqlResult.js.map +1 -0
  89. package/core/XansqlResult.mjs +32 -0
  90. package/core/XansqlResult.mjs.map +1 -0
  91. package/core/classes/EventManager.d.ts +72 -0
  92. package/core/classes/EventManager.js +21 -0
  93. package/core/classes/EventManager.js.map +1 -0
  94. package/core/classes/EventManager.mjs +21 -0
  95. package/core/classes/EventManager.mjs.map +1 -0
  96. package/core/classes/ForeignInfo.js +51 -0
  97. package/core/classes/ForeignInfo.js.map +1 -0
  98. package/core/classes/ForeignInfo.mjs +51 -0
  99. package/core/classes/ForeignInfo.mjs.map +1 -0
  100. package/core/classes/Migration/ForeingMigration.d.ts +12 -0
  101. package/core/classes/Migration/ForeingMigration.js +52 -0
  102. package/core/classes/Migration/ForeingMigration.js.map +1 -0
  103. package/core/classes/Migration/ForeingMigration.mjs +52 -0
  104. package/core/classes/Migration/ForeingMigration.mjs.map +1 -0
  105. package/core/classes/Migration/IndexMigration.d.ts +12 -0
  106. package/core/classes/Migration/IndexMigration.js +49 -0
  107. package/core/classes/Migration/IndexMigration.js.map +1 -0
  108. package/core/classes/Migration/IndexMigration.mjs +49 -0
  109. package/core/classes/Migration/IndexMigration.mjs.map +1 -0
  110. package/core/classes/Migration/TableMigration.d.ts +33 -0
  111. package/core/classes/Migration/TableMigration.js +215 -0
  112. package/core/classes/Migration/TableMigration.js.map +1 -0
  113. package/core/classes/Migration/TableMigration.mjs +215 -0
  114. package/core/classes/Migration/TableMigration.mjs.map +1 -0
  115. package/core/classes/Migration/index.d.ts +12 -0
  116. package/core/classes/Migration/index.js +189 -0
  117. package/core/classes/Migration/index.js.map +1 -0
  118. package/core/classes/Migration/index.mjs +189 -0
  119. package/core/classes/Migration/index.mjs.map +1 -0
  120. package/core/classes/ModelFormatter.js +166 -0
  121. package/core/classes/ModelFormatter.js.map +1 -0
  122. package/core/classes/ModelFormatter.mjs +166 -0
  123. package/core/classes/ModelFormatter.mjs.map +1 -0
  124. package/core/classes/TypesGenerator.d.ts +13 -0
  125. package/core/classes/TypesGenerator.js +170 -0
  126. package/core/classes/TypesGenerator.js.map +1 -0
  127. package/core/classes/TypesGenerator.mjs +170 -0
  128. package/core/classes/TypesGenerator.mjs.map +1 -0
  129. package/core/classes/XansqlConfig.js +33 -0
  130. package/core/classes/XansqlConfig.js.map +1 -0
  131. package/core/classes/XansqlConfig.mjs +33 -0
  132. package/core/classes/XansqlConfig.mjs.map +1 -0
  133. package/core/classes/XansqlFetch.js +304 -0
  134. package/core/classes/XansqlFetch.js.map +1 -0
  135. package/core/classes/XansqlFetch.mjs +304 -0
  136. package/core/classes/XansqlFetch.mjs.map +1 -0
  137. package/core/classes/XansqlTransaction.d.ts +13 -0
  138. package/core/classes/XansqlTransaction.js +46 -0
  139. package/core/classes/XansqlTransaction.js.map +1 -0
  140. package/core/classes/XansqlTransaction.mjs +46 -0
  141. package/core/classes/XansqlTransaction.mjs.map +1 -0
  142. package/core/type.d.ts +117 -0
  143. package/index.d.ts +3 -0
  144. package/index.js +1 -0
  145. package/index.js.map +1 -0
  146. package/index.mjs +1 -0
  147. package/index.mjs.map +1 -0
  148. package/model/Args/RelationExcuteArgs.js +5 -0
  149. package/model/Args/RelationExcuteArgs.js.map +1 -0
  150. package/model/Args/RelationExcuteArgs.mjs +5 -0
  151. package/model/Args/RelationExcuteArgs.mjs.map +1 -0
  152. package/model/Args/WhereArgs.js +226 -0
  153. package/model/Args/WhereArgs.js.map +1 -0
  154. package/model/Args/WhereArgs.mjs +226 -0
  155. package/model/Args/WhereArgs.mjs.map +1 -0
  156. package/model/Base.d.ts +26 -0
  157. package/model/Base.js +64 -0
  158. package/model/Base.js.map +1 -0
  159. package/model/Base.mjs +64 -0
  160. package/model/Base.mjs.map +1 -0
  161. package/model/Executer/Aggregate/SelectArgs.js +59 -0
  162. package/model/Executer/Aggregate/SelectArgs.js.map +1 -0
  163. package/model/Executer/Aggregate/SelectArgs.mjs +59 -0
  164. package/model/Executer/Aggregate/SelectArgs.mjs.map +1 -0
  165. package/model/Executer/Aggregate/index.js +59 -0
  166. package/model/Executer/Aggregate/index.js.map +1 -0
  167. package/model/Executer/Aggregate/index.mjs +59 -0
  168. package/model/Executer/Aggregate/index.mjs.map +1 -0
  169. package/model/Executer/Create/CreateDataArgs.js +145 -0
  170. package/model/Executer/Create/CreateDataArgs.js.map +1 -0
  171. package/model/Executer/Create/CreateDataArgs.mjs +145 -0
  172. package/model/Executer/Create/CreateDataArgs.mjs.map +1 -0
  173. package/model/Executer/Create/index.js +101 -0
  174. package/model/Executer/Create/index.js.map +1 -0
  175. package/model/Executer/Create/index.mjs +101 -0
  176. package/model/Executer/Create/index.mjs.map +1 -0
  177. package/model/Executer/Delete/index.js +112 -0
  178. package/model/Executer/Delete/index.js.map +1 -0
  179. package/model/Executer/Delete/index.mjs +112 -0
  180. package/model/Executer/Delete/index.mjs.map +1 -0
  181. package/model/Executer/Find/DistinctArgs.js +32 -0
  182. package/model/Executer/Find/DistinctArgs.js.map +1 -0
  183. package/model/Executer/Find/DistinctArgs.mjs +32 -0
  184. package/model/Executer/Find/DistinctArgs.mjs.map +1 -0
  185. package/model/Executer/Find/LimitArgs.js +31 -0
  186. package/model/Executer/Find/LimitArgs.js.map +1 -0
  187. package/model/Executer/Find/LimitArgs.mjs +31 -0
  188. package/model/Executer/Find/LimitArgs.mjs.map +1 -0
  189. package/model/Executer/Find/OrderByArgs.js +29 -0
  190. package/model/Executer/Find/OrderByArgs.js.map +1 -0
  191. package/model/Executer/Find/OrderByArgs.mjs +29 -0
  192. package/model/Executer/Find/OrderByArgs.mjs.map +1 -0
  193. package/model/Executer/Find/SelectArgs.js +119 -0
  194. package/model/Executer/Find/SelectArgs.js.map +1 -0
  195. package/model/Executer/Find/SelectArgs.mjs +119 -0
  196. package/model/Executer/Find/SelectArgs.mjs.map +1 -0
  197. package/model/Executer/Find/index.js +338 -0
  198. package/model/Executer/Find/index.js.map +1 -0
  199. package/model/Executer/Find/index.mjs +338 -0
  200. package/model/Executer/Find/index.mjs.map +1 -0
  201. package/model/Executer/Update/UpdateDataArgs.js +124 -0
  202. package/model/Executer/Update/UpdateDataArgs.js.map +1 -0
  203. package/model/Executer/Update/UpdateDataArgs.mjs +124 -0
  204. package/model/Executer/Update/UpdateDataArgs.mjs.map +1 -0
  205. package/model/Executer/Update/index.js +207 -0
  206. package/model/Executer/Update/index.js.map +1 -0
  207. package/model/Executer/Update/index.mjs +207 -0
  208. package/model/Executer/Update/index.mjs.map +1 -0
  209. package/model/include/ValueFormatter.js +99 -0
  210. package/model/include/ValueFormatter.js.map +1 -0
  211. package/model/include/ValueFormatter.mjs +99 -0
  212. package/model/include/ValueFormatter.mjs.map +1 -0
  213. package/model/index.d.ts +29 -0
  214. package/model/index.js +236 -0
  215. package/model/index.js.map +1 -0
  216. package/model/index.mjs +236 -0
  217. package/model/index.mjs.map +1 -0
  218. package/model/type.d.ts +106 -0
  219. package/package.json +32 -0
  220. package/readme.md +359 -0
  221. package/utils/chunker.js +53 -0
  222. package/utils/chunker.js.map +1 -0
  223. package/utils/chunker.mjs +53 -0
  224. package/utils/chunker.mjs.map +1 -0
  225. package/utils/index.js +49 -0
  226. package/utils/index.js.map +1 -0
  227. package/utils/index.mjs +49 -0
  228. package/utils/index.mjs.map +1 -0
  229. package/utils/sha256.js +66 -0
  230. package/utils/sha256.js.map +1 -0
  231. package/utils/sha256.mjs +66 -0
  232. 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":"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"}
@@ -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