alchemymvc 1.3.21 → 1.4.0-alpha.1
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/LICENSE +1 -1
- package/README.md +3 -3
- package/lib/app/behaviour/publishable_behaviour.js +5 -5
- package/lib/app/behaviour/revision_behaviour.js +10 -10
- package/lib/app/behaviour/sluggable_behaviour.js +14 -14
- package/lib/app/conduit/electron_conduit.js +9 -9
- package/lib/app/conduit/http_conduit.js +13 -13
- package/lib/app/conduit/loopback_conduit.js +15 -15
- package/lib/app/conduit/socket_conduit.js +43 -43
- package/lib/app/config/routes.js +26 -0
- package/lib/app/controller/00-default_app_controller.js +21 -0
- package/lib/app/controller/alchemy_info_controller.js +12 -12
- package/lib/app/datasource/mongo_datasource.js +16 -16
- package/lib/app/element/00-default_app_element.js +19 -0
- package/lib/app/element/time_ago.js +5 -5
- package/lib/app/helper/00-default_app_helper.js +11 -0
- package/lib/app/helper/alchemy_helper.js +22 -22
- package/lib/app/helper/backed_map.js +1 -1
- package/lib/app/helper/breadcrumb.js +10 -10
- package/lib/app/helper/client_collection.js +3 -3
- package/lib/app/helper/cron.js +29 -29
- package/lib/app/helper/enum_values.js +6 -6
- package/lib/app/helper/pagination_helper.js +36 -36
- package/lib/app/helper/router_helper.js +35 -35
- package/lib/app/helper/socket_helper.js +57 -57
- package/lib/app/helper/syncable.js +84 -59
- package/lib/app/helper_component/paginate_component.js +9 -9
- package/lib/app/helper_controller/component.js +1 -1
- package/lib/app/helper_controller/conduit.js +31 -31
- package/lib/app/helper_controller/controller.js +54 -39
- package/lib/app/helper_datasource/00-nosql_datasource.js +624 -70
- package/lib/app/helper_datasource/05-fallback_datasource.js +10 -10
- package/lib/app/helper_datasource/idb_datasource.js +6 -6
- package/lib/app/helper_datasource/indexed_db.js +22 -22
- package/lib/app/helper_datasource/remote_datasource.js +5 -5
- package/lib/app/helper_error/http_error.js +4 -4
- package/lib/app/helper_error/model_error.js +2 -2
- package/lib/app/helper_error/validation_error.js +12 -12
- package/lib/app/helper_field/00-objectid_field.js +7 -7
- package/lib/app/helper_field/05-string_field.js +16 -12
- package/lib/app/helper_field/06-text_field.js +2 -4
- package/lib/app/helper_field/10-number_field.js +9 -12
- package/lib/app/helper_field/11-date_field.js +15 -15
- package/lib/app/helper_field/15-local_temporal_field.js +10 -10
- package/lib/app/helper_field/20-decimal_field.js +8 -9
- package/lib/app/helper_field/belongsto_field.js +1 -1
- package/lib/app/helper_field/big_int_field.js +8 -8
- package/lib/app/helper_field/boolean_field.js +9 -11
- package/lib/app/helper_field/datetime_field.js +3 -3
- package/lib/app/helper_field/enum_field.js +13 -8
- package/lib/app/helper_field/fixed_decimal_field.js +6 -7
- package/lib/app/helper_field/geopoint_field.js +9 -10
- package/lib/app/helper_field/habtm_field.js +3 -3
- package/lib/app/helper_field/hasoneparent_field.js +1 -1
- package/lib/app/helper_field/html_field.js +2 -4
- package/lib/app/helper_field/integer_field.js +8 -11
- package/lib/app/helper_field/local_date_field.js +5 -5
- package/lib/app/helper_field/local_date_time_field.js +5 -5
- package/lib/app/helper_field/local_time_field.js +5 -5
- package/lib/app/helper_field/mixed_field.js +5 -5
- package/lib/app/helper_field/object_field.js +8 -8
- package/lib/app/helper_field/password_field.js +3 -3
- package/lib/app/helper_field/regexp_field.js +7 -9
- package/lib/app/helper_field/schema_field.js +91 -88
- package/lib/app/helper_field/settings_field.js +92 -0
- package/lib/app/helper_field/time_field.js +6 -6
- package/lib/app/helper_field/url_field.js +2 -4
- package/lib/app/helper_model/00-base_criteria.js +662 -0
- package/lib/app/helper_model/05-criteria_expressions.js +605 -0
- package/lib/app/helper_model/10-model_criteria.js +1182 -0
- package/lib/app/helper_model/data_provider.js +2 -2
- package/lib/app/helper_model/document.js +103 -92
- package/lib/app/helper_model/document_list.js +14 -14
- package/lib/app/helper_model/field_config.js +11 -11
- package/lib/app/helper_model/field_set.js +17 -17
- package/lib/app/helper_model/model.js +203 -124
- package/lib/app/helper_model/remote_data_provider.js +2 -2
- package/lib/app/helper_validator/00_validator.js +16 -16
- package/lib/app/helper_validator/not_empty_validator.js +9 -9
- package/lib/app/model/00-default_app_model.js +18 -0
- package/lib/app/model/05-system_model.js +27 -0
- package/lib/app/model/{alchemy_migration_model.js → system_migration_model.js} +4 -4
- package/lib/app/model/system_setting_model.js +154 -0
- package/lib/app/model/{alchemy_task_history_model.js → system_task_history_model.js} +7 -7
- package/lib/app/model/{alchemy_task_model.js → system_task_model.js} +11 -11
- package/lib/bootstrap.js +22 -312
- package/lib/class/accumulator.js +5 -5
- package/lib/class/behaviour.js +5 -5
- package/lib/class/component.js +3 -3
- package/lib/class/conduit.js +203 -163
- package/lib/class/controller.js +42 -42
- package/lib/class/datasource.js +74 -79
- package/lib/class/document.js +74 -95
- package/lib/class/document_list.js +5 -5
- package/lib/class/element.js +17 -17
- package/lib/class/error.js +3 -3
- package/lib/class/field.js +169 -91
- package/lib/class/field_value.js +6 -6
- package/lib/class/helper.js +3 -3
- package/lib/class/inode.js +17 -17
- package/lib/class/inode_dir.js +12 -12
- package/lib/class/inode_file.js +50 -25
- package/lib/class/inode_list.js +4 -4
- package/lib/class/migration.js +4 -4
- package/lib/class/model.js +182 -168
- package/lib/class/path_definition.js +22 -22
- package/lib/class/path_evaluator.js +5 -5
- package/lib/class/path_param_definition.js +7 -7
- package/lib/class/plugin.js +312 -0
- package/lib/class/postponement.js +29 -29
- package/lib/class/reciprocal.js +8 -8
- package/lib/class/route.js +33 -33
- package/lib/class/router.js +73 -73
- package/lib/class/schema.js +21 -21
- package/lib/class/schema_client.js +73 -67
- package/lib/class/session.js +63 -29
- package/lib/class/session_scene.js +4 -4
- package/lib/class/sitemap.js +16 -16
- package/lib/class/task.js +39 -39
- package/lib/class/task_service.js +43 -47
- package/lib/{init → core}/alchemy.js +413 -374
- package/lib/{init/functions.js → core/alchemy_functions.js} +171 -108
- package/lib/core/alchemy_load_functions.js +715 -0
- package/lib/core/base.js +50 -62
- package/lib/core/client_alchemy.js +144 -152
- package/lib/core/client_base.js +39 -52
- package/lib/core/discovery.js +16 -18
- package/lib/core/middleware.js +54 -43
- package/lib/core/{routing.js → prefix.js} +14 -16
- package/lib/core/setting.js +1684 -0
- package/lib/core/stage.js +758 -0
- package/lib/scripts/create_constants.js +119 -0
- package/lib/{init/languages.js → scripts/create_languages.js} +5 -5
- package/lib/scripts/create_settings.js +449 -0
- package/lib/scripts/create_shared_constants.js +95 -0
- package/lib/scripts/create_stages.js +55 -0
- package/lib/scripts/init_alchemy.js +51 -0
- package/lib/{init/requirements.js → scripts/preload_modules.js} +15 -2
- package/lib/scripts/setup_devwatch.js +238 -0
- package/lib/stages/00-load_core.js +342 -0
- package/lib/stages/05-load_app.js +57 -0
- package/lib/stages/10-datasource.js +61 -0
- package/lib/stages/15-tasks.js +27 -0
- package/lib/stages/20-settings.js +68 -0
- package/lib/stages/50-routes.js +218 -0
- package/lib/stages/90-server.js +347 -0
- package/package.json +5 -7
- package/lib/app/helper_model/criteria.js +0 -2294
- package/lib/app/helper_model/db_query.js +0 -1488
- package/lib/app/routes.js +0 -11
- package/lib/core/socket.js +0 -171
- package/lib/init/constants.js +0 -158
- package/lib/init/devwatch.js +0 -238
- package/lib/init/load_functions.js +0 -973
- package/lib/stages.js +0 -513
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @constructor
|
|
5
5
|
*
|
|
6
|
-
* @author Jelle De Loecker
|
|
6
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
7
7
|
* @since 0.2.0
|
|
8
8
|
* @version 1.1.0
|
|
9
9
|
*/
|
|
@@ -14,7 +14,7 @@ var Time = Function.inherits('Alchemy.Field', function Time(schema, name, option
|
|
|
14
14
|
/**
|
|
15
15
|
* Set the datatype name
|
|
16
16
|
*
|
|
17
|
-
* @author Jelle De Loecker
|
|
17
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
18
18
|
* @since 0.2.0
|
|
19
19
|
* @version 1.1.0
|
|
20
20
|
*/
|
|
@@ -23,7 +23,7 @@ Time.setDatatype('time');
|
|
|
23
23
|
/**
|
|
24
24
|
* Dates are self-contained objects
|
|
25
25
|
*
|
|
26
|
-
* @author Jelle De Loecker
|
|
26
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
27
27
|
* @since 1.1.0
|
|
28
28
|
* @version 1.1.0
|
|
29
29
|
*/
|
|
@@ -32,15 +32,15 @@ Time.setSelfContained(true);
|
|
|
32
32
|
/**
|
|
33
33
|
* Cast the given value to this field's type
|
|
34
34
|
*
|
|
35
|
-
* @author Jelle De Loecker
|
|
35
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
36
36
|
* @since 0.2.0
|
|
37
37
|
* @version 0.4.1
|
|
38
38
|
*
|
|
39
|
-
* @param {
|
|
39
|
+
* @param {*} value
|
|
40
40
|
*
|
|
41
41
|
* @return {Date}
|
|
42
42
|
*/
|
|
43
|
-
Time.
|
|
43
|
+
Time.setCastFunction(function cast(value) {
|
|
44
44
|
|
|
45
45
|
var result;
|
|
46
46
|
|
|
@@ -3,10 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @constructor
|
|
5
5
|
*
|
|
6
|
-
* @author Jelle De Loecker
|
|
6
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
7
7
|
* @since 1.1.0
|
|
8
8
|
* @version 1.1.0
|
|
9
9
|
*/
|
|
10
|
-
|
|
11
|
-
Url.super.call(this, schema, name, options);
|
|
12
|
-
});
|
|
10
|
+
const UrlField = Function.inherits('Alchemy.Field', 'Url');
|
|
@@ -0,0 +1,662 @@
|
|
|
1
|
+
const AUGMENTED = Symbol('AUGMENTED'),
|
|
2
|
+
CriteriaNS = Function.getNamespace('Alchemy.Criteria'),
|
|
3
|
+
Expressions = Function.getNamespace('Alchemy.Criteria.Expression');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The Criteria class
|
|
7
|
+
*
|
|
8
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
9
|
+
* @since 1.4.0
|
|
10
|
+
* @version 1.4.0
|
|
11
|
+
*/
|
|
12
|
+
const Criteria = Function.inherits('Alchemy.Base', 'Alchemy.Criteria', function Criteria(options) {
|
|
13
|
+
|
|
14
|
+
// The current active group
|
|
15
|
+
this.group = null;
|
|
16
|
+
|
|
17
|
+
// All the created expressions
|
|
18
|
+
this.all_expressions = [];
|
|
19
|
+
|
|
20
|
+
// Create the actual group (is always AND)
|
|
21
|
+
this.createGroup('and');
|
|
22
|
+
|
|
23
|
+
// Store the root group
|
|
24
|
+
this.root_group = this.group;
|
|
25
|
+
|
|
26
|
+
// Other options
|
|
27
|
+
this.options = options || {};
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Is the given argument a Criteria instance?
|
|
32
|
+
*
|
|
33
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
34
|
+
* @since 1.1.0
|
|
35
|
+
* @version 1.1.0
|
|
36
|
+
*
|
|
37
|
+
* @param {Object} instance
|
|
38
|
+
*
|
|
39
|
+
* @return {boolean}
|
|
40
|
+
*/
|
|
41
|
+
Criteria.setStatic(function isCriteria(instance) {
|
|
42
|
+
|
|
43
|
+
if (!instance || typeof instance != 'object') {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (instance instanceof Criteria) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return false;
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Make sure to get a criteria
|
|
56
|
+
*
|
|
57
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
58
|
+
* @since 1.4.0
|
|
59
|
+
* @version 1.4.0
|
|
60
|
+
*
|
|
61
|
+
* @param {Object|string|Criteria} conditions
|
|
62
|
+
* @param {Object} options
|
|
63
|
+
*
|
|
64
|
+
* @return {Criteria}
|
|
65
|
+
*/
|
|
66
|
+
Criteria.setStatic(function cast(conditions, options) {
|
|
67
|
+
|
|
68
|
+
if (Criteria.isCriteria(conditions)) {
|
|
69
|
+
return conditions;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (typeof conditions == 'string') {
|
|
73
|
+
conditions = Classes.Alchemy.Datasource.Nosql.convertAQLToConditions(conditions);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let instance = new Criteria(options);
|
|
77
|
+
|
|
78
|
+
if (conditions) {
|
|
79
|
+
instance.applyConditions(conditions);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return instance;
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Add a new value expression type
|
|
87
|
+
*
|
|
88
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
89
|
+
* @since 1.1.0
|
|
90
|
+
* @version 1.1.0
|
|
91
|
+
*
|
|
92
|
+
* @param {string} name The name of the expression
|
|
93
|
+
* @param {boolean} cast Cast the value [true]
|
|
94
|
+
*
|
|
95
|
+
* @return {Criteria}
|
|
96
|
+
*/
|
|
97
|
+
Criteria.setStatic(function addValueExpression(name, cast) {
|
|
98
|
+
this.setMethod(name, function valueExpressionAdder(value) {
|
|
99
|
+
|
|
100
|
+
var entry;
|
|
101
|
+
|
|
102
|
+
this._ensureExpression(name);
|
|
103
|
+
entry = this._active.addItem(name, value);
|
|
104
|
+
|
|
105
|
+
if (cast != null) {
|
|
106
|
+
entry.cast = cast;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return this;
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Add a new field expression type
|
|
115
|
+
*
|
|
116
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
117
|
+
* @since 1.1.0
|
|
118
|
+
* @version 1.1.0
|
|
119
|
+
*
|
|
120
|
+
* @param {string} name The name of the expression
|
|
121
|
+
*
|
|
122
|
+
* @return {Criteria}
|
|
123
|
+
*/
|
|
124
|
+
Criteria.setStatic(function addFieldExpression(name) {
|
|
125
|
+
this.setMethod(name, function fieldExpressionAdder(value) {
|
|
126
|
+
|
|
127
|
+
var entry;
|
|
128
|
+
|
|
129
|
+
this._ensureExpression(name);
|
|
130
|
+
entry = this._active.addItem(name, value);
|
|
131
|
+
entry.field_expression = true;
|
|
132
|
+
|
|
133
|
+
return this;
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Undry the given object
|
|
139
|
+
*
|
|
140
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
141
|
+
* @since 1.4.0
|
|
142
|
+
* @version 1.4.0
|
|
143
|
+
*
|
|
144
|
+
* @param {Object} data
|
|
145
|
+
*
|
|
146
|
+
* @return {Criteria}
|
|
147
|
+
*/
|
|
148
|
+
Criteria.setStatic(function unDry(data) {
|
|
149
|
+
|
|
150
|
+
let criteria = new this(data.options);
|
|
151
|
+
|
|
152
|
+
// Revive the group instance
|
|
153
|
+
criteria.group = Expressions.Group.revive(data.group, criteria);
|
|
154
|
+
|
|
155
|
+
return criteria;
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Dry this Criteria instance
|
|
160
|
+
*
|
|
161
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
162
|
+
* @since 1.1.0
|
|
163
|
+
* @version 1.1.0
|
|
164
|
+
*
|
|
165
|
+
* @return {Object}
|
|
166
|
+
*/
|
|
167
|
+
Criteria.setMethod(function toDry() {
|
|
168
|
+
|
|
169
|
+
// Augments cannot be dried, it's ALWAYS the original instance
|
|
170
|
+
let value = this.toJSON();
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
value : value
|
|
174
|
+
};
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Return object for jsonifying
|
|
179
|
+
*
|
|
180
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
181
|
+
* @since 1.1.0
|
|
182
|
+
* @version 1.4.0
|
|
183
|
+
*
|
|
184
|
+
* @return {Object}
|
|
185
|
+
*/
|
|
186
|
+
Criteria.setMethod(function toJSON() {
|
|
187
|
+
|
|
188
|
+
let result = {
|
|
189
|
+
group : this.group,
|
|
190
|
+
options : {...this.options},
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
return result;
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Return the elements to checksum in place of this object
|
|
198
|
+
*
|
|
199
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
200
|
+
* @since 1.1.0
|
|
201
|
+
* @version 1.2.3
|
|
202
|
+
*/
|
|
203
|
+
Criteria.setMethod(Blast.checksumSymbol, function toChecksum() {
|
|
204
|
+
|
|
205
|
+
let name = this.model ? this.model.name : undefined,
|
|
206
|
+
result = [name],
|
|
207
|
+
options = {},
|
|
208
|
+
key;
|
|
209
|
+
|
|
210
|
+
for (key in this.options) {
|
|
211
|
+
|
|
212
|
+
if (key == 'init_model' || key == 'init_record' || key == 'assoc_cache') {
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
options[key] = this.options[key];
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
result.push(options);
|
|
220
|
+
result.push(this.group);
|
|
221
|
+
|
|
222
|
+
return result;
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Create an augmented version of this instance
|
|
227
|
+
*
|
|
228
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
229
|
+
* @since 1.1.0
|
|
230
|
+
* @version 1.1.0
|
|
231
|
+
*
|
|
232
|
+
* @param {string} type
|
|
233
|
+
*
|
|
234
|
+
* @return {Criteria}
|
|
235
|
+
*/
|
|
236
|
+
Criteria.setMethod(function augment(type) {
|
|
237
|
+
|
|
238
|
+
let context = this;
|
|
239
|
+
|
|
240
|
+
if (context[AUGMENTED]) {
|
|
241
|
+
// NO don't do this, we want chaining!
|
|
242
|
+
//context = context[AUGMENTED];
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Create the new object with this instance as the prototype
|
|
246
|
+
let result = Object.create(context);
|
|
247
|
+
|
|
248
|
+
// Remembed which object we augmented
|
|
249
|
+
result[AUGMENTED] = context;
|
|
250
|
+
|
|
251
|
+
return result;
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Set a specific option
|
|
256
|
+
*
|
|
257
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
258
|
+
* @since 1.1.0
|
|
259
|
+
* @version 1.1.0
|
|
260
|
+
*
|
|
261
|
+
* @param {string} key
|
|
262
|
+
* @param {string} value
|
|
263
|
+
*
|
|
264
|
+
* @return {Criteria}
|
|
265
|
+
*/
|
|
266
|
+
Criteria.setMethod(function setOption(key, value) {
|
|
267
|
+
this.options[key] = value;
|
|
268
|
+
return this;
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Get all the queried fields
|
|
273
|
+
*
|
|
274
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
275
|
+
* @since 1.4.0
|
|
276
|
+
* @version 1.4.0
|
|
277
|
+
*
|
|
278
|
+
* @return {string[]}
|
|
279
|
+
*/
|
|
280
|
+
Criteria.setMethod(function getAllExpressionTargetPaths() {
|
|
281
|
+
|
|
282
|
+
let field_set = new Set(),
|
|
283
|
+
expression;
|
|
284
|
+
|
|
285
|
+
for (expression of this.all_expressions) {
|
|
286
|
+
|
|
287
|
+
if (!expression.target_path) {
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
field_set.add(expression.target_path);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return [...field_set];
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Create a new group
|
|
299
|
+
*
|
|
300
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
301
|
+
* @since 1.1.0
|
|
302
|
+
* @version 1.1.0
|
|
303
|
+
*
|
|
304
|
+
* @param {string} type
|
|
305
|
+
*/
|
|
306
|
+
Criteria.setMethod(function createGroup(type) {
|
|
307
|
+
|
|
308
|
+
let context = this,
|
|
309
|
+
group;
|
|
310
|
+
|
|
311
|
+
if (this.group) {
|
|
312
|
+
let old_group = context.group;
|
|
313
|
+
context = context.augment('group');
|
|
314
|
+
|
|
315
|
+
group = new Expressions.Group(context, type);
|
|
316
|
+
old_group.addItem(group);
|
|
317
|
+
|
|
318
|
+
context.group = group;
|
|
319
|
+
} else {
|
|
320
|
+
group = new Expressions.Group(this, type);
|
|
321
|
+
this.group = group;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return context;
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Close the current active group
|
|
329
|
+
*
|
|
330
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
331
|
+
* @since 1.1.0
|
|
332
|
+
* @version 1.1.0
|
|
333
|
+
*
|
|
334
|
+
* @return {Criteria}
|
|
335
|
+
*/
|
|
336
|
+
Criteria.setMethod(function closeGroup() {
|
|
337
|
+
|
|
338
|
+
let context = this;
|
|
339
|
+
|
|
340
|
+
if (this.group && this.group.current_group) {
|
|
341
|
+
context = this.group.current_group.criteria;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return context;
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Compile to a (NoSQL) conditions object
|
|
349
|
+
*
|
|
350
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
351
|
+
* @since 1.4.0
|
|
352
|
+
* @version 1.4.0
|
|
353
|
+
*
|
|
354
|
+
* @param {Object} context The optional context (for resolving values)
|
|
355
|
+
*
|
|
356
|
+
* @return {Object}
|
|
357
|
+
*/
|
|
358
|
+
Criteria.setMethod(function compileToConditions(context) {
|
|
359
|
+
return Classes.Alchemy.Datasource.Nosql.convertCriteriaToConditions(this, context);
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Apply old-style mongodb conditions
|
|
364
|
+
*
|
|
365
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
366
|
+
* @since 1.1.0
|
|
367
|
+
* @version 1.4.0
|
|
368
|
+
*
|
|
369
|
+
* @param {Object} conditions
|
|
370
|
+
*
|
|
371
|
+
* @return {Criteria}
|
|
372
|
+
*/
|
|
373
|
+
Criteria.setMethod(function applyConditions(conditions) {
|
|
374
|
+
|
|
375
|
+
if (!conditions || Object.isEmpty(conditions)) {
|
|
376
|
+
return this;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (conditions instanceof Criteria) {
|
|
380
|
+
conditions = conditions.compileToConditions();
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (typeof conditions == 'string') {
|
|
384
|
+
conditions = Classes.Alchemy.Datasource.Nosql.convertAQLToConditions(conditions);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
let context = this;
|
|
388
|
+
|
|
389
|
+
if (Array.isArray(conditions)) {
|
|
390
|
+
let i;
|
|
391
|
+
|
|
392
|
+
for (i = 0; i < conditions.length; i++) {
|
|
393
|
+
context.applyConditions(conditions[i]);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return context;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
let value,
|
|
400
|
+
group,
|
|
401
|
+
key,
|
|
402
|
+
i = -1;
|
|
403
|
+
|
|
404
|
+
for (key in conditions) {
|
|
405
|
+
value = conditions[key];
|
|
406
|
+
i++;
|
|
407
|
+
|
|
408
|
+
if (key[0] == '$') {
|
|
409
|
+
|
|
410
|
+
// Make sure no field is currently active,
|
|
411
|
+
// else it'll be added to the $and or $or group
|
|
412
|
+
context._active = null;
|
|
413
|
+
|
|
414
|
+
if (key == '$or') {
|
|
415
|
+
group = context.or();
|
|
416
|
+
} else if (key == '$and') {
|
|
417
|
+
|
|
418
|
+
group = context.and();
|
|
419
|
+
} else {
|
|
420
|
+
throw new Error('Unable to parse "' + key + '" group');
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
group.applyConditions(value);
|
|
424
|
+
|
|
425
|
+
} else {
|
|
426
|
+
|
|
427
|
+
if (i) {
|
|
428
|
+
// If an object contains multiple items,
|
|
429
|
+
// that's always treated as an $and group
|
|
430
|
+
context = context.and();
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
context = context.where(key);
|
|
434
|
+
|
|
435
|
+
if (Array.isArray(value)) {
|
|
436
|
+
context = context.in(value);
|
|
437
|
+
continue;
|
|
438
|
+
} else if (value && typeof value == 'object') {
|
|
439
|
+
let had_dollar,
|
|
440
|
+
method,
|
|
441
|
+
key;
|
|
442
|
+
|
|
443
|
+
for (key in value) {
|
|
444
|
+
if (key[0] == '$') {
|
|
445
|
+
had_dollar = true;
|
|
446
|
+
method = key.slice(1);
|
|
447
|
+
|
|
448
|
+
if (typeof context[method] != 'function') {
|
|
449
|
+
if (method == 'regex') {
|
|
450
|
+
let regex;
|
|
451
|
+
|
|
452
|
+
if (typeof value[key] == 'string') {
|
|
453
|
+
regex = RegExp.interpret(RegExp.escape(value[key]), value.$options);
|
|
454
|
+
} else {
|
|
455
|
+
regex = RegExp.interpret(value[key], value.$options);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
context.contains(regex);
|
|
459
|
+
break;
|
|
460
|
+
} else {
|
|
461
|
+
throw new Error('Unable to parse "' + key + '" expression');
|
|
462
|
+
}
|
|
463
|
+
} else {
|
|
464
|
+
context[method](value[key]);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
if (had_dollar) {
|
|
470
|
+
continue;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
context.equals(value);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Target a field
|
|
481
|
+
*
|
|
482
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
483
|
+
* @since 1.1.0
|
|
484
|
+
* @version 1.4.0
|
|
485
|
+
*
|
|
486
|
+
* @param {string} name
|
|
487
|
+
* @param {*} value
|
|
488
|
+
*/
|
|
489
|
+
Criteria.setMethod(function where(name, value) {
|
|
490
|
+
|
|
491
|
+
let context = this.augment('field'),
|
|
492
|
+
expression = new Expressions.Field(context, name);
|
|
493
|
+
|
|
494
|
+
this.addNewExpression(expression);
|
|
495
|
+
|
|
496
|
+
context._active = expression;
|
|
497
|
+
|
|
498
|
+
if (arguments.length == 2) {
|
|
499
|
+
context = context.equals(value);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
return context;
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Add a new expression
|
|
507
|
+
*
|
|
508
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
509
|
+
* @since 1.1.0
|
|
510
|
+
* @version 1.1.0
|
|
511
|
+
*
|
|
512
|
+
* @param {Expression} expression
|
|
513
|
+
*/
|
|
514
|
+
Criteria.setMethod(function addNewExpression(expression) {
|
|
515
|
+
|
|
516
|
+
// Make sure there is a criteria link
|
|
517
|
+
if (!expression.criteria) {
|
|
518
|
+
expression.criteria = this;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// Move the expression to the currently active group by default
|
|
522
|
+
expression.moveToGroup(this.group);
|
|
523
|
+
|
|
524
|
+
this.all_expressions.push(expression);
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Make sure there is an active expression
|
|
529
|
+
*
|
|
530
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
531
|
+
* @since 1.1.0
|
|
532
|
+
* @version 1.1.0
|
|
533
|
+
*
|
|
534
|
+
* @param {string} method
|
|
535
|
+
*/
|
|
536
|
+
Criteria.setMethod(function _ensureExpression(method) {
|
|
537
|
+
|
|
538
|
+
if (!this._active) {
|
|
539
|
+
throw new Error(method + '() must be called when an expression is active');
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
this._last_method = method;
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Create an or group
|
|
547
|
+
*
|
|
548
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
549
|
+
* @since 1.1.0
|
|
550
|
+
* @version 1.1.0
|
|
551
|
+
*
|
|
552
|
+
* @param {string} type Type of group: or, and, not, ...
|
|
553
|
+
* @param {string} value
|
|
554
|
+
*/
|
|
555
|
+
Criteria.setMethod(function _applyGroup(type, value) {
|
|
556
|
+
|
|
557
|
+
let context = this;
|
|
558
|
+
|
|
559
|
+
if (context._active) {
|
|
560
|
+
let temp = context._active.moveToGroup(type);
|
|
561
|
+
context = temp;
|
|
562
|
+
} else {
|
|
563
|
+
context = context.createGroup(type);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
if (arguments.length > 1) {
|
|
567
|
+
let method = context._last_method;
|
|
568
|
+
|
|
569
|
+
if (!method) {
|
|
570
|
+
throw new Error('Unable to call ' + type + '() with a value when no previous method is called');
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// Create new expression with the same field
|
|
574
|
+
context = context.where(context._active.target_path);
|
|
575
|
+
|
|
576
|
+
// Apply the method on it
|
|
577
|
+
context[method](value);
|
|
578
|
+
} else if (context._active) {
|
|
579
|
+
// Create new expression with the same field
|
|
580
|
+
context = context.where(context._active.target_path);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
return context;
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Create an or group
|
|
588
|
+
*
|
|
589
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
590
|
+
* @since 1.1.0
|
|
591
|
+
* @version 1.1.0
|
|
592
|
+
*
|
|
593
|
+
* @param {string} value
|
|
594
|
+
*/
|
|
595
|
+
Criteria.setMethod(function or(value) {
|
|
596
|
+
|
|
597
|
+
if (arguments.length) {
|
|
598
|
+
return this._applyGroup('or', value);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
return this._applyGroup('or');
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Create an and group
|
|
606
|
+
*
|
|
607
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
608
|
+
* @since 1.1.0
|
|
609
|
+
* @version 1.1.0
|
|
610
|
+
*
|
|
611
|
+
* @param {string} value
|
|
612
|
+
*/
|
|
613
|
+
Criteria.setMethod(function and(value) {
|
|
614
|
+
|
|
615
|
+
if (arguments.length) {
|
|
616
|
+
return this._applyGroup('and', value);
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
return this._applyGroup('and');
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
/**
|
|
623
|
+
* Alias for `ne`: Not equals check
|
|
624
|
+
*
|
|
625
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
626
|
+
* @since 1.3.21
|
|
627
|
+
* @version 1.3.2
|
|
628
|
+
*
|
|
629
|
+
* @param {*} value
|
|
630
|
+
*/
|
|
631
|
+
Criteria.setMethod(function notEquals(value) {
|
|
632
|
+
return this.ne(value);
|
|
633
|
+
});
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* Alias for `equals`
|
|
637
|
+
*
|
|
638
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
639
|
+
* @since 1.4.0
|
|
640
|
+
* @version 1.4.0
|
|
641
|
+
*
|
|
642
|
+
* @param {*} value
|
|
643
|
+
*/
|
|
644
|
+
Criteria.setMethod(function eq(value) {
|
|
645
|
+
return this.equals(value);
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
Criteria.addValueExpression('equals');
|
|
649
|
+
Criteria.addValueExpression('gte');
|
|
650
|
+
Criteria.addValueExpression('gt');
|
|
651
|
+
Criteria.addValueExpression('lte');
|
|
652
|
+
Criteria.addValueExpression('lt');
|
|
653
|
+
Criteria.addValueExpression('in');
|
|
654
|
+
|
|
655
|
+
// Add as value expressions of which we don't cast values
|
|
656
|
+
Criteria.addValueExpression('contains', false);
|
|
657
|
+
Criteria.addValueExpression('not', false);
|
|
658
|
+
Criteria.addValueExpression('ne', false);
|
|
659
|
+
|
|
660
|
+
Criteria.addFieldExpression('exists');
|
|
661
|
+
Criteria.addFieldExpression('isNull');
|
|
662
|
+
Criteria.addFieldExpression('isEmpty');
|