1
0
mirror of https://github.com/vrana/adminer.git synced 2025-08-05 06:07:57 +02:00

Use driver() instead of $driver

This commit is contained in:
Jakub Vrana
2025-03-29 21:00:44 +01:00
parent 845445baad
commit 168ea5ae6d
22 changed files with 83 additions and 109 deletions

View File

@@ -24,7 +24,7 @@ if ($row && !$error) {
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]);
}
?>

View File

@@ -140,7 +140,7 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
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" => "")),
@@ -171,7 +171,7 @@ $collations = collations();
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"])) {

View File

@@ -69,7 +69,7 @@ if (adminer()->homepage()) {
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();
}
}

View File

@@ -6,7 +6,7 @@ $fields = fields($TABLE);
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

View File

@@ -640,7 +640,6 @@ WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table)) as $row
}
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]";
@@ -664,7 +663,7 @@ WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table)) as $row
$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)";

View File

@@ -556,13 +556,12 @@ if (!defined('Adminer\DRIVER')) {
* @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
@@ -860,13 +859,12 @@ if (!defined('Adminer\DRIVER')) {
* @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();

View File

@@ -484,7 +484,6 @@ ORDER BY indisprimary DESC, indisunique DESC", $connection2) as $row
}
function foreign_keys($table) {
global $driver;
$return = array();
foreach (
get_rows("SELECT conname, condeferrable::int AS deferrable, pg_get_constraintdef(oid) AS definition
@@ -500,8 +499,8 @@ ORDER BY conkey, conname") as $row
$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;
}
}
@@ -793,12 +792,12 @@ AND typelem = 0"
}
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;
}
@@ -820,7 +819,6 @@ AND typelem = 0"
}
function create_sql($table, $auto_increment, $style) {
global $driver;
$return_parts = array();
$sequences = array();
@@ -872,7 +870,7 @@ AND typelem = 0"
}
}
foreach ($driver->checkConstraints($table) as $conname => $consrc) {
foreach (driver()->checkConstraints($table) as $conname => $consrc) {
$return_parts[] = "CONSTRAINT " . idf_escape($conname) . " CHECK $consrc";
}

View File

@@ -459,7 +459,6 @@ if (isset($_GET["sqlite"])) {
* @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) {
@@ -524,7 +523,7 @@ if (isset($_GET["sqlite"])) {
$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)";
}

View File

@@ -27,7 +27,7 @@ if ($_POST && !$error && !isset($_GET["select"])) {
queries_redirect(
$location,
lang('Item has been deleted.'),
$driver->delete($TABLE, $query_where, !$unique_array)
driver()->delete($TABLE, $query_where, !$unique_array)
);
} else {
@@ -46,7 +46,7 @@ if ($_POST && !$error && !isset($_GET["select"])) {
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();
@@ -54,7 +54,7 @@ if ($_POST && !$error && !isset($_GET["select"])) {
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
}
@@ -77,7 +77,7 @@ if ($_POST["save"]) {
$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 {
@@ -94,10 +94,10 @@ if ($_POST["save"]) {
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) {
@@ -105,7 +105,7 @@ if (!support("table") && !$fields) { // used by Mongo and SimpleDB
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));
}
}
}

View File

@@ -101,8 +101,8 @@ foreach ($row["source"] as $key => $val) {
?>
</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/",

View File

@@ -64,8 +64,7 @@ class Adminer {
* @return list<string> operators
*/
function operators(): array {
global $driver;
return $driver->operators;
return driver()->operators;
}
/** Get list of schemas
@@ -175,7 +174,6 @@ class Adminer {
* @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")) {
@@ -197,7 +195,7 @@ class Adminer {
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";
}
@@ -227,9 +225,8 @@ class Adminer {
* @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"
@@ -307,11 +304,10 @@ class Adminer {
* @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"]);
@@ -357,7 +353,6 @@ class Adminer {
* @param string[] $columns selectable columns
*/
function selectColumnsPrint(array $select, array $columns): void {
global $driver;
print_fieldset("select", lang('Select'), $select);
$i = 0;
$select[""] = array();
@@ -369,7 +364,7 @@ class Adminer {
$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";
@@ -507,13 +502,12 @@ class Adminer {
* @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];
}
}
@@ -527,7 +521,7 @@ class Adminer {
* @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] != "") {
@@ -554,7 +548,7 @@ class Adminer {
$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();
@@ -565,7 +559,7 @@ class Adminer {
&& (!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");
@@ -633,7 +627,6 @@ class Adminer {
* @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"])) {
@@ -645,7 +638,7 @@ class Adminer {
$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";
}
@@ -669,10 +662,9 @@ class Adminer {
* @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"])) {

View File

@@ -177,7 +177,7 @@ if (isset($_GET["username"]) && is_string(get_password())) {
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)));
}

View File

@@ -39,7 +39,7 @@ if ($_GET["script"] == "version") {
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"];

View File

@@ -12,8 +12,9 @@ function get_driver(string $id): string {
}
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;

View File

@@ -172,13 +172,12 @@ function json_row(string $key, $val = null): void {
* @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;
}
@@ -192,13 +191,13 @@ function edit_type(string $key, array $field, array $collations, array $foreign_
? "<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
);
}
@@ -220,8 +219,7 @@ function get_partitions_info(string $table): array {
/** 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))
@@ -232,10 +230,9 @@ function process_length(?string $length): string {
* @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"])) : "")
;
}
@@ -265,10 +262,9 @@ function process_field(array $field, array $type_field): array {
* @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
@@ -302,7 +298,6 @@ function type_class(string $type) {
* @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'");
@@ -333,7 +328,7 @@ function edit_fields(array $fields, array $collations, $type = "TABLE", array $f
$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'>";
}
@@ -342,8 +337,8 @@ function edit_fields(array $fields, array $collations, $type = "TABLE", array $f
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'>";
@@ -472,13 +467,12 @@ function create_trigger(string $on, array $row): string {
* @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"], ";");
@@ -500,7 +494,6 @@ function remove_definer(string $query): string {
* @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 "
@@ -508,8 +501,8 @@ function format_foreign_key(array $foreign_key): string {
. ($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]" : "")
;
}

View File

@@ -19,8 +19,7 @@ function adminer() {
/** Get Driver object */
function driver(): Driver {
global $driver;
return $driver;
return Driver::$instance;
}
/** Unescape database identifier
@@ -601,7 +600,6 @@ function column_foreign_keys(string $table): array {
* @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 != "") {
@@ -616,7 +614,7 @@ function fields_from_edit(): array { // used by Mongo and SimpleDB
"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;
@@ -830,10 +828,9 @@ function count_rows(string $table, array $where, bool $is_group, array $group):
* @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());

View File

@@ -189,7 +189,6 @@ function enum_input(string $type, string $attrs, array $field, $value, string $e
* @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) {
@@ -203,12 +202,12 @@ function input(array $field, $value, ?string $function, ?bool $autofocus = false
$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);
@@ -247,7 +246,7 @@ function input(array $field, $value, ?string $function, ?bool $autofocus = false
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)
@@ -283,14 +282,13 @@ function input(array $field, $value, ?string $function, ?bool $autofocus = false
* @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;
}
@@ -323,7 +321,7 @@ function process_input(array $field) {
if (!is_string($file)) {
return false; //! report errors
}
return $driver->quoteBinary($file);
return driver()->quoteBinary($file);
}
return adminer()->processInput($field, $value, $function);
}

View File

@@ -46,7 +46,7 @@ if ($_GET["val"] && is_ajax()) {
$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());
}
@@ -121,10 +121,10 @@ if ($_POST && !$error) {
$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;
@@ -136,10 +136,10 @@ if ($_POST && !$error) {
// 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) {
@@ -176,7 +176,7 @@ if ($_POST && !$error) {
$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),
@@ -201,7 +201,7 @@ if ($_POST && !$error) {
$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) {
@@ -218,12 +218,12 @@ if ($_POST && !$error) {
$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
}
}
@@ -299,7 +299,7 @@ if (!$columns && support("table")) {
}
}
}
$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";
@@ -411,7 +411,7 @@ if (!$columns && support("table")) {
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
}

View File

@@ -85,7 +85,7 @@ if (!$error && $_POST) {
$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 == '[' ? ']'
@@ -146,7 +146,7 @@ if (!$error && $_POST) {
. (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');", "");

View File

@@ -26,7 +26,7 @@ if ($fields) {
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) {
@@ -68,7 +68,7 @@ if (!is_view($table_status)) {
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) {

View File

@@ -24,7 +24,7 @@ if (!$row) {
<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>";

View File

@@ -354,7 +354,6 @@ ORDER BY ORDINAL_POSITION", null, "") as $row
}
function selectSearchProcess($fields, $indexes) {
global $driver;
$return = array();
foreach ((array) $_GET["where"] as $key => $where) {
$col = $where["col"];
@@ -370,7 +369,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row
} 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) . ")"