UNPKG

schematize

Version:

An encapsulation of 'Sequelize' and 'treble' packages to handle 3 databases using external schema files.

290 lines (257 loc) 9.52 kB
/**************************************************** "schematize" An encapsulation sequelize and treble to manage 3 mySql databases with external schemas. var schematize = require("schematize")(db,schema [,db3]); *****************************************************/ // TODO : add extra control on db & schema arguments var varServer = require("varserver")(); var Path = require("path"); var schemasPath= varServer.get("schematizePath" , { admin:"schemas/admin/", modele:"schemas/modele/", user:"schemas/user/" }); var promiseError = { success:function(){return this;}, done:function(){return this;}, error:function(err){err();return this;}, fail:function(err){err();return this;}, then:function(succ,err){err();return this;} }; function schemabatch(db , schemas , db3, force) { var remain = schemas.length, tables={}, err=false, onsuccess = function(){}, onerror = function(){}, successSchemaEvt = function(name) {return function(e){tables[ name ] = e; remain--; if (!remain) {err ? onerror(tables) : onsuccess(tables);} }}, errorSchemaEvt = function(name) {return function(e){err=true; tables[ name ] = null; remain--; if (!remain) {err ? onerror(tables) : onsuccess(tables);} }}; for(var index=0; index<schemas.length; index++) { schematize(db,schemas[index],db3,force) .success( successSchemaEvt(schemas[index]) ) .error( errorSchemaEvt(schemas[index]) ); } return { success:function(e){onsuccess=e;return this;}, error:function(e){onerror=e;return this;}, then:function(succ,err){onsuccess=succ||onsuccess;onerror=err||onerror;return this;} }; } function schematize(db, schema, db3, force) { var oSchema, oTable, oFields, oFieldsNoHidden, oFieldsKey; var jSchema; var pSchema; // schema file path var onsuccess=function(){}; var onerror=function(){}; // if schema is an array of strings, call 'schemabatch' if (typeof schema =="object" && "length" in schema) return schemabatch(db,schema,db3,force); switch (db){ case "a": case "admin" : db = "admin"; pSchema = Path.join(schemasPath.admin, schema); break; case "m": case "modele" : db = "modele"; pSchema = Path.join(schemasPath.modele, schema) ; break; default : db = "user"; pSchema = Path.join(schemasPath.user, schema); } try { oSchema = require(pSchema); } catch(err){ return promiseError; } jSchema = oSchema(require("./myTypes"))[1]; for(var field in jSchema) { delete jSchema[field].validate; delete jSchema[field].defaultValue; delete jSchema[field].allowNull; delete jSchema[field].unique; jSchema[field].type = jSchema[field].type.valueOf(); if (jSchema[field].hidden) delete jSchema[field]; } oSchema = oSchema(require('sequelize')); oCon = db3?db3.get(db):null; oFields = []; oFieldsNoHidden = []; oFieldsKey = []; for(var field in oSchema[1]) { oFields.push(field); if (oSchema[1][field].primaryKey) oFieldsKey.push(field); if (!oSchema[1][field].hidden) oFieldsNoHidden.push(field); } if (!oFieldsKey.length) { oFieldsKey.push("id"); oFields.push("id"); oFieldsNoHidden.push("id"); } // if no primary key given, "id" default primary key added oTable = oCon?oCon.define.apply( oCon , oSchema ):null; var sentObj={ fields:getFields, schema:function(){return oSchema[1]}, jSchema:function(){return {s:jSchema,k:oFieldsKey};}, table:function(con){if (con) oTable = con.define.apply( con , oSchema );return oTable;}, find:findData, findAll:loadData, update:updateData, destroy:destroyData, create:addData, count:countData } if (db3) { oTable.sync({force:!!force}) .then( function(){ onsuccess(sentObj); }, onerror ); return { success:function(succ){onsuccess=succ;return this;}, error:function(err){onerror=err;return this;}, then:function(succ,err){onsuccess=succ||onsuccess; onerror=err||onerror;return this;} } } else { // no connection given: operation succeded without syncing database return { success:function(succ){succ(sentObj);return this;}, error:function(err){return this;}, then:function(succ,err){succ(sentObj);return this;} } } function getFields(type){ switch(type){ case "nohidden": return oFieldsNoHidden; case "primary": return oFieldsKey; default : return oFields; } } function loadData( Options ) { var onsuccess = function(){}, onerror = function(){}; if (!oTable) return promiseError; Options = Options || {}; if (typeof Options.limit !== "number") Options.limit = 20; oTable.findAll(Options).then( function(result){onsuccess(data2func(result));}, function(e){onerror();} ); return { success:function(e){onsuccess=e;return this;}, error:function(e){onerror=e;return this;}, then:function(success,error){onsuccess=success||onsuccess;onerror=error||onerror;return this;} }; } function countData( Options ) { var onsuccess = function(){}, onerror = function(){}; if (!oTable) return promiseError; oTable.count(Options).then( function(result){onsuccess(result);}, function(e){onerror();} ); return { success:function(e){onsuccess=e;return this;}, error:function(e){onerror=e;return this;}, then:function(success,error){onsuccess=success||onsuccess;onerror=error||onerror;return this;} }; } function updateData(values , where , fields) { var onsuccess = function(){}, onerror = function(){}; if (!oTable) return promiseError; oTable.update(values , where , fields).then( function(result){onsuccess(data2func(result));}, function(){onerror();} ); return { success:function(e){onsuccess=e;return this;}, error:function(e){onerror=e;return this;}, then:function(success,error){onsuccess=success||onsuccess;onerror=error||onerror;return this;} } } function addData(values , fields) { var onsuccess = function(){}, onerror = function(){}; if (!oTable) return promiseError; oTable.create(values , fields).then( function(result){onsuccess(data2func(result));}, function(e){onerror(e);} ); return { success:function(e){onsuccess=e;return this;}, error:function(e){onerror=e;return this;}, then:function(success,error){onsuccess=success||onsuccess;onerror=error||onerror;return this;} } } function destroyData(where) { var onsuccess = function(){}, onerror = function(){}; if (!oTable) return promiseError; oTable.destroy(where).then( function(result){onsuccess(data2func(result));}, function(){onerror();} ); return { success:function(e){onsuccess=e;return this;}, error:function(e){onerror=e;return this;}, then:function(success,error){onsuccess=success||onsuccess;onerror=error||onerror;return this;} } } // receive the result of find or findAll // return a function: // data2func(result)( fields ) is an array // data2func(result)( fields , key ) is an object function data2func(data){ if (!data) return function(){}; if (typeof data.length == "number") return function(fields,key,methods, noHidden){return array2data( data , fields , key , methods, noHidden);} else return function(fields, methods, noHidden){return modele2data( data, fields, methods, noHidden );} } // Options : findAll values + // other possible values: (page, bypage) ==>> (limite,offset) function findData( Options ) { var onsuccess = function(){}, onerror = function(){}; if (!oTable) return promiseError; if (Options && Options.page){ Options.limit = Options.bypage || 20; Options.offset = Options.limit * (Options.page-1); delete Options.bypage; delete Options.page; } oTable.find(Options).then( function(result){onsuccess(data2func(result),result);}, function(err){onerror(null);} ); return { success:function(e){onsuccess=e;return this;}, error:function(e){onerror=e;return this;}, then:function(success,error){onsuccess=success||onsuccess;onerror=error||onerror;return this;} }; } function modele2data(data, fields, methods, noHidden) { var result; if (!data) result = null; // no data else if (typeof fields=="string") { result = data[ fields ]; } else { result = {} fields = fields || (noHidden?oFieldsNoHidden:oFields); fields.forEach(function(field){ if (data[ field ] !== null) result[ field ] = data[ field ];}) if (methods) methods.forEach(function(method){ result[method] = data[ method ].call(data);}) } return result; } // if you give a 'key', you get an {Object} // Without a 'key' you get an [Array] function array2data(data, fields, key, methods, noHidden) { var result = key ? {} : []; data.forEach( function(model){ var value = modele2data(model , fields , methods, noHidden); key ? (((model[key] !== null) && (typeof model[key] !== "undefined")) ? (result[model[key]] = value) : null ) : (result.push( value )); }); return result; } } schematize.config = function( options ){ if (options){ if (options.path){ if (typeof options.path == "string") { schemasPath.admin = options.path + "admin/"; schemasPath.modele = options.path + "modele/"; schemasPath.user = options.path + "user/"; varServer.set("schematizePath" , schemasPath); } else { if (options.path.admin) schemasPath.admin = options.path.admin; if (options.path.modele) schemasPath.modele = options.path.modele; if (options.path.user) schemasPath.user = options.path.user; varServer.set("schematizePath" , schemasPath); } } } return schematize; } module.exports = schematize;