Skip to content

Commit

Permalink
Merge pull request #30 from shubhvjain/main
Browse files Browse the repository at this point in the history
new way to load plugin, new ver release
  • Loading branch information
shubhvjain authored Nov 25, 2024
2 parents c3b8c72 + 41c7f9c commit 2010dd5
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 17 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "beanbagdb",
"version": "0.5.70",
"version": "0.5.71",
"description": "A JS library to introduce a schema layer to a No-SQL local database",
"main": "src/index.js",
"module": "src/index.js",
Expand Down
92 changes: 84 additions & 8 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export class BeanBagDB {
// this works on its own but is usually called by ready automatically if required
// check for schema_scehma : if yes, check if latest and upgrade if required, if no create a new schema doc
try {
let app_data = await this.initialize_app(sys_sch.default_app)
let app_data = await this.initialize_db(sys_sch.default_app)
console.log(app_data)
this.meta.beanbagdb_version_db = this._version;
this.active = true;
Expand All @@ -175,7 +175,7 @@ export class BeanBagDB {

}

async initialize_app(app_data){
async initialize_db(app_data){
// app_data : meta(name,description), schemas[] , default_records:[]
// TODO check if add_data is valid
// calculate the app_version
Expand Down Expand Up @@ -697,18 +697,35 @@ export class BeanBagDB {
}
}

/**
* To load a plugin in the current BeanBagDB instance.
* Plug_module has to be loaded manually first. It must export an object containing fields: `actions` and `schema`.
* `actions` is an object of methods which can be called after loading the plugin.
* `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
* 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.
* @param {string} plugin_name
* @param {object} plugin_module
*/
async load_plugin(plugin_name, plugin_module) {
this._check_ready_to_use();
this.plugins[plugin_name] = {};
for (let func_name in plugin_module) {
if (typeof plugin_module[func_name] == "function") {
this.plugins[plugin_name][func_name] = plugin_module[func_name].bind(null,this)
//console.log(plugin_module)
if(plugin_module.actions){
for (let func_name in plugin_module.actions) {
if (typeof plugin_module.actions[func_name] == "function") {
this.plugins[plugin_name][func_name] = plugin_module.actions[func_name].bind(null,this)
}
}
}
// Check if the plugin has an on_load method and call it
if (typeof this.plugins[plugin_name].on_load === "function") {
await this.plugins[plugin_name].on_load();

if(plugin_module.schemas){
await this._upgrade_schema_in_bulk(plugin_module.schemas,true,`Updating ${plugin_name} plugin schemas`)
}

// Check if the plugin has an on_load method and call it
// if (typeof this.plugins[plugin_name].on_load === "function") {
// await this.plugins[plugin_name].on_load();
// }
}

///////////////////////////////////////////////////////////
Expand Down Expand Up @@ -828,6 +845,65 @@ _check_nodes_edge(node1Rule, node2Rule, schema1, schema2) {
//////////////// Internal methods ////////////////////////
//////////////////////////////////////////////////////////


async _upgrade_schema_in_bulk(schemas,log_upgrade=false,log_message="Schema Upgrade in bulk"){
// TODO add a check to now allow default system schema to be updated from this method

let steps = ["schema update started"]
let update_was_required = false
for (let index = 0; index < schemas.length; index++) {
const schema_name = schemas[index]["name"];
const schema_data = schemas[index]
steps.push(`checking.${schema_name}`)
try {
let schema1 = await this.get("schema",{name:schema_name})
if (schema1["data"]["version"] != schema_data.version) {
steps.push(`old.${schema_name}.v.${schema1["data"]["version"]}`);
let full_doc = await this.db_api.get(schema1["_id"]);
full_doc["data"] = { ...schema_data };
full_doc["meta"]["updated_on"] = this.util_get_now_unix_timestamp();
console.log(full_doc)
await this.db_api.update(full_doc);
steps.push(`new.${schema_name}.v=${schema_data.version}`);
update_was_required = update_was_required || true
}else{
steps.push(`${schema_name}.v.${schema1["data"]["version"]}=latest`)
}
} catch (error) {
// console.log(error);
if (error instanceof DocNotFoundError) {
// inserting new schema doc
let system_schema = sys_sch.default_app.schemas[0]["schema"]
let new_schema_doc = this._get_blank_schema_doc(
"schema",
system_schema,
schema_data
);
await this.db_api.insert(new_schema_doc);

steps.push(`init.${schema_name}.v=${schema_data.version}`);
update_was_required = update_was_required || true
}else{
steps.push(`${schema_name}.error.message : ${error.message} `);
}
}
}
// console.log(JSON.stringify(steps))
// console.log(update_was_required)
if (update_was_required && log_upgrade){
// log it if asked
try {
let new_log_doc = this._get_blank_doc("system_log")
new_log_doc.data = {text:log_message,data:{steps},time:this.util_get_now_unix_timestamp()}
await this.db_api.insert(new_log_doc);
} catch (error) {
console.log(error)
}

}
return {update_was_required,logs:steps}
}

/**
* Retrieves the current version of the system by summing up the version numbers
* of all system-defined schemas.
Expand Down
6 changes: 2 additions & 4 deletions src/plugins/text_command.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@



const commands = {
new: {
parse: async (instance,parts) => {
Expand Down Expand Up @@ -187,7 +184,8 @@ const parse_and_run = async(instance, text) => {
let command_result = await run(instance,command)
return command_result
}
// const schemas = []

export const text_command = {
parse,run,parse_and_run
actions: {parse,run,parse_and_run}
};
28 changes: 24 additions & 4 deletions src/system_schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,46 +8,53 @@ export const default_app = {
name: "schema",
description:"Meta-schema or the schema for defining other schemas",
system_generated:true,
version:0.70,
version:0.80,
schema: {
type: "object",
additionalProperties: false,
properties: {
system_generated:{
title:"System generated schema",
type:"boolean",
default:false
},
version: {
type: "number",
title:"Version",
minimum: 0,
default: 1,
description:"This is an optional field.To be used primarily for system schemas"
},
name: {
type: "string",
title:"Name",
minLength: 4,
maxLength: 50,
pattern: "^[a-zA-Z][a-zA-Z0-9_]*$",
description:"This is the name of the schema.It cannot be changed later"
},
description:{
type:"string",
title:"About",
minLength:0,
maxLength:1000,
description:"A small description of what data in this schema stores."
},
schema: {
type: "object",
title:"JSON Schema specification",
additionalProperties: true,
minProperties: 1,
maxProperties: 50,
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/",
},
settings: {
type: "object",
title:"Additional Settings",
additionalProperties: true,
properties: {
primary_keys: {
title:"Primary key",
type: "array",
default: [],
items: {
Expand All @@ -58,6 +65,7 @@ export const default_app = {
},
non_editable_fields: {
type: "array",
title:"Non editable fields",
default: [],
items: {
type: "string",
Expand All @@ -68,23 +76,35 @@ export const default_app = {
},
encrypted_fields: {
type: "array",
title:"List of fields encrypted",
default: [],
items: {
type: "string",
},
maxItems: 50,
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"
},
display_fields: {
type: "array",
title:"List of fields to show in short view",
default: [],
items: {
type: "string",
},
maxItems: 50,
description:"These fields will be used when a record is displayed in short"
}
},
required :["primary_keys","non_editable_fields","encrypted_fields"]
},
},
required: ["name","description","schema", "settings"],
required: ["name","version","description","schema", "settings"],
},
settings: {
primary_keys: ["name"],
non_editable_fields:[],
encrypted_fields:[]
encrypted_fields:[],
display_fields:["name","version","description"]
},
},
{
Expand Down Expand Up @@ -295,7 +315,7 @@ export const default_app = {
non_editable_fields:[],
encrypted_fields:[]
},
},
}
],
records:[]
}
Expand Down

0 comments on commit 2010dd5

Please sign in to comment.