19 $rev =
"version 1.01, r113";
21 define(
'UP', chr(27).chr(91).chr(65));
22 define(
'DOWN', chr(27).chr(91).chr(66));
23 define(
'RIGHT', chr(27).chr(91).chr(67));
24 define(
'LEFT', chr(27).chr(91).chr(68));
27 if (function_exists(
"pcntl_signal")) {
30 function sig_handler($signal)
32 global $matrixSqlTerminal;
36 $matrixSqlTerminal->cancel();
40 $matrixSqlTerminal->resetTerminal();
44 pcntl_signal(SIGCONT,
"sig_handler");
45 pcntl_signal(SIGINT,
"sig_handler");
48 error_reporting(E_ALL);
49 mb_internal_encoding(
"UTF-8");
54 $matrixSqlTerminal->connect((isset($_SERVER[
'argv'][1])) ? $_SERVER[
'argv'][1] :
'');
55 $matrixSqlTerminal->setOption(
"HISTFILE",
"~/.matrixsqlclient_history");
56 $matrixSqlTerminal->run();
58 catch (Exception $e) {
62 $matrixSqlTerminal->restoreTerminal();
82 public static function left($c=1) {
83 for ($i=0; $i<$c; $i++) echo chr(8);
95 for ($i=0; $i<$c; $i++) echo
' ';
107 return explode(
"\n", `printf
"lines\ncols" | tput -S`);
140 private $_historyFile =
'';
145 private $_tty_saved =
'sane';
155 private $_output_buffer = array();
160 private $_options = array(
161 'HISTFILE' =>
'~/.phpsqlc_history',
164 'disable-completion' =>
"off",
173 private $_cancel =
false;
191 $this->_parseOptions();
199 $this->_shell->writeHistory($this->_historyFile);
207 echo
"Cancel request\n";
208 $this->_cancel =
true;
220 return $this->_db->connect($dsn);
230 $this->_shell->readHistory($this->_historyFile);
236 echo
"Welcome to matrixsqlclient";
237 if (!empty($GLOBALS[
'rev'])) {
238 echo
" (" . $GLOBALS[
'rev'] .
")";
240 echo
", the interactive database terminal in PHP.";
241 echo
"\n\nYou are now connected.";
242 echo
"\nDatabase type: " . $this->_db->getDbType() . $this->_db->getDbVersion() .
".\n\n";
248 $line = $this->_shell->readline($this->_db->getDbName() . $prompt);
256 if ((mb_substr(trim($line), 0, 4) ==
'exit') || (mb_substr(trim($line), 0, 4) ==
'quit') || (mb_substr(trim($line), 0, 2) ==
'\q')) {
260 if (mb_substr($line, mb_strlen($line)-1, mb_strlen($line)) === chr(4)) {
266 if (ord(mb_substr($line, mb_strlen($line)-1, mb_strlen($line))) === 3) {
274 if (mb_strlen($line) > 0) {
276 $this->_shell->addHistory(strtr($line,
"\n",
" "));
279 if (mb_substr(trim($line), 0, 7) ==
"\\timing") {
281 $this->
setOption(
"timing", !$this->_getOptionValue(
"timing"));
283 if ($this->_getOptionValue(
"timing")) {
284 echo
"\nTiming is on.";
286 echo
"\nTiming is off.";
294 if (strlen(trim($sql)) === 0 && mb_substr(trim($line), 0, 4) ==
"\set") {
296 $params = explode(
" ", $line, 3);
299 if (count($params) === 1) {
301 $options = $this->_getOptions();
303 if (count($options) > 0) {
305 foreach ($this->_getOptions() as $option => $value) {
306 $value = ($value ===
true) ?
"on" : $value;
307 $value = ($value ===
false) ?
"off" : $value;
308 echo
"\n" . $option .
" = '" . $value .
"'";
315 $params = array_pad($params, 3,
"");
316 $this->
setOption($params[1], $params[2]);
317 $this->_parseOptions();
324 $sql .=
"\n" . $line;
328 if ($this->_db->matchesMacro($sql) || mb_strpos($sql,
';')) {
337 $source_data = @$this->_db->execute($sql);
339 catch (Exception $e) {
340 echo
"\n" . $e->getMessage() .
"\n";
356 if ($this->_cancel) {
358 $this->_cancel =
false;
368 if (is_array($source_data)) {
370 $rowlimit = (int)$this->_getOptionValue(
"rowlimit");
372 if (count($source_data) > $rowlimit) {
373 $this->_addToLinesBuffer(explode(
"\n",
"\n\nWARNING: Number of rows returned exceeded rowlimit.\nOnly the first $rowlimit rows are being shown. Use \set rowlimit <num> to adjust.\n\n"));
374 $source_data = array_slice($source_data, 0, $rowlimit);
378 if (!empty($source_data)) {
382 $table->showHeaders(
true);
384 $data = explode(
"\n", $table->render(
true));
386 $this->_addToLinesBuffer($data);
390 $count_str =
"(" . count($source_data) .
" row";
391 if (count($source_data) !== 1) {
396 $this->_addToLinesBuffer(array($count_str,
""));
400 $this->_addToLinesBuffer(array($source_data));
403 if ($this->_getOptionValue(
"timing")) {
405 $this->_addToLinesBuffer(array(
"Time: " . $this->_db->getQueryExecutionTime() .
" ms"));
409 $this->_printLines();
415 } elseif (mb_strlen(trim($sql)) > 0) {
418 if ((substr_count($sql,
"(") > substr_count($sql,
")"))) {
435 system(
"stty '" . trim($this->_tty_saved) .
"'");
447 $last_word = ltrim(mb_substr($hint, mb_strrpos($hint,
' ')));
450 if (preg_match(
'/SELECT\s+.+\s+FROM\s+\w*$/i', $hint)) {
451 $candidates = $this->_db->getTableNames();
454 } elseif (preg_match(
'/UPDATE\s+\w*$/i', $hint)) {
455 $candidates = $this->_db->getTableNames();
458 } elseif (preg_match(
'/INSERT INTO\s+\w*$/i', $hint)) {
459 $candidates = $this->_db->getTableNames();
462 } elseif (preg_match(
'/SELECT\s+.+\s+FROM\s+(.+?)\s+WHERE\s+\w*$/i', $hint, $table_name_search)) {
463 $table_name = @$table_name_search[1];
464 $candidates = $this->_db->getColumnNames($table_name);
467 } elseif (preg_match(
'/UPDATE\s+(.+?)\s+SET\s+\w*$/i', $hint, $table_name_search)) {
468 $table_name = @$table_name_search[1];
469 $candidates = $this->_db->getColumnNames($table_name);
473 if (empty($candidates)) {
478 if ($last_word ===
"") {
485 foreach ($candidates as $candidate) {
486 if (mb_strpos($candidate, $last_word) === 0) {
487 $matches[] = $candidate;
505 if ($save_existing) {
506 $this->_tty_saved = `stty -g`;
510 system(
"stty raw opost -ocrnl onlcr -onocr -onlret icrnl -inlcr -echo isig intr undef");
521 private function _printLines($n=0)
524 $lines_printed = array();
529 $line_buffer_len = count($this->_output_buffer);
530 for ($i=0; $i<$line_buffer_len && $i<$n; $i++) {
531 $line = array_shift($this->_output_buffer);
533 $lines_printed[] = $line;
537 return $lines_printed;
542 $tty_size = $this->_getTtySize();
544 if (!(
bool)$this->_getOptionValue(
"pager") ===
true || count($this->_output_buffer) < $tty_size[0]) {
547 $this->_printLines(count($this->_output_buffer));
554 $last_lines = $this->_printLines($tty_size[0]-1);
555 if ($last_lines[count($last_lines)-1][mb_strlen($last_lines[count($last_lines)-1])-1] !=
"\n") {
558 echo
"\033[30;47m" .
"--More--" .
"\033[0m";
564 if (!count($this->_output_buffer) > 0) {
578 $this->_printLines(count($this->_output_buffer));
587 $last_lines = $this->_printLines(1);
588 if ($last_lines[count($last_lines)-1][mb_strlen($last_lines[count($last_lines)-1])-1] !=
"\n") {
591 echo
"\033[30;47m" .
"--More--" .
"\033[0m";
602 $last_lines = $this->_printLines($tty_size[0]-1);
603 if ($last_lines[count($last_lines)-1][mb_strlen($last_lines[count($last_lines)-1])-1] !=
"\n") {
606 echo
"\033[30;47m" .
"--More--" .
"\033[0m";
618 $this->_clearLineBuffer();
639 private function _addToLinesBuffer($data)
642 $tty_size = $this->_getTtySize();
645 for ($i=0; $i<count($data); $i++) {
651 foreach (str_split($data[$i], (
int)$tty_size[1]) as $line) {
652 $this->_output_buffer[] = $line;
662 private function _clearLineBuffer()
664 $this->_output_buffer = array();
677 $this->_options[$option] = $value;
678 $this->_parseOptions();
686 private function _getOptions()
688 return $this->_options;
698 private function _getOptionValue($option)
702 if (isset($this->_options[$option])) {
704 $value = trim(strtolower($this->_options[$option]));
733 private function _getTtySize()
735 return explode(
"\n", `printf
"lines\ncols" | tput -S`);
744 private function _parseOptions()
747 if (!$this->_getOptionValue(
"disable-completion")) {
748 $this->_shell->registerAutocompleteCallback(array($this,
"autoComplete"));
750 $this->_shell->registerAutocompleteCallback(null);
754 $this->_shell->setHistorySize($this->_getOptionValue(
"HISTSIZE"));
757 if (strpos($this->_getOptionValue(
"HISTFILE"),
"~") !==
false) {
758 if (isset($_ENV[
'HOME'])) {
759 $this->_historyFile = str_replace(
"~", $_ENV[
'HOME'], $this->_getOptionValue(
"HISTFILE"));
761 $this->_historyFile = str_replace(
"~",
"/tmp", $this->_getOptionValue(
"HISTFILE"));
764 $this->_historyFile = $this->_getOptionValue(
"HISTFILE");
778 function sortArrayByLength($a,$b)
780 return count($a)-count($b);
791 private $_history = array();
796 private $_history_tmp = array();
801 private $_history_position = -1;
806 private $_history_storage = null;
811 private $_buffer =
'';
816 private $_buffer_position = 0;
821 private $_autocomplete_callback = null;
826 private $_prompt = null;
831 private $_autocompleteTabPressCount = 0;
842 return ($this->_history[] = trim($line));
854 $this->_history_storage = null;
857 if ($this->_history_storage->load()) {
858 $this->_history = $this->_history_storage->getData();
874 if (is_integer($c)) {
875 $this->_history_storage->setMaxSize($c);
896 if ($prompt !== null) {
897 $this->_prompt = $prompt;
903 $c = self::readKey();
916 if ($this->_autocomplete_callback !== null) {
918 $autocomplete_text = $this->_doAutocomplete($this->_buffer);
920 if (!empty($autocomplete_text)) {
921 $this->_insert($autocomplete_text);
935 $this->_cursorLeft($this->_buffer_position);
940 $this->_cursorRight(mb_strlen($this->_buffer) - $this->_buffer_position);
945 $this->_backspace($this->_buffer_position);
952 $prev_word_pos = $this->_buffer_position-$this->_getPreviousWordPos();
955 if ($prev_word_pos > 0) {
956 $this->_backspace($this->_buffer_position-$this->_getPreviousWordPos());
964 case chr(27) . chr(91) . chr(53) . chr(68):
965 $this->_cursorLeft($this->_buffer_position-$this->_getPreviousWordPos());
969 case chr(27) . chr(91) . chr(53) . chr(67):
970 $this->_cursorRight($this->_getNextWordPos()-$this->_buffer_position);
975 $line = $this->_buffer . $c;
982 if (mb_strlen($this->_buffer) === 0) {
983 $line = $this->_buffer . $c;
991 if (!$this->_historyMovePosition(-1)) {
998 if (!$this->_historyMovePosition(1)) {
1005 if (!$this->_cursorLeft()) {
1012 if (!$this->_cursorRight()) {
1022 if (!$this->_backspace()) {
1031 $line = $this->_buffer;
1038 if (ord($c[0]) === 27) {
1048 if ($line !== null) {
1051 if ($this->_runInternalCommand(trim($line))) {
1061 array_pop($this->_history_tmp);
1086 if (ord($buffer[0]) === 27) {
1088 if ((strlen($buffer) === 1) && (ord($c) === 27)) {
1090 } elseif ((strlen($buffer) === 2) && (ord($c) === 91)) {
1092 } elseif (strlen($buffer) === 3 && ord($c) >= 30 && ord($c) <= 57) {
1100 if (self::_isValidChar($buffer)) {
1106 if (strlen($buffer) > 4) {
1123 $this->_autocomplete_callback = $f;
1135 if (get_class($this->_history_storage) !==
"HistoryStorage") {
1139 $this->_history_storage->setData($this->_history);
1141 if ($this->_history_storage->save() !==
false) {
1155 private function _backspace($n=1)
1157 if ($this->_buffer_position < $n) {
1164 for ($i=0; $i<$n; $i++) {
1165 if ($this->_buffer_position < mb_strlen($this->_buffer)) {
1167 $head = mb_substr($this->_buffer, 0, $this->_buffer_position);
1168 $tail = mb_substr($this->_buffer, $this->_buffer_position, mb_strlen($this->_buffer));
1175 $this->_buffer = mb_substr($head, 0, mb_strlen($head)-1) . $tail;
1180 $this->_buffer = mb_substr($this->_buffer, 0, mb_strlen($this->_buffer)-1);
1184 $this->_buffer_position--;
1199 private function _historyMovePosition($n)
1202 if (!array_key_exists($this->_history_position + $n, $this->_history_tmp)) {
1211 $this->_cursorRight(mb_strlen($this->_buffer) - $this->_buffer_position);
1212 $this->_backspace($this->_buffer_position);
1215 $this->_history_position = $this->_history_position + $n;
1218 echo $this->_history_tmp[$this->_history_position];
1219 $this->_buffer = $this->_history_tmp[$this->_history_position];
1220 $this->_buffer_position = mb_strlen($this->_buffer);
1236 private function _insert($c)
1239 if ($this->_buffer_position < mb_strlen($this->_buffer)) {
1241 $head = mb_substr($this->_buffer, 0, $this->_buffer_position);
1242 $tail = mb_substr($this->_buffer, $this->_buffer_position, mb_strlen($this->_buffer));
1247 $this->_buffer = $head . $c . $tail;
1253 $this->_buffer .= $c;
1257 $this->_buffer_position = $this->_buffer_position + mb_strlen($c);
1258 $this->_history_tmp[$this->_history_position] = $this->_buffer;
1269 private static function _isValidChar($sequence)
1272 $encoding = mb_internal_encoding();
1275 if (mb_check_encoding($sequence) ===
false) {
1280 $fs = $encoding ==
'UTF-8' ?
'UTF-32' : $encoding;
1281 $ts = $encoding ==
'UTF-32' ?
'UTF-8' : $encoding;
1283 if ($sequence !== mb_convert_encoding(mb_convert_encoding($sequence, $fs, $ts), $ts, $fs)) {
1297 private function _cursorLeft($n=1)
1300 if ($this->_buffer_position > 0) {
1302 $this->_buffer_position = $this->_buffer_position - $n;
1319 private function _cursorRight($n=1)
1321 if ($this->_buffer_position < mb_strlen($this->_buffer)) {
1323 for ($i=0; $i<$n; $i++) {
1324 echo mb_substr($this->_buffer, $this->_buffer_position, 1);
1325 $this->_buffer_position++;
1344 private function _doAutocomplete($hint)
1346 if ($this->_autocomplete_callback === null) {
1350 $candidates = call_user_func($this->_autocomplete_callback, $hint);
1352 if (empty($candidates)) {
1356 $last_word = mb_substr($hint, mb_strrpos($hint,
' ')+1);
1361 if ($last_word ===
'') {
1362 $this->_showAutoCompleteOptions($candidates);
1369 foreach ($candidates as $match) {
1370 if (mb_strpos($match, $last_word) === 0) {
1371 $matches[] = mb_substr($match, mb_strlen($last_word));
1375 if (empty($matches)) {
1380 if (count($matches) === 1) {
1381 return $matches[0] .
" ";
1386 $finalAutocompleteString =
'';
1389 $candidate_map = array();
1390 foreach ($matches as $match) {
1391 $candidate_map[] = preg_split(
'/(?<!^)(?!$)/u', $match);
1395 usort($candidate_map,
'sortArrayByLength');
1397 for ($i=0; $i<count($candidate_map[0]); $i++) {
1402 foreach ($candidate_map as &$candidate) {
1403 $chars[] = $candidate[$i];
1407 $chars_uniq = array_unique($chars);
1408 if (count($chars_uniq) === 1) {
1409 $finalAutocompleteString .= $chars_uniq[0];
1413 if ($finalAutocompleteString ===
'') {
1414 $this->_showAutoCompleteOptions($candidates);
1417 return $finalAutocompleteString;
1425 private function _getPreviousWordPos()
1427 $temp_str = mb_substr($this->_buffer, 0, $this->_buffer_position);
1430 $temp_str = rtrim($temp_str);
1433 if (mb_strlen($temp_str) === 0) {
1436 $prev_word_pos = mb_strrpos($temp_str,
' ');
1439 if ($prev_word_pos > 0) {
1443 return $prev_word_pos;
1451 private function _getNextWordPos()
1453 $temp_str = mb_substr($this->_buffer, $this->_buffer_position, mb_strlen($this->_buffer));
1456 $temp_str_len = mb_strlen($temp_str);
1459 $temp_str = ltrim($temp_str);
1462 $trimmed_spaces = $temp_str_len - mb_strlen($temp_str);
1465 $next_word_pos = mb_strpos($temp_str,
' ');
1468 if ($next_word_pos ===
false) {
1469 $next_word_pos = mb_strlen($this->_buffer);
1471 $next_word_pos = $this->_buffer_position + $trimmed_spaces + $next_word_pos;
1474 return $next_word_pos;
1482 private function _reset()
1485 $this->_buffer =
'';
1486 $this->_buffer_position = 0;
1489 $this->_history_tmp = $this->_history;
1490 $this->_history_tmp[] =
'';
1491 $this->_history_position = count($this->_history);
1501 private function _runInternalCommand($command)
1504 if (mb_substr($command, 0, 5) ===
"\hist") {
1509 for ($i=0; $i<count($this->_history); $i++) {
1510 $p = strlen((
string)count($this->_history)) + 1;
1511 printf(
"%" . $p .
"s %s\n", $i+1, $this->_history[$i]);
1527 private function _showAutoCompleteOptions($options)
1530 if (!$this->_autocompleteTabPressCount > 0) {
1531 $this->_autocompleteTabPressCount++;
1534 $this->_autocompleteTabPressCount = 0;
1537 $optionMaxChars = 0;
1540 foreach ($options as $option) {
1541 if (mb_strlen($option)+2 > $optionMaxChars) {
1542 $optionMaxChars = mb_strlen($option) + 2;
1548 $ttyChars = $ttySize[1];
1551 $linesRequired = ceil((count($options)*$optionMaxChars) / $ttyChars);
1554 $itemsPerLine = floor($ttyChars / $optionMaxChars);
1556 for ($i=0; $i < count($options); $i++) {
1557 if ($i % $itemsPerLine === 0) {
1561 printf(
"%-" . $optionMaxChars .
"s", $options[$i]);
1564 echo $this->_prompt . $this->_buffer;
1586 private $cs = array();
1591 private $rs = array();
1596 private $keys = array();
1606 private $mW = 10000;
1608 private $head =
false;
1609 private $pcen =
"+";
1610 private $prow =
"-";
1611 private $pcol =
"|";
1623 $this->rows =& $rows;
1627 if(!$xc = count($this->rows))
return false;
1628 $this->keys = array_keys($this->rows[0]);
1629 $columns = count($this->keys);
1631 for($x=0; $x<$xc; $x++)
1632 for($y=0; $y<$columns; $y++)
1633 $this->setMax($x, $y, $this->rows[$x][$this->keys[$y]]);
1643 if($bool) $this->setHeading();
1653 $this->mW = (int) $maxWidth;
1663 $this->mH = (int) $maxHeight;
1674 if($return) ob_start(null, 0,
true);
1677 $this->printHeading();
1679 $rc = count($this->rows);
1680 for($i=0; $i<$rc; $i++) $this->printRow($i);
1683 $contents = ob_get_contents();
1689 private function setHeading()
1692 foreach($this->keys as $colKey => $value)
1694 $this->setMax(
false, $colKey, $value);
1695 $data[$colKey] = $value;
1697 if(!is_array($data))
return false;
1698 $this->head = $data;
1701 private function printLine($nl=
true)
1705 foreach($this->cs as $key => $val) {
1707 str_pad(
'', $val, $this->prow, STR_PAD_RIGHT) .
1710 if ($i < count($this->cs)-1) {
1720 private function printHeading()
1722 if(!is_array($this->head))
return false;
1726 foreach($this->cs as $key => $val) {
1728 str_pad($this->head[$key], $val,
' ', STR_PAD_BOTH) .
1730 if ($i < count($this->cs)-1) {
1742 private function printRow($rowKey)
1745 for($line=1; $line <= $this->rs[$rowKey]; $line++)
1748 for($colKey=0; $colKey < count($this->keys); $colKey++)
1751 print str_pad(substr($this->rows[$rowKey][$this->keys[$colKey]], ($this->mW * ($line-1)), $this->mW), $this->cs[$colKey],
' ', STR_PAD_RIGHT);
1752 if ($colKey < count($this->keys)-1) {
1753 print
" " . $this->pcol;
1762 private function setMax($rowKey, $colKey, &$colVal)
1764 $w = mb_strlen($colVal);
1768 $h = ceil($w % $this->mW);
1769 if($h > $this->mH) $h=$this->mH;
1773 if(!isset($this->cs[$colKey]) || $this->cs[$colKey] < $w)
1774 $this->cs[$colKey] = $w;
1776 if($rowKey !==
false && (!isset($this->rs[$rowKey]) || $this->rs[$rowKey] < $h))
1777 $this->rs[$rowKey] = $h;
1794 private $_file =
'';
1799 private $_data = array();
1805 private $_autosave =
false;
1810 private $_maxsize = 500;
1820 $this->_file = $file;
1821 $this->_autosave = $autosave;
1829 if ($this->_autosave) {
1841 $data = @file($this->_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
1843 if (is_array($data) ===
true) {
1844 $this->_data = $data;
1859 while (count($this->_data) > $this->_maxsize) {
1860 array_shift($this->_data);
1863 return @file_put_contents($this->_file, implode(
"\n", $this->_data));
1873 return $this->_data;
1885 if (is_array($data)) {
1886 $this->_data = $data;
1902 $this->_maxsize = (int)$n;
1913 return $this->_maxsize;
1930 private $_executionTime;
1945 $pluginName =
'DbBackend_' . $pluginName;
1947 if (class_exists($pluginName)) {
1948 $backend =
new $pluginName;
1951 if (is_null($backend) || !get_parent_class($pluginName) ==
'DbBackendPlugin') {
1952 echo(
"Cannot find valid DbBackendPlugin class \"" . $pluginName .
"\".");
1956 $this->_backend = $backend;
1969 return $this->_backend->connect($dsn);
1979 return $this->_backend->getDbName();
1989 return $this->_backend->getDbType();
1999 return $this->_backend->getDbVersion();
2009 return $this->_backend->disconnect();
2021 $query_start_time = microtime(
true);
2022 $result = $this->_backend->execute($sql);
2023 $query_end_time = microtime(
true);
2025 $this->_executionTime = $query_end_time - $query_start_time;
2037 return round($this->_executionTime * 1000, 3);
2047 return $this->_backend->getTableNames();
2059 return $this->_backend->getColumnNames($table);
2071 return $this->_backend->matchesMacro($s);
2093 abstract public function connect($conn_string);
2109 abstract public function execute($sql);
2178 private $_db_type =
'';
2183 private $_macros = array();
2191 $this->_macros = array(
2196 SELECT n.nspname as \"Schema\",
2197 c.relname as \"Name\",
2198 CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 's' THEN 'special' END as \"Type\",
2199 r.rolname as \"Owner\"
2200 FROM pg_catalog.pg_class c
2201 JOIN pg_catalog.pg_roles r ON r.oid = c.relowner
2202 LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
2203 WHERE c.relkind IN ('r','')
2204 AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
2205 AND pg_catalog.pg_table_is_visible(c.oid)
2210 "\dt" =>
"SELECT * FROM tab ORDER BY tname ASC;",
2224 $SYSTEM_ROOT = $conn_string;
2226 if (empty($SYSTEM_ROOT) || !is_dir($SYSTEM_ROOT)) {
2227 echo
"You need to supply the path to the System Root as the first argument\n";
2231 require_once $SYSTEM_ROOT.
'/fudge/dev/dev.inc';
2232 require_once $SYSTEM_ROOT.
'/core/include/general.inc';
2233 require_once $SYSTEM_ROOT.
'/core/lib/DAL/DAL.inc';
2234 require_once $SYSTEM_ROOT.
'/core/lib/MatrixDAL/MatrixDAL.inc';
2235 require_once $SYSTEM_ROOT.
'/data/private/conf/db.inc';
2237 $this->_dsn = $db_conf[
'db2'];
2238 $this->_db_type = $db_conf[
'db2'][
'type'];
2257 $dsn = trim($this->_dsn[
'DSN']);
2258 if (preg_match(
"/SERVICE_NAME/i", $dsn)) {
2259 return preg_replace(
"/\A.*HOST\s*=\s*(.*?)\).*SERVICE_NAME\s*=\s*(.*?)\).*\z/i",
'$2 on $1', $dsn);
2272 return $this->_db_type;
2307 foreach ($this->_macros[$this->_db_type] as $pattern => $replacement) {
2309 $sql = str_replace($pattern, $replacement, $sql, $c);
2316 if ($this->_db_type ==
'oci') {
2317 $sql = mb_substr($sql, 0, mb_strlen($sql)-1);
2321 $query_type = $this->_getQueryType($sql);
2322 switch ($query_type) {
2331 $output = $query_type .
" " . $rows_affected;
2338 $output = $query_type;
2343 $output = $query_type;
2348 $output = $query_type;
2370 switch ($this->_db_type) {
2374 -- phpsqlc: tab-completion: table-names
2377 FROM pg_catalog.pg_class c
2378 JOIN pg_catalog.pg_roles r ON r.oid = c.relowner
2379 LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
2380 WHERE c.relkind IN (
'r',
'')
2381 AND n.nspname NOT IN (
'pg_catalog',
'pg_toast')
2382 AND pg_catalog.pg_table_is_visible(c.oid)
2390 $sql =
"SELECT tname FROM tab UNION SELECT LOWER(tname) FROM tab";
2403 catch (Exception $e) {
2423 switch ($this->_db_type) {
2428 $sql =
"SELECT column_name FROM all_tab_columns WHERE table_name = " . mb_strtoupper(
MatrixDAL::quote($table)) .
" UNION " .
2429 "SELECT LOWER(column_name) FROM all_tab_columns WHERE table_name = " . mb_strtoupper(
MatrixDAL::quote($table));
2434 -- phpsqlc: tab-completion: column-names
2435 SELECT a.attname FROM pg_catalog.pg_attribute a
2436 WHERE a.attrelid IN (
2438 FROM pg_catalog.pg_class c
2439 LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
2440 WHERE c.relname =
'$table' AND pg_catalog.pg_table_is_visible(c.oid)
2441 ) AND a.attnum > 0 AND NOT a.attisdropped;
2454 catch (Exception $e) {
2470 return array_key_exists(trim($s), $this->_macros[$this->_db_type]);
2480 private function _getQueryType($input_query)
2482 $input_query = mb_strtoupper($input_query);
2484 if (mb_strpos($input_query,
"SELECT") === 0) {
2486 } elseif (mb_strpos($input_query,
"UPDATE") === 0) {
2488 } elseif (mb_strpos($input_query,
"INSERT INTO") === 0) {
2490 } elseif (mb_strpos($input_query,
"BEGIN") === 0) {
2492 } elseif (mb_strpos($input_query,
"START TRANSACTION") === 0) {
2494 } elseif (mb_strpos($input_query,
"ABORT") === 0) {
2496 } elseif (mb_strpos($input_query,
"ROLLBACK") === 0) {
2498 } elseif (mb_strpos($input_query,
"COMMIT") === 0) {