/**
* ### Модуль сборки *.js по описанию метаданных
* © Evgeniy Malyarov http://www.oknosoft.ru 2014-2016
* @module metadata-prebuild
*/
"use strict";
var through = require('through2');
var path = require('path');
var gutil = require('gulp-util');
var PluginError = gutil.PluginError;
var File = gutil.File;
module.exports = function (package_data) {
if (!package_data) {
throw new PluginError('metadata-prebuild', 'Missing "package_data" option for metadata-prebuild');
}
var firstFile = null;
// подключим метадату
var $p = require('../../lib/metadata.core.js');
// установим параметры
$p.on("settings", function (prm) {
// разделитель для localStorage
prm.local_storage_prefix = package_data.config.prefix;
// по умолчанию, обращаемся к зоне 0
prm.zone = package_data.config.zone;
// расположение couchdb
prm.couch_path = package_data.config.couchdb;
// логин гостевого пользователя couchdb
prm.guest_name = "guest";
// пароль гостевого пользователя couchdb
prm.guest_pwd = "meta";
});
$p.eve.init();
function create_modules(_m){
var name,
text = "$p.md.create_managers=function(){\n",
categoties = {
cch: {mgr: "ChartOfCharacteristicManager", obj: "CatObj"},
cacc: {mgr: "ChartOfAccountManager", obj: "CatObj"},
cat: {mgr: "CatManager", obj: "CatObj"},
bp: {mgr: "BusinessProcessObj", obj: "BusinessProcessObj"},
tsk: {mgr: "TaskManager", obj: "TaskObj"},
doc: {mgr: "DocManager", obj: "DocObj"},
ireg: {mgr: "InfoRegManager", obj: "RegisterRow"},
areg: {mgr: "AccumRegManager", obj: "RegisterRow"},
dp: {mgr: "DataProcessorsManager", obj: "DataProcessorObj"},
rep: {mgr: "DataProcessorsManager", obj: "DataProcessorObj"}
};
// менеджеры перечислений
for(name in _m.enm)
text+= "$p.enm." + name + " = new $p.EnumManager('enm." + name + "');\n";
// менеджеры объектов данных, отчетов и обработок
for(var category in categoties){
for(name in _m[category]){
text+= obj_constructor_text(_m, category, name, categoties[category].obj);
if(name == "$log")
text+= "$p." + category + "." + name + " = new $p.LogManager('ireg.$log');\n";
else
text+= "$p." + category + "." + name + " = new $p." + categoties[category].mgr + "('" + category + "." + name + "');\n";
}
}
return text + "};\n";
}
function obj_constructor_text(_m, category, name, proto) {
var meta = _m[category][name],
fn_name = $p.DataManager.prototype.obj_constructor.call({class_name: category + "." + name}),
text = "\n/**\n* ### " + $p.msg.meta[category] + " " + meta.name,
f, props = "";
text += "\n* " + (meta.illustration || meta.synonym);
text += "\n* @class " + fn_name;
text += "\n* @extends " + proto;
text += "\n* @constructor \n*/\n";
text += "function " + fn_name + "(attr, manager){" + fn_name + ".superclass.constructor.call(this, attr, manager)}\n";
text += fn_name + "._extend($p." + proto + ");\n";
text += "$p." + fn_name + " = " + fn_name + ";\n";
// реквизиты по метаданным
if(meta.fields){
for(f in meta.fields){
if(props)
props += ",\n";
props += f + ": {get: function(){return this._getter('"+f+"')}, " +
"set: function(v){this._setter('"+f+"',v)}, enumerable: true, configurable: true}";
}
}else{
for(f in meta.dimensions){
if(props)
props += ",\n";
props += f + ": {get: function(){return this._getter('"+f+"')}, " +
"set: function(v){this._setter('"+f+"',v)}, enumerable: true, configurable: true}";
}
for(f in meta.resources){
if(props)
props += ",\n";
props += f + ": {get: function(){return this._getter('"+f+"')}, " +
"set: function(v){this._setter('"+f+"',v)}, enumerable: true, configurable: true}";
}
for(f in meta.attributes){
if(props)
props += ",\n";
props += f + ": {get: function(){return this._getter('"+f+"')}, " +
"set: function(v){this._setter('"+f+"',v)}, enumerable: true, configurable: true}";
}
}
if(props)
text += fn_name + ".prototype.__define({" + props + "});\n";
// табличные части по метаданным
props = "";
for(var ts in meta.tabular_sections){
// создаём конструктор строки табчасти
var row_fn_name = $p.DataManager.prototype.obj_constructor.call({class_name: category + "." + name}, ts);
text+= "function " + row_fn_name + "(owner){" + row_fn_name + ".superclass.constructor.call(this, owner)};\n";
text+= row_fn_name + "._extend($p.TabularSectionRow);\n";
text+= "$p." + row_fn_name + " = " + row_fn_name + ";\n";
// в прототипе строки табчасти создаём свойства в соответствии с полями табчасти
for(var rf in meta.tabular_sections[ts].fields){
if(props)
props += ",\n";
props += rf + ": {get: function(){return this._getter('"+rf+"')}, " +
"set: function(v){this._setter('"+rf+"',v)}, enumerable: true, configurable: true}";
}
if(props)
text += row_fn_name + ".prototype.__define({" + props + "});\n";
// устанавливаем геттер и сеттер для табличной части
text += fn_name + ".prototype.__define('"+ts+"', {get: function(){return this._getter_ts('"+ts+"')}, " +
"set: function(v){this._setter_ts('"+ts+"',v)}, enumerable: true, configurable: true});\n";
}
return text;
}
// т.к. содержимое входных файлов нам не интересно, сразу вызываем cb()
function bufferContents(file, enc, cb) {
if (!firstFile) {
firstFile = file;
}
cb();
}
function endStream(cb) {
var joinedFile,
t = this;
// if file opt was a file path
// clone everything from the latest file
if (firstFile) {
joinedFile = firstFile.clone({contents: false});
joinedFile.path = path.join(firstFile.base, 'prebuild.js');
} else {
joinedFile = new File(path.join(__dirname, 'prebuild.js'));
}
$p.md.init($p.wsql.pouch.local._meta)
.then(function (_m) {
// создаём текст модуля конструкторов данных
var text = create_modules(_m);
// выполняем текст модуля, чтобы появились менеджеры
eval(text);
$p.md.create_managers();
// получаем скрипт таблиц
$p.md.create_tables(function (sql) {
text = "$p.wsql.alasql('" + sql + "', []);\n\n"
+ text + "\n\n"
+ "$p.md.init(" + JSON.stringify(_m) + ");";
joinedFile.contents = new Buffer(text);
t.push(joinedFile);
// информируем внешний скрипт о завершении нашей работы
cb();
// отключаем все подписки и выгружаем менеджеров
$p.off();
for(var s in $p.wsql.pouch.local.sync){
try{
$p.wsql.pouch.local.sync[s].cancel();
}catch(e){}
}
$p = null;
})
})
.catch(function (err) {
throw new PluginError('metadata-prebuild', err);
});
}
return through.obj(bufferContents, endStream);
};