function _app_prepare_data($table, $querydata, $mode) { global $SCHEMA; global $PERM; global $TOOL, $TOOL_NAMES; $singular = _db_singular($table); $data = $TOOL; $data["DATA"] = db_force_data($table, $querydata); $data["TABLE"] = $table; $data["PRIMARY"] = _db_primary($table); $data["PRIMARIES"] = split(",", $data["PRIMARY"]); $data["UNIQUE"] = _db_unique($table); $data["UNIQUES"] = split(",", $data["UNIQUE"]); $data["PREFIX"] = ""; $data["SUFFIX"] = ""; $data["PERM"] = $PERM; $data["SCHEMA"] = $SCHEMA; $data["ACTION_SELF"] = $_SERVER["PHP_SELF"]; $action = dirname($_SERVER["PHP_SELF"]) . "/index.php?table={$table}"; $data["ACTION_BASE"] = $action; // generate link parameters reflecting current tools foreach ($TOOL_NAMES as $tool) { if (@$TOOL[$tool]) { $action .= "&{$tool}=" . htmlspecialchars($TOOL[$tool]); } } $data["ACTION"] = $action; if ($mode == "insert") { // check if immutable values are missing $immutable = array(); $oldrec = $data["DATA"][0]; $done = 0; foreach ($SCHEMA[$table]["FIELDS"] as $field => $info) { if (@$info["IMMUTABLE"]) { if (@$oldrec[$field]) { $done++; } //echo "immutable: $field<br>\n"; $immutable[$field] = true; $oldrec[$field] = @$oldrec[$field]; // ensure the key exists } } //echo "done: $done<br>\n"; if ($immutable && $done < count($immutable)) { // bail out any other fields $mode = "prepare"; $data["FIELDS"] = array(); $data["DATA"] = array(); foreach ($oldrec as $field => $value) { if (@$immutable[$field]) { //echo "transferring: $field<br>\n"; $data["FIELDS"][$field] = $field; $data["DATA"][0][$field] = $value; } } } else { $immutable = array(); } } $data["MODE"] = $mode; $data["IMMUTABLE"] = @$immutable; return $data; }
function _db_create_tables($OLD, $NEW, $database, &$count) { $count = 0; $query = ""; foreach ($NEW as $newtable => $newdef) { if (@$newdef["VIEW"]) { $query .= _db_create_view($NEW, $newtable, $newdef["VIEW"]); continue; } if ($newdef["DB"] != $database) { $query .= "/* skipping table '{$newtable}', not in database '{$database}' */\n\n"; continue; } if (!db_access_table($newtable, "w")) { $query .= "/* skipping table '{$newtable}', no write access */\n"; continue; } if (!@$newdef["SCHEMA_CONTROL"]) { $query .= "/* skipping table '{$newtable}', no schema control over it */\n"; continue; } $singular = _db_singular($newtable, $NEW); $primary = _db_primary($newtable, $NEW); $secondary = $singular . "_name"; // !!! not generic! $restrict = @$newdef["USER_RESTRICT"]; $tablename = $newtable; if ($restrict) { $tablename .= "_unrestr"; } $tablename .= "_tp"; // completely new table or delta? if (!isset($OLD[$newtable])) { $count++; $index = ""; $query .= "create table if not exists {$tablename} (\n"; foreach ($newdef["FIELDS"] as $field => $value) { if (@$value["VIRTUAL"]) { $query .= "/* omitting VIRTUAL {$field} */\n"; continue; } $query .= __db_create_field($field, $value); $query .= ",\n"; } $query .= " primary key({$primary}"; if ($newdef["TEMPORAL"]) { $query .= ", " . $NEW[$newtable]["FIELDNAME_VERSION"]; } $query .= "),\n"; $indices = _db_gen_indices($NEW, $newdef, $newtable, $secondary); foreach ($indices as $dummy => $index) { $query .= __db_create_index($index, false) . ",\n"; } $engine = isset($DEF[$newtable]["ENGINE"]) ? $DEF[$newtable]["ENGINE"] : ""; if (!$engine) { $engine = "myisam"; } $query = preg_replace("/,\\s*\\Z/m", "\n", $query); $query .= ") engine={$engine};\n"; $query .= __db_create_tpview($NEW, $newtable, $restrict); } else { // isset($OLD[$newtable]) => use "alter table" $olddef = $OLD[$newtable]; $flag = 0; $flag_col = 0; $after = ""; foreach ($newdef["FIELDS"] as $field => $value) { if (@$value["VIRTUAL"]) { //$query .= "/* omitting VIRTUAL $field */\n"; continue; } if (isset($value["CHANGE_FROM"])) { $count++; $oldfield = $value["CHANGE_FROM"]; $query .= "alter table {$tablename}\n"; $query .= " change column " . $oldfield . " " . __db_create_field($field, $value) . " {$after};\n"; unset($olddef["FIELDS"][$oldfield]); $flag++; $flag_col++; } elseif (isset($olddef["FIELDS"][$field])) { $oldvalue = $olddef["FIELDS"][$field]; $diff = false; foreach (array("SQL_TYPE", "DEFAULT", "BETWEEN", "LENGTH", "REGEX") as $test) { if (isset($value[$test]) && (!isset($oldvalue[$test]) || $value[$test] != $oldvalue[$test])) { $diff = true; } } if ($diff) { $count++; $query .= "alter table {$tablename}\n"; $query .= " modify column " . __db_create_field($field, $value) . " {$after};\n"; $flag++; $flag_col++; } if (!isset($value["DEFAULT"]) && isset($oldvalue["DEFAULT"])) { $query .= "alter table {$tablename}\n"; $query .= " alter column " . $field . " drop default;\n"; $flag++; $flag_col++; } } else { // create new column $count++; $query .= "alter table {$tablename}\n"; $query .= " add column" . __db_create_field($field, $value) . " {$after};\n"; $flag++; $flag_col++; } $after = "after {$field}"; } $oldindices = _db_gen_indices($OLD, $olddef, $newtable, $secondary); $newindices = _db_gen_indices($NEW, $newdef, $newtable, $secondary); foreach ($newindices as $index) { if (!in_array($index, $oldindices)) { $count++; $query .= "alter table {$tablename}\n"; $query .= " add" . __db_create_index($index, false) . ";\n"; $flag++; } } foreach ($oldindices as $index) { if (!in_array($index, $newindices)) { $count++; $query .= "alter table {$tablename}\n"; $query .= " drop" . __db_create_index($index, true) . ";\n"; $flag++; } } foreach ($olddef["FIELDS"] as $field => $value) { if (@$value["VIRTUAL"]) { //$query .= "/* omitting OLD VIRTUAL $field */\n"; continue; } if (!isset($newdef["FIELDS"][$field])) { $count++; $query .= "alter table {$tablename}\n"; $query .= " drop column {$field};\n"; $flag++; $flag_col++; } } if ($flag_col) { // whenever the *_tp table changes, mysql seems to require // recreation of the view (otherwise the old definition would remain) $count++; $query .= __db_create_tpview($NEW, $newtable, $restrict); } elseif ($flag) { $query .= "\n"; } } } foreach ($OLD as $oldtable => $olddef) { if (!isset($NEW[$newtable])) { $count++; $query .= "drop table " . $oldtable . "_tp\n"; $count++; $query .= "drop view " . $oldtable . "\n\n"; } } return $query; }
function _db_pass_main($MYSCHEMA) { // main pass $RES = array(); $maindatabase = _db_maindatabase(); foreach ($MYSCHEMA as $table => $tdef) { $newtdef = $tdef; if (@$tdef["VIEW"]) { global $SCHEMA; $SCHEMA = $MYSCHEMA; $databases = array(); $q2 = _db_mangle_query($databases, $tdef["VIEW"]); $tdef["FIELDS"] = $q2["SCHEMA_FIELDS"]; $newtdef["ACCESS"] = "R"; $newtdef["TEMPORAL"] = false; $newtdef["TOOLS"] = array("tool_search" => true, "tool_page" => true); } if (!@$tdef["SCHEMA_CONTROL"]) { $newtdef["SCHEMA_CONTROL"] = true; } if (!@$tdef["REALNAME"]) { $newtdef["REALNAME"] = $table; } if (!($singular = @$tdef["SINGULAR"])) { $singular = _db_singular($table, $MYSCHEMA); $newtdef["SINGULAR"] = $singular; } if (!($primary = @$tdef["PRIMARY"])) { $primary = _db_primary($table, $MYSCHEMA); $newtdef["PRIMARY"] = $primary; } if (!@$tdef["DB"]) { $newtdef["DB"] = $maindatabase; } $newfields = array(); foreach ($tdef["FIELDS"] as $field => $fdef) { if (!@$fdef["REALNAME"]) { $fdef["REALNAME"] = $field; } if (isset($fdef["REFERENCES"])) { $assoc = $fdef["REFERENCES"]; foreach ($assoc as $foreign => $props) { $all = preg_split("/\\s*\\.\\s*/s", $foreign, 2); $ftable = $all[0]; $ffield = $all[1]; if (!isset($MYSCHEMA[$ftable])) { die("REFERENCES: foreign table '{$ftable}' does not exist"); } if (!isset($MYSCHEMA[$ftable]["FIELDS"][$ffield])) { die("REFERENCES: foreign field '{$ffield}' of table '{$ftable}' does not exist"); } // the follwing will not work for cyclic references, deliberately $RES[$ftable]["XREF"][$ffield][] = array($table, $field, $props); } } $newfields[$field] = $fdef; } //echo "<br>newfields: "; print_r($newfields); echo "<br>\n"; $newtdef["FIELDS"] = $newfields; $MYSCHEMA[$table] = $newtdef; $RES[$table] = $newtdef; } return $RES; }