libf пре 2 година
родитељ
комит
1a7fea19aa
6 измењених фајлова са 474 додато и 418 уклоњено
  1. 75 71
      ajs/InitJsonImporter.js
  2. 31 23
      ajs/JsonImporter.template.js
  3. 341 321
      ajs/JsonImporterFuncs.js
  4. 7 2
      ajs/checkfields.js
  5. 9 1
      ajs/test.js
  6. 11 0
      ajs/test_gen.sh

+ 75 - 71
ajs/InitJsonImporter.js

@@ -11,56 +11,60 @@ defaultinput = {
     fields: { idUnique: "string,key" },
     mustfield: "id,idUnique",
 };
-inputmapping = {
-    "change": {
-        classname: "/cncc/action/v2_change_main",
+cfgs = [
+    {
+        classname: "/cncc/action/change_main",
         datafiledir: "/opt/cncc/action/change_main",
-        jsfilename: "/script/cncc/ITIL/v2_变更单.js",
-        clsoption: "with ttl=10 day, version=true, nickname='v2_change_main'",
+        jsfilename: "/script/cncc/ITIL/变更单.js",
+        clsoption: "with ttl=10 day, version=true, nickname='change_main'",
     },
-    "event": {
-        classname: "/cncc/action/v2_event",
-        datafiledir: "/opt/cncc/ITIL/event",
-        jsfilename: "/script/cncc/ITIL/v2_事件单.js",
-        clsoption: "with ttl=10 day, version=true, nickname='v2_event'",
+    {
+        classname: "/cncc/action/event",
+        datafiledir: "/opt/cncc/action/event",
+        jsfilename: "/script/cncc/ITIL/事件单.js",
+        clsoption: "with ttl=10 day, version=true, nickname='event'",
     },
-    "problem": {
-        classname: "/cncc/action/v2_problem",
-        datafiledir: "/opt/cncc/ITIL/problem",
-        jsfilename: "/script/cncc/ITIL/v2_问题单.js",
-        clsoption: "with ttl=10 day, version=true, nickname='v2_problem'",
+    {
+        classname: "/cncc/action/problem",
+        datafiledir: "/opt/cncc/action/problem",
+        jsfilename: "/script/cncc/ITIL/问题单.js",
+        clsoption: "with ttl=10 day, version=true, nickname='problem'",
     },
-    "report": {
-        classname: "/cncc/action/v2_report",
-        datafiledir: "/opt/cncc/ITIL/report",
-        jsfilename: "/script/cncc/ITIL/v2_报备.js",
-        clsoption: "with ttl=10 day, version=true, nickname='v2_report'",
+    {
+        classname: "/cncc/action/report",
+        datafiledir: "/opt/cncc/action/report",
+        jsfilename: "/script/cncc/ITIL/报备.js",
+        clsoption: "with ttl=10 day, version=true, nickname='report'",
     },
-    "device_power_on_off": {
-        classname: "/cncc/action/v2_device_power_on_off",
-        datafiledir: "/opt/cncc/ITIL/device_power_on_off",
-        jsfilename: "/script/cncc/ITIL/v2_设备上下电.js",
-        clsoption: "with ttl=10 day, version=true, nickname='v2_device_power_on_off'",
+    {
+        classname: "/cncc/action/device_power_on_off",
+        datafiledir: "/opt/cncc/action/device_power_on_off",
+        jsfilename: "/script/cncc/ITIL/设备上下电.js",
+        clsoption: "with ttl=10 day, version=true, nickname='device_power_on_off'",
     },
-    "data_collect": {
-        classname: "/cncc/action/v2_data_collect",
-        datafiledir: "/opt/cncc/ITIL/data_collect",
-        jsfilename: "/script/cncc/ITIL/v2_数据获取.js",
-        clsoption: "with ttl=10 day, version=true, nickname='v2_data_collect'",
+    {
+        classname: "/cncc/action/data_collect",
+        datafiledir: "/opt/cncc/action/data_collect",
+        jsfilename: "/script/cncc/ITIL/数据获取.js",
+        clsoption: "with ttl=10 day, version=true, nickname='data_collect'",
     },
-    "drill": {
-        classname: "/cncc/action/v2_drill",
-        datafiledir: "/opt/cncc/ITIL/drill",
-        jsfilename: "/script/cncc/ITIL/v2_应急演练.js",
-        clsoption: "with ttl=10 day, version=true, nickname='v2_drill'",
+    {
+        classname: "/cncc/action/drill",
+        datafiledir: "/opt/cncc/action/drill",
+        jsfilename: "/script/cncc/ITIL/应急演练.js",
+        clsoption: "with ttl=10 day, version=true, nickname='drill'",
     },
-    "implement": {
-        classname: "/cncc/action/v2_implement",
-        datafiledir: "/opt/cncc/ITIL/implement",
-        jsfilename: "/script/cncc/ITIL/v2_项目实施或巡检.js",
-        clsoption: "with ttl=10 day, version=true, nickname='v2_implement'",
-    }
-};
+    {
+        classname: "/cncc/action/implement",
+        datafiledir: "/opt/cncc/action/implement",
+        jsfilename: "/script/cncc/ITIL/项目实施或巡检.js",
+        clsoption: "with ttl=10 day, version=true, nickname='implement'",
+    }
+];
+inputmapping = {};
+for (var i = 0; i < cfgs.length; i++) {
+    inputmapping[cfgs[i].classname] = cfgs[i];
+}
 
 // 输入输出参数格式化
 input = INPUT;
@@ -91,22 +95,8 @@ eval(dfs.read("/script/matrix/utils/ajs/JsonImporterFuncs.js"));
 
 // 定义主程序
 function main() {
-    output.info = {};
-    output.info.p0 = { name: "确认参数" };
-    p = inputmapping[input.name];
-    if (p) {
-        for (var k in p) {
-            defaultinput[k] = p[k];
-        }
-    }
-    server = input.server;
-    if (!server) {
-        server = defaultinput.server;
-    }
-    author = input.author;
-    if (!author) {
-        author = defaultinput.author;
-    }
+    output.detail = {};
+    output.detail.p0 = { step: "确认参数" };
     classname = input.classname;
     if (!classname) {
         classname = defaultinput.classname;
@@ -117,6 +107,12 @@ function main() {
     if (classname.substring(0, 8) == "/matrix/") {
         throw ("classname不能以 /matrix/ 开头");
     }
+    p = inputmapping[classname];
+    if (p) {
+        for (var k in p) {
+            defaultinput[k] = p[k];
+        }
+    }
     data = input.data;
     if (isempty(data)) {
         data = defaultinput.data;
@@ -182,6 +178,9 @@ function main() {
             }
         }
     }
+    if (data["--testing--"]) {
+        throw("一般程序怎么会用这样的字段名:“--testing--”")
+    }
     jsfilename = input.jsfilename;
     if (!jsfilename) {
         jsfilename = defaultinput.jsfilename;
@@ -211,27 +210,32 @@ function main() {
         mustfield: mustfield,
         data: data,
     };
-    output.info.p1 = { name: "生成类" };
-    output.info.p1.result = alterClass(reqinput);
-    if (output.info.p1.result.error) {
+    output.detail.p1 = { step: "生成类" };
+    output.detail.p1.result = alterClass(reqinput);
+    if (output.detail.p1.result.error) {
         return;
     }
-    output.info.p2 = { name: "生成脚本" };
-    output.info.p2.result = generateJsonImporterJS(reqinput);
-    if (output.info.p2.result.error) {
+    output.detail.p2 = { step: "生成脚本" };
+    output.detail.p2.result = generateJsonImporterJS(reqinput);
+    if (output.detail.p2.result.error) {
         return;
     }
-    output.info.p3 = { name: "激活脚本" };
-    output.info.p3.result = activeServerJS(jsfilename);
-    if (output.info.p3.result.error) {
+    output.detail.p3 = { step: "激活脚本" };
+    output.detail.p3.result = activeServerJS(jsfilename);
+    if (output.detail.p3.result.error) {
         return;
     }
-    output.info.p4 = { name: "验证测试" };
-    output.info.p4.result = runServerJS(jsfilename, data);
-    if (output.info.p4.result.error) {
+    output.detail.p4 = { step: "验证测试" };
+    data["--testing--"] = true
+    output.detail.p4.result = runServerJS(jsfilename, data);
+    delete(data, "--testing--")
+    if (output.detail.p4.result.error) {
         return;
     }
-    output.info.p5 = { name: "完成" };
+    output.detail.p5 = { step: "完成" };
+    for(var k in output.detail.p4.result) {
+        output[k] = output.detail.p4.result[k]
+    }
 }
 // 执行主程序
 try {

+ 31 - 23
ajs/JsonImporter.template.js

@@ -1,24 +1,24 @@
 // ___classname___ JSON数据导入程序
 // ___datetime_now___ 由 JsonImportGen.js 自动生成,请勿手动修改
-    
+
 // 输入输出参数格式化
 input = INPUT;
 try {
     input = decodeURIComponent(input);
-} catch(e) {}
+} catch (e) { }
 try {
     input = base64.decode(input);
-} catch(e) {}
+} catch (e) { }
 try {
     input = JSON.parse(input);
     input = JSON.parse(input);
-} catch(e) {}
+} catch (e) { }
 output = {};
 
 testcfg = {};
 try {
     testcfg = JSON.parse(etcd.get("/api/test.json"));
-} catch(e) {}
+} catch (e) { }
 function teststoredfs() {
     // 输入JSON临时存入DFS
     dir = "/opt___classname___";
@@ -41,38 +41,46 @@ function teststoredfs() {
         }
     }
     // 留最后10个
-    files.sort(function(a,b){ return a.mtime-b.mtime; });
-    for (i = 0; i < files.length-10; i++) {
+    files.sort(function (a, b) { return a.mtime - b.mtime; });
+    for (i = 0; i < files.length - 10; i++) {
         dfs.remove(files[i].fullname);
     }
 }
 // 主执行阶段
 try {
-    if (testcfg.stoedfs) {
-        teststoredfs();
-    }
-    if (testcfg.checkfields) {
-        eval(dfg.read("/script/matrix/utils/ajs/checkfields.js"));
-        checkfields();
+    if (!input["--testing--"]) {
+        if (testcfg.stoedfs) {
+            teststoredfs();
+        }
+        if (testcfg.checkfields) {
+            eval(dfs.read("/script/matrix/utils/ajs/checkfields.js"));
+            if (!checkfields(input, ___field_map___)) {
+                eval(dfs.read("/script/matrix/utils/ajs/JsonImporterFuncs.js"));
+                output = runServerJS("/matrix/utils/ajs/InitJsonImporter.js", {classname: "___classname___"});
+                throw("ok");
+            }
+        }
     }
     // 数据合法性检查
-    if (___datacheck___) {}
+    if (___datacheck___) { }
     // mql定义
     mql = `___mql___`;
     // 执行mql
     ret = odb.mql(mql, ___values___);
     // 打印完成信息
-    output.info=___datainfo___;
+    output.info = ___datainfo___;
     log.info(output.info);
-} catch(e) {
-    if (typeof(e) == "object") {
-        output.error = e;
-    } else if (typeof(e) == "string") {
-        output.error = "插库错误:" + e;
-    } else {
-        output.error = JSON.stringify(e);
+} catch (e) {
+    if (e != "ok") {
+        if (typeof (e) == "object") {
+            output.error = e;
+        } else if (typeof (e) == "string") {
+            output.error = "插库错误:" + e;
+        } else {
+            output.error = JSON.stringify(e);
+        }
+        log.error(output.error);
     }
-    log.error(output.error);
 }
 
 // 返回输出信息

+ 341 - 321
ajs/JsonImporterFuncs.js

@@ -12,54 +12,37 @@ eval(dfs.read("/script/matrix/utils/ajs/config.js"))
 function alterClass(input) {
     // 返回信息
     var output = {};
-    // 参数检查
-    if (!input.classname) { // like /cncc/itil/project
-        throw ("需要指定classname");
-    }
-    if (input.classname[0] != "/") { // like /cncc/itil/project
-        throw ("classname必须以 / 开头");
-    }
-    if (!input.data || typeof(input.data)!="object") {
-        throw ("data必须指定为一个对象");
-    }
-    // 检查父类是否存在,不存在就创建
-    cns = input.classname.split("/");
-    clsname = "";
-    for (var cni = 1; cni < cns.length - 1; cni++) {
-        clsname += "/" + cns[cni];
-        odb.mql("create class if not exists " + clsname + "()");
-    }
-    pclsname = clsname;
-    clsname += "/" + cns[cns.length - 1];
-
-    // 提取现有类的字段信息
-    clsexist = false;
-    clsfields = {};
     try {
-        fieldslist = odb.classfields(clsname);
-        for (var fi = 0; fi < fieldslist.length; fi++) {
-            fld = fieldslist[fi];
-            fname = fld.name;
-            if (/^\w+\:.*/.test(fname)) {
-                fname = fname.replace(/^\w+\:/, ""); 
-            }
-            if (fname && fld.ftype) {
-                clsfields[fname] = {
-                    iskey: fld.iskey,
-                    ftype: fld.ftype,
-                };
-            }
+        // 参数检查
+        if (!input.classname) { // like /cncc/itil/project
+            throw ("需要指定classname");
         }
-        clsexist = true;
-    } catch(e) {}
-    if (!clsexist) {
+        if (input.classname[0] != "/") { // like /cncc/itil/project
+            throw ("classname必须以 / 开头");
+        }
+        if (!input.data || typeof (input.data) != "object") {
+            throw ("data必须指定为一个对象");
+        }
+        // 检查父类是否存在,不存在就创建
+        cns = input.classname.split("/");
+        clsname = "";
+        for (var cni = 1; cni < cns.length - 1; cni++) {
+            clsname += "/" + cns[cni];
+            odb.mql("create class if not exists " + clsname + "()");
+        }
+        pclsname = clsname;
+        clsname += "/" + cns[cns.length - 1];
+
+        // 提取现有类的字段信息
+        clsexist = false;
+        clsfields = {};
         try {
-            fieldslist = odb.classfields(pclsname);
+            fieldslist = odb.classfields(clsname);
             for (var fi = 0; fi < fieldslist.length; fi++) {
                 fld = fieldslist[fi];
                 fname = fld.name;
                 if (/^\w+\:.*/.test(fname)) {
-                    fname = fname.replace(/^\w+\:/, ""); 
+                    fname = fname.replace(/^\w+\:/, "");
                 }
                 if (fname && fld.ftype) {
                     clsfields[fname] = {
@@ -68,180 +51,207 @@ function alterClass(input) {
                     };
                 }
             }
-        } catch(e) {}
-    }
-    output.clsfields = clsfields;
-
-    // 通过参数确定的字段类型信息
-    fields = input.fields;
-    if (!fields) {
-        fields = {};
-    }
-    // 字段名映射,参数中指定的字段名均为JSON对象中的属性名,默认将 camelStyle 转换为 snake_style
-    fieldmap = input.fieldmap;
-    if (!fieldmap) {
-        fieldmap = {};
-    }
-    // 反向字段名映射,类中的字段名映射为JSON对象中的属性名
-    xfieldmap = {};
-    // 类中的字段名列表,用于排序
-    xfieldslist = [];
-    // 类字段类型信息
-    xfields = {};
-    xpks = [];
-    for (var jk in input.data) {
-        xk = fieldmap[jk];
-        // 通过参数确定的字段类型信息
-        if (!xk) {
-            // 默认将 camelStyle 转换为 snake_style
-            xk = "j_"; // 区别于其它字段,自动创建的字段以 j_ 开头
-            for (var i = 0; i < jk.length; i++) {
-                if (jk[i] >= 'A' && jk[i] <= 'Z') {
-                    xk += "_" + jk[i].toLowerCase();
-                } else {
-                    xk += jk[i];
+            clsexist = true;
+        } catch (e) { }
+        if (!clsexist) {
+            try {
+                fieldslist = odb.classfields(pclsname);
+                for (var fi = 0; fi < fieldslist.length; fi++) {
+                    fld = fieldslist[fi];
+                    fname = fld.name;
+                    if (/^\w+\:.*/.test(fname)) {
+                        fname = fname.replace(/^\w+\:/, "");
+                    }
+                    if (fname && fld.ftype) {
+                        clsfields[fname] = {
+                            iskey: fld.iskey,
+                            ftype: fld.ftype,
+                        };
+                    }
                 }
-            }
-            fieldmap[jk] = xk;
+            } catch (e) { }
         }
-        xfieldslist.push(xk);
-        xfieldmap[xk] = jk;
-        dt = fields[jk];
-        if (dt && dt.indexOf(",key") > 0) {
-            dt = dt.replace(",key", "");
-            xpks.push(xk);
+        output.clsfields = clsfields;
+
+        // 通过参数确定的字段类型信息
+        fields = input.fields;
+        if (!fields) {
+            fields = {};
         }
-        switch (dt) {
-        case "date":
-        case "time":
-        case "datetime":
-            dt = "timestamp";
-            break;
-        case "int":
-        case "integer":
-            dt = "bigint";
-            break;
-        case "number":
-        case "float":
-            dt = "double";
-            break;
-        case "text":
-            dt = "text";
-            break;
-        case "string":
-            dt = "varchar";
-            break;
-        case "boolean":
-            dt = "boolean";
-            break;
+        // 字段名映射,参数中指定的字段名均为JSON对象中的属性名,默认将 camelStyle 转换为 snake_style
+        fieldmap = input.fieldmap;
+        if (!fieldmap) {
+            fieldmap = {};
         }
-        if (!dt) {
-            // 没有明确定义的字段类型
-            // 根据数据判断类型
-            dt = "varchar";
-            d = input.data[jk];
-            if (d || d == "" || d == 0 || d == false) { 
-                switch (typeof(d)) {
-                case 'object':
-                    // 转为text
-                    dt = "text"; 
-                    break;
-                case 'number':
-                    // 是否为整数
-                    if ((""+d).indexOf(".")<0) {
-                        dt = "bigint";
+        // 反向字段名映射,类中的字段名映射为JSON对象中的属性名
+        xfieldmap = {};
+        // 类中的字段名列表,用于排序
+        xfieldslist = [];
+        // 类字段类型信息
+        xfields = {};
+        xpks = [];
+        for (var jk in input.data) {
+            xk = fieldmap[jk];
+            // 通过参数确定的字段类型信息
+            if (!xk) {
+                // 默认将 camelStyle 转换为 snake_style
+                xk = "j_"; // 区别于其它字段,自动创建的字段以 j_ 开头
+                for (var i = 0; i < jk.length; i++) {
+                    if (jk[i] >= 'A' && jk[i] <= 'Z') {
+                        xk += "_" + jk[i].toLowerCase();
                     } else {
-                        dt = "double";
+                        xk += jk[i];
                     }
+                }
+                fieldmap[jk] = xk;
+            }
+            xfieldslist.push(xk);
+            xfieldmap[xk] = jk;
+            dt = fields[jk];
+            if (dt && dt.indexOf(",key") > 0) {
+                dt = dt.replace(",key", "");
+                xpks.push(xk);
+            }
+            switch (dt) {
+                case "date":
+                case "time":
+                case "datetime":
+                    dt = "timestamp";
+                    break;
+                case "int":
+                case "integer":
+                    dt = "bigint";
                     break;
-                case 'boolean':
+                case "number":
+                case "float":
+                    dt = "double";
+                    break;
+                case "text":
+                    dt = "text";
+                    break;
+                case "string":
+                    dt = "varchar";
+                    break;
+                case "boolean":
                     dt = "boolean";
                     break;
-                case 'string':
-                default:
-                    // 是否为日期时间
+            }
+            if (!dt) {
+                // 没有明确定义的字段类型
+                // 根据数据判断类型
+                dt = "varchar";
+                d = input.data[jk];
+                if (d || d == "" || d == 0 || d == false) {
+                    switch (typeof (d)) {
+                        case 'object':
+                            // 转为text
+                            dt = "text";
+                            break;
+                        case 'number':
+                            // 是否为整数
+                            if (("" + d).indexOf(".") < 0) {
+                                dt = "bigint";
+                            } else {
+                                dt = "double";
+                            }
+                            break;
+                        case 'boolean':
+                            dt = "boolean";
+                            break;
+                        case 'string':
+                        default:
+                            // 是否为日期时间
+                            if (/_time/.test(xk) || /_date/.test(xk)) {
+                                dt = "timestamp";
+                            } else {
+                                dt = "varchar";
+                            }
+                            break;
+                    }
+                } else {
                     if (/_time/.test(xk) || /_date/.test(xk)) {
                         dt = "timestamp";
                     } else {
                         dt = "varchar";
                     }
-                    break;
-                }
-            } else {
-                if (/_time/.test(xk) || /_date/.test(xk)) {
-                    dt = "timestamp";
-                } else {
-                    dt = "varchar";
                 }
             }
+            xfields[xk] = dt;
         }
-        xfields[xk] = dt;
-    }
-    output.xfields = xfields;
-    
-    if (!clsexist) {
-        // 类不存在,自动创建类
-        mql = "create class if not exists " + clsname + "(";
-        indexes = "indexes(";
-        for (var fi = 0; fi < xfieldslist.length; fi++) {
-            xk = xfieldslist[fi];
-            if (xk in {"id":"", "class":"", "name":"", "day":"", "tags":"", "vtime":""}) {
-                throw("内部使用字段名 " + xk + ",需要映射成其它名称");
-            }
-            if (clsfields[xk] && clsfields[xk].ftype != xfields[xk]) {
-                throw ("类继承字段 "+ xk +" 信息不一致,"+clsfields[xk].ftype + "!=" + xfields[xk]+",需手动干预");
-            }
-            mql += fi==0 ? "\n": ",\n";
-            mql += xk + " " + xfields[xk];
-            if (fi > 0) {
-                indexes += ",";
+        output.xfields = xfields;
+
+        if (!clsexist) {
+            // 类不存在,自动创建类
+            mql = "create class if not exists " + clsname + "(";
+            indexes = "indexes(";
+            for (var fi = 0; fi < xfieldslist.length; fi++) {
+                xk = xfieldslist[fi];
+                if (xk in { "id": "", "class": "", "name": "", "day": "", "tags": "", "vtime": "" }) {
+                    throw ("内部使用字段名 " + xk + ",需要映射成其它名称");
+                }
+                if (clsfields[xk] && clsfields[xk].ftype != xfields[xk]) {
+                    throw ("类继承字段 " + xk + " 信息不一致," + clsfields[xk].ftype + "!=" + xfields[xk] + ",需手动干预");
+                }
+                mql += fi == 0 ? "\n" : ",\n";
+                mql += xk + " " + xfields[xk];
+                if (fi > 0) {
+                    indexes += ",";
+                }
+                indexes += xk;
             }
-            indexes += xk;
-        }
-        indexes += ")";
-        mql += ",\n" + indexes;
-        if (xpks.length > 0) {
-            mql += ",\n";
-            mql += "keys(";
-            for (var pki = 0; pki < xpks.length; pki++) {
-                if (pki > 0) {
-                    mql += ",";
+            indexes += ")";
+            mql += ",\n" + indexes;
+            if (xpks.length > 0) {
+                mql += ",\n";
+                mql += "keys(";
+                for (var pki = 0; pki < xpks.length; pki++) {
+                    if (pki > 0) {
+                        mql += ",";
+                    }
+                    mql += xpks[pki];
                 }
-                mql += xpks[pki];
+                mql += ")";
             }
+            mql += "\n";
             mql += ")";
-        }
-        mql += "\n";
-        mql += ")";
-        if (input.clsoption) {
-            mql += input.clsoption;
-        }
-        odb.mql(mql);
-        output = {mql:mql};
-    } else {
-        // 类已存在,检查主键信息是否存在
-        for (var pki = 0; pki < xpks.length; pki++) {
-            xk = xpks[pki];
-            if (!clsfields[xk] || !clsfields[xk].iskey) {
-                throw ("已经存在同名类主键 "+ xk +" 信息不一致,需手动干预");
+            if (input.clsoption) {
+                mql += input.clsoption;
             }
-        }
-        // 追加字段
-        mql = "alter class " + clsname + " add index column";
-        addn = 0;
-        for (var fi = 0; fi < xfieldslist.length; fi++) {
-            xk = xfieldslist[fi];
-            if (!clsfields[xk]) {
-                mql += (addn == 0)?" ":", ";
-                mql += xk + " " + xfields[xk];
-                addn++;
-            } else if (clsfields[xk].ftype != xfields[xk]) {
-                throw ("已经存在同名类字段 "+ xk +" 信息不一致,需手动干预");
+            odb.mql(mql);
+            output = { mql: mql };
+        } else {
+            // 类已存在,检查主键信息是否存在
+            // for (var pki = 0; pki < xpks.length; pki++) {
+            //     xk = xpks[pki];
+            //     if (!clsfields[xk] || !clsfields[xk].iskey) {
+            //         throw ("已经存在同名类主键 " + xk + " 信息不一致,需手动干预");
+            //     }
+            // }
+            // 追加字段
+            mql = "alter class " + clsname + " add index column";
+            addn = 0;
+            for (var fi = 0; fi < xfieldslist.length; fi++) {
+                xk = xfieldslist[fi];
+                if (!clsfields[xk]) {
+                    mql += (addn == 0) ? " " : ", ";
+                    mql += xk + " " + xfields[xk];
+                    addn++;
+                } else if (clsfields[xk].ftype != xfields[xk]) {
+                    throw ("已经存在同名类字段 " + xk + " 信息不一致,需手动干预");
+                }
+            }
+            if (addn > 0) {
+                odb.mql(mql);
+                output = { mql: mql };
             }
         }
-        if (addn > 0) {
-            odb.mql(mql);
-            output = {mql:mql};
+    } catch (e) {
+        if (typeof (e) == "object") {
+            output.error = e;
+        } else if (typeof (e) == "string") {
+            output.error = "错误:" + e;
+        } else {
+            output.error = JSON.stringify(e);
         }
     }
     return output
@@ -250,139 +260,149 @@ function alterClass(input) {
 // 根据 JSON 数据生成导入脚本
 function generateJsonImporterJS(input) {
     var output = {};
-    // 参数检查
-    if (!input.classname) { // like /cncc/itil/project
-        throw ("需要指定classname");
-    }
-    if (input.classname[0] != "/") { // like /cncc/itil/project
-        throw ("classname必须以 / 开头");
-    }
-    sjsfn = input.jsfilename;
-    if (!sjsfn) {
-        sjsfn = "/script" + input.classname; // like /script/cncc/itil/project
-    }
-    if (sjsfn.substring(0, 8) != "/script/") {
-        throw ("jsfilename必须以 /script/ 开头");
-    }
-    sjsfn = sjsfn.replace(/\.js$/, "");
-    output.file = sjsfn;
-
-    dtm = new Date().toJSON();
-    mql = "insert into " + input.classname + " (\n";
-    mql_values = ") values (\n";
-    mql_end = ")";
-    values = "";
-    fieldmap = input.fieldmap;
-    if (!fieldmap) {
-        fieldmap = {};
-    }
-    xfieldmap = {};
-    xfields = [];
-    clsfields = {};
     try {
-        fieldslist = odb.classfields(input.classname);
-        for (var fi = 0; fi < fieldslist.length; fi++) {
-            fld = fieldslist[fi];
-            fname = fld.name;
-            if (/^\w+\:.*/.test(fname)) {
-                fname = fname.replace(/^\w+\:/, ""); 
-            }
-            if (fname && fld.ftype) {
-                clsfields[fname] = {
-                    iskey: fld.iskey,
-                    ftype: fld.ftype,
-                };
-            }
+        // 参数检查
+        if (!input.classname) { // like /cncc/itil/project
+            throw ("需要指定classname");
         }
-    } catch(e) {}
-    for (var k in input.data) {
-        xk = fieldmap[k];
-        if (!xk) {
-            xk = "j_"; // 区别于其它字段,自动创建的字段以 j_ 开头
-            for (var i = 0; i < k.length; i++) {
-                if (k[i] >= 'A' && k[i] <= 'Z') {
-                    xk += "_" + k[i].toLowerCase();
-                } else {
-                    xk += k[i];
-                }
-            }
-            fieldmap[k] = xk;
+        if (input.classname[0] != "/") { // like /cncc/itil/project
+            throw ("classname必须以 / 开头");
         }
-        xfields.push(xk);
-        xfieldmap[xk] = k;
-    }
-    xfields.sort();
-    fsep = ",";
-    for (var i = 0; i < xfields.length; i++) {
-        if (i == xfields.length - 1) {
-            fsep = "";
+        sjsfn = input.jsfilename;
+        if (!sjsfn) {
+            sjsfn = "/script" + input.classname; // like /script/cncc/itil/project
         }
-        xk = xfields[i];
-        k = xfieldmap[xk];
-        mql += xk + fsep + "\n";
-        mql_values += "?" + fsep + "\n";
-        values += "    ";
-        v = input.data[k];
-        if (!clsfields[xk]) {
-            throw("字段不存在", xk)
+        if (sjsfn.substring(0, 8) != "/script/") {
+            throw ("jsfilename必须以 /script/ 开头");
         }
-        switch (clsfields[xk].ftype) {
-        case "text":
-        case "varchar":
-            if (typeof(v) == "object") {
-                values += "JSON.stringify(";
-                values += "input." + k + ", \" \", 4)" + fsep;
-                values += JSON.stringify(v, " ", 4).replace(/^/mg, "            // ").replace(/            /, " ");
-            } else {
-                values += "\"\"+";
-                values += "input." + k + fsep;
-                values += (""+v).replace(/^/mg, "            // ").replace(/            /, " ");
+        sjsfn = sjsfn.replace(/\.js$/, "");
+        output.file = sjsfn;
+
+        dtm = new Date().toJSON();
+        mql = "insert into " + input.classname + " (\n";
+        mql_values = ") values (\n";
+        mql_end = ")";
+        values = "";
+        fieldmap = input.fieldmap;
+        if (!fieldmap) {
+            fieldmap = {};
+        }
+        xfieldmap = {};
+        xfields = [];
+        clsfields = {};
+        try {
+            fieldslist = odb.classfields(input.classname);
+            for (var fi = 0; fi < fieldslist.length; fi++) {
+                fld = fieldslist[fi];
+                fname = fld.name;
+                if (/^\w+\:.*/.test(fname)) {
+                    fname = fname.replace(/^\w+\:/, "");
+                }
+                if (fname && fld.ftype) {
+                    clsfields[fname] = {
+                        iskey: fld.iskey,
+                        ftype: fld.ftype,
+                    };
+                }
+            }
+        } catch (e) { }
+        for (var k in input.data) {
+            xk = fieldmap[k];
+            if (!xk) {
+                xk = "j_"; // 区别于其它字段,自动创建的字段以 j_ 开头
+                for (var i = 0; i < k.length; i++) {
+                    if (k[i] >= 'A' && k[i] <= 'Z') {
+                        xk += "_" + k[i].toLowerCase();
+                    } else {
+                        xk += k[i];
+                    }
+                }
+                fieldmap[k] = xk;
             }
-            break;
-        default:
-            values += "input." + k + fsep;
-            values += (""+v).replace(/^/mg, "            // ").replace(/            /, " ");
+            xfields.push(xk);
+            xfieldmap[xk] = k;
         }
-        values += "\n    ";
-    }
-    mql += mql_values + mql_end;
-    values = "\n    " + values;
-
-    datainfo = "{";
-    datacheck = "";
-    if (input.mustfield) {
-        ids = input.mustfield.split(",");
-        for (var i = 0; i < ids.length; i++) {
-            id = ids[i];
-            if (i > 0) {
-                datacheck += "\n    ";
+        xfields.sort();
+        fsep = ",";
+        for (var i = 0; i < xfields.length; i++) {
+            if (i == xfields.length - 1) {
+                fsep = "";
             }
-            datacheck += "if (!input." + id + ") {\n    ";
-            datacheck += "    throw (\"输入参数必须为对象,且指定属性" + id + "\");\n    ";
-            datacheck += "}";
-            if (i == 0) {
-                datainfo += "\n    ";
-            } else {
-                datainfo += ",\n    ";
+            xk = xfields[i];
+            k = xfieldmap[xk];
+            mql += xk + fsep + "\n";
+            mql_values += "?" + fsep + "\n";
+            values += "    ";
+            v = input.data[k];
+            if (!clsfields[xk]) {
+                throw ("字段不存在", xk)
             }
-            datainfo += "    " + id + ": input." + id;
+            switch (clsfields[xk].ftype) {
+                case "text":
+                case "varchar":
+                    if (typeof (v) == "object") {
+                        values += "JSON.stringify(";
+                        values += "input." + k + ", \" \", 4)" + fsep;
+                        values += JSON.stringify(v, " ", 4).replace(/^/mg, "            // ").replace(/            /, " ");
+                    } else {
+                        values += "\"\"+";
+                        values += "input." + k + fsep;
+                        values += ("" + v).replace(/^/mg, "            // ").replace(/            /, " ");
+                    }
+                    break;
+                default:
+                    values += "input." + k + fsep;
+                    values += ("" + v).replace(/^/mg, "            // ").replace(/            /, " ");
+            }
+            values += "\n    ";
         }
-    }
-    datainfo += "\n    ";
-    datainfo += "}";
+        mql += mql_values + mql_end;
+        values = "\n    " + values;
 
-    importjs = dfs.read("/script/matrix/utils/ajs/JsonImporter.template.js");
-    importjs = importjs.replace(/___istesting___/mg, input.istesting);
-    importjs = importjs.replace(/___classname___/mg, input.classname);
-    importjs = importjs.replace(/___datetime_now___/mg, dtm);
-    importjs = importjs.replace(/if\s*\(\s*___datacheck___\s*\)\s*\{.*\}/mg, datacheck);
-    importjs = importjs.replace(/___mql___/mg, mql);
-    importjs = importjs.replace(/___values___/mg, values);
-    importjs = importjs.replace(/___datainfo___/mg, datainfo);
+        datainfo = "{";
+        datacheck = "";
+        if (input.mustfield) {
+            ids = input.mustfield.split(",");
+            for (var i = 0; i < ids.length; i++) {
+                id = ids[i];
+                if (i > 0) {
+                    datacheck += "\n    ";
+                }
+                datacheck += "if (!input." + id + ") {\n    ";
+                datacheck += "    throw (\"输入参数必须为对象,且指定属性" + id + "\");\n    ";
+                datacheck += "}";
+                if (i == 0) {
+                    datainfo += "\n    ";
+                } else {
+                    datainfo += ",\n    ";
+                }
+                datainfo += "    " + id + ": input." + id;
+            }
+        }
+        datainfo += "\n    ";
+        datainfo += "}";
 
-    output.content = importjs;
+        importjs = dfs.read("/script/matrix/utils/ajs/JsonImporter.template.js");
+        importjs = importjs.replace(/___field_map___/mg, JSON.stringify(fieldmap));
+        importjs = importjs.replace(/___classname___/mg, input.classname);
+        importjs = importjs.replace(/___datetime_now___/mg, dtm);
+        importjs = importjs.replace(/if\s*\(\s*___datacheck___\s*\)\s*\{.*\}/mg, datacheck);
+        importjs = importjs.replace(/___mql___/mg, mql);
+        importjs = importjs.replace(/___values___/mg, values);
+        importjs = importjs.replace(/___datainfo___/mg, datainfo);
 
-    dfs.write(sjsfn + ".js", importjs);
+        output.content = importjs;
+
+        dfs.write(sjsfn + ".js", importjs);
+    } catch (e) {
+        if (typeof (e) == "object") {
+            output.error = e;
+        } else if (typeof (e) == "string") {
+            output.error = "错误:" + e;
+        } else {
+            output.error = JSON.stringify(e);
+        }
+    }
     return output
 }
 
@@ -390,11 +410,11 @@ function generateJsonImporterJS(input) {
 function activeServerJS(jsfilename) {
     result = {};
     calljsfp = encodeURIComponent(jsfilename.replace(/\/script/, ""));
-    http.do("POST", 
-        cfg.server+"/fs/tolocal/script"+calljsfp+"?issys=true",
-        {"Authorization": "Basic "+cfg.author},
+    http.do("POST",
+        cfg.server + "/fs/tolocal/script" + calljsfp + "?issys=true",
+        { "Authorization": "Basic " + cfg.author },
         '',
-        function(response){
+        function (response) {
             // success func
             ret = response.data;
             if (ret.message) {
@@ -403,7 +423,7 @@ function activeServerJS(jsfilename) {
                 result = ret;
             }
         },
-        function(response){
+        function (response) {
             // error func
             result.error = response.data;
         });
@@ -415,11 +435,11 @@ function runServerJS(jsfilename, data) {
     result = {};
     reqinput = encodeURIComponent(base64.encode(JSON.stringify(data)));
     calljsfp = encodeURIComponent(jsfilename.replace(/\/script/, ""));
-    http.do("POST", 
-        cfg.server+"/script/exec/js?filepath="+calljsfp+"&input="+reqinput,
-        {"Authorization": "Basic "+cfg.author},
+    http.do("POST",
+        cfg.server + "/script/exec/js?filepath=" + calljsfp + "&input=" + reqinput,
+        { "Authorization": "Basic " + cfg.author },
         '',
-        function(response){
+        function (response) {
             // success func
             ret = response.data;
             if (ret.message) {
@@ -428,7 +448,7 @@ function runServerJS(jsfilename, data) {
                 result = ret;
             }
         },
-        function(response){
+        function (response) {
             // error func
             result.error = response.data;
         });

+ 7 - 2
ajs/checkfields.js

@@ -1,4 +1,9 @@
 
-function checkfields() {
-
+function checkfields(data, fieldmap) {
+    for (var k in data) {
+        if (!fieldmap[k]) {
+            return false;
+        }
+    }
+    return true;
 }

+ 9 - 1
ajs/test.js

@@ -4,7 +4,15 @@ output = {};
 try {
     eval(dfs.read("/script/matrix/utils/ajs/JsonImporterFuncs.js"));
 
-    output.result = runServerJS("/matrix/utils/ajs/InitJsonImporter.js", {name:"change"});
+    output.result = {};
+    output.result.change_main         = runServerJS("/matrix/utils/ajs/InitJsonImporter.js", {classname:"/cncc/action/change_main"});
+    output.result.event               = runServerJS("/matrix/utils/ajs/InitJsonImporter.js", {classname:"/cncc/action/event"});
+    output.result.problem             = runServerJS("/matrix/utils/ajs/InitJsonImporter.js", {classname:"/cncc/action/problem"});
+    output.result.report              = runServerJS("/matrix/utils/ajs/InitJsonImporter.js", {classname:"/cncc/action/report"});
+    output.result.device_power_on_off = runServerJS("/matrix/utils/ajs/InitJsonImporter.js", {classname:"/cncc/action/device_power_on_off"});
+    output.result.data_collect        = runServerJS("/matrix/utils/ajs/InitJsonImporter.js", {classname:"/cncc/action/data_collect"});
+    output.result.drill               = runServerJS("/matrix/utils/ajs/InitJsonImporter.js", {classname:"/cncc/action/drill"});
+    output.result.implement           = runServerJS("/matrix/utils/ajs/InitJsonImporter.js", {classname:"/cncc/action/implement"});
 } catch (e) {
     if (typeof (e) == "object") {
         output.error = e;

+ 11 - 0
ajs/test_gen.sh

@@ -0,0 +1,11 @@
+
+URL='http://47.92.151.165:8080/script/exec/js?filepath=/matrix/utils/InitJsonImporter.js'
+FORM='input={"classname":"/bofengtest/aaaa", "datafilename":"/opt/bofengtest/aaa/test.json"}'
+curl --location --request POST "${URL}" --header 'Authorization: Basic d2VjaXNlLmFkbWluOmFkbWlu' --form "${FORM}" ;echo
+
+URL='http://47.92.151.165:8080/script/exec/js?filepath=/matrix/utils/InitJsonImporter.js'
+FORM='input={"classname":"/bofengtest/aaaa", "datafilename":"/opt/bofengtest/aaa/test.json"}'
+curl --location --request POST "${URL}" --header 'Authorization: Basic d2VjaXNlLmFkbWluOmFkbWlu' --form "${FORM}" ;echo
+
+echo
+