alchemymvc 1.1.7 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/app/behaviour/sluggable_behaviour.js +2 -4
- package/lib/app/conduit/http_conduit.js +173 -192
- package/lib/app/conduit/loopback_conduit.js +0 -0
- package/lib/app/conduit/socket_conduit.js +620 -620
- package/lib/app/datasource/mongo_datasource.js +75 -10
- package/lib/app/element/time_ago.js +0 -0
- package/lib/app/helper/socket_helper.js +613 -613
- package/lib/app/helper_datasource/00-nosql_datasource.js +73 -19
- package/lib/app/helper_datasource/remote_datasource.js +0 -0
- package/lib/app/helper_field/05-string_field.js +0 -0
- package/lib/app/helper_field/schema_field.js +7 -2
- package/lib/app/helper_model/criteria.js +76 -18
- package/lib/app/helper_model/field_config.js +24 -5
- package/lib/app/helper_model/model.js +65 -7
- package/lib/app/model/alchemy_migration_model.js +33 -0
- package/lib/bootstrap.js +9 -0
- package/lib/class/conduit.js +2474 -2412
- package/lib/class/datasource.js +8 -8
- package/lib/class/field.js +7 -1
- package/lib/class/inode.js +62 -0
- package/lib/class/inode_dir.js +115 -0
- package/lib/class/inode_file.js +112 -111
- package/lib/class/migration.js +138 -0
- package/lib/class/model.js +1765 -1772
- package/lib/class/reciprocal.js +8 -2
- package/lib/class/router.js +0 -0
- package/lib/class/schema.js +14 -12
- package/lib/core/base.js +37 -10
- package/lib/core/client_base.js +1 -9
- package/lib/core/middleware.js +4 -8
- package/lib/core/socket.js +159 -159
- package/lib/init/alchemy.js +1779 -1779
- package/lib/init/devwatch.js +1 -1
- package/lib/init/functions.js +2 -56
- package/lib/init/load_functions.js +8 -2
- package/lib/init/requirements.js +101 -96
- package/lib/stages.js +12 -0
- package/package.json +74 -76
- package/CHANGELOG.md +0 -445
package/lib/class/datasource.js
CHANGED
|
@@ -165,7 +165,7 @@ Datasource.setMethod(function getSchema(schema) {
|
|
|
165
165
|
*
|
|
166
166
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
167
167
|
* @since 0.2.0
|
|
168
|
-
* @version 1.
|
|
168
|
+
* @version 1.2.0
|
|
169
169
|
*
|
|
170
170
|
* @param {Schema|Model} schema
|
|
171
171
|
* @param {Object} data
|
|
@@ -187,7 +187,7 @@ Datasource.setMethod(function toDatasource(schema, data, callback) {
|
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
if (!schema) {
|
|
190
|
-
log.todo('Schema not found: not normalizing data');
|
|
190
|
+
log.todo('Schema not found: not normalizing data', data);
|
|
191
191
|
pledge = Pledge.resolve(data);
|
|
192
192
|
pledge.done(callback);
|
|
193
193
|
return pledge;
|
|
@@ -285,6 +285,12 @@ Datasource.setMethod(function toApp(schema, query, options, data, callback) {
|
|
|
285
285
|
return pledge;
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
+
options = Object.assign({}, options);
|
|
289
|
+
|
|
290
|
+
if (!options._root_data) {
|
|
291
|
+
options._root_data = data;
|
|
292
|
+
}
|
|
293
|
+
|
|
288
294
|
if (data[schema.name]) {
|
|
289
295
|
tasks = {};
|
|
290
296
|
|
|
@@ -338,12 +344,6 @@ Datasource.setMethod(function toApp(schema, query, options, data, callback) {
|
|
|
338
344
|
data = Object.assign({}, data);
|
|
339
345
|
tasks = {};
|
|
340
346
|
|
|
341
|
-
options = Object.assign({}, options);
|
|
342
|
-
|
|
343
|
-
if (!options._root_data) {
|
|
344
|
-
options._root_data = data;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
347
|
Object.each(data, function eachField(value, fieldName) {
|
|
348
348
|
|
|
349
349
|
var field = schema.get(fieldName);
|
package/lib/class/field.js
CHANGED
|
@@ -594,7 +594,7 @@ Field.setMethod(function castCondition(value, field_paths) {
|
|
|
594
594
|
*
|
|
595
595
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
596
596
|
* @since 0.5.0
|
|
597
|
-
* @version 1.0
|
|
597
|
+
* @version 1.2.0
|
|
598
598
|
*
|
|
599
599
|
* @param {Mixed} value
|
|
600
600
|
* @param {Array} field_paths The path to the field
|
|
@@ -602,6 +602,12 @@ Field.setMethod(function castCondition(value, field_paths) {
|
|
|
602
602
|
* @return {Mixed}
|
|
603
603
|
*/
|
|
604
604
|
Field.setMethod(function _castCondition(value, field_paths) {
|
|
605
|
+
|
|
606
|
+
// Always allow regex values, we'll use those in the projection stage
|
|
607
|
+
if (value && RegExp.isRegExp(value)) {
|
|
608
|
+
return value;
|
|
609
|
+
}
|
|
610
|
+
|
|
605
611
|
return this.cast(value, true);
|
|
606
612
|
});
|
|
607
613
|
|
package/lib/class/inode.js
CHANGED
|
@@ -137,4 +137,66 @@ Inode.setProperty(function rootname() {
|
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
return libpath.basename(this.name, extension);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Get the stat object
|
|
144
|
+
*
|
|
145
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
146
|
+
* @since 1.1.8
|
|
147
|
+
* @version 1.1.8
|
|
148
|
+
*
|
|
149
|
+
* @param {boolean} refresh
|
|
150
|
+
*
|
|
151
|
+
* @return {Pledge<fs.Stats>}
|
|
152
|
+
*/
|
|
153
|
+
Inode.setMethod(function getStats(refresh) {
|
|
154
|
+
|
|
155
|
+
if (!refresh && this.stat) {
|
|
156
|
+
return Pledge.resolve(this.stat);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
let pledge = new Pledge();
|
|
160
|
+
|
|
161
|
+
fs.stat(this.path, (err, stat) => {
|
|
162
|
+
|
|
163
|
+
if (err) {
|
|
164
|
+
return pledge.reject(err);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
this.stat = stat;
|
|
168
|
+
pledge.resolve(stat);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
return pledge;
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Does this inode still exist?
|
|
176
|
+
*
|
|
177
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
178
|
+
* @since 1.1.8
|
|
179
|
+
* @version 1.1.8
|
|
180
|
+
*
|
|
181
|
+
* @return {boolean}
|
|
182
|
+
*/
|
|
183
|
+
Inode.setMethod(async function exists() {
|
|
184
|
+
|
|
185
|
+
let stat;
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
stat = await this.getStats(true);
|
|
189
|
+
} catch (err) {
|
|
190
|
+
if (err.code == 'ENOENT') {
|
|
191
|
+
return false;
|
|
192
|
+
} else {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (!stat) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return true;
|
|
140
202
|
});
|
package/lib/class/inode_dir.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const libpath = alchemy.use('path');
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* The Directory class
|
|
3
5
|
*
|
|
@@ -108,3 +110,116 @@ Directory.setMethod(Symbol.iterator, function* iterate() {
|
|
|
108
110
|
yield this.contents.entries[i];
|
|
109
111
|
}
|
|
110
112
|
});
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Get a file from this directory, or its subdirectory
|
|
116
|
+
*
|
|
117
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
118
|
+
* @since 1.1.8
|
|
119
|
+
* @version 1.1.8
|
|
120
|
+
*
|
|
121
|
+
* @param {string|string[]} path
|
|
122
|
+
*
|
|
123
|
+
* @return {Alchemy.Inode}
|
|
124
|
+
*/
|
|
125
|
+
Directory.setMethod(async function get(path) {
|
|
126
|
+
|
|
127
|
+
if (!Array.isArray(path)) {
|
|
128
|
+
path = path.split(libpath.sep);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (!this.contents.length) {
|
|
132
|
+
await this.loadContents();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
let current,
|
|
136
|
+
result = this,
|
|
137
|
+
piece,
|
|
138
|
+
entry;
|
|
139
|
+
|
|
140
|
+
for (piece of path) {
|
|
141
|
+
current = result;
|
|
142
|
+
result = null;
|
|
143
|
+
|
|
144
|
+
// If the current piece isn't a directory we can end now
|
|
145
|
+
if (!current.is_directory) {
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Loop over all the entries of the current directory
|
|
150
|
+
for (entry of current) {
|
|
151
|
+
if (piece == entry.name) {
|
|
152
|
+
result = entry;
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (!result) {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return result;
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Return a list of all files
|
|
167
|
+
*
|
|
168
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
169
|
+
* @since 1.1.8
|
|
170
|
+
* @version 1.1.8
|
|
171
|
+
*
|
|
172
|
+
* @return {Alchemy.Inode.List}
|
|
173
|
+
*/
|
|
174
|
+
Directory.setMethod(async function flatten() {
|
|
175
|
+
|
|
176
|
+
if (!this.contents.length) {
|
|
177
|
+
await this.loadContents({recursive: true});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
let info = {
|
|
181
|
+
start : this.path,
|
|
182
|
+
seen : new Set(),
|
|
183
|
+
list : new Classes.Alchemy.Inode.List([]),
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
flattenFiles(this, info);
|
|
187
|
+
|
|
188
|
+
return info.list;
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Add all files to the given list
|
|
193
|
+
*
|
|
194
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
195
|
+
* @since 1.1.8
|
|
196
|
+
* @version 1.1.8
|
|
197
|
+
*
|
|
198
|
+
* @param {Alchemy.Inode.Directory} current
|
|
199
|
+
* @param {Object} info
|
|
200
|
+
*
|
|
201
|
+
* @return {Alchemy.Inode.List}
|
|
202
|
+
*/
|
|
203
|
+
function flattenFiles(current, info) {
|
|
204
|
+
|
|
205
|
+
if (info.seen.has(current.path)) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
info.seen.add(current.path);
|
|
210
|
+
|
|
211
|
+
let entry,
|
|
212
|
+
dirs = [];
|
|
213
|
+
|
|
214
|
+
for (entry of current) {
|
|
215
|
+
if (entry.is_file) {
|
|
216
|
+
info.list.entries.push(entry);
|
|
217
|
+
} else {
|
|
218
|
+
dirs.push(entry);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
for (entry of dirs) {
|
|
223
|
+
flattenFiles(entry, info);
|
|
224
|
+
}
|
|
225
|
+
}
|
package/lib/class/inode_file.js
CHANGED
|
@@ -1,112 +1,113 @@
|
|
|
1
|
-
const fs = alchemy.use('fs');
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* The File class
|
|
5
|
-
*
|
|
6
|
-
* @constructor
|
|
7
|
-
*
|
|
8
|
-
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
9
|
-
* @since 1.1.0
|
|
10
|
-
* @version 1.1.0
|
|
11
|
-
*
|
|
12
|
-
* @param {String} path Path to the file
|
|
13
|
-
*/
|
|
14
|
-
var File = Function.inherits('Alchemy.Inode', function File(path) {
|
|
15
|
-
|
|
16
|
-
if (typeof path == 'object') {
|
|
17
|
-
return File.from(path);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
this.type = null;
|
|
21
|
-
this.hash = null;
|
|
22
|
-
|
|
23
|
-
File.super.call(this, path);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Files are obviously files
|
|
28
|
-
*
|
|
29
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
30
|
-
* @since 1.1.0
|
|
31
|
-
* @version 1.1.0
|
|
32
|
-
*
|
|
33
|
-
* @type {Boolean}
|
|
34
|
-
*/
|
|
35
|
-
File.setProperty('is_file', true);
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Create a File instance from the given variable
|
|
39
|
-
*
|
|
40
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
41
|
-
* @since 1.1.0
|
|
42
|
-
* @version 1.
|
|
43
|
-
*/
|
|
44
|
-
File.setStatic(function from(obj) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
file.
|
|
64
|
-
file.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* @
|
|
75
|
-
* @
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* @
|
|
103
|
-
* @
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
1
|
+
const fs = alchemy.use('fs');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The File class
|
|
5
|
+
*
|
|
6
|
+
* @constructor
|
|
7
|
+
*
|
|
8
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
9
|
+
* @since 1.1.0
|
|
10
|
+
* @version 1.1.0
|
|
11
|
+
*
|
|
12
|
+
* @param {String} path Path to the file
|
|
13
|
+
*/
|
|
14
|
+
var File = Function.inherits('Alchemy.Inode', function File(path) {
|
|
15
|
+
|
|
16
|
+
if (typeof path == 'object') {
|
|
17
|
+
return File.from(path);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
this.type = null;
|
|
21
|
+
this.hash = null;
|
|
22
|
+
|
|
23
|
+
File.super.call(this, path);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Files are obviously files
|
|
28
|
+
*
|
|
29
|
+
* @author Jelle De Loecker <jelle@develry.be>
|
|
30
|
+
* @since 1.1.0
|
|
31
|
+
* @version 1.1.0
|
|
32
|
+
*
|
|
33
|
+
* @type {Boolean}
|
|
34
|
+
*/
|
|
35
|
+
File.setProperty('is_file', true);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Create a File instance from the given variable
|
|
39
|
+
*
|
|
40
|
+
* @author Jelle De Loecker <jelle@develry.be>
|
|
41
|
+
* @since 1.1.0
|
|
42
|
+
* @version 1.2.0
|
|
43
|
+
*/
|
|
44
|
+
File.setStatic(function from(obj) {
|
|
45
|
+
|
|
46
|
+
let path;
|
|
47
|
+
|
|
48
|
+
if (typeof obj == 'string') {
|
|
49
|
+
path = obj;
|
|
50
|
+
obj = null;
|
|
51
|
+
} else {
|
|
52
|
+
path = obj.path;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let file = new File(path);
|
|
56
|
+
|
|
57
|
+
if (obj) {
|
|
58
|
+
file.stat = {
|
|
59
|
+
size : obj.size
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
file.name = obj.name;
|
|
63
|
+
file.type = obj.type;
|
|
64
|
+
file.hash = obj.hash;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return file;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Read and return the contents
|
|
72
|
+
*
|
|
73
|
+
* @author Jelle De Loecker <jelle@develry.be>
|
|
74
|
+
* @since 1.1.0
|
|
75
|
+
* @version 1.1.8
|
|
76
|
+
*/
|
|
77
|
+
File.setMethod(function read(options) {
|
|
78
|
+
|
|
79
|
+
let pledge = new Pledge();
|
|
80
|
+
|
|
81
|
+
if (!options) {
|
|
82
|
+
options = {flag: 'r'};
|
|
83
|
+
} else if (!options.flag) {
|
|
84
|
+
options.flag = 'r';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
fs.readFile(this.path, options, function done(err, data) {
|
|
88
|
+
|
|
89
|
+
if (err) {
|
|
90
|
+
return pledge.reject(err);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
pledge.resolve(data);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
return pledge;
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Read and return the contents as a string
|
|
101
|
+
*
|
|
102
|
+
* @author Jelle De Loecker <jelle@develry.be>
|
|
103
|
+
* @since 1.1.0
|
|
104
|
+
* @version 1.1.0
|
|
105
|
+
*/
|
|
106
|
+
File.setMethod(function readString(encoding) {
|
|
107
|
+
|
|
108
|
+
if (!encoding) {
|
|
109
|
+
encoding = 'utf8';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return this.read({encoding: encoding});
|
|
112
113
|
});
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
const libpath = alchemy.use('path');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Migrations
|
|
5
|
+
*
|
|
6
|
+
* @constructor
|
|
7
|
+
*
|
|
8
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
9
|
+
* @since 1.2.0
|
|
10
|
+
* @version 1.2.0
|
|
11
|
+
*/
|
|
12
|
+
const Migration = Function.inherits('Alchemy.Base', function Migration(document) {
|
|
13
|
+
this.document = document;
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Start the necesary migrations
|
|
18
|
+
*
|
|
19
|
+
* @constructor
|
|
20
|
+
*
|
|
21
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
22
|
+
* @since 1.2.0
|
|
23
|
+
* @version 1.2.0
|
|
24
|
+
*/
|
|
25
|
+
Migration.setStatic(async function start() {
|
|
26
|
+
|
|
27
|
+
const AlchemyMigration = Model.get('AlchemyMigration');
|
|
28
|
+
|
|
29
|
+
console.log('Starting migration task...');
|
|
30
|
+
|
|
31
|
+
let dir = new Classes.Alchemy.Inode.Directory(libpath.resolve(PATH_APP, 'migrations'));
|
|
32
|
+
|
|
33
|
+
await dir.loadContents();
|
|
34
|
+
|
|
35
|
+
for (let entry of dir) {
|
|
36
|
+
|
|
37
|
+
let name = entry.name.beforeLast('.js');
|
|
38
|
+
|
|
39
|
+
if (!name) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
let crit = AlchemyMigration.find();
|
|
44
|
+
crit.where('name').equals(name);
|
|
45
|
+
|
|
46
|
+
let record = await AlchemyMigration.find('first', crit);
|
|
47
|
+
|
|
48
|
+
if (record) {
|
|
49
|
+
if (record.ended) {
|
|
50
|
+
console.log(' »» Migration "' + name + '" already finished on ' + record.ended.format('Y-m-d H:i'));
|
|
51
|
+
} else if (record.error) {
|
|
52
|
+
console.log(' »» Migration "' + name + '" failed with error: ' + record.error);
|
|
53
|
+
console.log('Migrations stopped');
|
|
54
|
+
return;
|
|
55
|
+
} else {
|
|
56
|
+
console.log(' »» Migration "' + name + '" has not yet finished!');
|
|
57
|
+
console.log('Migrations stopped');
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
record = AlchemyMigration.createDocument();
|
|
65
|
+
record.name = name;
|
|
66
|
+
record.path = entry.path;
|
|
67
|
+
|
|
68
|
+
await record.save();
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
|
|
72
|
+
console.log(' »» Starting migration "' + name + '"');
|
|
73
|
+
|
|
74
|
+
let migration = new Migration(record);
|
|
75
|
+
|
|
76
|
+
await Blast.require(entry.path, {
|
|
77
|
+
client: false,
|
|
78
|
+
async : true,
|
|
79
|
+
arguments: {
|
|
80
|
+
names : [
|
|
81
|
+
'Blast',
|
|
82
|
+
'Collection',
|
|
83
|
+
'Bound',
|
|
84
|
+
'Obj',
|
|
85
|
+
'Fn',
|
|
86
|
+
'migration'
|
|
87
|
+
],
|
|
88
|
+
values : [
|
|
89
|
+
Blast,
|
|
90
|
+
Blast.Collection,
|
|
91
|
+
Blast.Bound,
|
|
92
|
+
Blast.Bound.Object,
|
|
93
|
+
Blast.Collection.Function,
|
|
94
|
+
migration,
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
record.ended = new Date();
|
|
100
|
+
await record.save();
|
|
101
|
+
|
|
102
|
+
} catch (err) {
|
|
103
|
+
console.log(' »» Migration error:', err);
|
|
104
|
+
record.error = err.message + '\n' + err.stack;
|
|
105
|
+
await record.save();
|
|
106
|
+
console.log('Migrations stopped');
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
console.log('Executed all migrations');
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Migrate methods
|
|
116
|
+
*
|
|
117
|
+
* @constructor
|
|
118
|
+
*
|
|
119
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
120
|
+
* @since 1.2.0
|
|
121
|
+
* @version 1.2.0
|
|
122
|
+
*/
|
|
123
|
+
Migration.setMethod(function processRecords(model_name, fnc) {
|
|
124
|
+
|
|
125
|
+
const model = Model.get(model_name);
|
|
126
|
+
|
|
127
|
+
let options = {
|
|
128
|
+
document : false,
|
|
129
|
+
parallel_limit : 1,
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
return model.eachRecord(options, async (record, index, next) => {
|
|
133
|
+
await fnc(model, record[model_name], index);
|
|
134
|
+
next();
|
|
135
|
+
}, (err) => {
|
|
136
|
+
// Done!
|
|
137
|
+
});
|
|
138
|
+
});
|