@simonbackx/simple-database 1.35.0 → 1.36.3

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 (230) hide show
  1. package/dist/_virtual/_@oxc-project_runtime@0.115.0/helpers/decorate.cjs +9 -0
  2. package/dist/_virtual/_@oxc-project_runtime@0.115.0/helpers/decorate.mjs +9 -0
  3. package/dist/_virtual/_rolldown/runtime.cjs +23 -0
  4. package/dist/index.cjs +22 -0
  5. package/dist/index.d.cts +10 -0
  6. package/dist/index.d.mts +10 -0
  7. package/dist/index.mjs +10 -0
  8. package/dist/src/classes/Column.cjs +134 -0
  9. package/dist/src/classes/Column.d.cts +34 -0
  10. package/dist/src/classes/Column.d.cts.map +1 -0
  11. package/dist/src/classes/Column.d.mts +34 -0
  12. package/dist/src/classes/Column.d.mts.map +1 -0
  13. package/dist/src/classes/Column.mjs +135 -0
  14. package/dist/src/classes/Column.mjs.map +1 -0
  15. package/dist/src/classes/ColumnType.d.cts +5 -0
  16. package/dist/src/classes/ColumnType.d.cts.map +1 -0
  17. package/dist/src/classes/ColumnType.d.mts +5 -0
  18. package/dist/src/classes/ColumnType.d.mts.map +1 -0
  19. package/dist/src/classes/Database.cjs +157 -0
  20. package/dist/src/classes/Database.d.cts +59 -0
  21. package/dist/src/classes/Database.d.cts.map +1 -0
  22. package/dist/src/classes/Database.d.mts +59 -0
  23. package/dist/src/classes/Database.d.mts.map +1 -0
  24. package/dist/src/classes/Database.mjs +155 -0
  25. package/dist/src/classes/Database.mjs.map +1 -0
  26. package/dist/src/classes/DatabaseStoredValue.d.cts +5 -0
  27. package/dist/src/classes/DatabaseStoredValue.d.cts.map +1 -0
  28. package/dist/src/classes/DatabaseStoredValue.d.mts +5 -0
  29. package/dist/src/classes/DatabaseStoredValue.d.mts.map +1 -0
  30. package/dist/src/classes/Factory.cjs +48 -0
  31. package/dist/src/classes/Factory.d.cts +17 -0
  32. package/dist/src/classes/Factory.d.cts.map +1 -0
  33. package/dist/src/classes/Factory.d.mts +17 -0
  34. package/dist/src/classes/Factory.d.mts.map +1 -0
  35. package/dist/src/classes/Factory.mjs +50 -0
  36. package/dist/src/classes/Factory.mjs.map +1 -0
  37. package/dist/src/classes/ManyToManyRelation.cjs +193 -0
  38. package/dist/src/classes/ManyToManyRelation.d.cts +83 -0
  39. package/dist/src/classes/ManyToManyRelation.d.cts.map +1 -0
  40. package/dist/src/classes/ManyToManyRelation.d.mts +83 -0
  41. package/dist/src/classes/ManyToManyRelation.d.mts.map +1 -0
  42. package/dist/src/classes/ManyToManyRelation.mjs +195 -0
  43. package/dist/src/classes/ManyToManyRelation.mjs.map +1 -0
  44. package/dist/src/classes/ManyToOneRelation.cjs +41 -0
  45. package/dist/src/classes/ManyToOneRelation.d.cts +26 -0
  46. package/dist/src/classes/ManyToOneRelation.d.cts.map +1 -0
  47. package/dist/src/classes/ManyToOneRelation.d.mts +26 -0
  48. package/dist/src/classes/ManyToOneRelation.d.mts.map +1 -0
  49. package/dist/src/classes/ManyToOneRelation.mjs +43 -0
  50. package/dist/src/classes/ManyToOneRelation.mjs.map +1 -0
  51. package/dist/src/classes/Migration.cjs +123 -0
  52. package/dist/src/classes/Migration.d.cts +16 -0
  53. package/dist/src/classes/Migration.d.cts.map +1 -0
  54. package/dist/src/classes/Migration.d.mts +16 -0
  55. package/dist/src/classes/Migration.d.mts.map +1 -0
  56. package/dist/src/classes/Migration.mjs +123 -0
  57. package/dist/src/classes/Migration.mjs.map +1 -0
  58. package/dist/src/classes/Model.cjs +459 -0
  59. package/dist/src/classes/Model.d.cts +162 -0
  60. package/dist/src/classes/Model.d.cts.map +1 -0
  61. package/dist/src/classes/Model.d.mts +162 -0
  62. package/dist/src/classes/Model.d.mts.map +1 -0
  63. package/dist/src/classes/Model.mjs +460 -0
  64. package/dist/src/classes/Model.mjs.map +1 -0
  65. package/dist/src/classes/OneToManyRelation.cjs +66 -0
  66. package/dist/src/classes/OneToManyRelation.d.cts +42 -0
  67. package/dist/src/classes/OneToManyRelation.d.cts.map +1 -0
  68. package/dist/src/classes/OneToManyRelation.d.mts +42 -0
  69. package/dist/src/classes/OneToManyRelation.d.mts.map +1 -0
  70. package/dist/src/classes/OneToManyRelation.mjs +68 -0
  71. package/dist/src/classes/OneToManyRelation.mjs.map +1 -0
  72. package/dist/src/classes/data/boys.cjs +1005 -0
  73. package/dist/src/classes/data/boys.mjs +1007 -0
  74. package/dist/src/classes/data/boys.mjs.map +1 -0
  75. package/dist/src/classes/data/family-names.cjs +1005 -0
  76. package/dist/src/classes/data/family-names.mjs +1007 -0
  77. package/dist/src/classes/data/family-names.mjs.map +1 -0
  78. package/dist/src/classes/data/girls.cjs +1004 -0
  79. package/dist/src/classes/data/girls.mjs +1006 -0
  80. package/dist/src/classes/data/girls.mjs.map +1 -0
  81. package/dist/src/decorators/Column.cjs +26 -0
  82. package/dist/src/decorators/Column.d.cts +22 -0
  83. package/dist/src/decorators/Column.d.cts.map +1 -0
  84. package/dist/src/decorators/Column.d.mts +22 -0
  85. package/dist/src/decorators/Column.d.mts.map +1 -0
  86. package/dist/src/decorators/Column.mjs +28 -0
  87. package/dist/src/decorators/Column.mjs.map +1 -0
  88. package/dist/src/models/Migration.cjs +37 -0
  89. package/dist/src/models/Migration.mjs +39 -0
  90. package/dist/src/models/Migration.mjs.map +1 -0
  91. package/package.json +16 -13
  92. package/dist/cjs/index.d.ts +0 -10
  93. package/dist/cjs/index.d.ts.map +0 -1
  94. package/dist/cjs/index.js +0 -13
  95. package/dist/cjs/index.js.map +0 -1
  96. package/dist/cjs/package.json +0 -1
  97. package/dist/cjs/src/classes/Column.d.ts +0 -30
  98. package/dist/cjs/src/classes/Column.d.ts.map +0 -1
  99. package/dist/cjs/src/classes/Column.js +0 -183
  100. package/dist/cjs/src/classes/Column.js.map +0 -1
  101. package/dist/cjs/src/classes/ColumnType.d.ts +0 -2
  102. package/dist/cjs/src/classes/ColumnType.d.ts.map +0 -1
  103. package/dist/cjs/src/classes/ColumnType.js +0 -3
  104. package/dist/cjs/src/classes/ColumnType.js.map +0 -1
  105. package/dist/cjs/src/classes/Database.d.ts +0 -59
  106. package/dist/cjs/src/classes/Database.d.ts.map +0 -1
  107. package/dist/cjs/src/classes/Database.js +0 -176
  108. package/dist/cjs/src/classes/Database.js.map +0 -1
  109. package/dist/cjs/src/classes/DatabaseStoredValue.d.ts +0 -2
  110. package/dist/cjs/src/classes/DatabaseStoredValue.d.ts.map +0 -1
  111. package/dist/cjs/src/classes/DatabaseStoredValue.js +0 -3
  112. package/dist/cjs/src/classes/DatabaseStoredValue.js.map +0 -1
  113. package/dist/cjs/src/classes/Factory.d.ts +0 -14
  114. package/dist/cjs/src/classes/Factory.d.ts.map +0 -1
  115. package/dist/cjs/src/classes/Factory.js +0 -56
  116. package/dist/cjs/src/classes/Factory.js.map +0 -1
  117. package/dist/cjs/src/classes/ManyToManyRelation.d.ts +0 -79
  118. package/dist/cjs/src/classes/ManyToManyRelation.d.ts.map +0 -1
  119. package/dist/cjs/src/classes/ManyToManyRelation.js +0 -258
  120. package/dist/cjs/src/classes/ManyToManyRelation.js.map +0 -1
  121. package/dist/cjs/src/classes/ManyToOneRelation.d.ts +0 -22
  122. package/dist/cjs/src/classes/ManyToOneRelation.d.ts.map +0 -1
  123. package/dist/cjs/src/classes/ManyToOneRelation.js +0 -51
  124. package/dist/cjs/src/classes/ManyToOneRelation.js.map +0 -1
  125. package/dist/cjs/src/classes/Migration.d.ts +0 -14
  126. package/dist/cjs/src/classes/Migration.d.ts.map +0 -1
  127. package/dist/cjs/src/classes/Migration.js +0 -206
  128. package/dist/cjs/src/classes/Migration.js.map +0 -1
  129. package/dist/cjs/src/classes/Model.d.ts +0 -159
  130. package/dist/cjs/src/classes/Model.d.ts.map +0 -1
  131. package/dist/cjs/src/classes/Model.js +0 -640
  132. package/dist/cjs/src/classes/Model.js.map +0 -1
  133. package/dist/cjs/src/classes/OneToManyRelation.d.ts +0 -38
  134. package/dist/cjs/src/classes/OneToManyRelation.d.ts.map +0 -1
  135. package/dist/cjs/src/classes/OneToManyRelation.js +0 -79
  136. package/dist/cjs/src/classes/OneToManyRelation.js.map +0 -1
  137. package/dist/cjs/src/classes/data/boys.d.ts +0 -3
  138. package/dist/cjs/src/classes/data/boys.d.ts.map +0 -1
  139. package/dist/cjs/src/classes/data/boys.js +0 -1005
  140. package/dist/cjs/src/classes/data/boys.js.map +0 -1
  141. package/dist/cjs/src/classes/data/family-names.d.ts +0 -3
  142. package/dist/cjs/src/classes/data/family-names.d.ts.map +0 -1
  143. package/dist/cjs/src/classes/data/family-names.js +0 -1005
  144. package/dist/cjs/src/classes/data/family-names.js.map +0 -1
  145. package/dist/cjs/src/classes/data/girls.d.ts +0 -3
  146. package/dist/cjs/src/classes/data/girls.d.ts.map +0 -1
  147. package/dist/cjs/src/classes/data/girls.js +0 -1004
  148. package/dist/cjs/src/classes/data/girls.js.map +0 -1
  149. package/dist/cjs/src/classes/data/streets.d.ts +0 -3
  150. package/dist/cjs/src/classes/data/streets.d.ts.map +0 -1
  151. package/dist/cjs/src/classes/data/streets.js +0 -296
  152. package/dist/cjs/src/classes/data/streets.js.map +0 -1
  153. package/dist/cjs/src/decorators/Column.d.ts +0 -18
  154. package/dist/cjs/src/decorators/Column.d.ts.map +0 -1
  155. package/dist/cjs/src/decorators/Column.js +0 -39
  156. package/dist/cjs/src/decorators/Column.js.map +0 -1
  157. package/dist/cjs/src/models/Migration.d.ts +0 -11
  158. package/dist/cjs/src/models/Migration.d.ts.map +0 -1
  159. package/dist/cjs/src/models/Migration.js +0 -52
  160. package/dist/cjs/src/models/Migration.js.map +0 -1
  161. package/dist/cjs/tsconfig.cjs.tsbuildinfo +0 -1
  162. package/dist/esm/index.d.ts +0 -10
  163. package/dist/esm/index.d.ts.map +0 -1
  164. package/dist/esm/index.js +0 -10
  165. package/dist/esm/index.js.map +0 -1
  166. package/dist/esm/src/classes/Column.d.ts +0 -30
  167. package/dist/esm/src/classes/Column.d.ts.map +0 -1
  168. package/dist/esm/src/classes/Column.js +0 -179
  169. package/dist/esm/src/classes/Column.js.map +0 -1
  170. package/dist/esm/src/classes/ColumnType.d.ts +0 -2
  171. package/dist/esm/src/classes/ColumnType.d.ts.map +0 -1
  172. package/dist/esm/src/classes/ColumnType.js +0 -2
  173. package/dist/esm/src/classes/ColumnType.js.map +0 -1
  174. package/dist/esm/src/classes/Database.d.ts +0 -59
  175. package/dist/esm/src/classes/Database.d.ts.map +0 -1
  176. package/dist/esm/src/classes/Database.js +0 -171
  177. package/dist/esm/src/classes/Database.js.map +0 -1
  178. package/dist/esm/src/classes/DatabaseStoredValue.d.ts +0 -2
  179. package/dist/esm/src/classes/DatabaseStoredValue.d.ts.map +0 -1
  180. package/dist/esm/src/classes/DatabaseStoredValue.js +0 -2
  181. package/dist/esm/src/classes/DatabaseStoredValue.js.map +0 -1
  182. package/dist/esm/src/classes/Factory.d.ts +0 -14
  183. package/dist/esm/src/classes/Factory.d.ts.map +0 -1
  184. package/dist/esm/src/classes/Factory.js +0 -51
  185. package/dist/esm/src/classes/Factory.js.map +0 -1
  186. package/dist/esm/src/classes/ManyToManyRelation.d.ts +0 -79
  187. package/dist/esm/src/classes/ManyToManyRelation.d.ts.map +0 -1
  188. package/dist/esm/src/classes/ManyToManyRelation.js +0 -254
  189. package/dist/esm/src/classes/ManyToManyRelation.js.map +0 -1
  190. package/dist/esm/src/classes/ManyToOneRelation.d.ts +0 -22
  191. package/dist/esm/src/classes/ManyToOneRelation.d.ts.map +0 -1
  192. package/dist/esm/src/classes/ManyToOneRelation.js +0 -47
  193. package/dist/esm/src/classes/ManyToOneRelation.js.map +0 -1
  194. package/dist/esm/src/classes/Migration.d.ts +0 -14
  195. package/dist/esm/src/classes/Migration.d.ts.map +0 -1
  196. package/dist/esm/src/classes/Migration.js +0 -168
  197. package/dist/esm/src/classes/Migration.js.map +0 -1
  198. package/dist/esm/src/classes/Model.d.ts +0 -159
  199. package/dist/esm/src/classes/Model.d.ts.map +0 -1
  200. package/dist/esm/src/classes/Model.js +0 -635
  201. package/dist/esm/src/classes/Model.js.map +0 -1
  202. package/dist/esm/src/classes/OneToManyRelation.d.ts +0 -38
  203. package/dist/esm/src/classes/OneToManyRelation.d.ts.map +0 -1
  204. package/dist/esm/src/classes/OneToManyRelation.js +0 -75
  205. package/dist/esm/src/classes/OneToManyRelation.js.map +0 -1
  206. package/dist/esm/src/classes/data/boys.d.ts +0 -3
  207. package/dist/esm/src/classes/data/boys.d.ts.map +0 -1
  208. package/dist/esm/src/classes/data/boys.js +0 -1003
  209. package/dist/esm/src/classes/data/boys.js.map +0 -1
  210. package/dist/esm/src/classes/data/family-names.d.ts +0 -3
  211. package/dist/esm/src/classes/data/family-names.d.ts.map +0 -1
  212. package/dist/esm/src/classes/data/family-names.js +0 -1003
  213. package/dist/esm/src/classes/data/family-names.js.map +0 -1
  214. package/dist/esm/src/classes/data/girls.d.ts +0 -3
  215. package/dist/esm/src/classes/data/girls.d.ts.map +0 -1
  216. package/dist/esm/src/classes/data/girls.js +0 -1002
  217. package/dist/esm/src/classes/data/girls.js.map +0 -1
  218. package/dist/esm/src/classes/data/streets.d.ts +0 -3
  219. package/dist/esm/src/classes/data/streets.d.ts.map +0 -1
  220. package/dist/esm/src/classes/data/streets.js +0 -294
  221. package/dist/esm/src/classes/data/streets.js.map +0 -1
  222. package/dist/esm/src/decorators/Column.d.ts +0 -18
  223. package/dist/esm/src/decorators/Column.d.ts.map +0 -1
  224. package/dist/esm/src/decorators/Column.js +0 -36
  225. package/dist/esm/src/decorators/Column.js.map +0 -1
  226. package/dist/esm/src/models/Migration.d.ts +0 -11
  227. package/dist/esm/src/models/Migration.d.ts.map +0 -1
  228. package/dist/esm/src/models/Migration.js +0 -48
  229. package/dist/esm/src/models/Migration.js.map +0 -1
  230. package/dist/esm/tsconfig.esm.tsbuildinfo +0 -1
@@ -0,0 +1,459 @@
1
+ const require_Database = require("./Database.cjs");
2
+ //#region src/classes/Model.ts
3
+ /**
4
+ * Controls the fetching and decrypting of members
5
+ */
6
+ var ModelEventBus = class {
7
+ listeners = /* @__PURE__ */ new Map();
8
+ addListener(owner, listener) {
9
+ const existing = this.listeners.get(owner);
10
+ if (existing) existing.push({ listener });
11
+ else this.listeners.set(owner, [{ listener }]);
12
+ }
13
+ removeListener(owner) {
14
+ this.listeners.delete(owner);
15
+ }
16
+ async sendEvent(value) {
17
+ const values = [];
18
+ for (const owner of this.listeners.values()) for (const listener of owner) {
19
+ const v = listener.listener(value);
20
+ if (v) values.push(v);
21
+ }
22
+ return await Promise.all(values);
23
+ }
24
+ };
25
+ var Model = class Model {
26
+ static primary;
27
+ static modelEventBus = new ModelEventBus();
28
+ /**
29
+ * Properties that are stored in the table (including foreign keys, but without mapped relations!)
30
+ */
31
+ static columns;
32
+ static debug = false;
33
+ static showWarnings = false;
34
+ static table;
35
+ static relations;
36
+ existsInDatabase = false;
37
+ savedProperties = /* @__PURE__ */ new Map();
38
+ /**
39
+ * Sometimes we have skipUpdate properties that still should get saved on specific occasions.
40
+ * E.g. update updatedAt field manually if is the only changed field.
41
+ */
42
+ forceSaveProperties = /* @__PURE__ */ new Set();
43
+ constructor() {
44
+ if (!this.static.relations) this.static.relations = [];
45
+ if (!this.static.columns) this.static.columns = /* @__PURE__ */ new Map();
46
+ }
47
+ /**
48
+ * Delete the value of a key from memory
49
+ */
50
+ eraseProperty(key) {
51
+ if (!this.static.columns.get(key)) throw new Error("Unknown property " + key);
52
+ delete this[key];
53
+ this.savedProperties.delete(key);
54
+ }
55
+ /**
56
+ * Make sure this key will get saved on the next save, even when it is not changed or when it is skipUpdate
57
+ */
58
+ forceSaveProperty(key) {
59
+ this.forceSaveProperties.add(key);
60
+ }
61
+ /**
62
+ * Mark all properties as changed, so they will get updated on the next save
63
+ */
64
+ markAllChanged() {
65
+ this.savedProperties.clear();
66
+ }
67
+ /**
68
+ * Returns the default select to select the needed properties of this table
69
+ * @param namespace: optional namespace of this select
70
+ */
71
+ static getDefaultSelect(namespace = this.table) {
72
+ return "`" + namespace + "`.*";
73
+ }
74
+ static selectColumnsWithout(namespace = this.table, ...exclude) {
75
+ const properties = Array.from(this.columns.keys()).flatMap((name) => exclude.includes(name) ? [] : [name]);
76
+ if (properties.length === 0) throw new Error("Not implemented yet");
77
+ return "`" + namespace + "`.`" + properties.join("`, `" + namespace + "`.`") + "`";
78
+ }
79
+ /**
80
+ * Set a relation to undefined, marking it as not loaded (so it won't get saved in the next save)
81
+ * @param relation
82
+ */
83
+ unloadRelation(relation) {
84
+ const t = this;
85
+ delete t[relation.modelKey];
86
+ return t;
87
+ }
88
+ /**
89
+ * Set a relation to null, deleting it on the next save (unless unloadRelation is called)
90
+ * @param relation
91
+ */
92
+ unsetRelation(relation) {
93
+ return this.setOptionalRelation(relation, null);
94
+ }
95
+ setOptionalRelation(relation, value) {
96
+ if (value !== null && !value.existsInDatabase) throw new Error("You cannot set a relation to a model that are not yet saved in the database.");
97
+ const t = this;
98
+ t[relation.modelKey] = value;
99
+ t[relation.foreignKey] = value ? value.getPrimaryKey() : null;
100
+ return t;
101
+ }
102
+ setRelation(relation, value) {
103
+ if (!value.existsInDatabase) throw new Error("You cannot set a relation to a model that are not yet saved in the database.");
104
+ const t = this;
105
+ t[relation.modelKey] = value;
106
+ t[relation.foreignKey] = value.getPrimaryKey();
107
+ return t;
108
+ }
109
+ /**
110
+ * Set a many relation. Note that this doesn't save the relation! You'll need to use the methods of the relation instead
111
+ */
112
+ setManyRelation(relation, value) {
113
+ value.forEach((v) => {
114
+ if (!v.existsInDatabase) throw new Error("You cannot set a relation to models that are not yet saved in the database.");
115
+ });
116
+ const t = this;
117
+ t[relation.modelKey] = value;
118
+ return t;
119
+ }
120
+ /**
121
+ * Set a many relation. Note that this doesn't save the relation! You'll need to use the methods of the relation instead
122
+ */
123
+ getManyRelation(relation) {
124
+ return this[relation.modelKey] ?? null;
125
+ }
126
+ /**
127
+ * Load the returned properties from a DB response row into the model
128
+ * If the row's primary key is null, undefined is returned
129
+ */
130
+ static fromRow(row) {
131
+ if (row === void 0 || this.primary && (row[this.primary.name] === null || row[this.primary.name] === void 0)) return;
132
+ const model = new this();
133
+ for (const column of this.columns.values()) if (row[column.name] !== void 0) {
134
+ const value = column.from(row[column.name]);
135
+ model[column.name] = value;
136
+ } else model[column.name] = void 0;
137
+ model.markSaved(row, { fromMySQL: true });
138
+ return model;
139
+ }
140
+ static fromRows(rows, namespace) {
141
+ return rows.flatMap((row) => {
142
+ const model = this.fromRow(row[namespace]);
143
+ if (model) return [model];
144
+ return [];
145
+ });
146
+ }
147
+ markSaved(fields, options) {
148
+ this.existsInDatabase = true;
149
+ this.forceSaveProperties.clear();
150
+ for (const column of this.static.columns.values()) if ((fields ? fields[column.name] : this[column.name]) !== void 0) this.savedProperties.set(column.name, fields ? column.type === "json" && options?.fromMySQL ? {
151
+ to() {
152
+ if (this._to) return this._to;
153
+ const value = this._from ?? column.from(fields[column.name]);
154
+ this._from = value;
155
+ const found = column.to(value);
156
+ this._to = found;
157
+ return found;
158
+ },
159
+ from() {
160
+ if (this._from) return this._from;
161
+ const from = column.from(fields[column.name]);
162
+ this._from = from;
163
+ return from;
164
+ }
165
+ } : fields[column.name] : column.to(this[column.name]));
166
+ for (const relation of this.static.relations) if (relation.isLoaded(this)) if (relation.isSet(this)) {
167
+ const model = this[relation.modelKey];
168
+ this[relation.foreignKey] = model.getPrimaryKey();
169
+ } else this[relation.foreignKey] = null;
170
+ }
171
+ copyFrom(from) {
172
+ for (const column of this.static.columns.values()) this[column.name] = from[column.name];
173
+ for (const relation of this.static.relations) if (relation.isLoaded(this)) this[relation.modelKey] = void 0;
174
+ this.savedProperties = from.savedProperties;
175
+ this.forceSaveProperties = from.forceSaveProperties;
176
+ this.existsInDatabase = from.existsInDatabase;
177
+ }
178
+ get static() {
179
+ return this.constructor;
180
+ }
181
+ getPrimaryKey() {
182
+ return this[this.static.primary.name];
183
+ }
184
+ /**
185
+ * Get a model by its primary key
186
+ * @param id primary key
187
+ */
188
+ static async getByID(id) {
189
+ const [rows] = await require_Database.Database.select(`SELECT ${this.getDefaultSelect()} FROM \`${this.table}\` WHERE \`${this.primary.name}\` = ? LIMIT 1`, [id]);
190
+ if (rows.length === 0) return;
191
+ const row = rows[0][this.table];
192
+ return this.fromRow(row);
193
+ }
194
+ /**
195
+ * Get multiple models by their ID
196
+ * @param ids primary key of the models you want to fetch
197
+ */
198
+ static async getByIDs(...ids) {
199
+ if (ids.length === 0) return [];
200
+ const [rows] = await require_Database.Database.select(`SELECT ${this.getDefaultSelect()} FROM \`${this.table}\` WHERE \`${this.primary.name}\` IN (?) LIMIT ?`, [ids, ids.length]);
201
+ return this.fromRows(rows, this.table);
202
+ }
203
+ static buildWhereOperator(key, value) {
204
+ let whereQuery;
205
+ const params = [];
206
+ switch (value.sign) {
207
+ case "MATCH": {
208
+ let suffix = "";
209
+ if (value.mode) switch (value.mode) {
210
+ case "BOOLEAN":
211
+ suffix = " IN BOOLEAN MODE";
212
+ break;
213
+ default: throw new Error("Unknown match mode " + value.mode);
214
+ }
215
+ whereQuery = `MATCH(\`${this.table}\`.\`${key}\`) AGAINST(?${suffix})`;
216
+ params.push(value.value);
217
+ break;
218
+ }
219
+ case "LIKE":
220
+ whereQuery = `\`${this.table}\`.\`${key}\` LIKE ?`;
221
+ params.push(value.value);
222
+ break;
223
+ case "!=":
224
+ if (value.value === null) whereQuery = `\`${this.table}\`.\`${key}\` IS NOT NULL`;
225
+ else {
226
+ whereQuery = `\`${this.table}\`.\`${key}\` != ?`;
227
+ params.push(value.value);
228
+ }
229
+ break;
230
+ case "<":
231
+ whereQuery = `\`${this.table}\`.\`${key}\` < ?`;
232
+ params.push(value.value);
233
+ break;
234
+ case ">":
235
+ whereQuery = `\`${this.table}\`.\`${key}\` > ?`;
236
+ params.push(value.value);
237
+ break;
238
+ case "<=":
239
+ whereQuery = `\`${this.table}\`.\`${key}\` <= ?`;
240
+ params.push(value.value);
241
+ break;
242
+ case ">=":
243
+ whereQuery = `\`${this.table}\`.\`${key}\` >= ?`;
244
+ params.push(value.value);
245
+ break;
246
+ case "=":
247
+ if (value.value === null) whereQuery = `\`${this.table}\`.\`${key}\` IS NULL`;
248
+ else {
249
+ whereQuery = `\`${this.table}\`.\`${key}\` = ?`;
250
+ params.push(value.value);
251
+ }
252
+ break;
253
+ case "IN":
254
+ if (!Array.isArray(value.value)) throw new Error("Expected an array for IN where query");
255
+ if (value.value.includes(null)) {
256
+ const filtered = value.value.filter((v) => v !== null);
257
+ if (filtered.length === 0) whereQuery = `\`${this.table}\`.\`${key}\` IS NULL`;
258
+ else if (filtered.length === 1) {
259
+ whereQuery = `(\`${this.table}\`.\`${key}\` = ? OR \`${this.table}\`.\`${key}\` IS NULL)`;
260
+ params.push(filtered[0]);
261
+ } else {
262
+ whereQuery = `(\`${this.table}\`.\`${key}\` IN (?) OR \`${this.table}\`.\`${key}\` IS NULL)`;
263
+ params.push(filtered);
264
+ }
265
+ } else {
266
+ whereQuery = `\`${this.table}\`.\`${key}\` IN (?)`;
267
+ params.push(value.value);
268
+ }
269
+ break;
270
+ default: throw new Error("Sign not supported.");
271
+ }
272
+ return [whereQuery, params];
273
+ }
274
+ static buildWhereQuery(where) {
275
+ const whereQuery = [];
276
+ const params = [];
277
+ for (const key in where) if (Object.hasOwnProperty.call(where, key)) {
278
+ const value = where[key];
279
+ if (Array.isArray(value)) for (const v of value) {
280
+ const [w, p] = this.buildWhereOperator(key, v);
281
+ whereQuery.push(w);
282
+ params.push(...p);
283
+ }
284
+ else if (typeof value === "object" && value !== null && !(value instanceof Date)) {
285
+ const [w, p] = this.buildWhereOperator(key, value);
286
+ whereQuery.push(w);
287
+ params.push(...p);
288
+ } else if (value === null) whereQuery.push(`\`${this.table}\`.\`${key}\` IS NULL`);
289
+ else {
290
+ whereQuery.push(`\`${this.table}\`.\`${key}\` = ?`);
291
+ params.push(value);
292
+ }
293
+ }
294
+ return [whereQuery.join(" AND "), params];
295
+ }
296
+ /**
297
+ * @deprecated Use the new SQL package instead
298
+ * Get multiple models by a simple where
299
+ */
300
+ static async where(where, extra) {
301
+ const params = [];
302
+ let query = `SELECT ${extra?.select ?? this.getDefaultSelect()} FROM \`${this.table}\``;
303
+ if (Object.keys(where).length !== 0) {
304
+ const [whereQuery, p] = this.buildWhereQuery(where);
305
+ query += `WHERE ` + whereQuery;
306
+ params.push(...p);
307
+ }
308
+ if (extra && extra.sort !== void 0) {
309
+ const sortQuery = [];
310
+ for (const item of extra.sort) if (typeof item === "string") sortQuery.push(require_Database.Database.escapeId(item) + " ASC");
311
+ else if (typeof item.column === "string") sortQuery.push(require_Database.Database.escapeId(item.column) + " " + (item.direction ?? "ASC"));
312
+ else {
313
+ const [w, p] = this.buildWhereQuery(item.column);
314
+ sortQuery.push("(" + w + ") " + (item.direction ?? "ASC"));
315
+ params.push(...p);
316
+ }
317
+ query += ` ORDER BY ` + sortQuery.join(", ");
318
+ }
319
+ if (extra && extra.limit !== void 0) {
320
+ query += ` LIMIT ?`;
321
+ params.push(extra.limit);
322
+ }
323
+ const [rows] = await require_Database.Database.select(query, params);
324
+ return this.fromRows(rows, this.table);
325
+ }
326
+ /**
327
+ * Get multiple models by a simple where
328
+ */
329
+ static async all(limit) {
330
+ const params = [];
331
+ let query = `SELECT ${this.getDefaultSelect()} FROM \`${this.table}\``;
332
+ if (limit) {
333
+ query += ` LIMIT ?`;
334
+ params.push(limit);
335
+ }
336
+ const [rows] = await require_Database.Database.select(query, params);
337
+ return this.fromRows(rows, this.table);
338
+ }
339
+ /**
340
+ * Return an object of all the properties that are changed and their database representation
341
+ */
342
+ getChangedDatabaseProperties() {
343
+ const set = {};
344
+ let skipUpdate = 0;
345
+ for (const column of this.static.columns.values()) {
346
+ if (column.primary && column.type === "integer" && this.static.primary.name === "id") continue;
347
+ if (!this.existsInDatabase && this[column.name] === void 0) throw new Error("Tried to create model " + this.constructor.name + " with undefined property " + column.name);
348
+ if (this[column.name] !== void 0) {
349
+ const forceSave = this.forceSaveProperties.has(column.name);
350
+ const oldSavedValue = forceSave ? void 0 : this.savedProperties.get(column.name);
351
+ const saveValue = forceSave ? null : column.to(this[column.name]);
352
+ if (forceSave || oldSavedValue === void 0 || column.isChanged(typeof oldSavedValue === "object" && oldSavedValue !== null && "to" in oldSavedValue ? oldSavedValue.to() : oldSavedValue, saveValue)) {
353
+ set[column.name] = forceSave ? column.to(this[column.name]) : saveValue;
354
+ if (column.skipUpdate && !forceSave) skipUpdate++;
355
+ }
356
+ }
357
+ }
358
+ return {
359
+ fields: set,
360
+ skipUpdate
361
+ };
362
+ }
363
+ beforeSave() {
364
+ for (const column of this.static.columns.values()) if (column.beforeSave) this[column.name] = column.beforeSave.call(this, this[column.name]);
365
+ }
366
+ /**
367
+ * Return original value from the database or undefined if not known
368
+ */
369
+ getOriginalValue(key) {
370
+ const column = this.static.columns.get(key);
371
+ if (!column) throw new Error("Unknown property " + key);
372
+ const c = this.savedProperties.get(key);
373
+ if (c === void 0) return;
374
+ if (typeof c === "object" && c !== null && "from" in c) return c.from();
375
+ return column.from(c);
376
+ }
377
+ async save() {
378
+ if (!this.static.table) throw new Error("Table name not set");
379
+ if (!this.static.primary) throw new Error("Primary key not set for model " + this.constructor.name + " " + this.static);
380
+ for (const relation of this.static.relations) if (relation.isLoaded(this)) {
381
+ if (relation.isSet(this)) {
382
+ const model = this[relation.modelKey];
383
+ if (!model.existsInDatabase) throw new Error("You cannot set a relation that is not yet saved in the database.");
384
+ if (this[relation.foreignKey] !== model.getPrimaryKey()) throw new Error("You cannot modify the value of a foreign key when the relation is loaded. Unload the relation first or modify the relation with setRelation");
385
+ } else if (this[relation.foreignKey] !== null) throw new Error("You cannot set a foreign key when the relation is loaded. Unload the relation first or modify the relation with setRelation");
386
+ }
387
+ const id = this.getPrimaryKey();
388
+ if (!id) {
389
+ if (this.existsInDatabase) throw new Error("Model " + this.constructor.name + " was loaded from the Database, but didn't select the ID. Saving not possible.");
390
+ } else if (!this.existsInDatabase && this.static.primary.type === "integer" && this.static.primary.name === "id") throw new Error(`PrimaryKey was set programmatically without fetching the model ${this.constructor.name} from the database. This is not allowed for integer primary keys.`);
391
+ this.beforeSave();
392
+ const { fields, skipUpdate } = this.getChangedDatabaseProperties();
393
+ if (Object.keys(fields).length === 0) {
394
+ if (Model.showWarnings) console.warn("Tried to update model without any properties modified");
395
+ return false;
396
+ }
397
+ if (this.existsInDatabase && skipUpdate === Object.keys(fields).length) {
398
+ if (Model.showWarnings) console.warn("Tried to update model without any properties modified");
399
+ return false;
400
+ }
401
+ if (Model.debug) console.log("Saving " + this.constructor.name + " to...", fields);
402
+ if (!this.existsInDatabase) {
403
+ if (Model.debug) console.log(`Creating new ${this.constructor.name}`);
404
+ const [result] = await require_Database.Database.insert("INSERT INTO `" + this.static.table + "` SET ?", [fields]);
405
+ if (this.static.primary.type === "integer" && this.static.primary.name === "id") {
406
+ this[this.static.primary.name] = result.insertId;
407
+ fields[this.static.primary.name] = result.insertId;
408
+ if (Model.debug) console.log(`New id = ${this[this.static.primary.name]}`);
409
+ }
410
+ } else {
411
+ if (Model.debug) console.log(`Updating ${this.constructor.name} where ${this.static.primary.name} = ${id}`);
412
+ const [result] = await require_Database.Database.update("UPDATE `" + this.static.table + "` SET ? WHERE `" + this.static.primary.name + "` = ?", [fields, id]);
413
+ if (result.changedRows !== 1 && Model.showWarnings) console.warn(`Updated ${this.constructor.name}, but it didn't change a row. Check if ID exists.`);
414
+ }
415
+ if (this.existsInDatabase) {
416
+ const originalProperties = Object.fromEntries(Array.from(this.savedProperties.entries()).map(([key, value]) => {
417
+ if (typeof value === "object" && value !== null && "to" in value) return [key, value.to()];
418
+ return [key, value];
419
+ }));
420
+ this.markSaved(fields);
421
+ await this.static.modelEventBus.sendEvent({
422
+ type: "updated",
423
+ model: this,
424
+ changedFields: fields,
425
+ originalFields: originalProperties,
426
+ getOldModel: () => {
427
+ const v = this.static.fromRow(originalProperties);
428
+ if (v === void 0) throw new Error("Failed to create old model: primary key might be missing");
429
+ return v;
430
+ }
431
+ });
432
+ } else {
433
+ this.markSaved(fields);
434
+ await this.static.modelEventBus.sendEvent({
435
+ type: "created",
436
+ model: this
437
+ });
438
+ }
439
+ return true;
440
+ }
441
+ async delete() {
442
+ const id = this.getPrimaryKey();
443
+ if (!id && this.existsInDatabase) throw new Error("Model " + this.constructor.name + " was loaded from the Database, but didn't select the ID. Deleting not possible.");
444
+ if (!id || !this.existsInDatabase) throw new Error("Model " + this.constructor.name + " can't be deleted if it doesn't exist in the database already");
445
+ if (Model.debug) console.log(`Deleting ${this.constructor.name} where ${this.static.primary.name} = ${id}`);
446
+ const [result] = await require_Database.Database.delete("DELETE FROM `" + this.static.table + "` WHERE `" + this.static.primary.name + "` = ?", [id]);
447
+ if (result.affectedRows !== 1 && Model.showWarnings) console.warn(`Deleted ${this.constructor.name}, but it didn't change a row. Check if ID exists.`);
448
+ this.existsInDatabase = false;
449
+ if (this.static.primary.type === "integer" && this.static.primary.name === "id") this.eraseProperty(this.static.primary.name);
450
+ this.savedProperties.clear();
451
+ await this.static.modelEventBus.sendEvent({
452
+ type: "deleted",
453
+ model: this
454
+ });
455
+ }
456
+ };
457
+ //#endregion
458
+ exports.Model = Model;
459
+ exports.ModelEventBus = ModelEventBus;
@@ -0,0 +1,162 @@
1
+ import { DatabaseStoredValue } from "./DatabaseStoredValue.cjs";
2
+ import { Column } from "./Column.cjs";
3
+ import { ManyToOneRelation } from "./ManyToOneRelation.cjs";
4
+ import { OneToManyRelation } from "./OneToManyRelation.cjs";
5
+ import { ManyToManyRelation } from "./ManyToManyRelation.cjs";
6
+
7
+ //#region src/classes/Model.d.ts
8
+ type SQLWhere = {
9
+ sign: string;
10
+ value: string | Date | number | null | (string | null)[] | (number | null)[];
11
+ mode?: string;
12
+ };
13
+ type SQLWhereQuery = {
14
+ [key: string]: string | Date | number | null | SQLWhere | SQLWhere[];
15
+ };
16
+ type Listener<Value> = (value: Value) => Promise<void> | void;
17
+ /**
18
+ * Controls the fetching and decrypting of members
19
+ */
20
+ declare class ModelEventBus<Value> {
21
+ protected listeners: Map<any, {
22
+ listener: Listener<Value>;
23
+ }[]>;
24
+ addListener(owner: any, listener: Listener<Value>): void;
25
+ removeListener(owner: any): void;
26
+ sendEvent(value: Value): Promise<void[]>;
27
+ }
28
+ type ModelEventType = 'created' | 'updated' | 'deleted';
29
+ type ModelEvent<M extends Model = Model> = {
30
+ type: 'created';
31
+ model: M;
32
+ } | {
33
+ type: 'updated';
34
+ model: M;
35
+ changedFields: Record<string, DatabaseStoredValue>;
36
+ originalFields: Record<string, DatabaseStoredValue>;
37
+ /**
38
+ * Use this method to compare changes
39
+ */
40
+ getOldModel(): M;
41
+ } | {
42
+ type: 'deleted';
43
+ model: M;
44
+ };
45
+ declare class Model {
46
+ static primary: Column;
47
+ static modelEventBus: ModelEventBus<ModelEvent<Model>>;
48
+ /**
49
+ * Properties that are stored in the table (including foreign keys, but without mapped relations!)
50
+ */
51
+ static columns: Map<string, Column>;
52
+ static debug: boolean;
53
+ static showWarnings: boolean;
54
+ static table: string;
55
+ static relations: ManyToOneRelation<string, Model>[];
56
+ existsInDatabase: boolean;
57
+ savedProperties: Map<string, DatabaseStoredValue | {
58
+ to: () => DatabaseStoredValue;
59
+ from: () => unknown;
60
+ }>;
61
+ /**
62
+ * Sometimes we have skipUpdate properties that still should get saved on specific occasions.
63
+ * E.g. update updatedAt field manually if is the only changed field.
64
+ */
65
+ forceSaveProperties: Set<string>;
66
+ constructor();
67
+ /**
68
+ * Delete the value of a key from memory
69
+ */
70
+ eraseProperty(key: string): void;
71
+ /**
72
+ * Make sure this key will get saved on the next save, even when it is not changed or when it is skipUpdate
73
+ */
74
+ forceSaveProperty(key: string): void;
75
+ /**
76
+ * Mark all properties as changed, so they will get updated on the next save
77
+ */
78
+ markAllChanged(): void;
79
+ /**
80
+ * Returns the default select to select the needed properties of this table
81
+ * @param namespace: optional namespace of this select
82
+ */
83
+ static getDefaultSelect(namespace?: string): string;
84
+ static selectColumnsWithout(namespace?: string, ...exclude: string[]): string;
85
+ /**
86
+ * Set a relation to undefined, marking it as not loaded (so it won't get saved in the next save)
87
+ * @param relation
88
+ */
89
+ unloadRelation<Key extends keyof any, Value extends Model>(this: this & Record<Key, Value>, relation: ManyToOneRelation<Key, any>): this & Record<Key, undefined>;
90
+ /**
91
+ * Set a relation to null, deleting it on the next save (unless unloadRelation is called)
92
+ * @param relation
93
+ */
94
+ unsetRelation<Key extends keyof any, Value extends Model>(this: this & Record<Key, Value>, relation: ManyToOneRelation<Key, any>): this & Record<Key, null>;
95
+ setOptionalRelation<Key extends keyof any, Value extends Model>(relation: ManyToOneRelation<Key, Value>, value: Value | null): this & Record<Key, Value | null>;
96
+ setRelation<Key extends keyof any, Value extends Model, V extends Value>(relation: ManyToOneRelation<Key, Value>, value: V): this & Record<Key, V>;
97
+ /**
98
+ * Set a many relation. Note that this doesn't save the relation! You'll need to use the methods of the relation instead
99
+ */
100
+ setManyRelation<Key extends keyof any, Value extends Model>(relation: ManyToManyRelation<Key, any, Value, any> | OneToManyRelation<Key, any, Value>, value: Value[]): this & Record<Key, Value[]>;
101
+ /**
102
+ * Set a many relation. Note that this doesn't save the relation! You'll need to use the methods of the relation instead
103
+ */
104
+ getManyRelation<Key extends keyof any, Value extends Model>(relation: ManyToManyRelation<Key, any, Value, any> | OneToManyRelation<Key, any, Value>): Value[] | null;
105
+ /**
106
+ * Load the returned properties from a DB response row into the model
107
+ * If the row's primary key is null, undefined is returned
108
+ */
109
+ static fromRow<T extends typeof Model>(this: T, row: Record<string, DatabaseStoredValue>): InstanceType<T> | undefined;
110
+ static fromRows<T extends typeof Model>(this: T, rows: Record<string, Record<string, DatabaseStoredValue>>[], namespace: string): InstanceType<T>[];
111
+ markSaved(fields?: Record<string, DatabaseStoredValue>, options?: {
112
+ fromMySQL?: boolean;
113
+ }): void;
114
+ copyFrom<T extends Model>(this: T, from: T): void;
115
+ get static(): typeof Model;
116
+ getPrimaryKey(): number | string | null;
117
+ /**
118
+ * Get a model by its primary key
119
+ * @param id primary key
120
+ */
121
+ static getByID<T extends typeof Model>(this: T, id: number | string): Promise<InstanceType<T> | undefined>;
122
+ /**
123
+ * Get multiple models by their ID
124
+ * @param ids primary key of the models you want to fetch
125
+ */
126
+ static getByIDs<T extends typeof Model>(this: T, ...ids: (number | string)[]): Promise<InstanceType<T>[]>;
127
+ static buildWhereOperator(key: string, value: SQLWhere): [string, any[]];
128
+ static buildWhereQuery(where: SQLWhereQuery): [string, any[]];
129
+ /**
130
+ * @deprecated Use the new SQL package instead
131
+ * Get multiple models by a simple where
132
+ */
133
+ static where<T extends typeof Model>(this: T, where: SQLWhereQuery, extra?: {
134
+ limit?: number;
135
+ sort?: (string | {
136
+ column: string | SQLWhereQuery;
137
+ direction?: 'ASC' | 'DESC';
138
+ })[];
139
+ select?: string;
140
+ }): Promise<InstanceType<T>[]>;
141
+ /**
142
+ * Get multiple models by a simple where
143
+ */
144
+ static all<T extends typeof Model>(this: T, limit?: number): Promise<InstanceType<T>[]>;
145
+ /**
146
+ * Return an object of all the properties that are changed and their database representation
147
+ */
148
+ getChangedDatabaseProperties(): {
149
+ fields: Record<string, DatabaseStoredValue>;
150
+ skipUpdate: number;
151
+ };
152
+ beforeSave(): void;
153
+ /**
154
+ * Return original value from the database or undefined if not known
155
+ */
156
+ getOriginalValue(key: string): unknown | undefined;
157
+ save(): Promise<boolean>;
158
+ delete(): Promise<void>;
159
+ }
160
+ //#endregion
161
+ export { Model, ModelEvent, ModelEventBus, ModelEventType };
162
+ //# sourceMappingURL=Model.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Model.d.cts","names":[],"sources":["../../../src/classes/Model.ts"],"mappings":"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"}