page_header(($name != "" ? lang('Alter check') . ": " . h($name) : lang('Create check')), $error, array("table" => $TABLE));
if (!$row) {
- $checks = $driver->checkConstraints($TABLE);
+ $checks = driver()->checkConstraints($TABLE);
$row = array("name" => $name, "clause" => $checks[$name]);
}
?>
page_header(($TABLE != "" ? lang('Alter table') : lang('Create table')), $error, array("table" => $TABLE), h($TABLE));
if (!$_POST) {
- $types = $driver->types();
+ $types = driver()->types();
$row = array(
"Engine" => $_COOKIE["adminer_engine"],
"fields" => array(array("field" => "", "type" => (isset($types["int"]) ? "int" : (isset($types["integer"]) ? "integer" : "")), "on_update" => "")),
if (is_array(reset($collations))) {
$collations = call_user_func_array('array_merge', array_values($collations));
}
-$engines = $driver->engines();
+$engines = driver()->engines();
// case of engine may differ
foreach ($engines as $engine) {
if (!strcasecmp($engine, $row["Engine"])) {
echo " <input type='submit' name='search' value='" . lang('Search') . "'>\n";
echo "</div></fieldset>\n";
if ($_POST["search"] && $_POST["query"] != "") {
- $_GET["where"][0]["op"] = $driver->convertOperator("LIKE %%");
+ $_GET["where"][0]["op"] = driver()->convertOperator("LIKE %%");
search_tables();
}
}
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=" . friendly_url("$TABLE-" . implode("_", $_GET["where"])) . "." . friendly_url($_GET["field"]));
$select = array(idf_escape($_GET["field"]));
-$result = $driver->select($TABLE, $select, array(where($_GET, $fields)), $select);
+$result = driver()->select($TABLE, $select, array(where($_GET, $fields)), $select);
$row = ($result ? $result->fetch_row() : array());
-echo $driver->value($row[0], $fields[$_GET["field"]]);
+echo driver()->value($row[0], $fields[$_GET["field"]]);
exit; // don't output footer
}
function create_sql($table, $auto_increment, $style) {
- global $driver;
if (is_view(table_status1($table))) {
$view = view($table);
return "CREATE VIEW " . table($table) . " AS $view[select]";
$fields[] = ($index["type"] == "INDEX" ? "INDEX $name" : "CONSTRAINT $name " . ($index["type"] == "UNIQUE" ? "UNIQUE" : "PRIMARY KEY")) . " (" . implode(", ", $columns) . ")";
}
}
- foreach ($driver->checkConstraints($table) as $name => $check) {
+ foreach (driver()->checkConstraints($table) as $name => $check) {
$fields[] = "CONSTRAINT " . idf_escape($name) . " CHECK ($check)";
}
return "CREATE TABLE " . table($table) . " (\n\t" . implode(",\n\t", $fields) . "\n)";
* @return ForeignKey[]
*/
function foreign_keys(string $table): array {
- global $driver;
static $pattern = '(?:`(?:[^`]|``)+`|"(?:[^"]|"")+")';
$return = array();
$create_table = get_val("SHOW CREATE TABLE " . table($table), 1);
if ($create_table) {
preg_match_all(
- "~CONSTRAINT ($pattern) FOREIGN KEY ?\\(((?:$pattern,? ?)+)\\) REFERENCES ($pattern)(?:\\.($pattern))? \\(((?:$pattern,? ?)+)\\)(?: ON DELETE ($driver->onActions))?(?: ON UPDATE ($driver->onActions))?~",
+ "~CONSTRAINT ($pattern) FOREIGN KEY ?\\(((?:$pattern,? ?)+)\\) REFERENCES ($pattern)(?:\\.($pattern))? \\(((?:$pattern,? ?)+)\\)(?: ON DELETE (driver()->onActions))?(?: ON UPDATE (driver()->onActions))?~",
$create_table,
$matches,
PREG_SET_ORDER
* @return Routine
*/
function routine(string $name, string $type): array {
- global $driver;
$aliases = array("bool", "boolean", "integer", "double precision", "real", "dec", "numeric", "fixed", "national char", "national varchar");
$space = "(?:\\s|/\\*[\s\S]*?\\*/|(?:#|-- )[^\n]*\n?|--\r?\n)";
- $enum = $driver->enumLength;
- $type_pattern = "((" . implode("|", array_merge(array_keys($driver->types()), $aliases)) . ")\\b(?:\\s*\\(((?:[^'\")]|$enum)++)\\))?"
+ $enum = driver()->enumLength;
+ $type_pattern = "((" . implode("|", array_merge(array_keys(driver()->types()), $aliases)) . ")\\b(?:\\s*\\(((?:[^'\")]|$enum)++)\\))?"
. "\\s*(zerofill\\s*)?(unsigned(?:\\s+zerofill)?)?)(?:\\s*(?:CHARSET|CHARACTER\\s+SET)\\s*['\"]?([^'\"\\s,]+)['\"]?)?";
- $pattern = "$space*(" . ($type == "FUNCTION" ? "" : $driver->inout) . ")?\\s*(?:`((?:[^`]|``)*)`\\s*|\\b(\\S+)\\s+)$type_pattern";
+ $pattern = "$space*(" . ($type == "FUNCTION" ? "" : driver()->inout) . ")?\\s*(?:`((?:[^`]|``)*)`\\s*|\\b(\\S+)\\s+)$type_pattern";
$create = get_val("SHOW CREATE $type " . idf_escape($name), 2);
preg_match("~\\(((?:$pattern\\s*,?)*)\\)\\s*" . ($type == "FUNCTION" ? "RETURNS\\s+$type_pattern\\s+" : "") . "(.*)~is", $create, $match);
$fields = array();
}
function foreign_keys($table) {
- global $driver;
$return = array();
foreach (
get_rows("SELECT conname, condeferrable::int AS deferrable, pg_get_constraintdef(oid) AS definition
$row['table'] = idf_unescape($match2[4]);
}
$row['target'] = array_map('Adminer\idf_unescape', array_map('trim', explode(',', $match[3])));
- $row['on_delete'] = (preg_match("~ON DELETE ($driver->onActions)~", $match[4], $match2) ? $match2[1] : 'NO ACTION');
- $row['on_update'] = (preg_match("~ON UPDATE ($driver->onActions)~", $match[4], $match2) ? $match2[1] : 'NO ACTION');
+ $row['on_delete'] = (preg_match("~ON DELETE (driver()->onActions)~", $match[4], $match2) ? $match2[1] : 'NO ACTION');
+ $row['on_update'] = (preg_match("~ON UPDATE (driver()->onActions)~", $match[4], $match2) ? $match2[1] : 'NO ACTION');
$return[$row['conname']] = $row;
}
}
}
function set_schema($schema, $connection2 = null) {
- global $connection, $driver;
+ global $connection;
if (!$connection2) {
$connection2 = $connection;
}
$return = $connection2->query("SET search_path TO " . idf_escape($schema));
- $driver->setUserTypes(types()); //! get types from current_schemas('t')
+ driver()->setUserTypes(types()); //! get types from current_schemas('t')
return $return;
}
}
function create_sql($table, $auto_increment, $style) {
- global $driver;
$return_parts = array();
$sequences = array();
}
}
- foreach ($driver->checkConstraints($table) as $conname => $consrc) {
+ foreach (driver()->checkConstraints($table) as $conname => $consrc) {
$return_parts[] = "CONSTRAINT " . idf_escape($conname) . " CHECK $consrc";
}
* @param string $add_check CHECK constraint to add
*/
function recreate_table(string $table, string $name, array $fields, array $originals, array $foreign, int $auto_increment = 0, $indexes = array(), string $drop_check = "", string $add_check = ""): bool {
- global $driver;
if ($table != "") {
if (!$fields) {
foreach (fields($table) as $key => $field) {
$changes[] = " " . implode($field);
}
$changes = array_merge($changes, array_filter($foreign));
- foreach ($driver->checkConstraints($table) as $check) {
+ foreach (driver()->checkConstraints($table) as $check) {
if ($check != $drop_check) {
$changes[] = " CHECK ($check)";
}
queries_redirect(
$location,
lang('Item has been deleted.'),
- $driver->delete($TABLE, $query_where, !$unique_array)
+ driver()->delete($TABLE, $query_where, !$unique_array)
);
} else {
queries_redirect(
$location,
lang('Item has been updated.'),
- $driver->update($TABLE, $set, $query_where, !$unique_array)
+ driver()->update($TABLE, $set, $query_where, !$unique_array)
);
if (is_ajax()) {
page_headers();
exit;
}
} else {
- $result = $driver->insert($TABLE, $set);
+ $result = driver()->insert($TABLE, $set);
$last_id = ($result ? last_id($result) : 0);
queries_redirect($location, lang('Item%s has been inserted.', ($last_id ? " $last_id" : "")), $result); //! link
}
$select = array("*");
}
if ($select) {
- $result = $driver->select($TABLE, $select, array($where), $select, array(), (isset($_GET["select"]) ? 2 : 1));
+ $result = driver()->select($TABLE, $select, array($where), $select, array(), (isset($_GET["select"]) ? 2 : 1));
if (!$result) {
$error = error();
} else {
if (!support("table") && !$fields) { // used by Mongo and SimpleDB
if (!$where) { // insert
- $result = $driver->select($TABLE, array("*"), $where, array("*"));
+ $result = driver()->select($TABLE, array("*"), $where, array("*"));
$row = ($result ? $result->fetch_assoc() : false);
if (!$row) {
- $row = array($driver->primary => "");
+ $row = array(driver()->primary => "");
}
}
if ($row) {
if (!$where) {
$row[$key] = null;
}
- $fields[$key] = array("field" => $key, "null" => ($key != $driver->primary), "auto_increment" => ($key == $driver->primary));
+ $fields[$key] = array("field" => $key, "null" => ($key != driver()->primary), "auto_increment" => ($key == driver()->primary));
}
}
}
?>
</table>
<p>
-<?php echo lang('ON DELETE'); ?>: <?php echo html_select("on_delete", array(-1 => "") + explode("|", $driver->onActions), $row["on_delete"]); ?>
- <?php echo lang('ON UPDATE'); ?>: <?php echo html_select("on_update", array(-1 => "") + explode("|", $driver->onActions), $row["on_update"]); ?>
+<?php echo lang('ON DELETE'); ?>: <?php echo html_select("on_delete", array(-1 => "") + explode("|", driver()->onActions), $row["on_delete"]); ?>
+ <?php echo lang('ON UPDATE'); ?>: <?php echo html_select("on_update", array(-1 => "") + explode("|", driver()->onActions), $row["on_update"]); ?>
<?php echo doc_link(array(
'sql' => "innodb-foreign-key-constraints.html",
'mariadb' => "foreign-keys/",
* @return list<string> operators
*/
function operators(): array {
- global $driver;
- return $driver->operators;
+ return driver()->operators;
}
/** Get list of schemas
* @param ?string $set new item options, NULL for no new item
*/
function selectLinks(array $tableStatus, ?string $set = ""): void {
- global $driver;
echo '<p class="links">';
$links = array("select" => lang('Select data'));
if (support("table") || support("indexes")) {
foreach ($links as $key => $val) {
echo " <a href='" . h(ME) . "$key=" . urlencode($name) . ($key == "edit" ? $set : "") . "'" . bold(isset($_GET[$key])) . ">$val</a>";
}
- echo doc_link(array(JUSH => $driver->tableHelp($name, $is_view)), "?");
+ echo doc_link(array(JUSH => driver()->tableHelp($name, $is_view)), "?");
echo "\n";
}
* @param float $start start time of the query
*/
function selectQuery(string $query, float $start, bool $failed = false): string {
- global $driver;
$return = "</p>\n"; // required for IE9 inline edit
- if (!$failed && ($warnings = $driver->warnings())) {
+ if (!$failed && ($warnings = driver()->warnings())) {
$id = "warnings";
$return = ", <a href='#$id'>" . lang('Warnings') . "</a>" . script("qsl('a').onclick = partial(toggle, '$id');", "")
. "$return<div id='$id' class='hidden'>\n$warnings</div>\n"
* @param TableStatus $tableStatus
*/
function tableStructurePrint(array $fields, array $tableStatus = null): void {
- global $driver;
echo "<div class='scrollable'>\n";
echo "<table class='nowrap odds'>\n";
echo "<thead><tr><th>" . lang('Column') . "<td>" . lang('Type') . (support("comment") ? "<td>" . lang('Comment') : "") . "</thead>\n";
- $structured_types = $driver->structuredTypes();
+ $structured_types = driver()->structuredTypes();
foreach ($fields as $field) {
echo "<tr><th>" . h($field["field"]);
$type = h($field["full_type"]);
* @param string[] $columns selectable columns
*/
function selectColumnsPrint(array $select, array $columns): void {
- global $driver;
print_fieldset("select", lang('Select'), $select);
$i = 0;
$select[""] = array();
$val["col"],
($key !== "" ? "selectFieldChange" : "selectAddRow")
);
- echo "<div>" . ($driver->functions || $driver->grouping ? html_select("columns[$i][fun]", array(-1 => "") + array_filter(array(lang('Functions') => $driver->functions, lang('Aggregation') => $driver->grouping)), $val["fun"])
+ echo "<div>" . (driver()->functions || driver()->grouping ? html_select("columns[$i][fun]", array(-1 => "") + array_filter(array(lang('Functions') => driver()->functions, lang('Aggregation') => driver()->grouping)), $val["fun"])
. on_help("event.target.value && event.target.value.replace(/ |\$/, '(') + ')'", 1)
. script("qsl('select').onchange = function () { helpClose();" . ($key !== "" ? "" : " qsl('select, input', this.parentNode).onchange();") . " };", "")
. "($column)" : $column) . "</div>\n";
* @return list<list<string>> [[select_expressions], [group_expressions]]
*/
function selectColumnsProcess(array $columns, array $indexes): array {
- global $driver;
$select = array(); // select expressions, empty for *
$group = array(); // expressions without aggregation - will be used for GROUP BY if an aggregation function is used
foreach ((array) $_GET["columns"] as $key => $val) {
- if ($val["fun"] == "count" || ($val["col"] != "" && (!$val["fun"] || in_array($val["fun"], $driver->functions) || in_array($val["fun"], $driver->grouping)))) {
+ if ($val["fun"] == "count" || ($val["col"] != "" && (!$val["fun"] || in_array($val["fun"], driver()->functions) || in_array($val["fun"], driver()->grouping)))) {
$select[$key] = apply_sql_function($val["fun"], ($val["col"] != "" ? idf_escape($val["col"]) : "*"));
- if (!in_array($val["fun"], $driver->grouping)) {
+ if (!in_array($val["fun"], driver()->grouping)) {
$group[] = $select[$key];
}
}
* @return list<string> expressions to join by AND
*/
function selectSearchProcess(array $fields, array $indexes): array {
- global $connection, $driver;
+ global $connection;
$return = array();
foreach ($indexes as $i => $index) {
if ($index["type"] == "FULLTEXT" && $_GET["fulltext"][$i] != "") {
$cond .= " " . adminer()->processInput($fields[$val["col"]], $val["val"]);
}
if ($val["col"] != "") {
- $return[] = $prefix . $driver->convertSearch(idf_escape($val["col"]), $val, $fields[$val["col"]]) . $cond;
+ $return[] = $prefix . driver()->convertSearch(idf_escape($val["col"]), $val, $fields[$val["col"]]) . $cond;
} else {
// find anywhere
$cols = array();
&& (!preg_match("~[\x80-\xFF]~", $val["val"]) || preg_match('~char|text|enum|set~', $field["type"]))
&& (!preg_match('~date|timestamp~', $field["type"]) || preg_match('~^\d+-\d+-\d+~', $val["val"]))
) {
- $cols[] = $prefix . $driver->convertSearch(idf_escape($name), $val, $field) . $cond;
+ $cols[] = $prefix . driver()->convertSearch(idf_escape($name), $val, $field) . $cond;
}
}
$return[] = ($cols ? "(" . implode(" OR ", $cols) . ")" : "1 = 0");
* @param string $time elapsed time
*/
function messageQuery(string $query, string $time, bool $failed = false): string {
- global $driver;
restart_session();
$history = &get_session("queries");
if (!idx($history, $_GET["db"])) {
$history[$_GET["db"]][] = array($query, time(), $time); // not DB - $_GET["db"] is changed in database.inc.php //! respect $_GET["ns"]
$sql_id = "sql-" . count($history[$_GET["db"]]);
$return = "<a href='#$sql_id' class='toggle'>" . lang('SQL command') . "</a>\n";
- if (!$failed && ($warnings = $driver->warnings())) {
+ if (!$failed && ($warnings = driver()->warnings())) {
$id = "warnings-" . count($history[$_GET["db"]]);
$return = "<a href='#$id' class='toggle'>" . lang('Warnings') . "</a>, $return<div id='$id' class='hidden'>\n$warnings</div>\n";
}
* @return list<string>
*/
function editFunctions(array $field): array {
- global $driver;
$return = ($field["null"] ? "NULL/" : "");
$update = isset($_GET["select"]) || where($_GET);
- foreach (array($driver->insertFunctions, $driver->editFunctions) as $key => $functions) {
+ foreach (array(driver()->insertFunctions, driver()->editFunctions) as $key => $functions) {
if (!$key || (!isset($_GET["call"]) && $update)) { // relative functions
foreach ($functions as $pattern => $val) {
if (!$pattern || preg_match("~$pattern~", $field["type"])) {
check_invalid_login($permanent);
$connection = connect(adminer()->credentials());
if (is_object($connection)) {
- $driver = new Driver($connection);
+ Driver::$instance = new Driver($connection);
if ($connection->flavor) {
save_settings(array("vendor-" . DRIVER . "-" . SERVER => get_driver(DRIVER)));
}
exit;
}
-global $connection, $driver, $translations; // allows including Adminer inside a function
+global $connection, $translations; // allows including Adminer inside a function
if (!$_SERVER["REQUEST_URI"]) { // IIS 5 compatibility
$_SERVER["REQUEST_URI"] = $_SERVER["ORIG_PATH_INFO"];
}
abstract class SqlDriver {
- /** @var string[] */ static array $drivers = array();
- /** @var list<string> */ static array $extensions = array(); // possible extensions
+ static Driver $instance;
+ /** @var string[] */ static array $drivers = array(); // all available drivers
+ /** @var list<string> */ static array $extensions = array(); // possible extensions in the current driver
static string $jush; // JUSH identifier
protected Db $conn;
* @param list<string> $extra_types extra types to prepend
*/
function edit_type(string $key, array $field, array $collations, array $foreign_keys = array(), array $extra_types = array()): void {
- global $driver;
$type = $field["type"];
echo "<td><select name='" . h($key) . "[type]' class='type' aria-labelledby='label-type'>";
- if ($type && !array_key_exists($type, $driver->types()) && !isset($foreign_keys[$type]) && !in_array($type, $extra_types)) {
+ if ($type && !array_key_exists($type, driver()->types()) && !isset($foreign_keys[$type]) && !in_array($type, $extra_types)) {
$extra_types[] = $type;
}
- $structured_types = $driver->structuredTypes();
+ $structured_types = driver()->structuredTypes();
if ($foreign_keys) {
$structured_types[lang('Foreign keys')] = $foreign_keys;
}
? "<input list='collations' name='" . h($key) . "[collation]'" . (preg_match('~(char|text|enum|set)$~', $type) ? "" : " class='hidden'") . " value='" . h($field["collation"]) . "' placeholder='(" . lang('collation') . ")'>"
: ''
);
- echo ($driver->unsigned ? "<select name='" . h($key) . "[unsigned]'" . (!$type || preg_match(number_type(), $type) ? "" : " class='hidden'") . '><option>' . optionlist($driver->unsigned, $field["unsigned"]) . '</select>' : '');
+ echo (driver()->unsigned ? "<select name='" . h($key) . "[unsigned]'" . (!$type || preg_match(number_type(), $type) ? "" : " class='hidden'") . '><option>' . optionlist(driver()->unsigned, $field["unsigned"]) . '</select>' : '');
echo (isset($field['on_update']) ? "<select name='" . h($key) . "[on_update]'" . (preg_match('~timestamp|datetime~', $type) ? "" : " class='hidden'") . '>'
. optionlist(array("" => "(" . lang('ON UPDATE') . ")", "CURRENT_TIMESTAMP"), (preg_match('~^CURRENT_TIMESTAMP~i', $field["on_update"]) ? "CURRENT_TIMESTAMP" : $field["on_update"]))
. '</select>' : ''
);
echo ($foreign_keys
- ? "<select name='" . h($key) . "[on_delete]'" . (preg_match("~`~", $type) ? "" : " class='hidden'") . "><option value=''>(" . lang('ON DELETE') . ")" . optionlist(explode("|", $driver->onActions), $field["on_delete"]) . "</select> "
+ ? "<select name='" . h($key) . "[on_delete]'" . (preg_match("~`~", $type) ? "" : " class='hidden'") . "><option value=''>(" . lang('ON DELETE') . ")" . optionlist(explode("|", driver()->onActions), $field["on_delete"]) . "</select> "
: " " // space for IE
);
}
/** Filter length value including enums */
function process_length(?string $length): string {
- global $driver;
- $enum_length = $driver->enumLength;
+ $enum_length = driver()->enumLength;
return (preg_match("~^\\s*\\(?\\s*$enum_length(?:\\s*,\\s*$enum_length)*+\\s*\\)?\\s*\$~", $length) && preg_match_all("~$enum_length~", $length, $matches)
? "(" . implode(",", $matches[0]) . ")"
: preg_replace('~^[0-9].*~', '(\0)', preg_replace('~[^-0-9,+()[\]]~', '', $length))
* @param FieldType $field
*/
function process_type(array $field, string $collate = "COLLATE"): string {
- global $driver;
return " $field[type]"
. process_length($field["length"])
- . (preg_match(number_type(), $field["type"]) && in_array($field["unsigned"], $driver->unsigned) ? " $field[unsigned]" : "")
+ . (preg_match(number_type(), $field["type"]) && in_array($field["unsigned"], driver()->unsigned) ? " $field[unsigned]" : "")
. (preg_match('~char|text|enum|set~', $field["type"]) && $field["collation"] ? " $collate " . (JUSH == "mssql" ? $field["collation"] : q($field["collation"])) : "")
;
}
* @param Field $field
*/
function default_value(array $field): string {
- global $driver;
$default = $field["default"];
$generated = $field["generated"];
- return ($default === null ? "" : (in_array($generated, $driver->generated)
+ return ($default === null ? "" : (in_array($generated, driver()->generated)
? (JUSH == "mssql" ? " AS ($default)" . ($generated == "VIRTUAL" ? "" : " $generated") . "" : " GENERATED ALWAYS AS ($default) $generated")
: " DEFAULT " . (!preg_match('~^GENERATED ~i', $default) && (preg_match('~char|binary|text|json|enum|set~', $field["type"]) || preg_match('~^(?![a-z])~i', $default))
? (JUSH == "sql" && preg_match('~text|json~', $field["type"]) ? "(" . q($default) . ")" : q($default)) // MySQL requires () around default value of text column
* @param string[] $foreign_keys
*/
function edit_fields(array $fields, array $collations, $type = "TABLE", array $foreign_keys = array()): void {
- global $driver;
$fields = array_values($fields);
$default_class = (($_POST ? $_POST["defaults"] : get_setting("defaults")) ? "" : " class='hidden'");
$comment_class = (($_POST ? $_POST["comments"] : get_setting("comments")) ? "" : " class='hidden'");
$orig = $field[($_POST ? "orig" : "field")];
$display = (isset($_POST["add"][$i-1]) || (isset($field["field"]) && !idx($_POST["drop_col"], $i))) && (support("drop_col") || $orig == "");
echo "<tr" . ($display ? "" : " style='display: none;'") . ">\n";
- echo ($type == "PROCEDURE" ? "<td>" . html_select("fields[$i][inout]", explode("|", $driver->inout), $field["inout"]) : "") . "<th>";
+ echo ($type == "PROCEDURE" ? "<td>" . html_select("fields[$i][inout]", explode("|", driver()->inout), $field["inout"]) : "") . "<th>";
if ($display) {
echo "<input name='fields[$i][field]' value='" . h($field["field"]) . "' data-maxlength='64' autocapitalize='off' aria-labelledby='label-name'>";
}
if ($type == "TABLE") {
echo "<td>" . checkbox("fields[$i][null]", 1, $field["null"], "", "", "block", "label-null");
echo "<td><label class='block'><input type='radio' name='auto_increment_col' value='$i'" . ($field["auto_increment"] ? " checked" : "") . " aria-labelledby='label-ai'></label>";
- echo "<td$default_class>" . ($driver->generated
- ? html_select("fields[$i][generated]", array_merge(array("", "DEFAULT"), $driver->generated), $field["generated"]) . " "
+ echo "<td$default_class>" . (driver()->generated
+ ? html_select("fields[$i][generated]", array_merge(array("", "DEFAULT"), driver()->generated), $field["generated"]) . " "
: checkbox("fields[$i][generated]", 1, $field["generated"], "", "", "", "label-default")
);
echo "<input name='fields[$i][default]' value='" . h($field["default"]) . "' aria-labelledby='label-default'>";
* @param Routine $row
*/
function create_routine($routine, array $row): string {
- global $driver;
$set = array();
$fields = (array) $row["fields"];
ksort($fields); // enforce fields order
foreach ($fields as $field) {
if ($field["field"] != "") {
- $set[] = (preg_match("~^($driver->inout)\$~", $field["inout"]) ? "$field[inout] " : "") . idf_escape($field["field"]) . process_type($field, "CHARACTER SET");
+ $set[] = (preg_match("~^(driver()->inout)\$~", $field["inout"]) ? "$field[inout] " : "") . idf_escape($field["field"]) . process_type($field, "CHARACTER SET");
}
}
$definition = rtrim($row["definition"], ";");
* @param ForeignKey $foreign_key
*/
function format_foreign_key(array $foreign_key): string {
- global $driver;
$db = $foreign_key["db"];
$ns = $foreign_key["ns"];
return " FOREIGN KEY (" . implode(", ", array_map('Adminer\idf_escape', $foreign_key["source"])) . ") REFERENCES "
. ($ns != "" && $ns != $_GET["ns"] ? idf_escape($ns) . "." : "")
. idf_escape($foreign_key["table"])
. " (" . implode(", ", array_map('Adminer\idf_escape', $foreign_key["target"])) . ")" //! reuse $name - check in older MySQL versions
- . (preg_match("~^($driver->onActions)\$~", $foreign_key["on_delete"]) ? " ON DELETE $foreign_key[on_delete]" : "")
- . (preg_match("~^($driver->onActions)\$~", $foreign_key["on_update"]) ? " ON UPDATE $foreign_key[on_update]" : "")
+ . (preg_match("~^(driver()->onActions)\$~", $foreign_key["on_delete"]) ? " ON DELETE $foreign_key[on_delete]" : "")
+ . (preg_match("~^(driver()->onActions)\$~", $foreign_key["on_update"]) ? " ON UPDATE $foreign_key[on_update]" : "")
;
}
/** Get Driver object */
function driver(): Driver {
- global $driver;
- return $driver;
+ return Driver::$instance;
}
/** Unescape database identifier
* @return Field[] same as fields()
*/
function fields_from_edit(): array { // used by Mongo and SimpleDB
- global $driver;
$return = array();
foreach ((array) $_POST["field_keys"] as $key => $val) {
if ($val != "") {
"field" => $name,
"privileges" => array("insert" => 1, "update" => 1, "where" => 1, "order" => 1),
"null" => 1,
- "auto_increment" => ($key == $driver->primary),
+ "auto_increment" => ($key == driver()->primary),
);
}
return $return;
* @return string[]
*/
function slow_query(string $query): array {
- global $driver;
$db = adminer()->database();
$timeout = adminer()->queryTimeout();
- $slow_query = $driver->slowQuery($query, $timeout);
+ $slow_query = driver()->slowQuery($query, $timeout);
$connection2 = null;
if (!$slow_query && support("kill")) {
$connection2 = connect(adminer()->credentials());
* @param mixed $value
*/
function input(array $field, $value, ?string $function, ?bool $autofocus = false): void {
- global $driver;
$name = h(bracket_escape($field["field"]));
echo "<td class='function'>";
if (is_array($value) && !$function) {
$functions = (isset($_GET["select"]) || $reset ? array("orig" => lang('original')) : array()) + adminer()->editFunctions($field);
$disabled = stripos($field["default"], "GENERATED ALWAYS AS ") === 0 ? " disabled=''" : "";
$attrs = " name='fields[$name]'$disabled" . ($autofocus ? " autofocus" : "");
- $enums = $driver->enumLength($field);
+ $enums = driver()->enumLength($field);
if ($enums) {
$field["type"] = "enum";
$field["length"] = $enums;
}
- echo $driver->unconvertFunction($field) . " ";
+ echo driver()->unconvertFunction($field) . " ";
$table = $_GET["edit"] ?: $_GET["select"];
if ($field["type"] == "enum") {
echo h($functions[""]) . "<td>" . adminer()->editInput($table, $field, $attrs, $value);
echo "<textarea$attrs>" . h($value) . '</textarea>';
} else {
// int(3) is only a display hint
- $types = $driver->types();
+ $types = driver()->types();
$maxlength = (!preg_match('~int~', $field["type"]) && preg_match('~^(\d+)(,(\d+))?$~', $field["length"], $match)
? ((preg_match("~binary~", $field["type"]) ? 2 : 1) * $match[1] + ($match[3] ? 1 : 0) + ($match[2] && !$field["unsigned"] ? 1 : 0))
: ($types[$field["type"]] ? $types[$field["type"]] + ($field["unsigned"] ? 0 : 1) : 0)
* @return mixed false to leave the original value
*/
function process_input(array $field) {
- global $driver;
if (stripos($field["default"], "GENERATED ALWAYS AS ") === 0) {
return;
}
$idf = bracket_escape($field["field"]);
$function = idx($_POST["function"], $idf);
$value = $_POST["fields"][$idf];
- if ($field["type"] == "enum" || $driver->enumLength($field)) {
+ if ($field["type"] == "enum" || driver()->enumLength($field)) {
if ($value == -1) {
return false;
}
if (!is_string($file)) {
return false; //! report errors
}
- return $driver->quoteBinary($file);
+ return driver()->quoteBinary($file);
}
return adminer()->processInput($field, $value, $function);
}
$as = convert_field($fields[key($row)]);
$select = array($as ?: idf_escape(key($row)));
$where[] = where_check($unique_idf, $fields);
- $return = $driver->select($TABLE, $select, $where, $select);
+ $return = driver()->select($TABLE, $select, $where, $select);
if ($return) {
echo first($return->fetch_row());
}
$query = ($_POST["clone"] ? "INTO " . table($TABLE) . " (" . implode(", ", array_keys($set)) . ")\nSELECT " . implode(", ", $set) . "\nFROM " . table($TABLE) : "");
if ($_POST["all"] || ($primary && is_array($_POST["check"])) || $is_group) {
$result = ($_POST["delete"]
- ? $driver->delete($TABLE, $where_check)
+ ? driver()->delete($TABLE, $where_check)
: ($_POST["clone"]
- ? queries("INSERT $query$where_check" . $driver->insertReturning($TABLE))
- : $driver->update($TABLE, $set, $where_check)
+ ? queries("INSERT $query$where_check" . driver()->insertReturning($TABLE))
+ : driver()->update($TABLE, $set, $where_check)
)
);
$affected = $connection->affected_rows;
// where is not unique so OR can't be used
$where2 = "\nWHERE " . ($where ? implode(" AND ", $where) . " AND " : "") . where_check($val, $fields);
$result = ($_POST["delete"]
- ? $driver->delete($TABLE, $where2, 1)
+ ? driver()->delete($TABLE, $where2, 1)
: ($_POST["clone"]
? queries("INSERT" . limit1($TABLE, $query, $where2))
- : $driver->update($TABLE, $set, $where2, 1)
+ : driver()->update($TABLE, $set, $where2, 1)
)
);
if (!$result) {
$key = bracket_escape($key, true); // true - back
$set[idf_escape($key)] = (preg_match('~char|text~', $fields[$key]["type"]) || $val != "" ? adminer()->processInput($fields[$key], $val) : "NULL");
}
- $result = $driver->update(
+ $result = driver()->update(
$TABLE,
$set,
" WHERE " . ($where ? implode(" AND ", $where) . " AND " : "") . where_check($unique_idf, $fields),
$cols = array_keys($fields);
preg_match_all('~(?>"[^"]*"|[^"\r\n]+)+~', $file, $matches);
$affected = count($matches[0]);
- $driver->begin();
+ driver()->begin();
$separator = ($_POST["separator"] == "csv" ? "," : ($_POST["separator"] == "tsv" ? "\t" : ";"));
$rows = array();
foreach ($matches[0] as $key => $val) {
$rows[] = $set;
}
}
- $result = (!$rows || $driver->insertUpdate($TABLE, $rows, $primary));
+ $result = (!$rows || driver()->insertUpdate($TABLE, $rows, $primary));
if ($result) {
- $driver->commit();
+ driver()->commit();
}
queries_redirect(remove_from_uri("page"), lang('%d row(s) have been imported.', $affected), $result);
- $driver->rollback(); // after queries_redirect() to not overwrite error
+ driver()->rollback(); // after queries_redirect() to not overwrite error
}
}
}
}
}
- $result = $driver->select($TABLE, $select2, $where, $group2, $order, $limit, $page, true);
+ $result = driver()->select($TABLE, $select2, $where, $group2, $order, $limit, $page, true);
if (!$result) {
echo "<p class='error'>" . error() . "\n";
foreach ($row as $key => $val) {
if (isset($names[$key])) {
$field = $fields[$key];
- $val = $driver->value($val, $field);
+ $val = driver()->value($val, $field);
if ($val != "" && (!isset($email_fields[$key]) || $email_fields[$key] != "")) {
$email_fields[$key] = (is_mail($val) ? $names[$key] : ""); //! filled e-mails can be contained on other pages
}
$offset = $pos + strlen($found);
if ($found && rtrim($found) != $delimiter) { // find matching quote or comment end
- $c_style_escapes = $driver->hasCStyleEscapes() || (JUSH == "pgsql" && ($pos > 0 && strtolower($query[$pos - 1]) == "e"));
+ $c_style_escapes = driver()->hasCStyleEscapes() || (JUSH == "pgsql" && ($pos > 0 && strtolower($query[$pos - 1]) == "e"));
$pattern = ($found == '/*' ? '\*/'
: ($found == '[' ? ']'
. (strlen($q) < 1000 ? " <a href='" . h(ME) . "sql=" . urlencode(trim($q)) . "'>" . lang('Edit') . "</a>" : "") // 1000 - maximum length of encoded URL in IE is 2083 characters
;
$affected = $connection->affected_rows; // getting warnings overwrites this
- $warnings = ($_POST["only_errors"] ? "" : $driver->warnings());
+ $warnings = ($_POST["only_errors"] ? "" : driver()->warnings());
$warnings_id = "warnings-$commands";
if ($warnings) {
$time .= ", <a href='#$warnings_id'>" . lang('Warnings') . "</a>" . script("qsl('a').onclick = partial(toggle, '$warnings_id');", "");
adminer()->tableStructurePrint($fields, $table_status);
}
-if (support("indexes") && $driver->supportsIndex($table_status)) {
+if (support("indexes") && driver()->supportsIndex($table_status)) {
echo "<h3 id='indexes'>" . lang('Indexes') . "</h3>\n";
$indexes = indexes($TABLE);
if ($indexes) {
if (support("check")) {
echo "<h3 id='checks'>" . lang('Checks') . "</h3>\n";
- $check_constraints = $driver->checkConstraints($TABLE);
+ $check_constraints = driver()->checkConstraints($TABLE);
if ($check_constraints) {
echo "<table>\n";
foreach ($check_constraints as $key => $val) {
<p>
<?php
if ($TYPE != "") {
- $types = $driver->types();
+ $types = driver()->types();
$enums = type_values($types[$TYPE]);
if ($enums) {
echo "<code class='jush-" . JUSH . "'>ENUM (" . h($enums) . ")</code>\n<p>";
}
function selectSearchProcess($fields, $indexes) {
- global $driver;
$return = array();
foreach ((array) $_GET["where"] as $key => $where) {
$col = $where["col"];
} else {
$text_type = preg_match('~char|text|enum|set~', $field["type"]);
$value = adminer()->processInput($field, (!$op && $text_type && preg_match('~^[^%]+$~', $val) ? "%$val%" : $val));
- $conds[] = $driver->convertSearch($name, $where, $field) . ($value == "NULL" ? " IS" . ($op == ">=" ? " NOT" : "") . " $value"
+ $conds[] = driver()->convertSearch($name, $where, $field) . ($value == "NULL" ? " IS" . ($op == ">=" ? " NOT" : "") . " $value"
: (in_array($op, adminer()->operators()) || $op == "=" ? " $op $value"
: ($text_type ? " LIKE $value"
: " IN (" . str_replace(",", "', '", $value) . ")"