13 require_once dirname(dirname(__FILE__)).
'/Exceptions/DALConverterException.inc';
36 protected $dataTypes = array(
38 'varchar' =>
'VARCHAR',
42 'smallint' =>
'SMALLINT',
43 'numeric' =>
'NUMERIC',
46 'double_precision' =>
'DOUBLE PRECISION',
47 'boolean' =>
'BOOLEAN',
50 'timestamp' =>
'TIMESTAMP',
51 'interval' =>
'INTERVAL',
62 protected $sqlConstructs = array(
69 'group-by' =>
'GROUP BY',
71 'order-by' =>
'ORDER BY',
73 'not-exists' =>
'NOT EXISTS',
74 'start-with' =>
'START WITH',
75 'connect-by' =>
'CONNECT BY PRIOR',
87 protected $mathOps = array(
100 protected $query = array();
108 protected $name =
'';
117 private $_whereConditions = array(
120 'equal-or-greater' =>
'>=',
121 'equal-or-less' =>
'<=',
125 'not-in' =>
'NOT IN',
127 'not-like' =>
'NOT LIKE',
128 'is-null' =>
'IS NULL',
129 'not-null' =>
'NOT NULL',
145 $dataType = strtolower($type);
146 if (isset($this->dataTypes[$dataType]) === TRUE) {
147 $dataType = $this->dataTypes[$dataType];
181 if (isset($this->sqlConstructs[$name]) === TRUE) {
182 $construct = $this->sqlConstructs[$name];
200 $this->query = $sqlArray;
203 if (isset($sqlArray[
'SELECT']) === TRUE) {
205 }
else if (isset($sqlArray[
'INSERT']) === TRUE) {
207 }
else if (isset($sqlArray[
'UPDATE']) === TRUE) {
209 }
else if (isset($sqlArray[
'DELETE']) === TRUE) {
211 }
else if (isset($sqlArray[
'TRUNCATE']) === TRUE) {
212 $tableName = $sqlArray[
'TRUNCATE'][
'from'];
214 }
else if (isset($sqlArray[
'ALTER']) === TRUE) {
216 }
else if (isset($sqlArray[
'FUNCTION']) === TRUE) {
218 }
else if (isset($sqlArray[
'DROP']) === TRUE) {
219 if (isset($sqlArray[
'DROP'][
'TABLE']) === TRUE) {
221 }
else if (isset($sqlArray[
'DROP'][
'SEQUENCE']) === TRUE) {
224 }
else if (isset($sqlArray[
'WITH']) === TRUE) {
226 }
else if (isset($sqlArray[
'CALL']) === TRUE) {
228 }
else if (isset($sqlArray[
'AND']) === TRUE) {
229 $sqlArray = array(
'WHERE' => $sqlArray);
231 }
else if (isset($sqlArray[
'FROM']) === TRUE) {
257 if (isset($sqlArray[
'SELECT'][
'distinct']) === TRUE) {
258 if ($sqlArray[
'SELECT'][
'distinct'] === TRUE) {
259 $sql .=
' DISTINCT ';
263 $sql .=
"\n".$this->convertSelectFieldList($sqlArray[
'SELECT'][
'FIELDS'], ($level + 1));
264 $sql .=
"\n".$this->addSpaces($level);
265 if (isset($sqlArray[
'FROM']) === TRUE) {
270 $sql .=
"\n".$this->addSpaces($level);
272 if (in_array(
'join', $ignore) === FALSE) {
274 if (isset($sqlArray[
'JOIN']) === TRUE) {
280 $sql .=
"\n".$joins.
"\n";
284 if (in_array(
'where', $ignore) === FALSE) {
285 if (isset($sqlArray[
'WHERE']) === TRUE) {
292 $sql .=
"\n".$this->convertWhereClause($sqlArray[
'WHERE'], $level);
316 if (isset($sqlArray[
'GROUP-BY']) === TRUE) {
321 if (isset($sqlArray[
'HAVING']) === TRUE) {
322 $sql .=
"\n".$this->getConstructName(
'having');
323 $sql .=
"\n".$this->convertWhereClause($sqlArray[
'HAVING']);
327 if (isset($sqlArray[
'ORDER-BY']) === TRUE) {
328 $sql .=
"\n".$this->convertOrderBy($sqlArray[
'ORDER-BY']);
332 if (isset($sqlArray[
'LIMIT']) === TRUE) {
333 $sql .=
"\n".$this->convertLimit($sqlArray[
'LIMIT']);
353 foreach ($fields as $field) {
357 $sql = $this->
addSpaces($level).$this->separateFields($list);
377 if (is_array($field) === TRUE) {
378 if (isset($field[
'FUNCTION']) === TRUE) {
381 }
else if (isset($field[
'table']) === TRUE) {
384 }
else if (isset($field[
'MATH-OP']) === TRUE) {
386 }
else if (isset($field[
'SELECT']) === TRUE) {
387 $sql =
'('.$this->convertSelectQuery($field).
')';
412 if (isset($field[
'FUNCTION']) === TRUE) {
414 if (isset($function[
'FUNCTION'][
'alias']) === TRUE) {
415 $name = $function[
'FUNCTION'][
'alias'];
417 }
else if (isset($field[
'table']) === TRUE) {
419 if (isset($field[
'alias']) === TRUE) {
420 $name = $field[
'alias'];
422 $name = $field[
'column'];
424 }
else if (isset($field[
'MATH-OP']) === TRUE) {
425 if (isset($mathOp[
'MATH-OP'][
'alias']) === TRUE) {
426 $name = $mathOp[
'MATH-OP'][
'alias'];
428 }
else if (isset($field[
'SELECT']) === TRUE) {
431 if (isset($field[
'alias']) === TRUE) {
432 $name = $field[
'alias'];
434 $name = $field[
'value'];
454 if (isset($field[
'FUNCTION']) === TRUE) {
456 $function[
'FUNCTION'][
'alias'] = $alias;
457 }
else if (isset($field[
'table']) === TRUE) {
459 $field[
'alias'] = $alias;
460 }
else if (isset($field[
'MATH-OP']) === TRUE) {
461 $mathOp[
'MATH-OP'][
'alias'] = $alias;
462 }
else if (isset($field[
'SELECT']) === TRUE) {
465 $field[
'alias'] = $alias;
484 foreach ($fields as $field) {
504 if ($field[
'table'] !==
'') {
505 $sql .= $field[
'table'];
506 if ($field[
'column'] !==
'') {
511 if ($field[
'column'] !==
'') {
512 $sql .= $field[
'column'];
513 if (isset($field[
'alias']) === TRUE) {
514 $sql .=
' as '.$field[
'alias'];
534 if (is_array($field) === TRUE) {
535 if ((isset($field[
'value']) === TRUE) && (isset($field[
'alias']) === TRUE)) {
536 $sql .= $field[
'value'].
' as '.$field[
'alias'];
539 if (empty($field) === FALSE) {
542 if (is_numeric($field) === FALSE) {
543 $sql =
"'".$field.
"'";
566 $fnName = $function[
'FUNCTION'][
'function'];
567 $fnHandler =
'handleFunction'.$fnName;
569 foreach ($function[
'FUNCTION'][
'ARGS'] as $arg) {
573 if (method_exists($this, $fnHandler) === FALSE) {
574 $sql .= $function[
'FUNCTION'][
'function'].
'(';
578 $sql .= $this->$fnHandler($args);
581 if (isset($function[
'FUNCTION'][
'alias']) === TRUE) {
582 $sql .=
' as '.$function[
'FUNCTION'][
'alias'];
601 $sql =
"\n".$this->addSpaces($level);
602 if ((isset($from[
'UNION']) !== TRUE) && (isset($from[
'UNION-ALL']) !== TRUE)) {
605 foreach ($from as $table) {
607 if (is_array($table) === TRUE && isset($table[
'FROM']) === TRUE) {
609 if ($subTables !==
'') {
610 $subTables =
','.$subTables;
613 if (is_array($table) === TRUE) {
614 if (isset($table[
'name']) === TRUE) {
616 if (is_array($table[
'name']) === TRUE && isset($table[
'name'][
'SELECT']) === TRUE) {
617 $newTable =
'('.$this->convertSelectQuery($table[
'name']).
')';
619 $newTable = $table[
'name'];
623 if (isset($table[
'alias']) === TRUE) {
626 }
else if (isset($table[
'FUNCTION']) === TRUE) {
633 if (strpos($newTable,
'HOOKID') === FALSE) {
634 $tables[] = $newTable;
660 return ' as '.$alias;
681 if (isset($mathOp[
'MATH-OP']) === TRUE) {
682 if (isset($mathOp[
'MATH-OP'][
'alias']) === TRUE) {
683 $alias =
' as '.$mathOp[
'MATH-OP'][
'alias'];
686 $mathOp = $mathOp[
'MATH-OP'][0];
689 $operations = array();
690 foreach ($mathOp as $currentOp => $args) {
691 if (is_array($args) === TRUE) {
692 foreach ($args as $value) {
694 if (is_array($value) === TRUE) {
695 $keys = array_keys($value);
696 $op = array_shift($keys);
697 if (isset($this->mathOps[$op]) === TRUE) {
703 if ($field === TRUE) {
704 if (is_array($value) === TRUE && isset($value[
'SELECT']) === TRUE) {
705 $operations[] =
'('.$this->convertSelectQuery($value).
')';
714 $sql =
'('.implode(
' '.$this->mathOps[$currentOp].
' ', $operations).
')';
733 return implode(
', ', $fields);
748 return implode(
', ', $tables);
767 if ($addBrackets === TRUE) {
772 foreach ($where as $condType => $conditions) {
774 foreach ($conditions as $condition) {
775 $sql .= str_repeat(
' ', (($level + 1) * 4));
776 if ($beg === FALSE) {
777 $sql .= $condType.
' ';
782 if (is_array($condition) === FALSE) {
784 $sql .=
'(1=1)'.
"\n";
785 }
else if (isset($condition[
'IN']) === TRUE) {
788 }
else if (isset($condition[
'NOT-IN']) === TRUE) {
791 }
else if (isset($condition[
'EXISTS']) === TRUE) {
793 }
else if (isset($condition[
'NOT-EXISTS']) === TRUE) {
795 }
else if (isset($condition[
'OR']) === TRUE || isset($condition[
'AND']) === TRUE) {
797 $sql .=
"\n".$this->convertWhereClause($condition, ($level + 1));
798 }
else if ((isset($condition[
'type']) === TRUE) && ($condition[
'type'] ===
'is-null')) {
801 }
else if ((isset($condition[
'type']) === TRUE) && ($condition[
'type'] ===
'not-null')) {
804 }
else if ((isset($condition[
'type']) === TRUE) && ($condition[
'type'] ===
'like')) {
807 }
else if (isset($condition[
'compare']) === TRUE) {
810 $sql .=
' '.$wc[$condition[
'type']];
811 $sql .=
' ('.$this->convertSingleField($condition[
'to']).
')';
814 $msg =
'Unable to convert WHERE/HAVING condition.';
820 if ($addBrackets === TRUE) {
821 $sql .= str_repeat(
' ', ($level * 4)).
")\n";
842 $sql .= $in[$type][
'table'].
'.'.$in[$type][
'column'];
843 $sql .=
' '.$this->getConstructName(strtolower($type)).
'(';
846 if (isset($in[$type][
'CONDITIONS'][
'SELECT']) === TRUE) {
847 $sql .=
"\n".$this->convertSelectQuery($in[$type][
'CONDITIONS'], ($level + 1));
848 $sql .= str_repeat(
' ', ($level * 4));
850 $conditions = array();
851 foreach ($in[$type][
'CONDITIONS'] as $condition) {
880 $sql .= str_repeat(
' ', ($level * 4)).
")\n";
899 if (isset($isNull[
'compare']) === TRUE) {
900 if (empty($isNull[
'compare']) === FALSE) {
904 $msg =
'is-null value cannot be empty.';
908 $msg =
'Found is-null tag with no value.';
929 if (isset($notNull[
'compare']) === TRUE) {
930 if (empty($notNull[
'compare']) === FALSE) {
932 $sql .=
' IS NOT NULL';
934 $msg =
'not-null value cannot be empty.';
938 $msg =
'Found not-null tag with no value.';
959 $sql =
"(\n".$this->addSpaces($level);
961 $sql .=
') AS '.$union[$type][
'alias'];
978 if (isset($union[
'UNION']) === TRUE) {
980 }
else if (isset($union[
'UNION-ALL']) === TRUE) {
1003 if (isset($union[$type][
'SELECTS']) === TRUE) {
1004 $selectSqls = array();
1005 foreach ($union[$type][
'SELECTS'] as $select) {
1006 if (is_array($select) === TRUE) {
1009 $selectSqls[] = $this->
addSpaces($level).$select.
"\n";
1013 $spaces =
"\n".$this->addSpaces($level);
1014 $sql .= implode($spaces.$displayType.
"\n\n", $selectSqls);
1052 foreach ($groupBy as $field) {
1053 if (is_array($field) === TRUE) {
1081 foreach ($orderBy as $key => $field) {
1082 if ($key !==
'direction') {
1083 if (is_array($field) === TRUE) {
1089 $direction =
' '.$field;
1111 $sql .= $limit[
'rows'].
' OFFSET '.$limit[
'offset'];
1130 foreach ($joins as $join) {
1134 $sql = implode(
"\nAND ", $list);
1152 if (isset($join[
'ARGS']) === TRUE) {
1154 $sql = $join[
'ARGS'][0][
'table'].
'.'.$join[
'ARGS'][0][
'column'];
1155 $sql .=
' '.$this->getComparisonOperators($join[
'type']).
' ';
1156 $sql .= $join[
'ARGS'][1][
'table'].
'.'.$join[
'ARGS'][1][
'column'];
1179 $sql =
'INSERT INTO '.$sqlArray[
'INSERT'][
'into'];
1199 return str_repeat(
' ', ($level * 4));
1215 if (empty($fields) === FALSE) {
1216 $sql =
'('.$this->separateFields($fields).
') ';
1239 if (isset($insert[
'VALUES'][
'SELECT']) === FALSE) {
1240 $valuesList = array();
1241 foreach ($insert[
'FIELDS'] as $field) {
1242 if (isset($insert[
'VALUES'][$field]) === TRUE) {
1243 $value = $insert[
'VALUES'][$field];
1245 $msg =
'Could not convert INSERT query.';
1246 $msg .=
' Field "'.$field.
'" not found in values list.';
1250 $valuesList[] =
'('.$this->convertSingleField($value).
')';
1253 $sql .=
'VALUES ('.$this->separateFields($valuesList).
') ';
1256 $sql .=
'('.$this->convertSelectQuery($insert[
'VALUES']).
')';
1279 $sql =
'UPDATE '.$sqlArray[
'UPDATE'][
'table'];
1281 $sql .=
"\n".$this->convertUpdateQuerySetValues($sqlArray[
'UPDATE'][
'VALUES']);
1282 if (isset($sqlArray[
'UPDATE'][
'WHERE']) === TRUE) {
1283 $sql .=
"\n".
'WHERE ';
1303 foreach ($values as $col => $val) {
1305 $vals[] = $col.
' = '.$val;
1309 $sql = $spaces.implode(
",\n".$spaces, $vals);
1331 $sql =
'DELETE FROM '.$sqlArray[
'DELETE'][
'from'];
1332 $sql .=
"\n".$this->getConstructName(
'where');
1355 $sql =
'ALTER TABLE '.$tableName.
"\n";
1373 foreach ($sqlArray[
'ALTER'] as $key => $value) {
1374 if ($key !==
'table') {
1375 $key = ucwords(str_replace(
'-',
' ', strtolower($key)));
1376 $alterType =
'convertAlterQuery'.str_replace(
' ',
'', $key);
1377 $sql .= $this->$alterType($value);
1401 if (isset($addColumn[
'COLUMNS']) === TRUE) {
1403 foreach ($addColumn[
'COLUMNS'] as $column) {
1407 $sql .= implode(
', ', $cols);
1409 $msg =
'Cannot convert ALTER TABLE ADD COLUMN without columns.';
1433 $sql =
'DROP COLUMN ';
1434 if (($column !==
'') && (is_string($column) === TRUE)) {
1437 $msg =
'Cannot convert ALTER TABLE DROP COLUMN without column name.';
1460 $sql =
'RENAME COLUMN ';
1461 if ((isset($renameColumn[
'OLD']) === TRUE) && (isset($renameColumn[
'NEW'])) === TRUE) {
1462 $sql .= $renameColumn[
'OLD'].
' TO '.$renameColumn[
'NEW'];
1464 $msg =
'Cannot convert ALTER TABLE RENAME COLUMN.';
1488 if (isset($modifyColumns[
'COLUMNS']) === TRUE) {
1490 foreach ($modifyColumns[
'COLUMNS'] as $column) {
1494 $sql .= implode(
', ', $cols);
1496 $msg =
'Cannot convert ALTER TABLE MODIFY COLUMN without columns.';
1521 if (empty($constraints) === FALSE) {
1522 if ($tableName !== NULL) {
1549 if ($dropConstraint !==
'') {
1550 $sql .=
'DROP '.$dropConstraint;
1552 $msg =
'Cannot convert ALTER TABLE DROP CONSTRAINT without constraint name.';
1576 if ((isset($renameTable[
'OLD']) === TRUE) && (isset($renameTable[
'NEW'])) === TRUE) {
1577 $sql .= $renameTable[
'OLD'].
' TO '.$renameTable[
'NEW'];
1579 $msg =
'Cannot convert ALTER TABLE RENAME.';
1604 $sql .=
"\n".$this->convertCreateColumns($table);
1607 if ($constraints !==
'') {
1608 $sql .=
",\n".$constraints;
1613 if ($indexes !==
'') {
1614 $sql .=
"\n".$indexes;
1617 if (isset($table[
'SEQUENCES']) === TRUE) {
1618 $sql .=
"\n".$this->convertCreateSequences($table[
'SEQUENCES']);
1638 $sql =
'CREATE TABLE '.$table[
'table'];
1674 foreach ($table[
'COLUMNS'] as $col) {
1678 $sql = implode(
",\n", $sql);
1701 $sql = $col[
'name'].
' '.$this->
getDataType($col[
'type']);
1704 if ($col[
'size'] !==
'') {
1705 $sql .=
'('.$col[
'size'];
1706 if ($col[
'scale'] !==
'') {
1707 $sql .=
','.$col[
'scale'];
1714 if ($col[
'default'] !==
'') {
1715 $sql .=
' DEFAULT '.$col[
'default'];
1719 if ($col[
'allow-null'] ===
'false') {
1720 $sql .=
' NOT NULL';
1746 $constraints = array();
1749 foreach ($constraintsList[
'PRIMARY-KEYS'] as $pk) {
1754 if (isset($constraintsList[
'FOREIGN-KEYS']) === TRUE) {
1755 foreach ($constraintsList[
'FOREIGN-KEYS'] as $fk) {
1760 if (isset($constraintsList[
'UNIQUES']) === TRUE) {
1761 foreach ($constraintsList[
'UNIQUES'] as $un) {
1766 if ($asArray === FALSE) {
1767 $sql .= implode(
",\n", $constraints);
1770 return $constraints;
1788 $sql =
'CONSTRAINT '.$pk[
'name'].
' PRIMARY KEY (';
1808 $sql =
'CONSTRAINT '.$fk[
'name'].
' FOREIGN KEY (';
1811 foreach ($fk[
'COLUMNS'] as $col) {
1812 $cols[] = $col[
'name'];
1813 $refs[] = $col[
'references'];
1817 $sql .=
'REFERENCES '.$fk[
'table'].
'(';
1819 if ($fk[
'on-delete'] !==
'NO ACTION') {
1820 $sql .=
' ON DELETE '.$fk[
'on-delete'];
1840 $sql =
'CONSTRAINT '.$un[
'name'].
' UNIQUE (';
1859 foreach ($table[
'INDEXES'] as $index) {
1863 if (empty($indexes) === FALSE) {
1864 $sql .= implode(
";\n", $indexes).
';';
1885 $sql =
'CREATE INDEX '.$idx[
'name'].
' ON '.$tableName.
' (';
1904 if (empty($sequences) === FALSE) {
1905 foreach ($sequences as $sequence) {
1909 if (empty($seqs) === FALSE) {
1910 $sql = implode(
";\n", $seqs);
1929 $sql =
'CREATE SEQUENCE ';
1949 $sql =
'DROP TABLE '.$tableName;
1950 if ($cascade === TRUE) {
1969 $sql =
'delete from '.$tableName;
1985 $sql =
'DROP SEQUENCE '.$sequenceName;
2002 $sql =
"SELECT setval('$sequenceName', 1); ";
2020 $sql .=
"\nAS\n(\n";
2058 if (is_array($tableName) === TRUE) {
2059 $tableName = $tableName[0];
2062 if ($schema === NULL) {
2063 $schema =
'\''.DAL::getDbName().
'\'';
2066 $sql =
'SELECT count(*) FROM INFORMATION_SCHEMA.tables WHERE TABLE_NAME = '.$tableName.
' AND TABLE_SCHEMA = '.$schema;
2082 $sql =
'CONCAT('.implode(
', ', $args).
')';
2098 $sql =
'ARRAY('.$args[0].
')';
2116 $sql = $compare.
' LIKE '.$to;
2133 $sql =
'CAST('.$args[0].
' AS '.$this->
getDataType($args[1]).
')';
2167 $sql =
'LENGTH('.$this->convertSingleField($args[0]).
')';
2185 foreach ($args as $arg) {
2189 $sql .= implode(
',', $fnArgs).
')';
2206 if (count($args) !== 1) {
2207 $msg =
'The MAX() aggregate function accepts only one parameter: the expression to find the maximum value of in the table.';
2230 if (count($args) !== 1) {
2231 $msg =
'The MIN() aggregate function accepts only one parameter: the expression to find the maximum value of in the table.';
2254 if (count($args) != 1) {
2255 $msg =
'The COUNT() aggregate function accepts exactly one parameter.';
2282 if (count($args) != 2 && count($args) != 3) {
2283 $msg =
'The SUBSTRING() function only accepts two or three parameters.';
2289 $length = isset($args[2]) ?
" FOR $args[2]" :
'';
2290 $sql =
"SUBSTRING($input FROM $start $length)";
2307 if ($type !== NULL) {
2308 if (isset($this->_whereConditions[$type]) === TRUE) {
2309 return $this->_whereConditions[$type];
2315 return $this->_whereConditions;