beanbagdb 0.5.61 → 0.5.71
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/package.json +1 -1
- package/src/index.js +201 -69
- package/src/plugins/text_command.js +2 -4
- package/src/system_schema.js +297 -238
- package/test/operations.test.js +2 -2
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -114,7 +114,7 @@ export class BeanBagDB {
|
|
|
114
114
|
*
|
|
115
115
|
* This method performs the following actions:
|
|
116
116
|
* - Pings the database.
|
|
117
|
-
* - Searches the database for the `
|
|
117
|
+
* - Searches the database for the `system_setting.beanbagdb_version` document.
|
|
118
118
|
* - Sets the class state as active if the version matches the current BeanBagDB version.
|
|
119
119
|
* - If the version does not match, calls `initialize()` to set up the database to the latest version.
|
|
120
120
|
* @todo Code to ping the DB and throw Connection error if failed to connect
|
|
@@ -123,17 +123,22 @@ export class BeanBagDB {
|
|
|
123
123
|
*/
|
|
124
124
|
async ready() {
|
|
125
125
|
// TODO Ping db
|
|
126
|
+
console.log("running ready....")
|
|
126
127
|
let version_search = await this.db_api.search({
|
|
127
|
-
selector: { schema: "
|
|
128
|
-
})
|
|
128
|
+
selector: { schema: "system_setting", "data.name": "beanbagdb_system" },
|
|
129
|
+
})
|
|
130
|
+
//console.log(version_search)
|
|
129
131
|
if (version_search.docs.length > 0) {
|
|
130
132
|
let doc = version_search.docs[0];
|
|
131
|
-
|
|
132
|
-
this.
|
|
133
|
+
//console.log(doc)
|
|
134
|
+
this.active = doc["data"]["value"]["version"] == this._version;
|
|
135
|
+
this.meta.beanbagdb_version_db = doc["data"]["value"]["version"];
|
|
133
136
|
}
|
|
134
137
|
if (this.active) {
|
|
135
138
|
console.log("Ready");
|
|
136
139
|
} else {
|
|
140
|
+
console.log("Not ready. Init required")
|
|
141
|
+
//throw new Error("Initialization required")
|
|
137
142
|
await this.initialize();
|
|
138
143
|
}
|
|
139
144
|
}
|
|
@@ -155,81 +160,132 @@ export class BeanBagDB {
|
|
|
155
160
|
*/
|
|
156
161
|
async initialize() {
|
|
157
162
|
// this works on its own but is usually called by ready automatically if required
|
|
158
|
-
|
|
159
163
|
// check for schema_scehma : if yes, check if latest and upgrade if required, if no create a new schema doc
|
|
160
|
-
let logs = ["init started"];
|
|
161
164
|
try {
|
|
162
|
-
let
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
full_doc["meta"]["updated_on"] = this.util_get_now_unix_timestamp();
|
|
168
|
-
await this.db_api.update(full_doc);
|
|
169
|
-
logs.push("new schema_schema v " + sys_sch.schema_schema.version);
|
|
170
|
-
}
|
|
165
|
+
let app_data = await this.initialize_db(sys_sch.default_app)
|
|
166
|
+
console.log(app_data)
|
|
167
|
+
this.meta.beanbagdb_version_db = this._version;
|
|
168
|
+
this.active = true;
|
|
169
|
+
return app_data
|
|
171
170
|
} catch (error) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
let schema_schema_doc = this._get_blank_doc("schema");
|
|
176
|
-
schema_schema_doc.data = sys_sch.schema_schema;
|
|
177
|
-
await this.db_api.insert(schema_schema_doc);
|
|
178
|
-
logs.push("init schema_schema v " + sys_sch.schema_schema.version);
|
|
179
|
-
}
|
|
171
|
+
console.log("Error in initializing instance")
|
|
172
|
+
console.log(error)
|
|
173
|
+
throw error
|
|
180
174
|
}
|
|
181
175
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async initialize_db(app_data){
|
|
179
|
+
// app_data : meta(name,description), schemas[] , default_records:[]
|
|
180
|
+
// TODO check if add_data is valid
|
|
181
|
+
// calculate the app_version
|
|
182
|
+
let latest_version = 0
|
|
183
|
+
app_data.schemas.map(sch=>{latest_version = latest_version + sch.version})
|
|
184
|
+
app_data.records.map(sch=>{latest_version = latest_version + sch.version})
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
// check if app setting record exists
|
|
188
|
+
let version_search = await this.db_api.search({
|
|
189
|
+
selector: { schema: "system_setting", "data.name": app_data.meta.name },
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
let update_required = true
|
|
193
|
+
let doc
|
|
194
|
+
if (version_search.docs.length > 0) {
|
|
195
|
+
doc = version_search.docs[0];
|
|
196
|
+
if(doc["data"]["value"]["version"] == latest_version){
|
|
197
|
+
update_required = false
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// if no update required return the document
|
|
202
|
+
if(!update_required){return doc}
|
|
203
|
+
// if version is latest no additional steps required
|
|
204
|
+
// version mismatch => update all docs
|
|
205
|
+
|
|
206
|
+
let text = `Initializing ${app_data.meta.name} app to v.${latest_version}`
|
|
207
|
+
let steps = ["update started"]
|
|
208
|
+
|
|
209
|
+
for (let index = 0; index < app_data.schemas.length; index++) {
|
|
210
|
+
const schema_name = app_data.schemas[index]["name"];
|
|
211
|
+
const schema_data = app_data.schemas[index]
|
|
212
|
+
steps.push(`checking.${schema_name}`)
|
|
186
213
|
try {
|
|
187
214
|
// console.log(schema_name)
|
|
188
215
|
let schema1 = await this.get("schema",{name:schema_name})
|
|
189
216
|
if (schema1["data"]["version"] != schema_data.version) {
|
|
190
|
-
|
|
217
|
+
steps.push(`old.${schema_name}.v.${schema1["data"]["version"]}`);
|
|
191
218
|
let full_doc = await this.db_api.get(schema1["_id"]);
|
|
192
219
|
full_doc["data"] = { ...schema_data };
|
|
193
220
|
full_doc["meta"]["updated_on"] = this.util_get_now_unix_timestamp();
|
|
221
|
+
console.log(full_doc)
|
|
194
222
|
await this.db_api.update(full_doc);
|
|
195
|
-
|
|
223
|
+
|
|
224
|
+
steps.push(`new.${schema_name}.v=${schema_data.version}`);
|
|
225
|
+
}else{
|
|
226
|
+
steps.push(`${schema_name}.v.${schema1["data"]["version"]}=latest`)
|
|
196
227
|
}
|
|
197
228
|
} catch (error) {
|
|
198
229
|
// console.log(error);
|
|
199
230
|
if (error instanceof DocNotFoundError) {
|
|
200
231
|
// inserting new schema doc
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
schema_data
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
232
|
+
if(schema_name=="schema"&& app_data.meta.name=="beanbagdb_system"){
|
|
233
|
+
// this is to initialize the system schema
|
|
234
|
+
let schema_schema_doc = this._get_blank_doc("schema");
|
|
235
|
+
schema_schema_doc.data = schema_data;
|
|
236
|
+
//console.log(schema_schema_doc)
|
|
237
|
+
await this.db_api.insert(schema_schema_doc);
|
|
238
|
+
}else{
|
|
239
|
+
let system_schema = sys_sch.default_app.schemas[0]["schema"]
|
|
240
|
+
let new_schema_doc = this._get_blank_schema_doc(
|
|
241
|
+
"schema",
|
|
242
|
+
system_schema,
|
|
243
|
+
schema_data
|
|
244
|
+
);
|
|
245
|
+
await this.db_api.insert(new_schema_doc);
|
|
246
|
+
}
|
|
247
|
+
steps.push(`init.${schema_name}.v=${schema_data.version}`);
|
|
248
|
+
}else{
|
|
249
|
+
steps.push(`${schema_name}.error.message : ${error.message} `);
|
|
208
250
|
}
|
|
209
251
|
}
|
|
210
252
|
}
|
|
211
|
-
// store the logs in the log_doc , generate it for the first time
|
|
212
|
-
// console.log(logs)
|
|
213
|
-
if (logs.length > 1) {
|
|
214
|
-
// version needs to be updated in the object as well as settings and must be logged
|
|
215
|
-
logs.push("Init done");
|
|
216
|
-
|
|
217
|
-
await this.save_setting_doc("system_logs", {
|
|
218
|
-
value: { text: logs.join(","), added: this.util_get_now_unix_timestamp() },
|
|
219
|
-
on_update_array: "append",
|
|
220
|
-
});
|
|
221
|
-
await this.save_setting_doc("beanbagdb_version", {
|
|
222
|
-
value: this._version,
|
|
223
|
-
});
|
|
224
253
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
254
|
+
for (let index = 0; index < app_data.records.length; index++) {
|
|
255
|
+
const schema_name = app_data.records[index]["schema"]
|
|
256
|
+
const schema_data = app_data.records[index]["record"]
|
|
257
|
+
const record_title = app_data.records[index]["title"]
|
|
258
|
+
steps.push(`checking.records.${record_title}`)
|
|
259
|
+
try {
|
|
260
|
+
let new_doc = await this.create(schema_name,schema_data,app_data.records[index]["meta"])
|
|
261
|
+
steps.push(`doc.${record_title}.created`)
|
|
262
|
+
} catch (error) {
|
|
263
|
+
if(!(error instanceof DocCreationError)){
|
|
264
|
+
steps.push(`error in doc ${record_title} insertion: ${error.message}, doc: ${JSON.stringify(schema_data)}`)
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
let app_doc = { ... app_data.meta, version: latest_version}
|
|
270
|
+
try {
|
|
271
|
+
await this.save_setting_doc(app_data.meta.name, {
|
|
272
|
+
value: app_doc,
|
|
273
|
+
});
|
|
274
|
+
} catch (error) {
|
|
275
|
+
console.log(error)
|
|
276
|
+
console.log("error in storing/updating beanbagdb_version")
|
|
231
277
|
}
|
|
232
|
-
|
|
278
|
+
|
|
279
|
+
try {
|
|
280
|
+
let new_log_doc = this._get_blank_doc("system_log")
|
|
281
|
+
new_log_doc.data = {text,data:{steps},time:this.util_get_now_unix_timestamp(),app:app_data.meta.name}
|
|
282
|
+
await this.db_api.insert(new_log_doc);
|
|
283
|
+
console.log("init logged")
|
|
284
|
+
} catch (error) {
|
|
285
|
+
console.log(error)
|
|
286
|
+
}
|
|
287
|
+
return app_doc
|
|
288
|
+
}
|
|
233
289
|
|
|
234
290
|
|
|
235
291
|
/**
|
|
@@ -263,7 +319,7 @@ export class BeanBagDB {
|
|
|
263
319
|
}
|
|
264
320
|
|
|
265
321
|
let doc_search = await this.db_api.search({
|
|
266
|
-
selector: { schema: "
|
|
322
|
+
selector: { schema: "system_setting", "data.name": name },
|
|
267
323
|
});
|
|
268
324
|
if (doc_search.docs.length > 0) {
|
|
269
325
|
// doc already exists, check schema and update it : if it exists then it's value already exists and can be
|
|
@@ -293,7 +349,7 @@ export class BeanBagDB {
|
|
|
293
349
|
new_val.value = [new_data.value];
|
|
294
350
|
new_val.on_update_array = new_data.on_update_array;
|
|
295
351
|
}
|
|
296
|
-
let new_doc = this._get_blank_doc("
|
|
352
|
+
let new_doc = this._get_blank_doc("system_setting");
|
|
297
353
|
new_doc["data"] = {
|
|
298
354
|
name: name,
|
|
299
355
|
...new_val,
|
|
@@ -641,18 +697,35 @@ export class BeanBagDB {
|
|
|
641
697
|
}
|
|
642
698
|
}
|
|
643
699
|
|
|
700
|
+
/**
|
|
701
|
+
* To load a plugin in the current BeanBagDB instance.
|
|
702
|
+
* Plug_module has to be loaded manually first. It must export an object containing fields: `actions` and `schema`.
|
|
703
|
+
* `actions` is an object of methods which can be called after loading the plugin.
|
|
704
|
+
* `schema` is an array of JSON schemas that are required by the plugin. Every time a plugin is loaded, this list is schemas is verified. New updates are added automatically to the database and logged
|
|
705
|
+
* methods inside actions must be async and must have at least one parameter : `db_instance` which is assumed to be the current instance of the BeanBagDB object itself. They ideally must also return some value.
|
|
706
|
+
* @param {string} plugin_name
|
|
707
|
+
* @param {object} plugin_module
|
|
708
|
+
*/
|
|
644
709
|
async load_plugin(plugin_name, plugin_module) {
|
|
645
710
|
this._check_ready_to_use();
|
|
646
711
|
this.plugins[plugin_name] = {};
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
712
|
+
//console.log(plugin_module)
|
|
713
|
+
if(plugin_module.actions){
|
|
714
|
+
for (let func_name in plugin_module.actions) {
|
|
715
|
+
if (typeof plugin_module.actions[func_name] == "function") {
|
|
716
|
+
this.plugins[plugin_name][func_name] = plugin_module.actions[func_name].bind(null,this)
|
|
717
|
+
}
|
|
650
718
|
}
|
|
651
719
|
}
|
|
652
|
-
|
|
653
|
-
if
|
|
654
|
-
await this.
|
|
720
|
+
|
|
721
|
+
if(plugin_module.schemas){
|
|
722
|
+
await this._upgrade_schema_in_bulk(plugin_module.schemas,true,`Updating ${plugin_name} plugin schemas`)
|
|
655
723
|
}
|
|
724
|
+
|
|
725
|
+
// Check if the plugin has an on_load method and call it
|
|
726
|
+
// if (typeof this.plugins[plugin_name].on_load === "function") {
|
|
727
|
+
// await this.plugins[plugin_name].on_load();
|
|
728
|
+
// }
|
|
656
729
|
}
|
|
657
730
|
|
|
658
731
|
///////////////////////////////////////////////////////////
|
|
@@ -772,6 +845,65 @@ _check_nodes_edge(node1Rule, node2Rule, schema1, schema2) {
|
|
|
772
845
|
//////////////// Internal methods ////////////////////////
|
|
773
846
|
//////////////////////////////////////////////////////////
|
|
774
847
|
|
|
848
|
+
|
|
849
|
+
async _upgrade_schema_in_bulk(schemas,log_upgrade=false,log_message="Schema Upgrade in bulk"){
|
|
850
|
+
// TODO add a check to now allow default system schema to be updated from this method
|
|
851
|
+
|
|
852
|
+
let steps = ["schema update started"]
|
|
853
|
+
let update_was_required = false
|
|
854
|
+
for (let index = 0; index < schemas.length; index++) {
|
|
855
|
+
const schema_name = schemas[index]["name"];
|
|
856
|
+
const schema_data = schemas[index]
|
|
857
|
+
steps.push(`checking.${schema_name}`)
|
|
858
|
+
try {
|
|
859
|
+
let schema1 = await this.get("schema",{name:schema_name})
|
|
860
|
+
if (schema1["data"]["version"] != schema_data.version) {
|
|
861
|
+
steps.push(`old.${schema_name}.v.${schema1["data"]["version"]}`);
|
|
862
|
+
let full_doc = await this.db_api.get(schema1["_id"]);
|
|
863
|
+
full_doc["data"] = { ...schema_data };
|
|
864
|
+
full_doc["meta"]["updated_on"] = this.util_get_now_unix_timestamp();
|
|
865
|
+
console.log(full_doc)
|
|
866
|
+
await this.db_api.update(full_doc);
|
|
867
|
+
steps.push(`new.${schema_name}.v=${schema_data.version}`);
|
|
868
|
+
update_was_required = update_was_required || true
|
|
869
|
+
}else{
|
|
870
|
+
steps.push(`${schema_name}.v.${schema1["data"]["version"]}=latest`)
|
|
871
|
+
}
|
|
872
|
+
} catch (error) {
|
|
873
|
+
// console.log(error);
|
|
874
|
+
if (error instanceof DocNotFoundError) {
|
|
875
|
+
// inserting new schema doc
|
|
876
|
+
let system_schema = sys_sch.default_app.schemas[0]["schema"]
|
|
877
|
+
let new_schema_doc = this._get_blank_schema_doc(
|
|
878
|
+
"schema",
|
|
879
|
+
system_schema,
|
|
880
|
+
schema_data
|
|
881
|
+
);
|
|
882
|
+
await this.db_api.insert(new_schema_doc);
|
|
883
|
+
|
|
884
|
+
steps.push(`init.${schema_name}.v=${schema_data.version}`);
|
|
885
|
+
update_was_required = update_was_required || true
|
|
886
|
+
}else{
|
|
887
|
+
steps.push(`${schema_name}.error.message : ${error.message} `);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
// console.log(JSON.stringify(steps))
|
|
892
|
+
// console.log(update_was_required)
|
|
893
|
+
if (update_was_required && log_upgrade){
|
|
894
|
+
// log it if asked
|
|
895
|
+
try {
|
|
896
|
+
let new_log_doc = this._get_blank_doc("system_log")
|
|
897
|
+
new_log_doc.data = {text:log_message,data:{steps},time:this.util_get_now_unix_timestamp()}
|
|
898
|
+
await this.db_api.insert(new_log_doc);
|
|
899
|
+
} catch (error) {
|
|
900
|
+
console.log(error)
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
}
|
|
904
|
+
return {update_was_required,logs:steps}
|
|
905
|
+
}
|
|
906
|
+
|
|
775
907
|
/**
|
|
776
908
|
* Retrieves the current version of the system by summing up the version numbers
|
|
777
909
|
* of all system-defined schemas.
|
|
@@ -783,10 +915,10 @@ _check_nodes_edge(node1Rule, node2Rule, schema1, schema2) {
|
|
|
783
915
|
*/
|
|
784
916
|
_get_current_version() {
|
|
785
917
|
// current version is the sum of versions of all system defined schemas
|
|
786
|
-
let sum =
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
})
|
|
918
|
+
let sum = 0
|
|
919
|
+
// sys_sch.schema_schema.version;
|
|
920
|
+
sys_sch.default_app.schemas.map((item) => {sum = sum + item.version})
|
|
921
|
+
sys_sch.default_app.records.map((item) => {sum = sum + item.version})
|
|
790
922
|
if (sum == NaN) {
|
|
791
923
|
throw Error("Error in system schema version numbers");
|
|
792
924
|
}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
1
|
const commands = {
|
|
5
2
|
new: {
|
|
6
3
|
parse: async (instance,parts) => {
|
|
@@ -187,7 +184,8 @@ const parse_and_run = async(instance, text) => {
|
|
|
187
184
|
let command_result = await run(instance,command)
|
|
188
185
|
return command_result
|
|
189
186
|
}
|
|
187
|
+
// const schemas = []
|
|
190
188
|
|
|
191
189
|
export const text_command = {
|
|
192
|
-
parse,run,parse_and_run
|
|
190
|
+
actions: {parse,run,parse_and_run}
|
|
193
191
|
};
|
package/src/system_schema.js
CHANGED
|
@@ -1,267 +1,326 @@
|
|
|
1
|
-
export const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
system_generated:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
1
|
+
export const default_app = {
|
|
2
|
+
meta :{
|
|
3
|
+
name:"beanbagdb_system",
|
|
4
|
+
description:"This is the default system app required for proper functioning of the database"
|
|
5
|
+
},
|
|
6
|
+
schemas:[
|
|
7
|
+
{
|
|
8
|
+
name: "schema",
|
|
9
|
+
description:"Meta-schema or the schema for defining other schemas",
|
|
10
|
+
system_generated:true,
|
|
11
|
+
version:0.80,
|
|
12
|
+
schema: {
|
|
13
|
+
type: "object",
|
|
14
|
+
additionalProperties: false,
|
|
15
|
+
properties: {
|
|
16
|
+
system_generated:{
|
|
17
|
+
title:"System generated schema",
|
|
18
|
+
type:"boolean",
|
|
19
|
+
default:false
|
|
20
|
+
},
|
|
21
|
+
version: {
|
|
22
|
+
type: "number",
|
|
23
|
+
title:"Version",
|
|
24
|
+
minimum: 0,
|
|
25
|
+
default: 1,
|
|
26
|
+
description:"This is an optional field.To be used primarily for system schemas"
|
|
27
|
+
},
|
|
28
|
+
name: {
|
|
29
|
+
type: "string",
|
|
30
|
+
title:"Name",
|
|
31
|
+
minLength: 4,
|
|
32
|
+
maxLength: 50,
|
|
33
|
+
pattern: "^[a-zA-Z][a-zA-Z0-9_]*$",
|
|
34
|
+
description:"This is the name of the schema.It cannot be changed later"
|
|
35
|
+
},
|
|
36
|
+
description:{
|
|
37
|
+
type:"string",
|
|
38
|
+
title:"About",
|
|
39
|
+
minLength:0,
|
|
40
|
+
maxLength:1000,
|
|
41
|
+
description:"A small description of what data in this schema stores."
|
|
42
|
+
},
|
|
43
|
+
schema: {
|
|
44
|
+
type: "object",
|
|
45
|
+
title:"JSON Schema specification",
|
|
46
|
+
additionalProperties: true,
|
|
47
|
+
minProperties: 1,
|
|
48
|
+
maxProperties: 50,
|
|
49
|
+
description:"This must be a valid JSON Schema which will be used to validate documents created with this schema.See this https://tour.json-schema.org/",
|
|
50
|
+
},
|
|
51
|
+
settings: {
|
|
52
|
+
type: "object",
|
|
53
|
+
title:"Additional Settings",
|
|
54
|
+
additionalProperties: true,
|
|
55
|
+
properties: {
|
|
56
|
+
primary_keys: {
|
|
57
|
+
title:"Primary key",
|
|
58
|
+
type: "array",
|
|
59
|
+
default: [],
|
|
60
|
+
items: {
|
|
61
|
+
type: "string",
|
|
62
|
+
},
|
|
63
|
+
maxItems: 10,
|
|
64
|
+
description:"Fields that makes each document unique in the schema.Leave it blank if you do not need it. You can still be able to distinguish documents using the link field and the document id."
|
|
65
|
+
},
|
|
66
|
+
non_editable_fields: {
|
|
67
|
+
type: "array",
|
|
68
|
+
title:"Non editable fields",
|
|
69
|
+
default: [],
|
|
70
|
+
items: {
|
|
71
|
+
type: "string",
|
|
72
|
+
},
|
|
73
|
+
maxItems: 50,
|
|
74
|
+
minItems:0,
|
|
75
|
+
description:"The list of fields whose values are added when the document is created but cannot be edited later in future."
|
|
76
|
+
},
|
|
77
|
+
encrypted_fields: {
|
|
78
|
+
type: "array",
|
|
79
|
+
title:"List of fields encrypted",
|
|
80
|
+
default: [],
|
|
81
|
+
items: {
|
|
82
|
+
type: "string",
|
|
83
|
+
},
|
|
84
|
+
maxItems: 50,
|
|
85
|
+
description:"Once set, all the data in this field will be encrypted before storing it in the database. Encryption key must be provided during the time of BeanBagDB initialization and must be managed by the user as it is NOT stored in the database"
|
|
86
|
+
},
|
|
87
|
+
display_fields: {
|
|
88
|
+
type: "array",
|
|
89
|
+
title:"List of fields to show in short view",
|
|
90
|
+
default: [],
|
|
91
|
+
items: {
|
|
92
|
+
type: "string",
|
|
93
|
+
},
|
|
94
|
+
maxItems: 50,
|
|
95
|
+
description:"These fields will be used when a record is displayed in short"
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
required :["primary_keys","non_editable_fields","encrypted_fields"]
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
required: ["name","version","description","schema", "settings"],
|
|
26
102
|
},
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
103
|
+
settings: {
|
|
104
|
+
primary_keys: ["name"],
|
|
105
|
+
non_editable_fields:[],
|
|
106
|
+
encrypted_fields:[],
|
|
107
|
+
display_fields:["name","version","description"]
|
|
32
108
|
},
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
system_generated:true,
|
|
112
|
+
version:0.60,
|
|
113
|
+
description:"To store user defined key. this can include anything like API tokens etc. There is a special method to fetch this. The values are encrypted",
|
|
114
|
+
name: "system_key",
|
|
33
115
|
schema: {
|
|
34
116
|
type: "object",
|
|
35
117
|
additionalProperties: true,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
118
|
+
required:["name","value"],
|
|
119
|
+
properties: {
|
|
120
|
+
name: {
|
|
121
|
+
type: "string",
|
|
122
|
+
minLength: 5,
|
|
123
|
+
maxLength: 50,
|
|
124
|
+
pattern: "^[a-zA-Z][a-zA-Z0-9_]*$",
|
|
125
|
+
},
|
|
126
|
+
value: {
|
|
127
|
+
type: "string",
|
|
128
|
+
minLength: 5,
|
|
129
|
+
maxLength: 5000,
|
|
130
|
+
pattern: "^[^\n\r]*$",
|
|
131
|
+
description:"Must be a single line string"
|
|
132
|
+
},
|
|
133
|
+
note: {
|
|
134
|
+
type: "string",
|
|
135
|
+
minLength: 1,
|
|
136
|
+
maxLength: 5000,
|
|
137
|
+
},
|
|
138
|
+
},
|
|
39
139
|
},
|
|
40
140
|
settings: {
|
|
141
|
+
primary_keys: ["name"],
|
|
142
|
+
encrypted_fields:["value"],
|
|
143
|
+
non_editable_fields:[]
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
version:0.60,
|
|
148
|
+
system_generated:true,
|
|
149
|
+
description:"The system relies on these settings for proper functioning or enabling optional features.",
|
|
150
|
+
name: "system_setting",
|
|
151
|
+
schema: {
|
|
152
|
+
required:["name","value"],
|
|
41
153
|
type: "object",
|
|
42
154
|
additionalProperties: true,
|
|
43
155
|
properties: {
|
|
44
|
-
|
|
45
|
-
type: "
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
},
|
|
50
|
-
maxItems: 10,
|
|
51
|
-
description:"Fields that makes each document unique in the schema.Leave it blank if you do not need it. You can still be able to distinguish documents using the link field and the document id."
|
|
156
|
+
name: {
|
|
157
|
+
type: "string",
|
|
158
|
+
minLength: 5,
|
|
159
|
+
maxLength: 1000,
|
|
160
|
+
pattern: "^[a-zA-Z][a-zA-Z0-9_]*$",
|
|
52
161
|
},
|
|
53
|
-
|
|
54
|
-
type: "array"
|
|
55
|
-
default: [],
|
|
56
|
-
items: {
|
|
57
|
-
type: "string",
|
|
58
|
-
},
|
|
59
|
-
maxItems: 50,
|
|
60
|
-
minItems:0,
|
|
61
|
-
description:"The list of fields whose values are added when the document is created but cannot be edited later in future."
|
|
162
|
+
value: {
|
|
163
|
+
type: ["string", "number", "boolean", "array"]
|
|
62
164
|
},
|
|
63
|
-
|
|
64
|
-
type:
|
|
65
|
-
default:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
},
|
|
69
|
-
maxItems: 50,
|
|
70
|
-
description:"Once set, all the data in this field will be encrypted before storing it in the database. Encryption key must be provided during the time of BeanBagDB initialization and must be managed by the user as it is NOT stored in the database"
|
|
165
|
+
on_update_array:{
|
|
166
|
+
type:"string",
|
|
167
|
+
default:"replace",
|
|
168
|
+
description:"Special operation only for updating Arrays. Either replace it or append new elements to it. Cannot be edited",
|
|
169
|
+
enum:["replace","append"],
|
|
71
170
|
}
|
|
72
171
|
},
|
|
73
|
-
required :["primary_keys","non_editable_fields","encrypted_fields"]
|
|
74
172
|
},
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
primary_keys: ["name"],
|
|
80
|
-
non_editable_fields:[],
|
|
81
|
-
encrypted_fields:[]
|
|
82
|
-
},
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
export const system_schemas = {
|
|
86
|
-
keys: {
|
|
87
|
-
system_generated:true,
|
|
88
|
-
version:0.53,
|
|
89
|
-
description:"To store user defined key. this can include anything like API tokens etc. There is a special method to fetch this. The values are encrypted",
|
|
90
|
-
name: "system_key",
|
|
91
|
-
schema: {
|
|
92
|
-
type: "object",
|
|
93
|
-
additionalProperties: true,
|
|
94
|
-
required:["name","value"],
|
|
95
|
-
properties: {
|
|
96
|
-
name: {
|
|
97
|
-
type: "string",
|
|
98
|
-
minLength: 5,
|
|
99
|
-
maxLength: 50,
|
|
100
|
-
pattern: "^[a-zA-Z][a-zA-Z0-9_]*$",
|
|
101
|
-
},
|
|
102
|
-
value: {
|
|
103
|
-
type: "string",
|
|
104
|
-
minLength: 5,
|
|
105
|
-
maxLength: 5000,
|
|
106
|
-
pattern: "^[^\n\r]*$",
|
|
107
|
-
description:"Must be a single line string"
|
|
108
|
-
},
|
|
109
|
-
note: {
|
|
110
|
-
type: "string",
|
|
111
|
-
minLength: 1,
|
|
112
|
-
maxLength: 5000,
|
|
113
|
-
},
|
|
173
|
+
settings: {
|
|
174
|
+
primary_keys: ["name"],
|
|
175
|
+
non_editable_fields: ["name"],
|
|
176
|
+
encrypted_fields:[]
|
|
114
177
|
},
|
|
115
178
|
},
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
179
|
+
{
|
|
180
|
+
name:"system_edge_constraint",
|
|
181
|
+
system_generated:true,
|
|
182
|
+
version:0.50,
|
|
183
|
+
description: "To define edge constraints for simple directed graph of records.",
|
|
184
|
+
schema:{
|
|
185
|
+
type: "object",
|
|
186
|
+
additionalProperties: true,
|
|
187
|
+
required:["node1","node2","edge_type"],
|
|
188
|
+
properties: {
|
|
189
|
+
node1: {
|
|
190
|
+
type: "string",
|
|
191
|
+
minLength: 1,
|
|
192
|
+
maxLength: 500,
|
|
193
|
+
pattern: "^(\\*|(\\*-[a-zA-Z0-9_-]+)(,[a-zA-Z0-9_-]+)*|[a-zA-Z0-9_-]+(,[a-zA-Z0-9_-]+)*)$"
|
|
194
|
+
},
|
|
195
|
+
node2: {
|
|
196
|
+
type: "string",
|
|
197
|
+
minLength: 1,
|
|
198
|
+
maxLength: 500,
|
|
199
|
+
pattern: "^(\\*|(\\*-[a-zA-Z0-9_-]+)(,[a-zA-Z0-9_-]+)*|[a-zA-Z0-9_-]+(,[a-zA-Z0-9_-]+)*)$"
|
|
200
|
+
},
|
|
201
|
+
name:{
|
|
202
|
+
type: "string",
|
|
203
|
+
minLength: 1,
|
|
204
|
+
maxLength: 500,
|
|
205
|
+
pattern: "^[a-zA-Z][a-zA-Z0-9_]*$",
|
|
206
|
+
},
|
|
207
|
+
label:{
|
|
208
|
+
type: "string",
|
|
209
|
+
maxLength: 500,
|
|
210
|
+
},
|
|
211
|
+
note:{
|
|
212
|
+
type: "string",
|
|
213
|
+
maxLength: 5000,
|
|
214
|
+
},
|
|
215
|
+
max_from_node1:{
|
|
216
|
+
type:"number",
|
|
217
|
+
default: -1,
|
|
218
|
+
},
|
|
219
|
+
max_to_node2:{
|
|
220
|
+
type:"number",
|
|
221
|
+
default: -1,
|
|
222
|
+
}
|
|
146
223
|
}
|
|
147
224
|
},
|
|
225
|
+
settings: {
|
|
226
|
+
primary_keys: ["name"],
|
|
227
|
+
non_editable_fields:["name"],
|
|
228
|
+
encrypted_fields:[]
|
|
229
|
+
},
|
|
148
230
|
},
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
maxLength: 500,
|
|
169
|
-
pattern: "^(\\*|(\\*-[a-zA-Z0-9_-]+)(,[a-zA-Z0-9_-]+)*|[a-zA-Z0-9_-]+(,[a-zA-Z0-9_-]+)*)$"
|
|
170
|
-
},
|
|
171
|
-
node2: {
|
|
172
|
-
type: "string",
|
|
173
|
-
minLength: 1,
|
|
174
|
-
maxLength: 500,
|
|
175
|
-
pattern: "^(\\*|(\\*-[a-zA-Z0-9_-]+)(,[a-zA-Z0-9_-]+)*|[a-zA-Z0-9_-]+(,[a-zA-Z0-9_-]+)*)$"
|
|
176
|
-
},
|
|
177
|
-
name:{
|
|
178
|
-
type: "string",
|
|
179
|
-
minLength: 1,
|
|
180
|
-
maxLength: 500,
|
|
181
|
-
pattern: "^[a-zA-Z][a-zA-Z0-9_]*$",
|
|
182
|
-
},
|
|
183
|
-
label:{
|
|
184
|
-
type: "string",
|
|
185
|
-
maxLength: 500,
|
|
186
|
-
},
|
|
187
|
-
note:{
|
|
188
|
-
type: "string",
|
|
189
|
-
maxLength: 5000,
|
|
190
|
-
},
|
|
191
|
-
max_from_node1:{
|
|
192
|
-
type:"number",
|
|
193
|
-
default: -1,
|
|
194
|
-
},
|
|
195
|
-
max_to_node2:{
|
|
196
|
-
type:"number",
|
|
197
|
-
default: -1,
|
|
231
|
+
{
|
|
232
|
+
name:"system_edge",
|
|
233
|
+
system_generated:true,
|
|
234
|
+
version:0.50,
|
|
235
|
+
description: "To define edges in the simple directed graph of records.",
|
|
236
|
+
schema:{
|
|
237
|
+
type: "object",
|
|
238
|
+
additionalProperties: true,
|
|
239
|
+
required:["node1","node2","edge_type"],
|
|
240
|
+
properties: {
|
|
241
|
+
node1: {
|
|
242
|
+
type: "string",
|
|
243
|
+
},
|
|
244
|
+
node2: {
|
|
245
|
+
type: "string",
|
|
246
|
+
},
|
|
247
|
+
edge_name:{
|
|
248
|
+
type: "string",
|
|
249
|
+
}
|
|
198
250
|
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
251
|
+
},
|
|
252
|
+
settings: {
|
|
253
|
+
primary_keys: ["node1","node2","edge_type"],
|
|
254
|
+
non_editable_fields:["edge_type"],
|
|
255
|
+
encrypted_fields:[]
|
|
256
|
+
},
|
|
205
257
|
},
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
258
|
+
{
|
|
259
|
+
name:"system_media",
|
|
260
|
+
system_generated:true,
|
|
261
|
+
version:0.60,
|
|
262
|
+
description: "To store images as Base64",
|
|
263
|
+
schema:{
|
|
264
|
+
type: "object",
|
|
265
|
+
additionalProperties: true,
|
|
266
|
+
required:["imageBase64","caption","source"],
|
|
267
|
+
properties: {
|
|
268
|
+
imageBase64: {
|
|
269
|
+
type: "string",
|
|
270
|
+
"media": {
|
|
271
|
+
"binaryEncoding": "base64"
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
caption: {
|
|
275
|
+
type: "string",
|
|
276
|
+
},
|
|
277
|
+
source:{
|
|
278
|
+
type: "string",
|
|
279
|
+
}
|
|
225
280
|
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
281
|
+
},
|
|
282
|
+
settings: {
|
|
283
|
+
primary_keys: ["caption"],
|
|
284
|
+
non_editable_fields:[],
|
|
285
|
+
encrypted_fields:[]
|
|
286
|
+
},
|
|
232
287
|
},
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
288
|
+
{
|
|
289
|
+
name:"system_log",
|
|
290
|
+
system_generated:true,
|
|
291
|
+
version:0.50,
|
|
292
|
+
description: "To define edges in the simple directed graph of records.",
|
|
293
|
+
schema:{
|
|
294
|
+
type: "object",
|
|
295
|
+
additionalProperties: true,
|
|
296
|
+
required:["text"],
|
|
297
|
+
properties: {
|
|
298
|
+
text: {
|
|
299
|
+
type: "string",
|
|
300
|
+
},
|
|
301
|
+
data: {
|
|
302
|
+
type: "object",
|
|
303
|
+
additionalProperties: true,
|
|
304
|
+
},
|
|
305
|
+
app:{
|
|
306
|
+
type: "string",
|
|
307
|
+
},
|
|
308
|
+
time:{
|
|
309
|
+
type:"string"
|
|
248
310
|
}
|
|
249
|
-
},
|
|
250
|
-
caption: {
|
|
251
|
-
type: "string",
|
|
252
|
-
},
|
|
253
|
-
source:{
|
|
254
|
-
type: "string",
|
|
255
311
|
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
|
|
312
|
+
},
|
|
313
|
+
settings: {
|
|
314
|
+
primary_keys: [],
|
|
315
|
+
non_editable_fields:[],
|
|
316
|
+
encrypted_fields:[]
|
|
317
|
+
},
|
|
318
|
+
}
|
|
319
|
+
],
|
|
320
|
+
records:[]
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
|
|
265
324
|
|
|
266
325
|
// this is not stored in the DB. only for validating the metadata during doc update
|
|
267
326
|
export const editable_metadata_schema = {
|
package/test/operations.test.js
CHANGED
|
@@ -1656,7 +1656,7 @@ describe("Doc search tests", async () => {
|
|
|
1656
1656
|
it('all docs', async () => {
|
|
1657
1657
|
try {
|
|
1658
1658
|
let udata = await database3.search({selector:{}})
|
|
1659
|
-
assert(udata.docs.length==
|
|
1659
|
+
assert(udata.docs.length==12)
|
|
1660
1660
|
} catch (error) {
|
|
1661
1661
|
//console.log(error)
|
|
1662
1662
|
throw error
|
|
@@ -1676,7 +1676,7 @@ describe("Doc search tests", async () => {
|
|
|
1676
1676
|
it('read docs 2', async () => {
|
|
1677
1677
|
try {
|
|
1678
1678
|
let udata = await database3.search({selector:{"schema":"schema"}})
|
|
1679
|
-
assert(udata.docs.length==
|
|
1679
|
+
assert(udata.docs.length==8) // schema,book,setting,key,edge,edge_constraints
|
|
1680
1680
|
} catch (error) {
|
|
1681
1681
|
//console.log(error)
|
|
1682
1682
|
throw error
|