UNPKG

biz9-data

Version:

BiZ9-Data Package is an object-relational mapper (ORM) that lets you build a clean, portable, reusable, and high-level data access layer with Node.js for data driven applications. The package consists of create, read, update and destroy (CRUD) methods to

528 lines (527 loc) 22.9 kB
/* Copyright 2016 Certified CoderZ Author: Brandon Poole Sr. (biz9framework@gmail.com) License GNU General Public License v3.0 Description: BiZ9 Framework: Data - Adapter */ const async = require('async'); const {Mongo}= require("./mongo.js"); const {Cache} = require('./redis.js'); const {Data_Logic,Data_Title,Data_Field,Data_Type}=require("/home/think1/www/doqbox/biz9-framework/biz9-data-logic/source"); const {Log,Str,Num,Obj}=require("/home/think1/www/doqbox/biz9-framework/biz9-utility/source"); class Adapter { static get_database=(data_config,option)=>{ return new Promise((callback) => { async function main() { const [error,biz_data] = await Mongo.get(data_config); biz_data.data_config=data_config; callback([error,biz_data]); } main(); }); } static delete_database=(database,option)=>{ return new Promise((callback) => { async function main() { const [error,biz_data] = await Mongo.delete(database); biz_data.data_config=data_config; callback([error,biz_data]); } main(); }); } static check_database=(database,option)=>{ return Mongo.check(database,option); } static post_item_list=(database,cache,item_data_list,option)=>{ return new Promise((callback) => { let error = null; let item_data_new_list=[]; async.series([ function(call){ async.forEachOf(item_data_list,(item,key,go)=>{ for(property in item[key]){ if(property!=Data_Field.ID&&property!=Data_Field.TABLE){ if(!item[key][property]){ delete item[key][property]; } } } go(); }, error => { if(error){ error=error; } call(); }); }, async function(call){ async.forEachOf(item_data_list,(item,key,go)=>{ if(item){ async function main() { const [error,data] = await Mongo.post_item(database,item.table,item); if(data){ item.id=data.id; Cache.delete_value(cache,Adapter.get_cache_item_attr_list_key(item.table,data.id)).then(([error,data]) => { go(); }).catch(error => { Log.error("Data-Adapter-Update-Item-List-2",error); callback([error,null]); }); }else{ go(); } }; main(); }else{ go(); } }, error => { if(error){ error=error; } }); }, function(call){ for(const item of item_data_list) { item.source=Data_Title.SOURCE_DATABASE; delete item._id; item_data_new_list.push(item); } call(); }, ]).then(result=>{ callback([error,item_data_new_list]); }).catch(error => { Log.error("Data-Adapter-Update-Item-List-5",error); callback([error,[]]); }); }); } static post_item=(database,cache,table,item_data,option) => { return new Promise((callback) => { let error = null; async.series([ async function(call){ const [biz_error,biz_data] = await Mongo.post_item(database,table,item_data,option); }, function(call){ if(item_data.id){ item_data.source=Data_Title.SOURCE_DATABASE; } call(); }, async function(call){ const [error,data] = await Cache.delete_value(cache,Adapter.get_cache_item_attr_list_key(item_data.table,item_data.id)); }, ]).then(result => { callback([error,item_data]); }).catch(error => { Log.error("Data-Adapter-Update-Item-Adapter-2",error); callback([error,[]]); }); }); } static get_item_list = (database,cache,table,filter,sort_by,page_current,page_size,option) => { return new Promise((callback) => { let error = null; let item_id_list = []; let item_data_list = []; let item_count = 0; let page_count = 0; async.series([ async function(call) { if(!page_current){ page_current=1; } const [error,total_count,data_list] = await Mongo.get_id_list(database,table,filter,sort_by,page_current,page_size,option); if(data_list.length>0){ item_count=total_count; item_id_list=data_list; } }, async function(call) { if(item_id_list.length>0){ for(const item of item_id_list) { const [biz_error,biz_data] = await Adapter.get_item_cache_db(database,cache,table,item.id,option); if(biz_data){ delete biz_data['_id']; item_data_list.push(biz_data); } } } }, //distinct function(call){ if(option.distinct){ item_data_list = item_data_list.filter((obj, index, self) => index === self.findIndex((t) => t[option.distinct.field] === obj[option.distinct.field]) ); let distinct_sort_by = option.distinct.sort_by ? option.distinct.sort_by : Data_Type.SORT_BY_ASC; item_data_list = Obj.sort_list_by_field(item_data_list,option.distinct.field,distinct_sort_by); item_count=item_data_list.length; call(); }else{ call(); } }, function(call) { page_count = !Str.check_is_null(Math.round(item_count/page_size+1)) ? Math.round(item_count/page_size+1) : 0; page_count = page_count == "Infinity" || Str.check_is_null(page_count) ? 1 : page_count; item_count = Str.check_is_null(item_count) ? "0" : item_count; page_size = Str.check_is_null(page_size) ? "0" : page_size; call(); } ]).then(result => { callback([error,item_data_list,item_count,page_count]); }).catch(error => { Log.error("Get-Item-List-Adapter-3",error); callback([error,[]]); }); }); } static get_item = (database,cache,table,id,option) => { return new Promise((callback) => { let error = null; if(!option){ option = {}; } let data = Data_Logic.get(table,id); option = option ?? {}; async.series([ async function(call) { if(!option.id_field){ const [biz_error,biz_data] = await Adapter.get_item_cache_db(database,cache,data.table,data.id,option); if(biz_data.id){ data = biz_data; }else{ data = Data_Logic.get_not_found(table,id); } }else{ let query_field={}; query_field[option.id_field] = id; let page_current=1; let page_size=0; const [biz_error,biz_data] = await Adapter.get_item_list(database,cache,table,query_field,{},page_current,page_size,option); if(biz_data.length>0){ delete biz_data['_id']; data = biz_data[0]; }else{ data = Data_Logic.get_not_found(table,id); data.id_field = option.id_field ? option.id_field : Data_Field.ID; } } }, ]).then(result => { callback([error,data]); }).catch(error => { Log.error("Adapter-Get-Item-Adapter-5",error); callback([error,null]); }); }); } static post_cache_item = (cache,table,id,item_data) => { return new Promise((callback) => { let error = null; let cache_string_str = ''; let prop_list = []; async.series([ function(call) { for (const prop in item_data) { if(prop != Data_Field.SOURCE){ prop_list.push({title:prop,value:item_data[prop]}); } } call(); }, async function(call) { for(const item of prop_list) { cache_string_str=cache_string_str+item.title+','; await Cache.post_value(cache,Adapter.get_cache_item_attr_key(table,id,item.title),item.value); } }, async function(call) { const [error,data] = await Cache.post_value(cache,Adapter.get_cache_item_attr_list_key(table,id),cache_string_str); }, ]).then(result => { callback([error,item_data]); }).catch(error => { Log.error("Data-Adapter-Set-Cache-Item-2",error); callback([error,null]); }); }); } static delete_item = (database,cache,table,id,option) => { return new Promise((callback) => { let error = null; let data = Data_Logic.get(table,id); data[Data_Type.RESULT_OK_DELETE] = false; data[Data_Type.RESULT_OK_DELETE_CACHE] = false; data[Data_Type.RESULT_OK_DELETE_DATABASE] = false; async.series([ async function(call) { const [biz_error,biz_data] = await Adapter.delete_item_cache_db(database,cache,table,id); if(biz_error){ error = biz_error; }else{ data = biz_data; data[Data_Type.RESULT_OK_DELETE] = true; data[Data_Type.RESULT_OK_DELETE_CACHE] = true; data[Data_Type.RESULT_OK_DELETE_DATABASE] = true; } }, ]).then(result => { callback([error,data]); }).catch(error => { Log.error("Adapter-Get-Item-Adapter-4",error); callback([error,null]); }); }); } static get_item_cache_db = (database,cache,table,id,option) => { return new Promise((callback) => { let error = null; let cache_key_list = []; let item_data = Data_Logic.get(table,id); let field_list = []; let hide_field_list = []; option = option ? option : {}; async.series([ //cache_field_list async function(call) { const [error,data] = await Cache.get_value(cache,Adapter.get_cache_item_attr_list_key(table,id)); if(data){ cache_key_list=data.split(','); } }, async function(call) { if(cache_key_list.length==0){ //db const [error,data] = await Mongo.get_item(database,table,id); if(data){ delete data['_id']; item_data = data; const [error,data2] = await Adapter.post_cache_item(cache,table,id,data); item_data[Data_Type.SOURCE] = Data_Title.SOURCE_DATABASE; }else{ item_data = Data_Logic.get_not_found(table,id); } }else{ //cache for(const item of cache_key_list) { if(item){ const [error,val] = await Cache.get_value(cache,Adapter.get_cache_item_attr_key(table,id,item)); if(val){ item_data[item] = val; }else{ item_data[item] = null; } } } item_data[Data_Field.SOURCE] = Data_Title.SOURCE_CACHE; } }, async function(call) { if(option.field){ for(const field in option.field) { let new_item = {}; new_item[field] = option.field[field]; if(new_item[field]){ field_list.push({field:field,value:new_item[field]}); }else{ hide_field_list.push({field:field,value:new_item[field]}); } } } }, async function(call) { if(field_list.length>0){ let field_data = {}; for(const item of field_list) { if(item_data[item.field]){ field_data[item.field] = item_data[item.field] }else{ field_data[item.field] = ''; } } item_data = field_data; } }, async function(call) { if(hide_field_list.length>0){ let field_data = {}; for(const item of hide_field_list) { delete item_data[item.field]; } } }, ]).then(result => { callback([error,item_data]); }).catch(error => { Log.error("Data-Adapter-Get-Item-Cache-DB",error); callback([error,null]); }); }); } static delete_item_list = (database,cache,table,filter,option) => { return new Promise((callback) => { let error = null; let item_id_list = []; let item_count = 0; let item_data_new_list = []; option = option ? option : {}; async.series([ async function(call) { const [error,total_count,data_list] = await Mongo.get_id_list(database,table,filter,{},0,9999,option); item_count=total_count; item_id_list=data_list; }, async function(call){ const [error,data] = await Mongo.delete_item_list(database,table,filter); }, async function(call) { var list = []; for(const item of item_id_list) { const [biz_error,biz_data] = await Adapter.delete_item_cache_db(database,cache,table,item.id); item_data_new_list.push(biz_data); }; }, ]).then(result => { callback([error,item_data_new_list]); }).catch(error => { Log.error("Data-Adapter-Delete-Item-List-Adapter-3",error); callback([error,[]]); }); }); } static delete_item_cache=(database,cache,table,id,option)=>{ return new Promise((callback)=>{ let error = null; let cache_key_list = ''; let cache_string_list = ''; let item_data = Data_Logic.get(table,id); async.series([ async function(call) { const [error,data] = await Cache.get_value(cache,Adapter.get_cache_item_attr_list_key(table,id)); cache_key_list=data; }, async function(call) { if(cache_key_list!=null){ cache_string_list =cache_key_list.split(','); } for(const item of cache_string_list) { if(item){ const [error,val] = await Cache.delete_value(cache,Adapter.get_cache_item_attr_key(table,id,item)); } } }, async function(call){ const [error,data] = await Cache.delete_value(cache,Adapter.get_cache_item_attr_list_key(table,id)); item_data[Data_Type.RESULT_OK_DELETE_CACHE] = true; item_data.cache_item_attr_list = Adapter.get_cache_item_attr_list_key(table,id); }, ]).then(result => { callback([error,item_data]); }).catch(error => { Log.error("Data-Adapter-Delete-Item-Cache-5",error); callback([error,null]); }); }); } static delete_item_cache_db = (database,cache,table,id) => { return new Promise((callback) => { let error = null; let cache_key_list = ''; let cache_string_list = ''; let data = Data_Logic.get(table,id); data[Data_Type.RESULT_OK_DELETE] = false; data[Data_Type.RESULT_OK_DELETE_CACHE] = false; data[Data_Type.RESULT_OK_DELETE_DATABASE] = false; async.series([ async function(call) { const [biz_error,biz_data] = await Cache.get_value(cache,Adapter.get_cache_item_attr_list_key(table,id)); cache_key_list=biz_data; }, async function(call) { if(cache_key_list!=null){ cache_string_list =cache_key_list.split(','); } for(const item of cache_string_list) { if(item){ const [biz_error,val] = await Cache.delete_value(cache,Adapter.get_cache_item_attr_key(table,id,item)); } } }, async function(call){ const [biz_error,biz_data] = await Cache.delete_value(cache,Adapter.get_cache_item_attr_list_key(table,id)); if(!error){ data[Data_Type.RESULT_OK_DELETE_CACHE] = true; } }, async function(call){ const [biz_error,biz_data] = await Mongo.delete_item(database,table,id); data[Data_Type.RESULT_OK_DELETE_COUNT] = biz_data ? biz_data.deletedCount : 0; if(!biz_error){ data[Data_Type.RESULT_OK_DELETE_DATABASE] = true; } }, async function(call){ if(data[Data_Type.RESULT_OK_DELETE_DATABASE] && data[Data_Type.RESULT_OK_DELETE_CACHE]){ data[Data_Type.RESULT_OK_DELETE] = true; } } ]).then(result => { callback([error,data]); }).catch(error => { Log.error("Data-Adapter-Delete-Item-Cache-DB-5",error); callback([error,null]); }); }); } static get_count_item_list = (database,table,filter) => { return new Promise((callback) => { let error = null; let item_data = {}; async.series([ async function(call) { const [error,data] = await Mongo.get_count_item_list(database,table,filter); item_data.count = data; item_data.table = table; item_data.filter = filter; }, ]).then(result => { callback([error,item_data]); }).catch(error => { Log.error("Data-Adapter-Count-Item-List",error); callback([error,null]); }); }); } static post_bulk=(database,cache,table,item_data_list) => { return new Promise((callback) => { let data ={result_OK:false}; async.series([ async function(call){ const [biz_error,biz_data] = await post_bulk_main(database,table,item_data_list); if(biz_data.result_OK){ data = biz_data; } }, ]).then(result => { callback([error,data]); }).catch(error => { Log.error("Data-Adapter-Update-Item-Adapter-END",error); callback([error,[]]); }); }); } static get_cache_item_attr_key = (table,id,key) => { return table + "_" + key + "_" + String(id); } static get_cache_item_attr_list_key = (table,id) => { return table+"_aik_"+String(id); } } module.exports = { Adapter };