function compile_engine()
{
    global $BASEDIR;
    global $APPEND;
    $order = "bp_name,rule_prio";
    $data = db_read("rules,bps", null, array(), $order, 0, 0);
    $table = array();
    foreach ($data as $def) {
        $bp_name = $def["bp_name"];
        $rule_prio = $def["rule_prio"];
        $statefield = $def["bp_statefield"];
        if ($bp_name == "GLOBAL") {
            $statefield = "GLOBAL.GLOBAL";
        }
        if (!$statefield) {
            // use default: bpstates
            $statefield = "states.state_value:state_env";
        }
        $def["rule_location"] = split("\n", $def["rule_location"]);
        $def["rule_condition"] = split("\n", $def["rule_condition"]);
        $def["rule_action"] = split("\n", $def["rule_action"]);
        $startvalue = $def["rule_startvalue"];
        echo "compiling business process '{$bp_name}' prio {$rule_prio}: acts on {$statefield}<br>\n";
        $subcond = array("bp_name" => $bp_name, "rule_prio" => $rule_prio);
        $subdata = db_read("conts", null, $subcond, "cont_prio", 0, 0);
        foreach ($subdata as $subidx => $subdef) {
            $subdata[$subidx]["cont_action"] = split("\n", $subdef["cont_action"]);
        }
        $def["CONTI"] = array_merge($subdata, $APPEND);
        $split = split(":", $statefield);
        $state_base = $split[0];
        $def["bp_statefield"] = $state_base;
        $def["ENV_FIELD"] = @$split[1];
        $newsplit = split("\\.", $split[0]);
        $def["TABLE"] = $newsplit[0];
        $def["FIELD"] = $newsplit[1];
        $table[$state_base][] = $def;
    }
    echo "done.<br>\n";
    $code = "<?php // this file was automatically generated by the engine compiler from database tables.\n\n// ====> DO NOT EDIT! <===\n\n";
    $code .= "\$ENGINE =\n" . db_data_to_code($table);
    $code .= "\n\n?>\n";
    $outname = "{$BASEDIR}/compiled/engine_table.php";
    $tmpname = "{$outname}.tmp";
    $fp = fopen($tmpname, "w");
    if (!$fp) {
        die("cannot create file '{$outname}'\n");
    }
    $len = fwrite($fp, $code);
    if ($len != strlen($code)) {
        die("cannot write temporary file '{$tmpname}'\n");
    }
    fclose($fp);
    rename($tmpname, $outname);
}
}
$new_schema = "{$BASEDIR}/schema/{$new_schema_name}";
echo "NEW schema: '{$new_schema}'<br><br>\n";
unset($SCHEMA);
unset($EXTRA);
require_once $new_schema;
if (@$EXTRA) {
    $SCHEMA = array_merge_recursive($SCHEMA, $EXTRA);
}
$check = db_check_syntax($SCHEMA, $SYNTAX);
if ($check) {
    die("bad syntax in NEW: {$check}\n");
}
$NEW = db_mangle_schema($SCHEMA);
$text = "<?php // this file was automatically generated by the schema precompiler from '{$new_schema}'.\n\n// ====> DO NOT EDIT! <===\n\n";
$text .= "\$SCHEMA =\n" . db_data_to_code($NEW);
$text .= ";\n?>\n";
$outname = "{$BASEDIR}/compiled/{$new_schema_name}";
_writefile($outname, $text);
$outname = "{$BASEDIR}/compiled/schema.php";
_writefile($outname, $text);
echo "done.<br>\n";
$SCHEMA = $NEW;
echo "<br>---------------------------------------------------<br><br>\n";
foreach ($CONFIG["CONNECTIONS"] as $database => $ddef) {
    $DB_NAME = $ddef["BASE"];
    echo "-----> Database '{$database}' name='{$DB_NAME}' <------<br><br>\n";
    $connection = _db_open($database, true, true);
    if (!$connection) {
        die("Cannot connect to database '{$database}' (fix connection and/or sourcecode in config.php<br>\n");
    }
function do_action(&$env, $action)
{
    global $RAW_ID;
    global $ERROR;
    if (is_array($action)) {
        foreach ($action as $sub) {
            if (!do_action($env, $sub)) {
                return false;
            }
            if (@$env["HAS_FORKED"] || @$env["DO_BREAK"]) {
                return true;
            }
        }
        return true;
    }
    if (!$action) {
        return true;
    }
    //echo "ACTION: $action\n";
    $oldlevel = $env["LEVEL"];
    $env["LEVEL"]++;
    $ok = false;
    if (!$action) {
        $ok = true;
    } elseif (preg_match("/\\A(script|url)\\s+(.*)/", $action, $matches)) {
        $op = $matches[1];
        $cmd = $matches[2];
        if ($op == "url") {
            $cmd = "wget -O - '{$cmd}'";
        }
        $cmd = subst_macros($env, $cmd);
        $ok = run_script($env, $cmd);
    } else {
        if (preg_match("/\\A(insert|update|delete)\\s+(?:({$RAW_ID})\\s+)?({$RAW_ID}\\s*=.*)/", $action, $matches)) {
            $mode = $matches[1];
            $table = $env["TABLE"];
            if (@$matches[2]) {
                $table = $matches[2];
            }
            $rest = $matches[3];
            $data = array();
            //echo "MODE: $mode\n";
            if ($mode == "update" || $mode == "delete") {
                $primary = _db_primary($table);
                foreach (split(",", $primary) as $pri) {
                    if (isset($env[$pri])) {
                        $data[0][$pri] = $env[$pri];
                    }
                }
            }
            while (preg_match("/\\A\\s*({$RAW_ID})\\s*=\\s*'((?:[^\\']|\\.)*)'(.*)/", $rest, $matches)) {
                $field = $matches[1];
                $value = $matches[2];
                $rest = $matches[3];
                $data[0][$field] = subst_macros($env, $value, "'", "\\'");
            }
            echo_rule($env);
            echo "{$mode} {$table}:";
            foreach ($data[0] as $field => $value) {
                echo " {$field} = '{$value}'";
            }
            echo "\n";
            if ($mode == "delete") {
                $ok = db_delete($table, $data) && !$ERROR;
                check_answer($env, "DELETE {$ok}");
            } elseif ($mode == "update") {
                $ok = db_update($table, $data) && !$ERROR;
                check_answer($env, "UPDATE {$ok}");
            } else {
                $ok = db_insert($table, $data) && !$ERROR;
                check_answer($env, "INSERT {$ok}");
            }
            if (!$ok) {
                check_answer($env, "DB_ERROR {$mode} ({$ERROR})");
            }
        } else {
            if (preg_match("/\\Aquery\\s+({$RAW_ID})\\s+({$RAW_ID})\\s+({$RAW_ID}\\s*=.*)/", $action, $matches)) {
                $var = $matches[1];
                $table = $matches[2];
                $rest = $matches[3];
                $cond = array();
                while (preg_match("/\\A\\s*({$RAW_ID})\\s*=\\s*'((?:[^\\']|\\.)*)'(.*)/", $rest, $matches)) {
                    $field = $matches[1];
                    $value = $matches[2];
                    $rest = $matches[3];
                    $cond[$field] = subst_macros($env, $value, "'", "\\'");
                }
                $data = db_read($table, null, $cond, null, 0, 0);
                //echo "got....."; print_r($data); echo "\n";
                $env[$var] = $data;
                $ok = true;
            } else {
                if (preg_match("/\\Avar\\s+({$RAW_ID}(?:->{$RAW_ID})*)\\s*=\\s*'((?:[^\\']|\\.)*)'/", $action, $matches)) {
                    $var = $matches[1];
                    $expr = $matches[2];
                    $lvalue =& $env;
                    while (preg_match("/\\A(?:->)?({$RAW_ID})(.*)/", $var, $matches)) {
                        $field = $matches[1];
                        $var = $matches[2];
                        $lvalue =& $lvalue[$field];
                    }
                    if ($var) {
                        engine_error("cannot assign to variable '{$var}'");
                    } else {
                        $lvalue = subst_macros($env, $expr, "'", "\\'");
                        $ok = true;
                    }
                } else {
                    if (preg_match("/\\A(call|start)\\s+({$RAW_ID})(.*)/", $action, $matches)) {
                        $ok = false;
                        $mode = $matches[1];
                        $call = $matches[2];
                        $rest = $matches[3];
                        $cond = array("bp_name" => $call);
                        $data = db_read("bps", null, $cond);
                        if (!$data || $ERROR) {
                            check_answer($env, "DB_ERROR read ({$ERROR})");
                        } else {
                            $newenv = array();
                            while (preg_match("/\\A\\s*({$RAW_ID})\\s*=\\s*'((?:[^\\']|\\.)*)'(.*)/", $rest, $matches)) {
                                $field = $matches[1];
                                $value = $matches[2];
                                $rest = $matches[3];
                                $newenv[$field] = subst_macros($env, $value, "'", "\\'");
                            }
                            if ($rest) {
                                engine_error("bad call '{$call}', syntax rest '{$rest}'");
                            } else {
                                $statefield = $data[0]["bp_statefield"];
                                $newrec = array();
                                $newrec["state_id"] = null;
                                $newrec["bp_name"] = $call;
                                if ($mode == "start") {
                                    // asynchronous call: make "return" later a nop
                                    $newenv["NO_RETURN"] = true;
                                }
                                $newrec["state_env"] = db_data_to_code($newenv);
                                if (@$newenv["state_value"]) {
                                    $newrec["state_value"] = $newenv["state_value"];
                                }
                                $table = $env["TABLE"];
                                $primary = _db_primary($table);
                                $field = $env["FIELD"];
                                $newrec["state_returnfield"] = "{$table}.{$field}";
                                $id_rec = array();
                                foreach (split(",", $primary) as $pri) {
                                    $id_rec[$pri] = $env[$pri];
                                }
                                $newrec["state_returnid"] = db_data_to_code($id_rec);
                                $ok = db_insert("states", array($newrec)) && !$ERROR;
                                if ($ok) {
                                    if (true) {
                                        echo_rule($env);
                                        echo "call {$table}.{$field} to states\n";
                                    }
                                    // decide whether to finish the caller or not
                                    if ($mode == "call") {
                                        //echo "SHOULD_BREAK....\n";
                                        $env["DO_BREAK"] = true;
                                    } else {
                                    }
                                } else {
                                    check_answer($env, "DB_ERROR insert ({$ERROR})");
                                }
                            }
                        }
                    } else {
                        if (preg_match("/\\Areturn\\s+'((?:[^\\']|\\.)*)'(.*)/", $action, $matches)) {
                            $returnvalue = subst_macros($env, $matches[1], "'", "\\'");
                            $rest = $matches[2];
                            if (@$env["NO_RETURN"]) {
                                // original call was asynchronous: ignore return statement
                                check_answer($env, "NO_RETURN");
                                if (true) {
                                    $table = $env["TABLE"];
                                    $field = $env["FIELD"];
                                    echo_rule($env);
                                    echo "done asynchronous call {$table}.{$field}\n";
                                }
                                $ok = true;
                            } else {
                                // advance the caller's state
                                $split = split("\\.", $env["state_returnfield"]);
                                $tablename = $split[0];
                                $fieldname = $split[1];
                                $oldrec = eval("return " . $env["state_returnid"] . ";");
                                $data = db_read($tablename, null, $oldrec);
                                if (!$data || $ERROR) {
                                    engine_error("cannot re-read caller's data from table {$tablename}");
                                } else {
                                    if ($test = @$data[0]["state_env"]) {
                                        // original caller had an environment
                                        $oldenv = eval("return {$test};");
                                        while (preg_match("/\\A\\s*({$RAW_ID})\\s*=\\s*'((?:[^\\']|\\.)*)'(.*)/", $rest, $matches)) {
                                            $field = $matches[1];
                                            $value = $matches[2];
                                            $rest = $matches[3];
                                            $oldenv[$field] = subst_macros($env, $value, "'", "\\'");
                                        }
                                        if ($rest) {
                                            engine_warn("return statement has unparsable rest '{$rest}'");
                                        }
                                        $oldrec["state_env"] = db_data_to_code($oldenv);
                                    }
                                    $oldrec[$fieldname] = $returnvalue;
                                    if (true) {
                                        echo_rule($env);
                                        echo "return to {$tablename}.{$fieldname} = '{$returnvalue}'\n";
                                    }
                                    $ok = db_update($tablename, array($oldrec)) && !$ERROR;
                                    //echo "RETURN $tablename $fieldname='$returnvalue' ok='$ok' ERROR='$ERROR'\n";
                                    if (!$ok) {
                                        check_answer($env, "DB_ERROR update ({$ERROR})");
                                    }
                                }
                            }
                        } else {
                            engine_error("cannot parse action '{$action}'. correct your rules!");
                        }
                    }
                }
            }
        }
    }
    if ($ok) {
        $env["HIT_FLAG"] = true;
    }
    $env["LEVEL"] = $oldlevel;
    return $ok;
}
function db_write_code($tablename, $fieldname, $data)
{
    return "return " . db_data_to_code($data);
}
Example #5
0
function write_syncstatus()
{
    global $SYNC_STATUS;
    global $BASEDIR;
    $tmp_name = "{$BASEDIR}/compiled/sync_status.tmp";
    $fin_name = "{$BASEDIR}/compiled/sync_status.php";
    $fp = fopen($tmp_name, "w");
    if (!$fp) {
        die("cannot open syncstatus file\n");
    }
    fwrite($fp, "<?php // this file is automatically generated by the DB syncing system.\n\n// ====> DO NOT EDIT unless you EXACTLY know what you are doing! <===\n\n");
    fwrite($fp, "\$SYNC_STATUS =\n" . db_data_to_code($SYNC_STATUS));
    fwrite($fp, ";\n?>\n");
    fclose($fp);
    rename($tmp_name, $fin_name);
}