mirror of
https://github.com/vrana/adminer.git
synced 2025-08-08 15:47:00 +02:00
SQLite: Support CHECK constraint
This commit is contained in:
@@ -4,10 +4,14 @@ $name = $_GET["name"];
|
||||
$row = $_POST;
|
||||
|
||||
if ($row && !$error) {
|
||||
if ($jush == "sqlite") {
|
||||
$result = recreate_table($TABLE, $TABLE, array(), array(), array(), 0, array(), $name, ($row["drop"] ? "" : $row["clause"]));
|
||||
} else {
|
||||
$result = ($name == "" || queries("ALTER TABLE " . table($TABLE) . " DROP CONSTRAINT " . idf_escape($name)));
|
||||
if (!$row["drop"]) {
|
||||
$result = queries("ALTER TABLE " . table($TABLE) . " ADD" . ($row["name"] != "" ? " CONSTRAINT " . idf_escape($row["name"]) . "" : "") . " CHECK ($row[clause])"); //! SQL injection
|
||||
}
|
||||
}
|
||||
queries_redirect(
|
||||
ME . "table=" . urlencode($TABLE),
|
||||
($row["drop"] ? lang('Check has been dropped.') : ($name != "" ? lang('Check has been altered.') : lang('Check has been created.'))),
|
||||
@@ -18,18 +22,24 @@ if ($row && !$error) {
|
||||
page_header(($name != "" ? lang('Alter check') . ": " . h($name) : lang('Create check')), $error, array("table" => $TABLE));
|
||||
|
||||
if (!$row) {
|
||||
$checks = check_constraints($TABLE);
|
||||
$checks = $driver->checkConstraints($TABLE);
|
||||
$row = array("name" => $name, "clause" => $checks[$name]);
|
||||
}
|
||||
?>
|
||||
|
||||
<form action="" method="post">
|
||||
<p><?php echo lang('Name'); ?>: <input name="name" value="<?php echo h($row["name"]); ?>" data-maxlength="64" autocapitalize="off"><?php echo doc_link(array(
|
||||
<p><?php
|
||||
if ($jush != "sqlite") {
|
||||
echo lang('Name') . ': <input name="name" value="' . h($row["name"]) . '" data-maxlength="64" autocapitalize="off"> ';
|
||||
}
|
||||
echo doc_link(array(
|
||||
'sql' => "create-table-check-constraints.html",
|
||||
'mariadb' => "constraint/",
|
||||
'pgsql' => "ddl-constraints.html#DDL-CONSTRAINTS-CHECK-CONSTRAINTS",
|
||||
'mssql' => "relational-databases/tables/create-check-constraints",
|
||||
)); ?>
|
||||
'sqlite' => "lang_createtable.html#check_constraints",
|
||||
), "?");
|
||||
?>
|
||||
<p><?php textarea("clause", $row["clause"]); ?>
|
||||
<p><input type="submit" value="<?php echo lang('Save'); ?>">
|
||||
<?php if ($name != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $name)); ?><?php } ?>
|
||||
|
@@ -227,6 +227,11 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
|
||||
}
|
||||
}
|
||||
|
||||
function checkConstraints($table) {
|
||||
preg_match_all('~ CHECK *(\( *(((?>[^()]*[^() ])|(?1))*) *\))~', $this->_conn->result("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table)), $matches); //! could be inside a comment
|
||||
return array_combine($matches[2], $matches[2]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -523,8 +528,20 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function recreate_table($table, $name, $fields, $originals, $foreign, $auto_increment = 0, $indexes = array()) {
|
||||
global $connection;
|
||||
/** Recreate table
|
||||
* @param string original name
|
||||
* @param string new name
|
||||
* @param array [process_field()], empty to preserve
|
||||
* @param array [$original => idf_escape($new_column)], empty to preserve
|
||||
* @param string [format_foreign_key()], empty to preserve
|
||||
* @param int set auto_increment to this value, 0 to preserve
|
||||
* @param array [array($type, $name, $columns)], empty to preserve
|
||||
* @param string CHECK constraint to drop
|
||||
* @param string CHECK constraint to add
|
||||
* @return bool
|
||||
*/
|
||||
function recreate_table($table, $name, $fields, $originals, $foreign, $auto_increment = 0, $indexes = array(), $drop_check = "", $add_check = "") {
|
||||
global $connection, $driver;
|
||||
if ($table != "") {
|
||||
if (!$fields) {
|
||||
foreach (fields($table) as $key => $field) {
|
||||
@@ -585,6 +602,14 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
|
||||
$fields[$key] = " " . implode($field);
|
||||
}
|
||||
$fields = array_merge($fields, array_filter($foreign));
|
||||
foreach ($driver->checkConstraints($table) as $check) {
|
||||
if ($check != $drop_check) {
|
||||
$fields[] = " CHECK ($check)";
|
||||
}
|
||||
}
|
||||
if ($add_check) {
|
||||
$fields[] = " CHECK ($add_check)";
|
||||
}
|
||||
$temp_name = ($table == $name ? "adminer_$name" : $name);
|
||||
if (!queries("CREATE TABLE " . table($temp_name) . " (\n" . implode(",\n", $fields) . "\n)")) {
|
||||
// implicit ROLLBACK to not overwrite $connection->error
|
||||
@@ -785,7 +810,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
|
||||
}
|
||||
|
||||
function support($feature) {
|
||||
return preg_match('~^(columns|database|drop_col|dump|indexes|descidx|move_col|sql|status|table|trigger|variables|view|view_trigger)$~', $feature);
|
||||
return preg_match('~^(check|columns|database|drop_col|dump|indexes|descidx|move_col|sql|status|table|trigger|variables|view|view_trigger)$~', $feature);
|
||||
}
|
||||
|
||||
function driver_config() {
|
||||
|
@@ -200,4 +200,18 @@ function get_driver($id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Get defined check constraints
|
||||
* @param string
|
||||
* @return array [$name => $clause]
|
||||
*/
|
||||
function checkConstraints($table) {
|
||||
// MariaDB contains CHECK_CONSTRAINTS.TABLE_NAME, MySQL and PostrgreSQL not
|
||||
return get_key_vals("SELECT c.CONSTRAINT_NAME, CHECK_CLAUSE
|
||||
FROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS c
|
||||
JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS t ON c.CONSTRAINT_SCHEMA = t.CONSTRAINT_SCHEMA AND c.CONSTRAINT_NAME = t.CONSTRAINT_NAME
|
||||
WHERE c.CONSTRAINT_SCHEMA = " . q($_GET["ns"] != "" ? $_GET["ns"] : DB) . "
|
||||
AND t.TABLE_NAME = " . q($table) . "
|
||||
AND CHECK_CLAUSE NOT LIKE '% IS NOT NULL'"); // ignore default IS NOT NULL checks in PostrgreSQL
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -531,20 +531,6 @@ function create_routine($routine, $row) {
|
||||
;
|
||||
}
|
||||
|
||||
/** Get defined check constraints
|
||||
* @param string
|
||||
* @return array [$name => $clause]
|
||||
*/
|
||||
function check_constraints($table) {
|
||||
// MariaDB contains CHECK_CONSTRAINTS.TABLE_NAME, MySQL and PostrgreSQL not
|
||||
return get_key_vals("SELECT c.CONSTRAINT_NAME, CHECK_CLAUSE
|
||||
FROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS c
|
||||
JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS t ON c.CONSTRAINT_SCHEMA = t.CONSTRAINT_SCHEMA AND c.CONSTRAINT_NAME = t.CONSTRAINT_NAME
|
||||
WHERE c.CONSTRAINT_SCHEMA = " . q($_GET["ns"] != "" ? $_GET["ns"] : DB) . "
|
||||
AND t.TABLE_NAME = " . q($table) . "
|
||||
AND CHECK_CLAUSE NOT LIKE '% IS NOT NULL'"); // ignore default IS NOT NULL checks in PostrgreSQL
|
||||
}
|
||||
|
||||
/** Remove current user definer from SQL command
|
||||
* @param string
|
||||
* @return string
|
||||
|
@@ -60,7 +60,7 @@ if (!is_view($table_status)) {
|
||||
|
||||
if (support("check")) {
|
||||
echo "<h3 id='checks'>" . lang('Checks') . "</h3>\n";
|
||||
$check_constraints = check_constraints($TABLE);
|
||||
$check_constraints = $driver->checkConstraints($TABLE);
|
||||
if ($check_constraints) {
|
||||
echo "<table>\n";
|
||||
foreach ($check_constraints as $key => $val) {
|
||||
|
@@ -1,4 +1,5 @@
|
||||
Adminer-4.17.2-dev:
|
||||
SQLite: Support CHECK constraint
|
||||
SQLite: Add command Check tables
|
||||
SQLite: Display all rows of variable values
|
||||
MongoDB: Remove support for deprecated extension mongo
|
||||
|
@@ -67,7 +67,6 @@ header("Cache-Control: immutable");
|
||||
); //! respect context (extension, class)
|
||||
$functions = array_combine($matches[1], $matches[0]);
|
||||
$requires = array(
|
||||
"check" => array("check_constraints"),
|
||||
"copy" => array("copy_tables"),
|
||||
"database" => array("create_database", "rename_database", "drop_databases"),
|
||||
"dump" => array("use_sql", "create_sql", "truncate_sql", "trigger_sql"),
|
||||
|
Reference in New Issue
Block a user