alchemymvc 1.4.0-alpha.1 → 1.4.0-alpha.2

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.
@@ -12,26 +12,49 @@ var jsondiffpatch = alchemy.use('jsondiffpatch'),
12
12
  * @since 0.0.1
13
13
  * @version 0.2.0
14
14
  */
15
- var Revision = Function.inherits('Alchemy.Behaviour', function RevisionBehaviour(model, options) {
16
- Behaviour.call(this, model, options);
17
- });
15
+ const Revision = Function.inherits('Alchemy.Behaviour', 'RevisionBehaviour');
18
16
 
19
17
  /**
20
- * Get the Revision Model class for the attached model
18
+ * Get the Revision model class for the given main model
21
19
  *
22
20
  * @author Jelle De Loecker <jelle@elevenways.be>
23
- * @since 1.0.3
24
- * @version 1.1.0
21
+ * @since 1.4.0
22
+ * @version 1.4.0
23
+ *
24
+ * @param {Schema} schema
25
+ * @param {Object} options
25
26
  */
26
- Revision.setProperty(function revision_model_class() {
27
+ Revision.setStatic(function getRevisionModel(model) {
27
28
 
28
- var class_name = this.model.name + 'DataRevision';
29
+ if (typeof model == 'function') {
30
+ model = model.model_name;
31
+ }
32
+
33
+ if (typeof model == 'string') {
34
+ model = Model.get(model);
35
+ }
36
+
37
+ if (!model) {
38
+ throw new Error('Unable to add Revision behaviour to undefined model');
39
+ }
40
+
41
+ let revision_model_name = model.model_name + 'DataRevision',
42
+ revision_model;
43
+
44
+ try {
45
+ revision_model = Model.get(revision_model_name, false);
46
+ } catch (err) {
47
+ // Ignore
48
+ }
29
49
 
30
- if (Classes.Alchemy.Model[class_name]) {
31
- return Classes.Alchemy.Model[class_name];
50
+ if (revision_model) {
51
+ return revision_model;
32
52
  }
53
+
54
+ let namespace = model.constructor.namespace,
55
+ class_name = model.name + 'DataRevision';
33
56
 
34
- let model_class = Function.inherits('Alchemy.Model', Function.create(class_name, function DataRevision(options) {
57
+ let model_class = Function.inherits('Alchemy.Model', namespace, Function.create(class_name, function DataRevision(options) {
35
58
  Model.call(this, options);
36
59
  }));
37
60
 
@@ -48,6 +71,12 @@ Revision.setProperty(function revision_model_class() {
48
71
  if (Classes.Alchemy.Model.User) {
49
72
  this.belongsTo('User');
50
73
  }
74
+
75
+ // Add an index on the record_id
76
+ this.addIndex('record_id', {
77
+ unique : false,
78
+ sparse : false,
79
+ });
51
80
  });
52
81
 
53
82
  // Force the constitutors to load now
@@ -56,6 +85,39 @@ Revision.setProperty(function revision_model_class() {
56
85
  return model_class;
57
86
  });
58
87
 
88
+ /**
89
+ * Listen to attachments to schema's
90
+ *
91
+ * @author Jelle De Loecker <jelle@elevenways.be>
92
+ * @since 1.0.3
93
+ * @version 1.4.0
94
+ *
95
+ * @param {Schema} schema
96
+ * @param {Object} options
97
+ */
98
+ Revision.setStatic(function attached(schema, new_options) {
99
+
100
+ const context = schema.model_class;
101
+
102
+ // Add the revision number to the main model
103
+ context.addField('__r', 'Number', {
104
+ title: 'Revision',
105
+ });
106
+
107
+ Revision.getRevisionModel(schema.model_class);
108
+ });
109
+
110
+ /**
111
+ * Get the Revision Model class for the attached model
112
+ *
113
+ * @author Jelle De Loecker <jelle@elevenways.be>
114
+ * @since 1.0.3
115
+ * @version 1.4.0
116
+ */
117
+ Revision.setProperty(function revision_model_class() {
118
+ return Revision.getRevisionModel(this.model);
119
+ });
120
+
59
121
  /**
60
122
  * Get the revision model for the attached model
61
123
  *
@@ -122,24 +184,6 @@ Revision.setProperty(function diff_patcher() {
122
184
  return diff_patch_instance;
123
185
  });
124
186
 
125
- /**
126
- * Listen to attachments to schema's
127
- *
128
- * @author Jelle De Loecker <jelle@elevenways.be>
129
- * @since 1.0.3
130
- * @version 1.0.3
131
- *
132
- * @param {Schema} schema
133
- * @param {Object} options
134
- */
135
- Revision.setStatic(function attached(schema, new_options) {
136
-
137
- var context = schema.model_class;
138
-
139
- // Add the revision
140
- context.addField('__r', 'Number', {title: 'Revision'});
141
- });
142
-
143
187
  /**
144
188
  * Compare 2 objects
145
189
  *
@@ -157,14 +201,14 @@ Revision.setMethod(function compare(left, right) {
157
201
  *
158
202
  * @author Jelle De Loecker <jelle@elevenways.be>
159
203
  * @since 0.0.1
160
- * @version 1.0.5
204
+ * @version 1.4.0
161
205
  */
162
206
  Revision.setMethod(function beforeSave(record, options, creating) {
163
207
 
164
- let main = record[this.model.name];
208
+ let main = record.$main;
165
209
 
166
210
  if (!main) {
167
- throw new Error('Unable to find main "' + this.model.name + '" data');
211
+ throw new Error('Unable to find main "' + this.model.model_name + '" data');
168
212
  }
169
213
 
170
214
  // No revision to save when creating a record
@@ -177,14 +221,12 @@ Revision.setMethod(function beforeSave(record, options, creating) {
177
221
  next = this.wait('series');
178
222
 
179
223
  // Find the original record
180
- Model.get(that.model.name).findById(main._id, async function gotRecord(err, result) {
181
-
182
- var ori;
224
+ Model.get(this.model.model_name).findById(record.$pk, async function gotRecord(err, result) {
183
225
 
184
226
  if (result) {
185
227
 
186
228
  // Get the original data
187
- ori = await that.model.convertRecordToDatasourceFormat(result);
229
+ let ori = await that.model.convertRecordToDatasourceFormat(result);
188
230
 
189
231
  // Store the original data in a weakmap for later
190
232
  revision_before.set(options, ori);
@@ -206,17 +248,11 @@ Revision.setMethod(function beforeSave(record, options, creating) {
206
248
  *
207
249
  * @author Jelle De Loecker <jelle@elevenways.be>
208
250
  * @since 0.0.1
209
- * @version 1.1.0
251
+ * @version 1.4.0
210
252
  */
211
253
  Revision.setMethod(function afterSave(record, options, created) {
212
254
 
213
- var that = this,
214
- earlier_data,
215
- right,
216
- main,
217
- that,
218
- left,
219
- next;
255
+ let earlier_data;
220
256
 
221
257
  if (created) {
222
258
  earlier_data = {};
@@ -229,11 +265,12 @@ Revision.setMethod(function afterSave(record, options, created) {
229
265
  return;
230
266
  }
231
267
 
232
- next = this.wait();
233
- main = record[that.model.name] || record;
268
+ let doc = this.model.createDocument(record);
269
+ let next = this.wait();
270
+ const that = this;
234
271
 
235
272
  // Find the complete saved item
236
- Model.get(that.model.name).findById(main._id, async function gotRecord(err, result) {
273
+ Model.get(this.model.model_name).findByPk(doc.$pk, async function gotRecord(err, result) {
237
274
 
238
275
  if (result) {
239
276
 
@@ -243,8 +280,8 @@ Revision.setMethod(function afterSave(record, options, created) {
243
280
  if (new_data) {
244
281
 
245
282
  // Convert the objects so they can be diffed properly
246
- left = JSON.toDryObject(earlier_data);
247
- right = JSON.toDryObject(new_data);
283
+ let left = JSON.toDryObject(earlier_data),
284
+ right = JSON.toDryObject(new_data);
248
285
 
249
286
  // Diff them
250
287
  let delta = that.compare(left, right);
@@ -267,7 +304,7 @@ Revision.setMethod(function afterSave(record, options, created) {
267
304
 
268
305
  // Add the delta information
269
306
  revision_data = {
270
- [that.revision_model.name] : revision_data
307
+ [that.revision_model.model_name] : revision_data
271
308
  };
272
309
 
273
310
  // Save the data
@@ -659,7 +659,7 @@ Mongo.setMethod(function _remove(model, query, options, callback) {
659
659
  *
660
660
  * @author Jelle De Loecker <jelle@elevenways.be>
661
661
  * @since 0.2.0
662
- * @version 1.3.17
662
+ * @version 1.4.0
663
663
  */
664
664
  Mongo.setMethod(function _ensureIndex(model, index, callback) {
665
665
 
@@ -696,11 +696,20 @@ Mongo.setMethod(function _ensureIndex(model, index, callback) {
696
696
 
697
697
  // Check for IndexOptionsConflict
698
698
  if (err.code === 85) {
699
+ let index_to_drop;
700
+
701
+ if (err.message.includes('already exists with a different name:')) {
702
+ index_to_drop = err.message.after('different name:').trim();
703
+ }
704
+
705
+ if (!index_to_drop) {
706
+ index_to_drop = options.name;
707
+ }
699
708
 
700
709
  try {
701
710
 
702
711
  // Index already exists, drop it
703
- await collection.dropIndex(options.name);
712
+ await collection.dropIndex(index_to_drop);
704
713
 
705
714
  // Try again
706
715
  await collection.createIndex(index_specs, options);
@@ -59,11 +59,6 @@ Model.postInherit(function setModelName() {
59
59
  model_name = ns + '_' + model_name;
60
60
  }
61
61
 
62
- if (model_name[0] == '_') {
63
- console.log(ns, model_name)
64
- throw new Error('KAK')
65
- }
66
-
67
62
  // The simple name of the model
68
63
  this.model_name = model_name;
69
64
  this.setProperty('model_name', model_name);
@@ -1186,10 +1181,6 @@ Model.setMethod(function auditRecord(document, options, callback) {
1186
1181
  */
1187
1182
  Model.setMethod(function convertRecordToDatasourceFormat(record, options, callback) {
1188
1183
 
1189
- var that = this,
1190
- pledge,
1191
- data;
1192
-
1193
1184
  if (typeof options == 'function') {
1194
1185
  callback = options;
1195
1186
  options = {};
@@ -1199,12 +1190,12 @@ Model.setMethod(function convertRecordToDatasourceFormat(record, options, callba
1199
1190
  options = {};
1200
1191
  }
1201
1192
 
1202
- data = record[this.name] || record;
1193
+ let data = record.$main || record[this.model_name] || record;
1203
1194
 
1204
1195
  // Normalize the data
1205
1196
  data = this.compose(data, options);
1206
1197
 
1207
- pledge = this.datasource.toDatasource(this, data);
1198
+ let pledge = this.datasource.toDatasource(this, data);
1208
1199
 
1209
1200
  pledge.handleCallback(callback);
1210
1201
 
@@ -1041,7 +1041,7 @@ Schema.setMethod(function getFieldNames() {
1041
1041
  *
1042
1042
  * @author Jelle De Loecker <jelle@elevenways.be>
1043
1043
  * @since 0.2.0
1044
- * @version 1.3.17
1044
+ * @version 1.4.0
1045
1045
  *
1046
1046
  * @param {string|FieldType} _field
1047
1047
  * @param {Object} options
@@ -1073,13 +1073,33 @@ Schema.setMethod(function addIndex(_field, _options) {
1073
1073
  // Set the default options
1074
1074
  options = Object.assign({}, this.indexOptions, options);
1075
1075
 
1076
- if (options.name == null) {
1077
- options.name = field.name;
1076
+ const setIndexName = () => {
1078
1077
 
1079
- if (options.unique) {
1080
- options.name += '_uq';
1078
+ if (options.name) {
1079
+ return;
1080
+ }
1081
+
1082
+ if (!this.model_name) {
1083
+ return;
1084
+ }
1085
+
1086
+ if (options.name == null) {
1087
+ options.name = field.path;
1088
+
1089
+ if (options.unique) {
1090
+ options.name += '_uq';
1091
+ }
1081
1092
  }
1082
- }
1093
+
1094
+ if (this.indexes[options.name] == null) {
1095
+ // Create the index group if it doesn't exist yet.
1096
+ // The first time it's called will define the group options.
1097
+ this.indexes[options.name] = {
1098
+ fields: {},
1099
+ options: options
1100
+ };
1101
+ }
1102
+ };
1083
1103
 
1084
1104
  if (typeof options.order == 'number') {
1085
1105
  if (options.order == 'asc') {
@@ -1089,15 +1109,6 @@ Schema.setMethod(function addIndex(_field, _options) {
1089
1109
  }
1090
1110
  }
1091
1111
 
1092
- if (this.indexes[options.name] == null) {
1093
- // Create the index group if it doesn't exist yet.
1094
- // The first time it's called will define the group options.
1095
- this.indexes[options.name] = {
1096
- fields: {},
1097
- options: options
1098
- };
1099
- }
1100
-
1101
1112
  // Even if an index is unique,
1102
1113
  // it needs the 'alternate' property in order to be used
1103
1114
  // as an alternate method of updating without _id
@@ -1105,6 +1116,9 @@ Schema.setMethod(function addIndex(_field, _options) {
1105
1116
  this.has_alternates++;
1106
1117
  }
1107
1118
 
1119
+ // Try to set the index name now, if possible
1120
+ setIndexName();
1121
+
1108
1122
  const that = this;
1109
1123
 
1110
1124
  that.getDatasource().done(function gotDs(err, datasource) {
@@ -1123,6 +1137,9 @@ Schema.setMethod(function addIndex(_field, _options) {
1123
1137
  return alchemy.printLog('error', ['Unable to ensure index on this datasource', options.name], {err: new Error()});
1124
1138
  }
1125
1139
 
1140
+ // Try to set the index name again, if it hasn't been done yet
1141
+ setIndexName();
1142
+
1126
1143
  let path = field.path;
1127
1144
 
1128
1145
  if (options.db_property) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "alchemymvc",
3
3
  "description": "MVC framework for Node.js",
4
- "version": "1.4.0-alpha.1",
4
+ "version": "1.4.0-alpha.2",
5
5
  "author": "Jelle De Loecker <jelle@elevenways.be>",
6
6
  "keywords": [
7
7
  "alchemy",
@@ -22,7 +22,7 @@
22
22
  "chokidar" : "~3.5.3",
23
23
  "formidable" : "~3.5.1",
24
24
  "graceful-fs" : "~4.2.11",
25
- "hawkejs" : "~2.3.16",
25
+ "hawkejs" : "~2.3.17",
26
26
  "jsondiffpatch" : "~0.5.0",
27
27
  "mime" : "~3.0.0",
28
28
  "minimist" : "~1.2.5",
@@ -31,7 +31,7 @@
31
31
  "mongodb" : "~6.1.0",
32
32
  "ncp" : "~2.0.0",
33
33
  "postcss" : "~8.4.31",
34
- "protoblast" : "~0.9.0",
34
+ "protoblast" : "~0.9.1",
35
35
  "semver" : "~7.5.4",
36
36
  "socket.io" : "~4.7.2",
37
37
  "@11ways/socket.io-stream" : "~0.9.2",