zoukankan      html  css  js  c++  java
  • plv8 中使用 eval 函数执行表达式计算

    在js 开发中我们都说eval 函数是邪恶的,但是此函数也有好多妙用,以下是几个简单的案例

    eval 执行基于js 的表达式计算

    比如我们有以下表

    CREATE TABLE rules (
        id SERIAL PRIMARY KEY,
        rule_expression text
    );
    -- Indices -------------------------------------------------------
    CREATE UNIQUE INDEX rules_pkey ON rules(id int4_ops);
    • 表内容
    INSERT INTO "public"."rules"("id","rule_expression")
    VALUES
    (1,E'"${vars_name}".length>10');
    • plv8 函数
    CREATE or replace FUNCTION rule_test(id int,args text) RETURNS json AS
    $$
       // 解决es 模版函数问题,string 转string template
        String.prototype.interpolate = function(params) {
          const names = Object.keys(params);
          const vals = Object.values(params);
          return new Function(...names, `return \`${this}\`;`)(...vals);
        }
        var result = {}
        var plan = plv8.prepare('SELECT rule_expression from rules where id = $1',['int']);
        // only for test fetch one row 
        var rule_row = plan.execute([ id ])[0];
        let vars_name = args;
        var rule_template = rule_row.rule_expression.interpolate({vars_name});
         var execresult = eval(rule_template);
        result = {
           id: id,
           validate: execresult
        }
        plan.free();
        return JSON.stringify(result);
    $$
    LANGUAGE plv8;
     
     
    • 调用函数
    select * from rule_test(1,'ddssaa');  // return   {"id":1,"validate":false}
    select * from rule_test(1,'dddaaasssssssssaa');  // return {"id":1,"validate":true}

    一个比较通用的基于eval 的规则校验

    • 约定
      通过vars. 进行key 的处理支持标准的js && ||
    • 参考例子
     
    "${vars.name}".length>10&& "${vars.version}"=="1.0"
    • 函数定义
     CREATE or replace FUNCTION rule_test3(id int,args json,rule_row text) RETURNS json AS
    $$
        String.prototype.interpolate = function(params) {
        const names = Object.keys(params);
        const vals = Object.values(params);
        return new Function(...names, `return \`${this}\`;`)(...vals);
      }
        var result = {}
        let vars = {...args};
        var rule_template = rule_row.interpolate({vars});
        var execresult = eval(rule_template);
        result = {
           id: id,
           validate: execresult
        }
        return JSON.stringify(result);
    $$
    LANGUAGE plv8;
    • 调用
    select a.*, rule_test3(3,'{"version":"1.0","name":"dddddddd"}',b.rule_expression) from apps a join rules b on a.id=b.id where a.id=2; /
    // 2    rong    {"id":3,"validate":false}
    select a.*, rule_test3(3,'{"version":"1.0","name":"dddddd1111dd"}',b.rule_expression) from apps a join rules b on a.id=b.id where a.id=2; 
    // 2    rong    {"id":3,"validate":true}
     

    说明

    以上是一个简单的使用plv8 使用js 实现的一个简单的规则判断,核心是对于string template 的函数处理

    参考资料

    https://plv8.github.io/#inline-statement-calls
    https://github.com/plv8/plv8

  • 相关阅读:
    第一次作业:阅读与准备作业
    第一阶段意见总结
    第一冲刺阶段总结与评审
    第一冲刺阶段总结
    第一冲刺阶段第七天
    第一冲刺阶段第六天
    第一冲刺阶段第五天
    第一冲刺阶段第四天
    第一冲刺阶段第三天
    第一冲刺阶段第二天
  • 原文地址:https://www.cnblogs.com/rongfengliang/p/11823452.html
Copyright © 2011-2022 走看看