Abstract DELETE, INSERT and INSERT+UPDATE
This commit is contained in:
parent
5557adf289
commit
1f7fa44923
|
@ -233,6 +233,30 @@ if (isset($_GET["mssql"])) {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Min_Driver extends Min_SQL {
|
||||
|
||||
function insertUpdate($table, $set, $primary) {
|
||||
$update = array();
|
||||
$where = array();
|
||||
foreach ($set as $key => $val) {
|
||||
$update[] = "$key = $val";
|
||||
if (isset($primary[idf_unescape($key)])) {
|
||||
$where[] = "$key = $val";
|
||||
}
|
||||
}
|
||||
// can use only one query for all rows with different API
|
||||
return queries("MERGE " . table($table) . " USING (VALUES(" . implode(", ", $set) . ")) AS source (c" . implode(", c", range(1, count($set))) . ") ON " . implode(" AND ", $where) //! source, c1 - possible conflict
|
||||
. " WHEN MATCHED THEN UPDATE SET " . implode(", ", $update)
|
||||
. " WHEN NOT MATCHED THEN INSERT (" . implode(", ", array_keys($set)) . ") VALUES (" . implode(", ", $set) . ");" // ; is mandatory
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function idf_escape($idf) {
|
||||
return "[" . str_replace("]", "]]", $idf) . "]";
|
||||
}
|
||||
|
@ -460,26 +484,6 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table)
|
|||
return queries("BEGIN TRANSACTION");
|
||||
}
|
||||
|
||||
function insert_into($table, $set) {
|
||||
return queries("INSERT INTO " . table($table) . ($set ? " (" . implode(", ", array_keys($set)) . ")\nVALUES (" . implode(", ", $set) . ")" : "DEFAULT VALUES"));
|
||||
}
|
||||
|
||||
function insert_update($table, $set, $primary) {
|
||||
$update = array();
|
||||
$where = array();
|
||||
foreach ($set as $key => $val) {
|
||||
$update[] = "$key = $val";
|
||||
if (isset($primary[idf_unescape($key)])) {
|
||||
$where[] = "$key = $val";
|
||||
}
|
||||
}
|
||||
// can use only one query for all rows with different API
|
||||
return queries("MERGE " . table($table) . " USING (VALUES(" . implode(", ", $set) . ")) AS source (c" . implode(", c", range(1, count($set))) . ") ON " . implode(" AND ", $where) //! source, c1 - possible conflict
|
||||
. " WHEN MATCHED THEN UPDATE SET " . implode(", ", $update)
|
||||
. " WHEN NOT MATCHED THEN INSERT (" . implode(", ", array_keys($set)) . ") VALUES (" . implode(", ", $set) . ");" // ; is mandatory
|
||||
);
|
||||
}
|
||||
|
||||
function last_id() {
|
||||
global $connection;
|
||||
return $connection->result("SELECT SCOPE_IDENTITY()"); // @@IDENTITY can return trigger INSERT
|
||||
|
|
|
@ -229,6 +229,26 @@ if (!defined("DRIVER")) {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Min_Driver extends Min_SQL {
|
||||
|
||||
function insert($table, $set) {
|
||||
return ($set ? parent::insert($table, $set) : queries("INSERT INTO " . table($table) . " ()\nVALUES ()"));
|
||||
}
|
||||
|
||||
function insertUpdate($table, $set, $primary) {
|
||||
foreach ($set as $key => $val) {
|
||||
$set[$key] = "$key = $val";
|
||||
}
|
||||
$update = implode(", ", $set);
|
||||
return queries("INSERT INTO " . table($table) . " SET $update ON DUPLICATE KEY UPDATE $update");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Escape database identifier
|
||||
* @param string
|
||||
* @return string
|
||||
|
@ -807,29 +827,6 @@ if (!defined("DRIVER")) {
|
|||
return queries("BEGIN");
|
||||
}
|
||||
|
||||
/** Insert data into table
|
||||
* @param string
|
||||
* @param array
|
||||
* @return bool
|
||||
*/
|
||||
function insert_into($table, $set) {
|
||||
return queries("INSERT INTO " . table($table) . " (" . implode(", ", array_keys($set)) . ")\nVALUES (" . implode(", ", $set) . ")");
|
||||
}
|
||||
|
||||
/** Insert or update data in the table
|
||||
* @param string
|
||||
* @param array
|
||||
* @param array columns in keys
|
||||
* @return bool
|
||||
*/
|
||||
function insert_update($table, $set, $primary) {
|
||||
foreach ($set as $key => $val) {
|
||||
$set[$key] = "$key = $val";
|
||||
}
|
||||
$update = implode(", ", $set);
|
||||
return queries("INSERT INTO " . table($table) . " SET $update ON DUPLICATE KEY UPDATE $update");
|
||||
}
|
||||
|
||||
/** Get last auto increment ID
|
||||
* @return string
|
||||
*/
|
||||
|
|
|
@ -132,6 +132,16 @@ if (isset($_GET["oracle"])) {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Min_Driver extends Min_SQL {
|
||||
|
||||
//! support empty $set in insert()
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function idf_escape($idf) {
|
||||
return '"' . str_replace('"', '""', $idf) . '"';
|
||||
}
|
||||
|
@ -322,10 +332,6 @@ ORDER BY uc.constraint_type, uic.column_position", $connection2) as $row) {
|
|||
return true; // automatic start
|
||||
}
|
||||
|
||||
function insert_into($table, $set) {
|
||||
return queries("INSERT INTO " . table($table) . " (" . implode(", ", array_keys($set)) . ")\nVALUES (" . implode(", ", $set) . ")"); //! no columns
|
||||
}
|
||||
|
||||
function last_id() {
|
||||
return 0; //!
|
||||
}
|
||||
|
|
|
@ -148,7 +148,30 @@ if (isset($_GET["pgsql"])) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class Min_Driver extends Min_SQL {
|
||||
|
||||
function insertUpdate($table, $set, $primary) {
|
||||
global $connection;
|
||||
$update = array();
|
||||
$where = array();
|
||||
foreach ($set as $key => $val) {
|
||||
$update[] = "$key = $val";
|
||||
if (isset($primary[idf_unescape($key)])) {
|
||||
$where[] = "$key = $val";
|
||||
}
|
||||
}
|
||||
return ($where && queries("UPDATE " . table($table) . " SET " . implode(", ", $update) . " WHERE " . implode(" AND ", $where)) && $connection->affected_rows)
|
||||
|| queries("INSERT INTO " . table($table) . " (" . implode(", ", array_keys($set)) . ") VALUES (" . implode(", ", $set) . ")")
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function idf_escape($idf) {
|
||||
return '"' . str_replace('"', '""', $idf) . '"';
|
||||
}
|
||||
|
@ -515,25 +538,6 @@ ORDER BY p.proname');
|
|||
return queries("BEGIN");
|
||||
}
|
||||
|
||||
function insert_into($table, $set) {
|
||||
return queries("INSERT INTO " . table($table) . ($set ? " (" . implode(", ", array_keys($set)) . ")\nVALUES (" . implode(", ", $set) . ")" : "DEFAULT VALUES"));
|
||||
}
|
||||
|
||||
function insert_update($table, $set, $primary) {
|
||||
global $connection;
|
||||
$update = array();
|
||||
$where = array();
|
||||
foreach ($set as $key => $val) {
|
||||
$update[] = "$key = $val";
|
||||
if (isset($primary[idf_unescape($key)])) {
|
||||
$where[] = "$key = $val";
|
||||
}
|
||||
}
|
||||
return ($where && queries("UPDATE " . table($table) . " SET " . implode(", ", $update) . " WHERE " . implode(" AND ", $where)) && $connection->affected_rows)
|
||||
|| queries("INSERT INTO " . table($table) . " (" . implode(", ", array_keys($set)) . ") VALUES (" . implode(", ", $set) . ")")
|
||||
;
|
||||
}
|
||||
|
||||
function last_id() {
|
||||
return 0; // there can be several sequences
|
||||
}
|
||||
|
|
|
@ -203,7 +203,19 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class Min_Driver extends Min_SQL {
|
||||
|
||||
function insertUpdate($table, $set, $primary) {
|
||||
return queries("REPLACE INTO " . table($table) . " (" . implode(", ", array_keys($set)) . ") VALUES (" . implode(", ", $set) . ")");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function idf_escape($idf) {
|
||||
return '"' . str_replace('"', '""', $idf) . '"';
|
||||
}
|
||||
|
@ -587,14 +599,6 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
|
|||
return queries("BEGIN");
|
||||
}
|
||||
|
||||
function insert_into($table, $set) {
|
||||
return queries("INSERT INTO " . table($table) . ($set ? " (" . implode(", ", array_keys($set)) . ")\nVALUES (" . implode(", ", $set) . ")" : "DEFAULT VALUES"));
|
||||
}
|
||||
|
||||
function insert_update($table, $set, $primary) {
|
||||
return queries("REPLACE INTO " . table($table) . " (" . implode(", ", array_keys($set)) . ") VALUES (" . implode(", ", $set) . ")");
|
||||
}
|
||||
|
||||
function last_id() {
|
||||
global $connection;
|
||||
return $connection->result("SELECT LAST_INSERT_ROWID()");
|
||||
|
|
|
@ -126,7 +126,7 @@ page_header(lang('Export'), $error, ($_GET["export"] != "" ? array("table" => $_
|
|||
$db_style = array('', 'USE', 'DROP+CREATE', 'CREATE');
|
||||
$table_style = array('', 'DROP+CREATE', 'CREATE');
|
||||
$data_style = array('', 'TRUNCATE+INSERT', 'INSERT');
|
||||
if ($jush == "sql") { //! use insert_update() in all drivers
|
||||
if ($jush == "sql") { //! use insertUpdate() in all drivers
|
||||
$data_style[] = 'INSERT+UPDATE';
|
||||
}
|
||||
parse_str($_COOKIE["adminer_export"], $row);
|
||||
|
|
|
@ -22,12 +22,12 @@ if ($_POST && !$error && !isset($_GET["select"])) {
|
|||
$query_where = "\nWHERE $where";
|
||||
|
||||
if (isset($_POST["delete"])) {
|
||||
$query = "FROM " . table($TABLE);
|
||||
query_redirect(
|
||||
"DELETE" . ($unique_array ? " $query$query_where" : limit1($query, $query_where)),
|
||||
queries_redirect(
|
||||
$location,
|
||||
lang('Item has been deleted.')
|
||||
lang('Item has been deleted.'),
|
||||
$driver->delete($TABLE, $query_where, !$unique_array)
|
||||
);
|
||||
|
||||
} else {
|
||||
$set = array();
|
||||
foreach ($fields as $name => $field) {
|
||||
|
@ -53,7 +53,7 @@ if ($_POST && !$error && !isset($_GET["select"])) {
|
|||
exit;
|
||||
}
|
||||
} else {
|
||||
$result = insert_into($TABLE, $set);
|
||||
$result = $driver->insert($TABLE, $set);
|
||||
$last_id = ($result ? last_id() : 0);
|
||||
queries_redirect($location, lang('Item%s has been inserted.', ($last_id ? " $last_id" : "")), $result); //! link
|
||||
}
|
||||
|
|
|
@ -116,6 +116,8 @@ if (is_string($connection) || !$adminer->login($_GET["username"], get_session("p
|
|||
exit;
|
||||
}
|
||||
|
||||
$driver = new Min_Driver($connection);
|
||||
|
||||
$token = $_SESSION["token"]; ///< @var string CSRF protection
|
||||
if ($auth && $_POST["token"]) {
|
||||
$_POST["token"] = $token; // reset token after explicit login
|
||||
|
|
|
@ -58,6 +58,7 @@ if (function_exists("set_magic_quotes_runtime")) { // removed in PHP 6
|
|||
include "../adminer/include/lang.inc.php";
|
||||
include "../adminer/lang/$LANG.inc.php";
|
||||
include "../adminer/include/pdo.inc.php";
|
||||
include "../adminer/include/driver.inc.php";
|
||||
include "../adminer/drivers/sqlite.inc.php";
|
||||
include "../adminer/drivers/pgsql.inc.php";
|
||||
include "../adminer/drivers/oracle.inc.php";
|
||||
|
|
43
adminer/include/driver.inc.php
Normal file
43
adminer/include/driver.inc.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
/*abstract*/ class Min_SQL {
|
||||
var $_conn;
|
||||
|
||||
/** Create object for performing database operations
|
||||
* @param Min_DB
|
||||
*/
|
||||
function Min_SQL($connection) {
|
||||
$this->_conn = $connection;
|
||||
}
|
||||
|
||||
/** Delete data from table
|
||||
* @param string
|
||||
* @param string " WHERE ..."
|
||||
* @param int 0 or 1
|
||||
* @return bool
|
||||
*/
|
||||
function delete($table, $queryWhere, $limit = 0) {
|
||||
$query = "FROM " . table($table);
|
||||
return queries("DELETE" . ($limit ? limit1($query, $queryWhere) : " $query$queryWhere"));
|
||||
}
|
||||
|
||||
/** Insert data into table
|
||||
* @param string
|
||||
* @param array
|
||||
* @return bool
|
||||
*/
|
||||
function insert($table, $set) {
|
||||
return queries("INSERT INTO " . table($table) . ($set ? " (" . implode(", ", array_keys($set)) . ")\nVALUES (" . implode(", ", $set) . ")" : "DEFAULT VALUES"));
|
||||
}
|
||||
|
||||
/** Insert or update data in table
|
||||
* @param string
|
||||
* @param array
|
||||
* @param array columns in keys
|
||||
* @return bool
|
||||
*/
|
||||
/*abstract*/ function insertUpdate($table, $set, $primary) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -103,21 +103,24 @@ if ($_POST && !$error) {
|
|||
}
|
||||
if ($_POST["delete"] || $set) {
|
||||
$command = "UPDATE";
|
||||
if ($_POST["delete"]) {
|
||||
$command = "DELETE";
|
||||
$query = "FROM $query";
|
||||
}
|
||||
if ($_POST["clone"]) {
|
||||
$command = "INSERT";
|
||||
$query = "INTO $query";
|
||||
}
|
||||
if ($_POST["all"] || ($unselected === array() && is_array($_POST["check"])) || $is_group) {
|
||||
$result = queries("$command $query$where_check");
|
||||
$result = ($_POST["delete"]
|
||||
? $driver->delete($TABLE, $where_check)
|
||||
: queries("$command $query$where_check")
|
||||
);
|
||||
$affected = $connection->affected_rows;
|
||||
} else {
|
||||
foreach ((array) $_POST["check"] as $val) {
|
||||
// where is not unique so OR can't be used
|
||||
$result = queries($command . limit1($query, "\nWHERE " . ($where ? implode(" AND ", $where) . " AND " : "") . where_check($val, $fields)));
|
||||
$where2 = "\nWHERE " . ($where ? implode(" AND ", $where) . " AND " : "") . where_check($val, $fields);
|
||||
$result = ($_POST["delete"]
|
||||
? $driver->delete($TABLE, $where2, 1)
|
||||
: queries($command . limit1($query, $where2))
|
||||
);
|
||||
if (!$result) {
|
||||
break;
|
||||
}
|
||||
|
@ -181,7 +184,7 @@ if ($_POST && !$error) {
|
|||
foreach ($matches2[1] as $i => $col) {
|
||||
$set[idf_escape($cols[$i])] = ($col == "" && $fields[$cols[$i]]["null"] ? "NULL" : q(str_replace('""', '"', preg_replace('~^"|"$~', '', $col))));
|
||||
}
|
||||
$result = insert_update($TABLE, $set, $primary);
|
||||
$result = $driver->insertUpdate($TABLE, $set, $primary);
|
||||
if (!$result) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -327,7 +327,7 @@ if ($_SERVER["argv"][1]) {
|
|||
$filename = dirname(__FILE__) . "/adminer/drivers/mysql.inc.php";
|
||||
preg_match_all('~\\bfunction ([^(]+)~', file_get_contents($filename), $matches); //! respect context (extension, class)
|
||||
$functions = array_combine($matches[1], $matches[0]);
|
||||
unset($functions["__destruct"], $functions["Min_DB"], $functions["Min_Result"]);
|
||||
unset($functions["__destruct"], $functions["Min_DB"], $functions["Min_Result"], $functions["Min_Driver"]);
|
||||
foreach (glob(dirname(__FILE__) . "/adminer/drivers/" . ($driver ? $driver : "*") . ".inc.php") as $filename) {
|
||||
if ($filename != "mysql.inc.php") {
|
||||
$file = file_get_contents($filename);
|
||||
|
@ -340,6 +340,7 @@ foreach (glob(dirname(__FILE__) . "/adminer/drivers/" . ($driver ? $driver : "*"
|
|||
}
|
||||
|
||||
include dirname(__FILE__) . "/adminer/include/pdo.inc.php";
|
||||
include dirname(__FILE__) . "/adminer/include/driver.inc.php";
|
||||
$features = array("call" => "routine", "dump", "event", "privileges", "procedure" => "routine", "processlist", "routine", "scheme", "sequence", "status", "trigger", "type", "user" => "privileges", "variables", "view");
|
||||
$lang_ids = array(); // global variable simplifies usage in a callback function
|
||||
$file = file_get_contents(dirname(__FILE__) . "/$project/index.php");
|
||||
|
|
Loading…
Reference in a new issue