Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 911 lines (831 sloc) 27.571 kb
3f5b683 Reintegrate sqlite branch
jakubvrana authored
1 <?php
2 $possible_drivers[] = "MySQLi";
3 $possible_drivers[] = "MySQL";
4 $possible_drivers[] = "PDO_MySQL";
5 if (extension_loaded("mysqli") || extension_loaded("mysql") || extension_loaded("pdo_mysql")) {
6 $drivers = array("server" => "MySQL") + $drivers;
7 }
8
9 if (!defined("DRIVER")) {
10 define("DRIVER", "server"); // server - backwards compatibility
11 // MySQLi supports everything, MySQL doesn't support multiple result sets, PDO_MySQL doesn't support orgtable
12 if (extension_loaded("mysqli")) {
13 class Min_DB extends MySQLi {
14 var $extension = "MySQLi";
15
16 function Min_DB() {
17 parent::init();
18 }
19
20 function connect($server, $username, $password) {
8455d05 Jakub Vrána Comment
authored
21 mysqli_report(MYSQLI_REPORT_OFF); // stays between requests, not required since PHP 5.3.4
3f5b683 Reintegrate sqlite branch
jakubvrana authored
22 list($host, $port) = explode(":", $server, 2); // part after : is used for port or socket
93f8157 Jakub Vrána Set charset natively to defend against Shift JIS on server
authored
23 $return = @$this->real_connect(
3f5b683 Reintegrate sqlite branch
jakubvrana authored
24 ($server != "" ? $host : ini_get("mysqli.default_host")),
25 ("$server$username" != "" ? $username : ini_get("mysqli.default_user")),
26 ("$server$username$password" != "" ? $password : ini_get("mysqli.default_pw")),
27 null,
28 (is_numeric($port) ? $port : ini_get("mysqli.default_port")),
29 (!is_numeric($port) ? $port : null)
30 );
93f8157 Jakub Vrána Set charset natively to defend against Shift JIS on server
authored
31 if ($return) {
32 if (method_exists($this, 'set_charset')) {
33 $this->set_charset("utf8");
34 } else {
35 $this->query("SET NAMES utf8");
36 }
37 }
38 return $return;
3f5b683 Reintegrate sqlite branch
jakubvrana authored
39 }
40
41 function result($query, $field = 0) {
42 $result = $this->query($query);
43 if (!$result) {
44 return false;
45 }
46 $row = $result->fetch_array();
47 return $row[$field];
48 }
49
50 function quote($string) {
51 return "'" . $this->escape_string($string) . "'";
52 }
53 }
54
55 } elseif (extension_loaded("mysql")) {
56 class Min_DB {
57 var
58 $extension = "MySQL", ///< @var string extension name
59 $server_info, ///< @var string server version
60 $affected_rows, ///< @var int number of affected rows
61 $error, ///< @var string last error message
62 $_link, $_result ///< @access private
63 ;
64
65 /** Connect to server
66 * @param string
67 * @param string
68 * @param string
69 * @return bool
70 */
71 function connect($server, $username, $password) {
72 $this->_link = @mysql_connect(
73 ($server != "" ? $server : ini_get("mysql.default_host")),
74 ("$server$username" != "" ? $username : ini_get("mysql.default_user")),
75 ("$server$username$password" != "" ? $password : ini_get("mysql.default_password")),
76 true,
77 131072 // CLIENT_MULTI_RESULTS for CALL
78 );
79 if ($this->_link) {
80 $this->server_info = mysql_get_server_info($this->_link);
93f8157 Jakub Vrána Set charset natively to defend against Shift JIS on server
authored
81 if (function_exists('mysql_set_charset')) {
82 mysql_set_charset("utf8", $this->_link);
83 } else {
84 $this->query("SET NAMES utf8");
85 }
3f5b683 Reintegrate sqlite branch
jakubvrana authored
86 } else {
87 $this->error = mysql_error();
88 }
89 return (bool) $this->_link;
90 }
91
92 /** Quote string to use in SQL
93 * @param string
94 * @return string escaped string enclosed in '
95 */
96 function quote($string) {
97 return "'" . mysql_real_escape_string($string, $this->_link) . "'";
98 }
99
100 /** Select database
101 * @param string
102 * @return bool
103 */
104 function select_db($database) {
105 return mysql_select_db($database, $this->_link);
106 }
107
108 /** Send query
109 * @param string
110 * @param bool
111 * @return mixed bool or Min_Result
112 */
113 function query($query, $unbuffered = false) {
114 $result = @($unbuffered ? mysql_unbuffered_query($query, $this->_link) : mysql_query($query, $this->_link)); // @ - mute mysql.trace_mode
115 if (!$result) {
116 $this->error = mysql_error($this->_link);
117 return false;
118 }
119 if ($result === true) {
120 $this->affected_rows = mysql_affected_rows($this->_link);
121 $this->info = mysql_info($this->_link);
122 return true;
123 }
124 return new Min_Result($result);
125 }
126
127 /** Send query with more resultsets
128 * @param string
129 * @return bool
130 */
131 function multi_query($query) {
132 return $this->_result = $this->query($query);
133 }
134
135 /** Get current resultset
136 * @return Min_Result
137 */
138 function store_result() {
139 return $this->_result;
140 }
141
142 /** Fetch next resultset
143 * @return bool
144 */
145 function next_result() {
146 // MySQL extension doesn't support multiple results
147 return false;
148 }
149
150 /** Get single field from result
151 * @param string
152 * @param int
153 * @return string
154 */
155 function result($query, $field = 0) {
156 $result = $this->query($query);
157 if (!$result) {
158 return false;
159 }
160 return mysql_result($result->_result, 0, $field);
161 }
162 }
163
164 class Min_Result {
165 var
166 $num_rows, ///< @var int number of rows in the result
167 $_result ///< @access private
168 ;
169
170 /** Constructor
171 * @param resource
172 */
173 function Min_Result($result) {
174 $this->_result = $result;
175 $this->num_rows = mysql_num_rows($result);
176 }
177
178 /** Fetch next row as associative array
179 * @return array
180 */
181 function fetch_assoc() {
182 return mysql_fetch_assoc($this->_result);
183 }
184
185 /** Fetch next row as numbered array
186 * @return array
187 */
188 function fetch_row() {
189 return mysql_fetch_row($this->_result);
190 }
191
192 /** Fetch next field
193 * @return object properties: name, type, orgtable, orgname, charsetnr
194 */
195 function fetch_field() {
196 $return = mysql_fetch_field($this->_result);
197 $return->orgtable = $return->table;
198 $return->orgname = $return->name;
199 $return->charsetnr = ($return->blob ? 63 : 0);
200 return $return;
201 }
202
203 /** Free result set
204 */
205 function __destruct() {
206 mysql_free_result($this->_result); //! not called in PHP 4 which is a problem with mysql.trace_mode
207 }
208 }
209
210 } elseif (extension_loaded("pdo_mysql")) {
211 class Min_DB extends Min_PDO {
212 var $extension = "PDO_MySQL";
213
214 function connect($server, $username, $password) {
5002b89 Jakub Vrána Big numbers without E
authored
215 $this->dsn("mysql:host=" . str_replace(":", ";unix_socket=", preg_replace('~:(\\d)~', ';port=\\1', $server)), $username, $password);
93f8157 Jakub Vrána Set charset natively to defend against Shift JIS on server
authored
216 $this->query("SET NAMES utf8"); // charset in DSN is ignored
3f5b683 Reintegrate sqlite branch
jakubvrana authored
217 return true;
218 }
219
220 function select_db($database) {
221 // database selection is separated from the connection so dbname in DSN can't be used
222 return $this->query("USE " . idf_escape($database));
223 }
224
225 function query($query, $unbuffered = false) {
226 $this->setAttribute(1000, !$unbuffered); // 1000 - PDO::MYSQL_ATTR_USE_BUFFERED_QUERY
227 return parent::query($query, $unbuffered);
228 }
229 }
230
231 }
232
233 /** Escape database identifier
234 * @param string
235 * @return string
236 */
237 function idf_escape($idf) {
238 return "`" . str_replace("`", "``", $idf) . "`";
239 }
240
60c7ed9 Jakub Vrána MS SQL schema support
authored
241 /** Get escaped table name
242 * @param string
243 * @return string
244 */
245 function table($idf) {
246 return idf_escape($idf);
247 }
248
3f5b683 Reintegrate sqlite branch
jakubvrana authored
249 /** Connect to the database
250 * @return mixed Min_DB or string for error
251 */
252 function connect() {
253 global $adminer;
254 $connection = new Min_DB;
255 $credentials = $adminer->credentials();
256 if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
257 $connection->query("SET SQL_QUOTE_SHOW_CREATE=1");
258 return $connection;
259 }
260 return $connection->error;
261 }
262
263 /** Get cached list of databases
264 * @param bool
265 * @return array
266 */
267 function get_databases($flush = true) {
268 // SHOW DATABASES can take a very long time so it is cached
49565e0 Jakub Vrána Rename variables to avoid conflict with Adminer 2 sessions and enabled r...
authored
269 $return = &get_session("dbs");
3f5b683 Reintegrate sqlite branch
jakubvrana authored
270 if (!isset($return)) {
271 if ($flush) {
272 restart_session();
273 ob_flush();
274 flush();
275 }
276 $return = get_vals("SHOW DATABASES");
277 }
278 return $return;
279 }
280
281 /** Formulate SQL query with limit
282 * @param string everything after SELECT
ee3e045 Jakub Vrána Separate $where in limit function
authored
283 * @param string including WHERE
3f5b683 Reintegrate sqlite branch
jakubvrana authored
284 * @param int
285 * @param int
99a643b LIMIT separator
jakubvrana authored
286 * @param string
3f5b683 Reintegrate sqlite branch
jakubvrana authored
287 * @return string
288 */
ee3e045 Jakub Vrána Separate $where in limit function
authored
289 function limit($query, $where, $limit, $offset = 0, $separator = " ") {
290 return " $query$where" . (isset($limit) ? $separator . "LIMIT $limit" . ($offset ? " OFFSET $offset" : "") : "");
3f5b683 Reintegrate sqlite branch
jakubvrana authored
291 }
292
293 /** Formulate SQL modification query with limit 1
294 * @param string everything after UPDATE or DELETE
295 * @return string
296 */
ee3e045 Jakub Vrána Separate $where in limit function
authored
297 function limit1($query, $where) {
298 return limit($query, $where, 1);
3f5b683 Reintegrate sqlite branch
jakubvrana authored
299 }
300
301 /** Get database collation
302 * @param string
303 * @param array result of collations()
304 * @return string
305 */
306 function db_collation($db, $collations) {
307 global $connection;
308 $return = null;
309 $create = $connection->result("SHOW CREATE DATABASE " . idf_escape($db), 1);
310 if (preg_match('~ COLLATE ([^ ]+)~', $create, $match)) {
311 $return = $match[1];
312 } elseif (preg_match('~ CHARACTER SET ([^ ]+)~', $create, $match)) {
313 // default collation
314 $return = $collations[$match[1]][0];
315 }
316 return $return;
317 }
318
319 /** Get supported engines
320 * @return array
321 */
322 function engines() {
323 $return = array();
b0d637b Jakub Vrána Avoid fatal errors
authored
324 foreach (get_rows("SHOW ENGINES") as $row) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
325 if (ereg("YES|DEFAULT", $row["Support"])) {
326 $return[] = $row["Engine"];
327 }
328 }
329 return $return;
330 }
331
332 /** Get logged user
333 * @return string
334 */
335 function logged_user() {
336 global $connection;
337 return $connection->result("SELECT USER()");
338 }
339
340 /** Get tables list
341 * @return array
342 */
343 function tables_list() {
344 global $connection;
345 return get_key_vals("SHOW" . ($connection->server_info >= 5 ? " FULL" : "") . " TABLES");
346 }
347
348 /** Count tables in all databases
349 * @param array
350 * @return array array($db => $tables)
351 */
352 function count_tables($databases) {
353 $return = array();
354 foreach ($databases as $db) {
355 $return[$db] = count(get_vals("SHOW TABLES IN " . idf_escape($db)));
356 }
357 return $return;
358 }
359
360 /** Get table status
361 * @param string
362 * @return array
363 */
364 function table_status($name = "") {
365 $return = array();
7e644b4 Jakub Vrána Save bytes ($connection->quote shortcut)
authored
366 foreach (get_rows("SHOW TABLE STATUS" . ($name != "" ? " LIKE " . q(addcslashes($name, "%_")) : "")) as $row) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
367 if ($row["Engine"] == "InnoDB") {
368 // ignore internal comment, unnecessary since MySQL 5.1.21
369 $row["Comment"] = preg_replace('~(?:(.+); )?InnoDB free: .*~', '\\1', $row["Comment"]);
370 }
371 if (!isset($row["Rows"])) {
372 $row["Comment"] = "";
373 }
374 if ($name != "") {
375 return $row;
376 }
377 $return[$row["Name"]] = $row;
378 }
379 return $return;
380 }
381
da6f1f8 Jakub Vrána Driver specific view detection
authored
382 /** Find out whether the identifier is view
383 * @param array
384 * @return bool
385 */
386 function is_view($table_status) {
387 return !isset($table_status["Rows"]);
388 }
389
3f5b683 Reintegrate sqlite branch
jakubvrana authored
390 /** Check if table supports foreign keys
391 * @param array result of table_status
392 * @return bool
393 */
394 function fk_support($table_status) {
395 return ($table_status["Engine"] == "InnoDB");
396 }
397
398 /** Get information about fields
399 * @param string
4c2268d Jakub Vrána PostgreSQL hidden columns support
authored
400 * @param bool display hidden table columns
3f5b683 Reintegrate sqlite branch
jakubvrana authored
401 * @return array array($name => array("field" => , "full_type" => , "type" => , "length" => , "unsigned" => , "default" => , "null" => , "auto_increment" => , "on_update" => , "collation" => , "privileges" => , "comment" => , "primary" => ))
402 */
4c2268d Jakub Vrána PostgreSQL hidden columns support
authored
403 function fields($table, $hidden = false) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
404 $return = array();
b0d637b Jakub Vrána Avoid fatal errors
authored
405 foreach (get_rows("SHOW FULL COLUMNS FROM " . table($table)) as $row) {
406 preg_match('~^([^( ]+)(?:\\((.+)\\))?( unsigned)?( zerofill)?$~', $row["Type"], $match);
407 $return[$row["Field"]] = array(
408 "field" => $row["Field"],
409 "full_type" => $row["Type"],
410 "type" => $match[1],
411 "length" => $match[2],
412 "unsigned" => ltrim($match[3] . $match[4]),
413 "default" => ($row["Default"] != "" || ereg("char", $match[1]) ? $row["Default"] : null),
414 "null" => ($row["Null"] == "YES"),
415 "auto_increment" => ($row["Extra"] == "auto_increment"),
416 "on_update" => (eregi('^on update (.+)', $row["Extra"], $match) ? $match[1] : ""), //! available since MySQL 5.1.23
417 "collation" => $row["Collation"],
418 "privileges" => array_flip(explode(",", $row["Privileges"])),
419 "comment" => $row["Comment"],
420 "primary" => ($row["Key"] == "PRI"),
421 );
3f5b683 Reintegrate sqlite branch
jakubvrana authored
422 }
423 return $return;
424 }
425
426 /** Get table indexes
427 * @param string
428 * @param string Min_DB to use
429 * @return array array($key_name => array("type" => , "columns" => array(), "lengths" => array()))
430 */
431 function indexes($table, $connection2 = null) {
432 global $connection;
433 if (!is_object($connection2)) { // use the main connection if the separate connection is unavailable
434 $connection2 = $connection;
435 }
436 $return = array();
b0d637b Jakub Vrána Avoid fatal errors
authored
437 foreach (get_rows("SHOW INDEX FROM " . table($table), $connection2) as $row) {
438 $return[$row["Key_name"]]["type"] = ($row["Key_name"] == "PRIMARY" ? "PRIMARY" : ($row["Index_type"] == "FULLTEXT" ? "FULLTEXT" : ($row["Non_unique"] ? "INDEX" : "UNIQUE")));
439 $return[$row["Key_name"]]["columns"][] = $row["Column_name"];
440 $return[$row["Key_name"]]["lengths"][] = $row["Sub_part"];
3f5b683 Reintegrate sqlite branch
jakubvrana authored
441 }
442 return $return;
443 }
444
445 /** Get foreign keys in table
446 * @param string
447 * @return array array($name => array("db" => , "table" => , "source" => array(), "target" => array(), "on_delete" => , "on_update" => ))
448 */
449 function foreign_keys($table) {
450 global $connection, $on_actions;
451 static $pattern = '`(?:[^`]|``)+`';
452 $return = array();
60c7ed9 Jakub Vrána MS SQL schema support
authored
453 $create_table = $connection->result("SHOW CREATE TABLE " . table($table), 1);
3f5b683 Reintegrate sqlite branch
jakubvrana authored
454 if ($create_table) {
455 preg_match_all("~CONSTRAINT ($pattern) FOREIGN KEY \\(((?:$pattern,? ?)+)\\) REFERENCES ($pattern)(?:\\.($pattern))? \\(((?:$pattern,? ?)+)\\)(?: ON DELETE (" . implode("|", $on_actions) . "))?(?: ON UPDATE (" . implode("|", $on_actions) . "))?~", $create_table, $matches, PREG_SET_ORDER);
456 foreach ($matches as $match) {
457 preg_match_all("~$pattern~", $match[2], $source);
458 preg_match_all("~$pattern~", $match[5], $target);
459 $return[idf_unescape($match[1])] = array(
460 "db" => idf_unescape($match[4] != "" ? $match[3] : $match[4]),
461 "table" => idf_unescape($match[4] != "" ? $match[4] : $match[3]),
462 "source" => array_map('idf_unescape', $source[0]),
463 "target" => array_map('idf_unescape', $target[0]),
464 "on_delete" => $match[6],
465 "on_update" => $match[7],
466 );
467 }
468 }
469 return $return;
470 }
471
472 /** Get view SELECT
473 * @param string
474 * @return array array("select" => )
475 */
476 function view($name) {
477 global $connection;
60c7ed9 Jakub Vrána MS SQL schema support
authored
478 return array("select" => preg_replace('~^(?:[^`]|`[^`]*`)*\\s+AS\\s+~isU', '', $connection->result("SHOW CREATE VIEW " . table($name), 1)));
3f5b683 Reintegrate sqlite branch
jakubvrana authored
479 }
480
481 /** Get sorted grouped list of collations
482 * @return array
483 */
484 function collations() {
485 $return = array();
b0d637b Jakub Vrána Avoid fatal errors
authored
486 foreach (get_rows("SHOW COLLATION") as $row) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
487 $return[$row["Charset"]][] = $row["Collation"];
488 }
489 ksort($return);
490 foreach ($return as $key => $val) {
491 sort($return[$key]);
492 }
493 return $return;
494 }
495
496 /** Find out if database is information_schema
497 * @param string
498 * @return bool
499 */
500 function information_schema($db) {
501 global $connection;
502 return ($connection->server_info >= 5 && $db == "information_schema");
503 }
504
505 /** Get escaped error message
506 * @return string
507 */
508 function error() {
509 global $connection;
510 return h(preg_replace('~^You have an error.*syntax to use~U', "Syntax error", $connection->error));
511 }
512
513 /** Return expression for binary comparison
514 * @param string
515 * @return string
516 */
517 function exact_value($val) {
7e644b4 Jakub Vrána Save bytes ($connection->quote shortcut)
authored
518 return q($val) . " COLLATE utf8_bin";
3f5b683 Reintegrate sqlite branch
jakubvrana authored
519 }
520
edb6401 Driver specific create and drop database
jakubvrana authored
521 /** Create database
522 * @param string
523 * @return string
524 */
525 function create_database($db, $collation) {
49565e0 Jakub Vrána Rename variables to avoid conflict with Adminer 2 sessions and enabled r...
authored
526 set_session("dbs", null);
7e644b4 Jakub Vrána Save bytes ($connection->quote shortcut)
authored
527 return queries("CREATE DATABASE " . idf_escape($db) . ($collation ? " COLLATE " . q($collation) : ""));
edb6401 Driver specific create and drop database
jakubvrana authored
528 }
529
530 /** Drop databases
531 * @param array
532 * @return bool
533 */
534 function drop_databases($databases) {
49565e0 Jakub Vrána Rename variables to avoid conflict with Adminer 2 sessions and enabled r...
authored
535 set_session("dbs", null);
dc45301 Jakub Vrána Typo
authored
536 return apply_queries("DROP DATABASE", $databases, 'idf_escape');
edb6401 Driver specific create and drop database
jakubvrana authored
537 }
538
3f5b683 Reintegrate sqlite branch
jakubvrana authored
539 /** Rename database from DB
540 * @param string new name
541 * @return string
542 * @return bool
543 */
544 function rename_database($name, $collation) {
edb6401 Driver specific create and drop database
jakubvrana authored
545 if (create_database($name, $collation)) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
546 //! move triggers
515325a Jakub Vrána Rename tables by single command
authored
547 $rename = array();
548 foreach (tables_list() as $table => $type) {
549 $rename[] = table($table) . " TO " . idf_escape($name) . "." . table($table);
3f5b683 Reintegrate sqlite branch
jakubvrana authored
550 }
515325a Jakub Vrána Rename tables by single command
authored
551 if (!$rename || queries("RENAME TABLE " . implode(", ", $rename))) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
552 queries("DROP DATABASE " . idf_escape(DB));
515325a Jakub Vrána Rename tables by single command
authored
553 return true;
3f5b683 Reintegrate sqlite branch
jakubvrana authored
554 }
555 }
515325a Jakub Vrána Rename tables by single command
authored
556 return false;
3f5b683 Reintegrate sqlite branch
jakubvrana authored
557 }
558
559 /** Generate modifier for auto increment column
560 * @return string
561 */
562 function auto_increment() {
563 $auto_increment_index = " PRIMARY KEY";
564 // don't overwrite primary key by auto_increment
565 if ($_GET["create"] != "" && $_POST["auto_increment_col"]) {
566 foreach (indexes($_GET["create"]) as $index) {
567 if (in_array($_POST["fields"][$_POST["auto_increment_col"]]["orig"], $index["columns"], true)) {
568 $auto_increment_index = "";
569 break;
570 }
571 if ($index["type"] == "PRIMARY") {
572 $auto_increment_index = " UNIQUE";
573 }
574 }
575 }
576 return " AUTO_INCREMENT$auto_increment_index";
577 }
578
579 /** Run commands to create or alter table
580 * @param string "" to create
581 * @param string new name
582 * @param array of array($orig, $process_field, $after)
583 * @param array of strings
584 * @param string
585 * @param string
586 * @param string
587 * @param int
588 * @param string
589 * @return bool
590 */
591 function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
592 $alter = array();
593 foreach ($fields as $field) {
594 $alter[] = ($field[1]
7f3ccd3 Jakub Vrána Utilize single parameter implode
authored
595 ? ($table != "" ? ($field[0] != "" ? "CHANGE " . idf_escape($field[0]) : "ADD") : " ") . " " . implode($field[1]) . ($table != "" ? " $field[2]" : "")
3f5b683 Reintegrate sqlite branch
jakubvrana authored
596 : "DROP " . idf_escape($field[0])
597 );
598 }
599 $alter = array_merge($alter, $foreign);
7e644b4 Jakub Vrána Save bytes ($connection->quote shortcut)
authored
600 $status = "COMMENT=" . q($comment)
601 . ($engine ? " ENGINE=" . q($engine) : "")
602 . ($collation ? " COLLATE " . q($collation) : "")
3f5b683 Reintegrate sqlite branch
jakubvrana authored
603 . ($auto_increment != "" ? " AUTO_INCREMENT=$auto_increment" : "")
604 . $partitioning
605 ;
606 if ($table == "") {
60c7ed9 Jakub Vrána MS SQL schema support
authored
607 return queries("CREATE TABLE " . table($name) . " (\n" . implode(",\n", $alter) . "\n) $status");
3f5b683 Reintegrate sqlite branch
jakubvrana authored
608 }
609 if ($table != $name) {
60c7ed9 Jakub Vrána MS SQL schema support
authored
610 $alter[] = "RENAME TO " . table($name);
3f5b683 Reintegrate sqlite branch
jakubvrana authored
611 }
612 $alter[] = $status;
60c7ed9 Jakub Vrána MS SQL schema support
authored
613 return queries("ALTER TABLE " . table($table) . "\n" . implode(",\n", $alter));
3f5b683 Reintegrate sqlite branch
jakubvrana authored
614 }
615
616 /** Run commands to alter indexes
617 * @param string escaped table name
618 * @param array of array("index type", "(columns definition)") or array("index type", "escaped name", "DROP")
619 * @return bool
620 */
621 function alter_indexes($table, $alter) {
622 foreach ($alter as $key => $val) {
623 $alter[$key] = ($val[2] ? "\nDROP INDEX " : "\nADD $val[0] " . ($val[0] == "PRIMARY" ? "KEY " : "")) . $val[1];
624 }
60c7ed9 Jakub Vrána MS SQL schema support
authored
625 return queries("ALTER TABLE " . table($table) . implode(",", $alter));
3f5b683 Reintegrate sqlite branch
jakubvrana authored
626 }
627
628 /** Run commands to truncate tables
629 * @param array
630 * @return bool
631 */
632 function truncate_tables($tables) {
f9bb1c5 Jakub Vrána Introduce apply_queries function
authored
633 return apply_queries("TRUNCATE TABLE", $tables);
3f5b683 Reintegrate sqlite branch
jakubvrana authored
634 }
635
636 /** Drop views
637 * @param array
638 * @return bool
639 */
640 function drop_views($views) {
60c7ed9 Jakub Vrána MS SQL schema support
authored
641 return queries("DROP VIEW " . implode(", ", array_map('table', $views)));
3f5b683 Reintegrate sqlite branch
jakubvrana authored
642 }
643
644 /** Drop tables
645 * @param array
646 * @return bool
647 */
648 function drop_tables($tables) {
60c7ed9 Jakub Vrána MS SQL schema support
authored
649 return queries("DROP TABLE " . implode(", ", array_map('table', $tables)));
3f5b683 Reintegrate sqlite branch
jakubvrana authored
650 }
651
44d572e Jakub Vrána Driver specific move tables
authored
652 /** Move tables to other schema
653 * @param array
654 * @param string
655 * @return bool
656 */
657 function move_tables($tables, $views, $target) {
658 $rename = array();
659 foreach (array_merge($tables, $views) as $table) { // views will report SQL error
60c7ed9 Jakub Vrána MS SQL schema support
authored
660 $rename[] = table($table) . " TO " . idf_escape($target) . "." . table($table);
44d572e Jakub Vrána Driver specific move tables
authored
661 }
662 return queries("RENAME TABLE " . implode(", ", $rename));
663 //! move triggers
664 }
665
3f5b683 Reintegrate sqlite branch
jakubvrana authored
666 /** Get information about trigger
667 * @param string trigger name
668 * @return array array("Trigger" => , "Timing" => , "Event" => , "Statement" => )
669 */
670 function trigger($name) {
7e644b4 Jakub Vrána Save bytes ($connection->quote shortcut)
authored
671 $rows = get_rows("SHOW TRIGGERS WHERE `Trigger` = " . q($name));
b0d637b Jakub Vrána Avoid fatal errors
authored
672 return reset($rows);
3f5b683 Reintegrate sqlite branch
jakubvrana authored
673 }
674
675 /** Get defined triggers
676 * @param string
677 * @return array array($name => array($timing, $event))
678 */
679 function triggers($table) {
680 $return = array();
7e644b4 Jakub Vrána Save bytes ($connection->quote shortcut)
authored
681 foreach (get_rows("SHOW TRIGGERS LIKE " . q(addcslashes($table, "%_"))) as $row) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
682 $return[$row["Trigger"]] = array($row["Timing"], $row["Event"]);
683 }
684 return $return;
685 }
686
edb6401 Driver specific create and drop database
jakubvrana authored
687 /** Get trigger options
688 * @return array ("Timing" => array(), "Type" => array())
689 */
f9dd7aa Driver specific trigger options
jakubvrana authored
690 function trigger_options() {
691 return array(
692 "Timing" => array("BEFORE", "AFTER"),
693 // Event is always INSERT, UPDATE, DELETE
694 "Type" => array("FOR EACH ROW"),
695 );
696 }
697
02a172e Driver specific routines
jakubvrana authored
698 /** Get information about stored routine
699 * @param string
700 * @param string FUNCTION or PROCEDURE
701 * @return array ("fields" => array("field" => , "type" => , "length" => , "unsigned" => , "inout" => , "collation" => ), "returns" => , "definition" => )
702 */
703 function routine($name, $type) {
704 global $connection, $enum_length, $inout, $types;
9e1d1c3 Jakub Vrána Respect unsupported types
authored
705 $aliases = array("bool", "boolean", "integer", "double precision", "real", "dec", "numeric", "fixed", "national char", "national varchar");
706 $type_pattern = "((" . implode("|", array_merge(array_keys($types), $aliases)) . ")(?:\\s*\\(((?:[^'\")]*|$enum_length)+)\\))?\\s*(zerofill\\s*)?(unsigned(?:\\s+zerofill)?)?)(?:\\s*(?:CHARSET|CHARACTER\\s+SET)\\s*['\"]?([^'\"\\s]+)['\"]?)?";
02a172e Driver specific routines
jakubvrana authored
707 $pattern = "\\s*(" . ($type == "FUNCTION" ? "" : implode("|", $inout)) . ")?\\s*(?:`((?:[^`]|``)*)`\\s*|\\b(\\S+)\\s+)$type_pattern";
708 $create = $connection->result("SHOW CREATE $type " . idf_escape($name), 2);
709 preg_match("~\\(((?:$pattern\\s*,?)*)\\)" . ($type == "FUNCTION" ? "\\s*RETURNS\\s+$type_pattern" : "") . "\\s*(.*)~is", $create, $match);
710 $fields = array();
711 preg_match_all("~$pattern\\s*,?~is", $match[1], $matches, PREG_SET_ORDER);
712 foreach ($matches as $param) {
713 $name = str_replace("``", "`", $param[2]) . $param[3];
714 $fields[] = array(
715 "field" => $name,
9e1d1c3 Jakub Vrána Respect unsupported types
authored
716 "type" => strtolower($param[5]),
02a172e Driver specific routines
jakubvrana authored
717 "length" => preg_replace_callback("~$enum_length~s", 'normalize_enum', $param[6]),
718 "unsigned" => strtolower(preg_replace('~\\s+~', ' ', trim("$param[8] $param[7]"))),
719 "full_type" => $param[4],
720 "inout" => strtoupper($param[1]),
721 "collation" => strtolower($param[9]),
722 );
723 }
724 if ($type != "FUNCTION") {
725 return array("fields" => $fields, "definition" => $match[11]);
726 }
727 return array(
728 "fields" => $fields,
729 "returns" => array("type" => $match[12], "length" => $match[13], "unsigned" => $match[15], "collation" => $match[16]),
730 "definition" => $match[17],
731 );
732 }
733
734 function routines() {
7e644b4 Jakub Vrána Save bytes ($connection->quote shortcut)
authored
735 return get_rows("SELECT * FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = " . q(DB));
02a172e Driver specific routines
jakubvrana authored
736 }
737
d0c72ec Driver specific BEGIN
jakubvrana authored
738 /** Begin transaction
739 * @return bool
740 */
741 function begin() {
742 return queries("BEGIN");
743 }
744
341362a Driver specific INSERT INTO
jakubvrana authored
745 /** Insert data into table
746 * @param string
747 * @param array
748 * @return bool
749 */
750 function insert_into($table, $set) {
60c7ed9 Jakub Vrána MS SQL schema support
authored
751 return queries("INSERT INTO " . table($table) . " (" . implode(", ", array_keys($set)) . ")\nVALUES (" . implode(", ", $set) . ")");
341362a Driver specific INSERT INTO
jakubvrana authored
752 }
753
782921b Jakub Vrána Finish SQLite
authored
754 /** Insert or update data in the table
755 * @param string
756 * @param array
6e50eb8 Jakub Vrána Pass primary key to insert_update function
authored
757 * @param array columns in keys
782921b Jakub Vrána Finish SQLite
authored
758 * @return bool
759 */
6e50eb8 Jakub Vrána Pass primary key to insert_update function
authored
760 function insert_update($table, $set, $primary) {
782921b Jakub Vrána Finish SQLite
authored
761 foreach ($set as $key => $val) {
762 $set[$key] = "$key = $val";
763 }
764 $update = implode(", ", $set);
765 return queries("INSERT INTO " . table($table) . " SET $update ON DUPLICATE KEY UPDATE $update");
766 }
767
29e7f04 Jakub Vrána Display auto_increment value of inserted item
authored
768 /** Get last auto increment ID
769 * @return string
770 */
771 function last_id() {
772 global $connection;
773 return $connection->result("SELECT LAST_INSERT_ID()"); // mysql_insert_id() truncates bigint
774 }
775
3f5b683 Reintegrate sqlite branch
jakubvrana authored
776 /** Explain select
777 * @param Min_DB
778 * @param string
779 * @return Min_Result
780 */
781 function explain($connection, $query) {
782 return $connection->query("EXPLAIN $query");
783 }
784
3308856 Jakub Vrána User types support for PostgreSQL
authored
785 /** Get user defined types
786 * @return array
787 */
788 function types() {
789 return array();
790 }
791
6420c58 Schema support for PostgreSQL
jakubvrana authored
792 /** Get existing schemas
793 * @return array
794 */
795 function schemas() {
796 return array();
797 }
798
799 /** Get current schema
800 * @return string
801 */
802 function get_schema() {
803 return "";
804 }
805
806 /** Set current schema
807 * @param string
808 * @return bool
809 */
810 function set_schema($schema) {
811 return true;
812 }
813
3f5b683 Reintegrate sqlite branch
jakubvrana authored
814 /** Get SQL command to create table
815 * @param string
fe53964 Jakub Vrána Allow disabling auto_increment value export
authored
816 * @param bool
3f5b683 Reintegrate sqlite branch
jakubvrana authored
817 * @return string
818 */
fe53964 Jakub Vrána Allow disabling auto_increment value export
authored
819 function create_sql($table, $auto_increment) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
820 global $connection;
fe53964 Jakub Vrána Allow disabling auto_increment value export
authored
821 $return = $connection->result("SHOW CREATE TABLE " . table($table), 1);
822 if (!$auto_increment) {
5002b89 Jakub Vrána Big numbers without E
authored
823 $return = preg_replace('~ AUTO_INCREMENT=\\d+~', '', $return); //! skip comments
fe53964 Jakub Vrána Allow disabling auto_increment value export
authored
824 }
825 return $return;
3f5b683 Reintegrate sqlite branch
jakubvrana authored
826 }
827
782921b Jakub Vrána Finish SQLite
authored
828 /** Get SQL command to truncate table
829 * @param string
830 * @return string
831 */
832 function truncate_sql($table) {
833 return "TRUNCATE " . table($table);
834 }
835
58c80e3 Driver specific USE
jakubvrana authored
836 /** Get SQL command to change database
837 * @param string
838 * @return string
839 */
840 function use_sql($database) {
841 return "USE " . idf_escape($database);
842 }
843
cc04be2 Driver specific trigger export
jakubvrana authored
844 /** Get SQL commands to create triggers
845 * @param string
846 * @param string
847 * @return string
848 */
849 function trigger_sql($table, $style) {
850 $return = "";
96544ba Jakub Vrána Report errors in get_rows()
authored
851 foreach (get_rows("SHOW TRIGGERS LIKE " . q(addcslashes($table, "%_")), null, "-- ") as $row) {
b0d637b Jakub Vrána Avoid fatal errors
authored
852 $return .= "\n" . ($style == 'CREATE+ALTER' ? "DROP TRIGGER IF EXISTS " . idf_escape($row["Trigger"]) . ";;\n" : "")
853 . "CREATE TRIGGER " . idf_escape($row["Trigger"]) . " $row[Timing] $row[Event] ON " . table($row["Table"]) . " FOR EACH ROW\n$row[Statement];;\n";
cc04be2 Driver specific trigger export
jakubvrana authored
854 }
855 return $return;
856 }
857
58c80e3 Driver specific USE
jakubvrana authored
858 /** Get server variables
859 * @return array ($name => $value)
860 */
984d090 SQLite variables
jakubvrana authored
861 function show_variables() {
862 return get_key_vals("SHOW VARIABLES");
863 }
864
58c80e3 Driver specific USE
jakubvrana authored
865 /** Get status variables
866 * @return array ($name => $value)
867 */
984d090 SQLite variables
jakubvrana authored
868 function show_status() {
869 return get_key_vals("SHOW STATUS");
870 }
871
3f5b683 Reintegrate sqlite branch
jakubvrana authored
872 /** Check whether a feature is supported
7b4aecb Jakub Vrána Comment
authored
873 * @param string "comment", "drop_col", "dump", "event", "partitioning", "routine", "scheme", "sequence", "status", "trigger", "type", "variables", "view"
3f5b683 Reintegrate sqlite branch
jakubvrana authored
874 * @return bool
875 */
876 function support($feature) {
877 global $connection;
3308856 Jakub Vrána User types support for PostgreSQL
authored
878 return !ereg("scheme|sequence|type" . ($connection->server_info < 5.1 ? "|event|partitioning" . ($connection->server_info < 5 ? "|view|routine|trigger" : "") : ""), $feature);
3f5b683 Reintegrate sqlite branch
jakubvrana authored
879 }
880
e672694 Jakub Vrána Rename $driver to $jush
authored
881 $jush = "sql"; ///< @var string JUSH identifier
3f5b683 Reintegrate sqlite branch
jakubvrana authored
882 $types = array(); ///< @var array ($type => $maximum_unsigned_length, ...)
883 $structured_types = array(); ///< @var array ($description => array($type, ...), ...)
884 foreach (array(
885 lang('Numbers') => array("tinyint" => 3, "smallint" => 5, "mediumint" => 8, "int" => 10, "bigint" => 20, "decimal" => 66, "float" => 12, "double" => 21),
886 lang('Date and time') => array("date" => 10, "datetime" => 19, "timestamp" => 19, "time" => 10, "year" => 4),
887 lang('Strings') => array("char" => 255, "varchar" => 65535, "tinytext" => 255, "text" => 65535, "mediumtext" => 16777215, "longtext" => 4294967295),
c0cc2a5 BIT data type
jakubvrana authored
888 lang('Binary') => array("bit" => 20, "binary" => 255, "varbinary" => 65535, "tinyblob" => 255, "blob" => 65535, "mediumblob" => 16777215, "longblob" => 4294967295),
3f5b683 Reintegrate sqlite branch
jakubvrana authored
889 lang('Lists') => array("enum" => 65535, "set" => 64),
890 ) as $key => $val) {
891 $types += $val;
892 $structured_types[$key] = array_keys($val);
893 }
894 $unsigned = array("unsigned", "zerofill", "unsigned zerofill"); ///< @var array number variants
895 $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "REGEXP", "IN", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL"); ///< @var array operators used in select
a52a327 Add date function in select (thanks to paranoiq)
jakubvrana authored
896 $functions = array("char_length", "date", "from_unixtime", "hex", "lower", "round", "sec_to_time", "time_to_sec", "upper"); ///< @var array functions used in select
3f5b683 Reintegrate sqlite branch
jakubvrana authored
897 $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum"); ///< @var array grouping functions used in select
898 $edit_functions = array( ///< @var array of array("$type|$type2" => "$function/$function2") functions used in editing, [0] - edit and insert, [1] - edit only
899 array(
900 "char" => "md5/sha1/password/encrypt/uuid", //! JavaScript for disabling maxlength
5a73c01 Jakub Vrána Treat binary type as hex
authored
901 "binary" => "md5/sha1/hex",
3f5b683 Reintegrate sqlite branch
jakubvrana authored
902 "date|time" => "now",
903 ), array(
904 "int|float|double|decimal" => "+/-",
905 "date" => "+ interval/- interval",
906 "time" => "addtime/subtime",
907 "char|text" => "concat",
908 )
909 );
910 }
Something went wrong with that request. Please try again.