Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
DALConverter.inc
1 <?php
13 require_once dirname(dirname(__FILE__)).'/Exceptions/DALConverterException.inc';
14 
26 {
27 
36  protected $dataTypes = array(
37  'char' => 'CHAR',
38  'varchar' => 'VARCHAR',
39  'clob' => 'TEXT',
40  'blob' => 'BYTEA',
41  'integer' => 'INT',
42  'smallint' => 'SMALLINT',
43  'numeric' => 'NUMERIC',
44  'float' => 'FLOAT',
45  'real' => 'REAL',
46  'double_precision' => 'DOUBLE PRECISION',
47  'boolean' => 'BOOLEAN',
48  'date' => 'DATE',
49  'time' => 'TIME',
50  'timestamp' => 'TIMESTAMP',
51  'interval' => 'INTERVAL',
52  );
53 
62  protected $sqlConstructs = array(
63  'select' => 'SELECT',
64  'from' => 'FROM',
65  'where' => 'WHERE',
66  'in' => 'IN',
67  'not-in' => 'NOT IN',
68  'limit' => 'LIMIT',
69  'group-by' => 'GROUP BY',
70  'having' => 'HAVING',
71  'order-by' => 'ORDER BY',
72  'exists' => 'EXISTS',
73  'not-exists' => 'NOT EXISTS',
74  'start-with' => 'START WITH',
75  'connect-by' => 'CONNECT BY PRIOR',
76  );
77 
87  protected $mathOps = array(
88  'SUBTRACT' => '-',
89  'ADD' => '+',
90  'MULTIPLY' => '*',
91  'DIVIDE' => '/',
92  );
93 
100  protected $query = array();
101 
108  protected $name = '';
109 
117  private $_whereConditions = array(
118  'equal' => '=',
119  'not-equal' => '!=',
120  'equal-or-greater' => '>=',
121  'equal-or-less' => '<=',
122  'greater' => '>',
123  'less' => '<',
124  'in' => 'IN',
125  'not-in' => 'NOT IN',
126  'like' => 'LIKE',
127  'not-like' => 'NOT LIKE',
128  'is-null' => 'IS NULL',
129  'not-null' => 'NOT NULL',
130  );
131 
132 
143  public function getDataType($type)
144  {
145  $dataType = strtolower($type);
146  if (isset($this->dataTypes[$dataType]) === TRUE) {
147  $dataType = $this->dataTypes[$dataType];
148  }
149 
150  return $dataType;
151 
152  }//end getDataType()
153 
154 
161  public function getName()
162  {
163  return $this->name;
164 
165  }//end getName()
166 
167 
178  public function getConstructName($name)
179  {
180  $construct = '';
181  if (isset($this->sqlConstructs[$name]) === TRUE) {
182  $construct = $this->sqlConstructs[$name];
183  }
184 
185  return $construct;
186 
187  }//end getConstructName()
188 
189 
198  public function convertToSql(array $sqlArray)
199  {
200  $this->query = $sqlArray;
201 
202  $sql = '';
203  if (isset($sqlArray['SELECT']) === TRUE) {
204  $sql = $this->convertSelectQuery($sqlArray);
205  } else if (isset($sqlArray['INSERT']) === TRUE) {
206  $sql = $this->convertInsertQuery($sqlArray);
207  } else if (isset($sqlArray['UPDATE']) === TRUE) {
208  $sql = $this->convertUpdateQuery($sqlArray);
209  } else if (isset($sqlArray['DELETE']) === TRUE) {
210  $sql = $this->convertDeleteQuery($sqlArray);
211  } else if (isset($sqlArray['TRUNCATE']) === TRUE) {
212  $tableName = $sqlArray['TRUNCATE']['from'];
213  $sql = $this->convertTruncateTable($tableName);
214  } else if (isset($sqlArray['ALTER']) === TRUE) {
215  $sql = $this->convertAlterQuery($sqlArray);
216  } else if (isset($sqlArray['FUNCTION']) === TRUE) {
217  $sql = $this->convertSingleFunction($sqlArray);
218  } else if (isset($sqlArray['DROP']) === TRUE) {
219  if (isset($sqlArray['DROP']['TABLE']) === TRUE) {
220  $sql = $this->convertDropTable($sqlArray['DROP']['TABLE']);
221  } else if (isset($sqlArray['DROP']['SEQUENCE']) === TRUE) {
222  $sql = $this->convertDropSequence($sqlArray['DROP']['SEQUENCE']);
223  }
224  } else if (isset($sqlArray['WITH']) === TRUE) {
225  $sql = $this->convertWithQuery($sqlArray['WITH']);
226  } else if (isset($sqlArray['CALL']) === TRUE) {
227  $sql = $this->convertCallQuery($sqlArray['CALL']);
228  } else if (isset($sqlArray['AND']) === TRUE) {
229  $sqlArray = array('WHERE' => $sqlArray);
230  $sql = $this->convertWhereClause($sqlArray['WHERE']);
231  } else if (isset($sqlArray['FROM']) === TRUE) {
232  $sql = $this->convertFromList($sqlArray['FROM']);
233  }//end if
234 
235  return $sql;
236 
237  }//end convertToSql()
238 
239 
251  protected function convertSelectQuery(array $sqlArray, $level=0, array $ignore=array())
252  {
253  $sql = $this->addSpaces($level);
254  $sql .= $this->getConstructName('select');
255 
256  // Add Distinct clause?
257  if (isset($sqlArray['SELECT']['distinct']) === TRUE) {
258  if ($sqlArray['SELECT']['distinct'] === TRUE) {
259  $sql .= ' DISTINCT ';
260  }
261  }
262 
263  $sql .= "\n".$this->convertSelectFieldList($sqlArray['SELECT']['FIELDS'], ($level + 1));
264  $sql .= "\n".$this->addSpaces($level);
265  if (isset($sqlArray['FROM']) === TRUE) {
266  $sql .= $this->getConstructName('from');
267  $sql .= $this->convertFromList($sqlArray['FROM'], ($level + 1));
268  }
269 
270  $sql .= "\n".$this->addSpaces($level);
271 
272  if (in_array('join', $ignore) === FALSE) {
273  $joins = '';
274  if (isset($sqlArray['JOIN']) === TRUE) {
275  $joins = $this->convertJoins($sqlArray['JOIN']);
276  }
277 
278  if ($joins !== '') {
279  $sql .= $this->getConstructName('where');
280  $sql .= "\n".$joins."\n";
281  }
282  }
283 
284  if (in_array('where', $ignore) === FALSE) {
285  if (isset($sqlArray['WHERE']) === TRUE) {
286  if ($joins === '') {
287  $sql .= $this->getConstructName('where');
288  } else {
289  $sql .= 'AND';
290  }
291 
292  $sql .= "\n".$this->convertWhereClause($sqlArray['WHERE'], $level);
293  }
294  }
295 
296  $sql .= $this->addSqlFilters($sqlArray);
297 
298  return $sql;
299 
300  }//end convertSelectQuery()
301 
302 
311  protected function addSqlFilters(array $sqlArray)
312  {
313  $sql = '';
314 
315  // Group by.
316  if (isset($sqlArray['GROUP-BY']) === TRUE) {
317  $sql .= $this->convertGroupBy($sqlArray['GROUP-BY']);
318  }
319 
320  // Having.
321  if (isset($sqlArray['HAVING']) === TRUE) {
322  $sql .= "\n".$this->getConstructName('having');
323  $sql .= "\n".$this->convertWhereClause($sqlArray['HAVING']);
324  }
325 
326  // Order By.
327  if (isset($sqlArray['ORDER-BY']) === TRUE) {
328  $sql .= "\n".$this->convertOrderBy($sqlArray['ORDER-BY']);
329  }
330 
331  // Limit.
332  if (isset($sqlArray['LIMIT']) === TRUE) {
333  $sql .= "\n".$this->convertLimit($sqlArray['LIMIT']);
334  }
335 
336  return $sql;
337 
338  }//end addSqlFilters()
339 
340 
350  protected function convertSelectFieldList(array $fields, $level=1)
351  {
352  $list = array();
353  foreach ($fields as $field) {
354  $list[] = $this->convertSingleField($field);
355  }
356 
357  $sql = $this->addSpaces($level).$this->separateFields($list);
358 
359  return $sql;
360 
361  }//end convertSelectFieldList()
362 
363 
374  protected function convertSingleField($field)
375  {
376  $sql = '';
377  if (is_array($field) === TRUE) {
378  if (isset($field['FUNCTION']) === TRUE) {
379  // Function call (i.e. CONCAT()).
380  $sql = $this->convertSingleFunction($field);
381  } else if (isset($field['table']) === TRUE) {
382  // Table column.
383  $sql = $this->convertField($field);
384  } else if (isset($field['MATH-OP']) === TRUE) {
385  $sql = $this->convertMathOperation($field);
386  } else if (isset($field['SELECT']) === TRUE) {
387  $sql = '('.$this->convertSelectQuery($field).')';
388  } else {
389  $sql = $this->convertSingleValue($field);
390  }
391  } else {
392  // Must be a single value.
393  $sql = $this->convertSingleValue($field);
394  }
395 
396  return $sql;
397 
398  }//end convertSingleField()
399 
400 
409  protected function getSelectFieldName(array $field)
410  {
411  $name = '';
412  if (isset($field['FUNCTION']) === TRUE) {
413  // Function call (i.e. CONCAT()).
414  if (isset($function['FUNCTION']['alias']) === TRUE) {
415  $name = $function['FUNCTION']['alias'];
416  }
417  } else if (isset($field['table']) === TRUE) {
418  // Table column.
419  if (isset($field['alias']) === TRUE) {
420  $name = $field['alias'];
421  } else {
422  $name = $field['column'];
423  }
424  } else if (isset($field['MATH-OP']) === TRUE) {
425  if (isset($mathOp['MATH-OP']['alias']) === TRUE) {
426  $name = $mathOp['MATH-OP']['alias'];
427  }
428  } else if (isset($field['SELECT']) === TRUE) {
429  $name = '';
430  } else {
431  if (isset($field['alias']) === TRUE) {
432  $name = $field['alias'];
433  } else {
434  $name = $field['value'];
435  }
436  }//end if()
437 
438  return $name;
439 
440  }//end getSelectFieldName()
441 
442 
452  protected function setSelectFieldAlias(array $field, $alias)
453  {
454  if (isset($field['FUNCTION']) === TRUE) {
455  // Function call (i.e. CONCAT()).
456  $function['FUNCTION']['alias'] = $alias;
457  } else if (isset($field['table']) === TRUE) {
458  // Table column.
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) {
463  // TODO: Aliases for SELECTs.
464  } else {
465  $field['alias'] = $alias;
466  }
467 
468  return $field;
469 
470  }//end setSelectFieldAlias()
471 
472 
481  protected function getSelectFieldNames(array $fields)
482  {
483  $names = array();
484  foreach ($fields as $field) {
485  $names[] = $this->getSelectFieldName($field);
486  }
487 
488  return $names;
489 
490  }//end getSelectFieldNames()
491 
492 
501  protected function convertField(array $field)
502  {
503  $sql = '';
504  if ($field['table'] !== '') {
505  $sql .= $field['table'];
506  if ($field['column'] !== '') {
507  $sql .= '.';
508  }
509  }
510 
511  if ($field['column'] !== '') {
512  $sql .= $field['column'];
513  if (isset($field['alias']) === TRUE) {
514  $sql .= ' as '.$field['alias'];
515  }
516  }
517 
518  return $sql;
519 
520  }//end convertField()
521 
522 
531  protected function convertSingleValue($field)
532  {
533  $sql = '';
534  if (is_array($field) === TRUE) {
535  if ((isset($field['value']) === TRUE) && (isset($field['alias']) === TRUE)) {
536  $sql .= $field['value'].' as '.$field['alias'];
537  }
538  } else {
539  if (empty($field) === FALSE) {
540  $sql = $field;
541  } else {
542  if (is_numeric($field) === FALSE) {
543  $sql = "'".$field."'";
544  } else {
545  $sql = $field;
546  }
547  }
548  }
549 
550  return $sql;
551 
552  }//end convertSingleValue()
553 
554 
563  protected function convertSingleFunction(array $function)
564  {
565  $sql = '';
566  $fnName = $function['FUNCTION']['function'];
567  $fnHandler = 'handleFunction'.$fnName;
568  $args = array();
569  foreach ($function['FUNCTION']['ARGS'] as $arg) {
570  $args[] = $this->convertSingleField($arg);
571  }
572 
573  if (method_exists($this, $fnHandler) === FALSE) {
574  $sql .= $function['FUNCTION']['function'].'(';
575  $sql .= $this->separateFields($args);
576  $sql .= ')';
577  } else {
578  $sql .= $this->$fnHandler($args);
579  }
580 
581  if (isset($function['FUNCTION']['alias']) === TRUE) {
582  $sql .= ' as '.$function['FUNCTION']['alias'];
583  }
584 
585  return $sql;
586 
587  }//end convertSingleFunction()
588 
589 
599  protected function convertFromList(array $from, $level=1)
600  {
601  $sql = "\n".$this->addSpaces($level);
602  if ((isset($from['UNION']) !== TRUE) && (isset($from['UNION-ALL']) !== TRUE)) {
603  $tables = array();
604  $subTables = '';
605  foreach ($from as $table) {
606  $newTable = '';
607  if (is_array($table) === TRUE && isset($table['FROM']) === TRUE) {
608  $subTables = $this->convertFromList($table['FROM']);
609  if ($subTables !== '') {
610  $subTables = ','.$subTables;
611  }
612  } else {
613  if (is_array($table) === TRUE) {
614  if (isset($table['name']) === TRUE) {
615  // This is could be a derived table.
616  if (is_array($table['name']) === TRUE && isset($table['name']['SELECT']) === TRUE) {
617  $newTable = '('.$this->convertSelectQuery($table['name']).')';
618  } else {
619  $newTable = $table['name'];
620  }
621 
622  // Append the alias.
623  if (isset($table['alias']) === TRUE) {
624  $newTable .= $this->convertTableAlias($table['alias']);
625  }
626  } else if (isset($table['FUNCTION']) === TRUE) {
627  $newTable = $this->convertSingleFunction($table);
628  }
629  } else {
630  $newTable = $table;
631  }
632 
633  if (strpos($newTable, 'HOOKID') === FALSE) {
634  $tables[] = $newTable;
635  }
636  }//end if
637  }//end foreach
638 
639  $sql .= $this->separateTables($tables).$subTables;
640  } else {
641  // We have unions in from clause.
642  $sql .= $this->convertUnionsInFromClause($from);
643  }//end if
644 
645  return $sql;
646 
647  }//end convertFromList()
648 
649 
658  protected function convertTableAlias($alias)
659  {
660  return ' as '.$alias;
661 
662  }//end convertTableAlias()
663 
664 
677  protected function convertMathOperation(array $mathOp)
678  {
679  // If this is the begining tag then jump to the 1st op.
680  $alias = '';
681  if (isset($mathOp['MATH-OP']) === TRUE) {
682  if (isset($mathOp['MATH-OP']['alias']) === TRUE) {
683  $alias = ' as '.$mathOp['MATH-OP']['alias'];
684  }
685 
686  $mathOp = $mathOp['MATH-OP'][0];
687  }
688 
689  $operations = array();
690  foreach ($mathOp as $currentOp => $args) {
691  if (is_array($args) === TRUE) {
692  foreach ($args as $value) {
693  $field = TRUE;
694  if (is_array($value) === TRUE) {
695  $keys = array_keys($value);
696  $op = array_shift($keys);
697  if (isset($this->mathOps[$op]) === TRUE) {
698  $field = FALSE;
699  $operations[] = $this->convertMathOperation($value);
700  }
701  }
702 
703  if ($field === TRUE) {
704  if (is_array($value) === TRUE && isset($value['SELECT']) === TRUE) {
705  $operations[] = '('.$this->convertSelectQuery($value).')';
706  } else {
707  $operations[] = $this->convertSingleField($value);
708  }
709  }
710  }
711  }//end if
712  }//end foreach
713 
714  $sql = '('.implode(' '.$this->mathOps[$currentOp].' ', $operations).')';
715  // If we have a alias then we should have something like (3+4) as ALIAS.
716  $sql .= $alias;
717 
718  return $sql;
719 
720  }//end convertMathOperation()
721 
722 
731  protected function separateFields(array $fields)
732  {
733  return implode(', ', $fields);
734 
735  }//end separateFields()
736 
737 
746  protected function separateTables(array $tables)
747  {
748  return implode(', ', $tables);
749 
750  }//end separateTables()
751 
752 
764  protected function convertWhereClause(array $where, $level=0, $addBrackets=TRUE)
765  {
766  $sql = $this->addSpaces($level);
767  if ($addBrackets === TRUE) {
768  $sql .= "(\n";
769  }
770 
771  $wc = $this->getComparisonOperators();
772  foreach ($where as $condType => $conditions) {
773  $beg = TRUE;
774  foreach ($conditions as $condition) {
775  $sql .= str_repeat(' ', (($level + 1) * 4));
776  if ($beg === FALSE) {
777  $sql .= $condType.' ';
778  } else {
779  $beg = FALSE;
780  }
781 
782  if (is_array($condition) === FALSE) {
783  // This is a hook.
784  $sql .= '(1=1)'."\n";
785  } else if (isset($condition['IN']) === TRUE) {
786  // Get IN clause.
787  $sql .= $this->convertInCondition($condition, ($level + 1));
788  } else if (isset($condition['NOT-IN']) === TRUE) {
789  // Get NOT IN clause.
790  $sql .= $this->convertInCondition($condition, ($level + 1), 'NOT-IN');
791  } else if (isset($condition['EXISTS']) === TRUE) {
792  $sql .= $this->convertExistsCondition($condition, ($level + 1));
793  } else if (isset($condition['NOT-EXISTS']) === TRUE) {
794  $sql .= $this->convertExistsCondition($condition, ($level + 1), 'NOT-EXISTS');
795  } else if (isset($condition['OR']) === TRUE || isset($condition['AND']) === TRUE) {
796  // Get OR/AND conditions.
797  $sql .= "\n".$this->convertWhereClause($condition, ($level + 1));
798  } else if ((isset($condition['type']) === TRUE) && ($condition['type'] === 'is-null')) {
799  $sql .= $this->convertIsNull($condition);
800  $sql .= "\n";
801  } else if ((isset($condition['type']) === TRUE) && ($condition['type'] === 'not-null')) {
802  $sql .= $this->convertNotNull($condition);
803  $sql .= "\n";
804  } else if ((isset($condition['type']) === TRUE) && ($condition['type'] === 'like')) {
805  $sql .= $this->convertLikeCondition($condition);
806  $sql .= "\n";
807  } else if (isset($condition['compare']) === TRUE) {
808  // Basic condition block.
809  $sql .= $this->convertSingleField($condition['compare']);
810  $sql .= ' '.$wc[$condition['type']];
811  $sql .= ' ('.$this->convertSingleField($condition['to']).')';
812  $sql .= "\n";
813  } else {
814  $msg = 'Unable to convert WHERE/HAVING condition.';
815  throw new DALConverterException($msg);
816  }//end if
817  }//end foreach
818  }//end foreach
819 
820  if ($addBrackets === TRUE) {
821  $sql .= str_repeat(' ', ($level * 4)).")\n";
822  }
823 
824  return $sql;
825 
826  }//end convertWhereClause()
827 
828 
839  protected function convertInCondition(array $in, $level=0, $type='IN')
840  {
841  $sql = '';
842  $sql .= $in[$type]['table'].'.'.$in[$type]['column'];
843  $sql .= ' '.$this->getConstructName(strtolower($type)).'(';
844 
845  // Get the elements of IN().
846  if (isset($in[$type]['CONDITIONS']['SELECT']) === TRUE) {
847  $sql .= "\n".$this->convertSelectQuery($in[$type]['CONDITIONS'], ($level + 1));
848  $sql .= str_repeat(' ', ($level * 4));
849  } else {
850  $conditions = array();
851  foreach ($in[$type]['CONDITIONS'] as $condition) {
852  $conditions[] = $this->convertSingleField($condition);
853  }
854 
855  $sql .= $this->separateFields($conditions);
856  }
857 
858  $sql .= ")\n";
859 
860  return $sql;
861 
862  }//end convertInCondition()
863 
864 
875  protected function convertExistsCondition(array $exists, $level=0, $type='EXISTS')
876  {
877  $sql = '';
878  $sql .= $this->getConstructName(strtolower($type))."(\n";
879  $sql .= $this->convertSelectQuery($exists[$type]['CONDITIONS'], ($level + 1));
880  $sql .= str_repeat(' ', ($level * 4)).")\n";
881 
882  return $sql;
883 
884  }//end convertExistsCondition()
885 
886 
896  protected function convertIsNull(array $isNull)
897  {
898  $sql = '';
899  if (isset($isNull['compare']) === TRUE) {
900  if (empty($isNull['compare']) === FALSE) {
901  $sql .= $this->convertSingleField($isNull['compare']);
902  $sql .= ' IS NULL';
903  } else {
904  $msg = 'is-null value cannot be empty.';
905  throw new DALConverterException($msg);
906  }
907  } else {
908  $msg = 'Found is-null tag with no value.';
909  throw new DALConverterException($msg);
910  }
911 
912  return $sql;
913 
914  }//end convertIsNull()
915 
916 
926  protected function convertNotNull(array $notNull)
927  {
928  $sql = '';
929  if (isset($notNull['compare']) === TRUE) {
930  if (empty($notNull['compare']) === FALSE) {
931  $sql .= $this->convertSingleField($notNull['compare']);
932  $sql .= ' IS NOT NULL';
933  } else {
934  $msg = 'not-null value cannot be empty.';
935  throw new DALConverterException($msg);
936  }
937  } else {
938  $msg = 'Found not-null tag with no value.';
939  throw new DALConverterException($msg);
940  }
941 
942  return $sql;
943 
944  }//end convertNotNull()
945 
946 
956  protected function convertUnionsInFromClause(array $union, $level=0)
957  {
958  $type = $this->getUnionType($union);
959  $sql = "(\n".$this->addSpaces($level);
960  $sql .= $this->convertUnions($union, ($level + 2));
961  $sql .= ') AS '.$union[$type]['alias'];
962  return $sql;
963 
964  }//end convertUnionsInFromClause()
965 
966 
975  protected function getUnionType(array $union)
976  {
977  $type = '';
978  if (isset($union['UNION']) === TRUE) {
979  $type = 'UNION';
980  } else if (isset($union['UNION-ALL']) === TRUE) {
981  $type = 'UNION-ALL';
982  }
983 
984  return $type;
985 
986  }//end getUnionType()
987 
988 
998  protected function convertUnions(array $union, $level=1)
999  {
1000  $sql = '';
1001  $type = $this->getUnionType($union);
1002  $displayType = $this->convertUnionDisplayName($type);
1003  if (isset($union[$type]['SELECTS']) === TRUE) {
1004  $selectSqls = array();
1005  foreach ($union[$type]['SELECTS'] as $select) {
1006  if (is_array($select) === TRUE) {
1007  $selectSqls[] = $this->convertSelectQuery($select, $level);
1008  } else {
1009  $selectSqls[] = $this->addSpaces($level).$select."\n";
1010  }
1011  }
1012 
1013  $spaces = "\n".$this->addSpaces($level);
1014  $sql .= implode($spaces.$displayType."\n\n", $selectSqls);
1015  }
1016 
1017  return $sql;
1018 
1019  }//end convertUnions()
1020 
1021 
1033  protected function convertUnionDisplayName($type)
1034  {
1035  return $type;
1036 
1037  }//end convertUnionDisplayName()
1038 
1039 
1048  protected function convertGroupBy(array $groupBy)
1049  {
1050  $sql = 'GROUP BY ';
1051  $list = array();
1052  foreach ($groupBy as $field) {
1053  if (is_array($field) === TRUE) {
1054  $list[] = $this->convertSingleField($field);
1055  } else {
1056  $list[] = $field;
1057  }
1058  }
1059 
1060  $sql .= $this->separateFields($list);
1061 
1062  return $sql;
1063 
1064  }//end convertGroupBy()
1065 
1066 
1075  protected function convertOrderBy(array $orderBy)
1076  {
1077  $sql = 'ORDER BY ';
1078  $list = array();
1079  $direction = '';
1080 
1081  foreach ($orderBy as $key => $field) {
1082  if ($key !== 'direction') {
1083  if (is_array($field) === TRUE) {
1084  $list[] = $this->convertSingleField($field);
1085  } else {
1086  $list[] = $field;
1087  }
1088  } else {
1089  $direction = ' '.$field;
1090  }
1091  }
1092 
1093  $sql .= $this->separateFields($list).' '.$direction;
1094 
1095  return $sql;
1096 
1097  }//end convertOrderBy()
1098 
1099 
1108  protected function convertLimit(array $limit)
1109  {
1110  $sql = 'LIMIT ';
1111  $sql .= $limit['rows'].' OFFSET '.$limit['offset'];
1112 
1113  return $sql;
1114 
1115  }//end convertLimit()
1116 
1117 
1126  protected function convertJoins(array $joins)
1127  {
1128  $sql = '';
1129  $list = array();
1130  foreach ($joins as $join) {
1131  $list[] = $this->convertSingleJoin($join);
1132  }
1133 
1134  $sql = implode("\nAND ", $list);
1135 
1136  return $sql;
1137 
1138  }//end convertJoins()
1139 
1140 
1149  protected function convertSingleJoin(array $join)
1150  {
1151  $sql = '';
1152  if (isset($join['ARGS']) === TRUE) {
1153  // Each join must have 2 elements.
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'];
1157  }
1158 
1159  return $sql;
1160 
1161  }//end convertSingleJoin()
1162 
1163 
1164  /*
1165  Convert Insert Query
1166  */
1167 
1168 
1177  protected function convertInsertQuery(array $sqlArray)
1178  {
1179  $sql = 'INSERT INTO '.$sqlArray['INSERT']['into'];
1180  $sql .= $this->convertInsertQueryFields($sqlArray['INSERT']['FIELDS']);
1181  $sql .= "\n";
1182  $sql .= $this->convertInsertQueryValues($sqlArray['INSERT']);
1183  return $sql;
1184 
1185  }//end convertInsertQuery()
1186 
1187 
1197  protected function addSpaces($level=0, $spaces=4)
1198  {
1199  return str_repeat(' ', ($level * 4));
1200 
1201  }//end addSpaces()
1202 
1203 
1212  protected function convertInsertQueryFields(array $fields)
1213  {
1214  $sql = '';
1215  if (empty($fields) === FALSE) {
1216  $sql = '('.$this->separateFields($fields).') ';
1217  }
1218 
1219  return $sql;
1220 
1221  }//end convertInsertQueryFields()
1222 
1223 
1236  protected function convertInsertQueryValues(array $insert)
1237  {
1238  $sql = '';
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];
1244  } else {
1245  $msg = 'Could not convert INSERT query.';
1246  $msg .= ' Field "'.$field.'" not found in values list.';
1247  throw new DALConverterException($msg);
1248  }
1249 
1250  $valuesList[] = '('.$this->convertSingleField($value).')';
1251  }
1252 
1253  $sql .= 'VALUES ('.$this->separateFields($valuesList).') ';
1254  } else {
1255  // Select statement.
1256  $sql .= '('.$this->convertSelectQuery($insert['VALUES']).')';
1257  }
1258 
1259  return $sql;
1260 
1261  }//end convertInsertQueryValues()
1262 
1263 
1264  /*
1265  Convert Update Query
1266  */
1267 
1268 
1277  protected function convertUpdateQuery(array $sqlArray)
1278  {
1279  $sql = 'UPDATE '.$sqlArray['UPDATE']['table'];
1280  $sql .= "\n".'SET';
1281  $sql .= "\n".$this->convertUpdateQuerySetValues($sqlArray['UPDATE']['VALUES']);
1282  if (isset($sqlArray['UPDATE']['WHERE']) === TRUE) {
1283  $sql .= "\n".'WHERE ';
1284  $sql .= $this->convertWhereClause($sqlArray['UPDATE']['WHERE']);
1285  }
1286 
1287  return $sql;
1288 
1289  }//end convertUpdateQuery()
1290 
1291 
1300  protected function convertUpdateQuerySetValues(array $values)
1301  {
1302  $vals = array();
1303  foreach ($values as $col => $val) {
1304  $val = $this->convertSingleField($val);
1305  $vals[] = $col.' = '.$val;
1306  }
1307 
1308  $spaces = $this->addSpaces(1);
1309  $sql = $spaces.implode(",\n".$spaces, $vals);
1310 
1311  return $sql;
1312 
1313  }//end convertUpdateQuerySetValues()
1314 
1315 
1316  /*
1317  Convert Delete Query
1318  */
1319 
1320 
1329  protected function convertDeleteQuery(array $sqlArray)
1330  {
1331  $sql = 'DELETE FROM '.$sqlArray['DELETE']['from'];
1332  $sql .= "\n".$this->getConstructName('where');
1333  $sql .= $this->convertWhereClause($sqlArray['DELETE']['WHERE']);
1334 
1335  return $sql;
1336 
1337  }//end convertDeleteQuery()
1338 
1339 
1340  /*
1341  Convert ALTER TABLE Query
1342  */
1343 
1344 
1353  protected function convertAlterQueryHeader($tableName)
1354  {
1355  $sql = 'ALTER TABLE '.$tableName."\n";
1356  return $sql;
1357 
1358  }//end convertAlterQueryHeader()
1359 
1360 
1369  protected function convertAlterQuery(array $sqlArray)
1370  {
1371  $sql = $this->convertAlterQueryHeader($sqlArray['ALTER']['table']);
1372 
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);
1378  }
1379  }
1380 
1381  return $sql;
1382 
1383  }//end convertAlterQuery()
1384 
1385 
1397  protected function convertAlterQueryAddColumn(array $addColumn)
1398  {
1399  $sql = 'ADD (';
1400 
1401  if (isset($addColumn['COLUMNS']) === TRUE) {
1402  $cols = array();
1403  foreach ($addColumn['COLUMNS'] as $column) {
1404  $cols[] = $this->convertSingleCreateColumn($column);
1405  }
1406 
1407  $sql .= implode(', ', $cols);
1408  } else {
1409  $msg = 'Cannot convert ALTER TABLE ADD COLUMN without columns.';
1410  throw new DALConverterException($msg);
1411  }
1412 
1413  $sql .= ')';
1414 
1415  return $sql;
1416 
1417  }//end convertAlterQueryAddColumn()
1418 
1419 
1431  protected function convertAlterQueryDropColumn($column)
1432  {
1433  $sql = 'DROP COLUMN ';
1434  if (($column !== '') && (is_string($column) === TRUE)) {
1435  $sql .= $column;
1436  } else {
1437  $msg = 'Cannot convert ALTER TABLE DROP COLUMN without column name.';
1438  throw new DALConverterException($msg);
1439  }
1440 
1441  return $sql;
1442 
1443  }//end convertAlterQueryDropColumn()
1444 
1445 
1458  protected function convertAlterQueryRenameColumn(array $renameColumn)
1459  {
1460  $sql = 'RENAME COLUMN ';
1461  if ((isset($renameColumn['OLD']) === TRUE) && (isset($renameColumn['NEW'])) === TRUE) {
1462  $sql .= $renameColumn['OLD'].' TO '.$renameColumn['NEW'];
1463  } else {
1464  $msg = 'Cannot convert ALTER TABLE RENAME COLUMN.';
1465  throw new DALConverterException($msg);
1466  }
1467 
1468  return $sql;
1469 
1470  }//end convertAlterQueryRenameColumn()
1471 
1472 
1484  protected function convertAlterQueryModifyColumn(array $modifyColumns)
1485  {
1486  $sql = 'MODIFY (';
1487 
1488  if (isset($modifyColumns['COLUMNS']) === TRUE) {
1489  $cols = array();
1490  foreach ($modifyColumns['COLUMNS'] as $column) {
1491  $cols[] = $this->convertSingleCreateColumn($column);
1492  }
1493 
1494  $sql .= implode(', ', $cols);
1495  } else {
1496  $msg = 'Cannot convert ALTER TABLE MODIFY COLUMN without columns.';
1497  throw new DALConverterException($msg);
1498  }
1499 
1500  $sql .= ')';
1501 
1502  return $sql;
1503 
1504  }//end convertAlterQueryModifyColumn()
1505 
1506 
1518  protected function convertAlterQueryAddConstraint(array $constraints, $tableName=NULL)
1519  {
1520  $sql = '';
1521  if (empty($constraints) === FALSE) {
1522  if ($tableName !== NULL) {
1523  $sql .= $this->convertAlterQueryHeader($tableName)."\n";
1524  }
1525 
1526  $sql .= 'ADD ';
1527  $sql .= $this->convertConstraints($constraints);
1528  }
1529 
1530  return $sql;
1531 
1532  }//end convertAlterQueryAddConstraint()
1533 
1534 
1546  protected function convertAlterQueryDropConstraint($dropConstraint)
1547  {
1548  $sql = '';
1549  if ($dropConstraint !== '') {
1550  $sql .= 'DROP '.$dropConstraint;
1551  } else {
1552  $msg = 'Cannot convert ALTER TABLE DROP CONSTRAINT without constraint name.';
1553  throw new DALConverterException($msg);
1554  }
1555 
1556  return $sql;
1557 
1558  }//end convertAlterQueryDropConstraint()
1559 
1560 
1573  protected function convertAlterQueryRenameTable(array $renameTable)
1574  {
1575  $sql = 'RENAME ';
1576  if ((isset($renameTable['OLD']) === TRUE) && (isset($renameTable['NEW'])) === TRUE) {
1577  $sql .= $renameTable['OLD'].' TO '.$renameTable['NEW'];
1578  } else {
1579  $msg = 'Cannot convert ALTER TABLE RENAME.';
1580  throw new DALConverterException($msg);
1581  }
1582 
1583  return $sql;
1584 
1585  }//end convertAlterQueryRenameTable()
1586 
1587 
1588  /*
1589  Convert Schema
1590  */
1591 
1592 
1601  public function convertCreateTable(array $table)
1602  {
1603  $sql = $this->convertCreateHeader($table);
1604  $sql .= "\n".$this->convertCreateColumns($table);
1605 
1606  $constraints = $this->convertConstraints($table['CONSTRAINTS']);
1607  if ($constraints !== '') {
1608  $sql .= ",\n".$constraints;
1609  $sql .= $this->convertCreateFooter($table);
1610  }
1611 
1612  $indexes = $this->convertCreateIndexes($table);
1613  if ($indexes !== '') {
1614  $sql .= "\n".$indexes;
1615  }
1616 
1617  if (isset($table['SEQUENCES']) === TRUE) {
1618  $sql .= "\n".$this->convertCreateSequences($table['SEQUENCES']);
1619  }
1620 
1621  return $sql;
1622 
1623  }//end convertCreateTable()
1624 
1625 
1636  protected function convertCreateHeader(array $table)
1637  {
1638  $sql = 'CREATE TABLE '.$table['table'];
1639  $sql .= ' (';
1640  return $sql;
1641 
1642  }//end convertCreateHeader()
1643 
1644 
1655  protected function convertCreateFooter(array $table)
1656  {
1657  $sql = ');';
1658  return $sql;
1659 
1660  }//end convertCreateFooter()
1661 
1662 
1671  protected function convertCreateColumns(array $table)
1672  {
1673  $sql = array();
1674  foreach ($table['COLUMNS'] as $col) {
1675  $sql[] = $this->convertSingleCreateColumn($col);
1676  }
1677 
1678  $sql = implode(",\n", $sql);
1679 
1680  return $sql;
1681 
1682  }//end convertCreateColumns()
1683 
1684 
1698  protected function convertSingleCreateColumn(array $col)
1699  {
1700  // Add column's name.
1701  $sql = $col['name'].' '.$this->getDataType($col['type']);
1702 
1703  // Add the size to the end of the type.
1704  if ($col['size'] !== '') {
1705  $sql .= '('.$col['size'];
1706  if ($col['scale'] !== '') {
1707  $sql .= ','.$col['scale'];
1708  }
1709 
1710  $sql .= ')';
1711  }
1712 
1713  // Add column's default value if it has one.
1714  if ($col['default'] !== '') {
1715  $sql .= ' DEFAULT '.$col['default'];
1716  }
1717 
1718  // Add NOT NULL if allow-null is set to false.
1719  if ($col['allow-null'] === 'false') {
1720  $sql .= ' NOT NULL';
1721  } else {
1722  $sql .= ' NULL';
1723  }
1724 
1725  return $sql;
1726 
1727  }//end convertSingleCreateColumn()
1728 
1729 
1743  protected function convertConstraints(array $constraintsList, $asArray=FALSE)
1744  {
1745  $sql = '';
1746  $constraints = array();
1747 
1748  // Primary keys.
1749  foreach ($constraintsList['PRIMARY-KEYS'] as $pk) {
1750  $constraints[] = $this->convertSinglePrimaryKey($pk);
1751  }
1752 
1753  // Foreign keys.
1754  if (isset($constraintsList['FOREIGN-KEYS']) === TRUE) {
1755  foreach ($constraintsList['FOREIGN-KEYS'] as $fk) {
1756  $constraints[] = $this->convertSingleForeignKey($fk);
1757  }
1758  }
1759 
1760  if (isset($constraintsList['UNIQUES']) === TRUE) {
1761  foreach ($constraintsList['UNIQUES'] as $un) {
1762  $constraints[] = $this->convertSingleUnique($un);
1763  }
1764  }
1765 
1766  if ($asArray === FALSE) {
1767  $sql .= implode(",\n", $constraints);
1768  return $sql;
1769  } else {
1770  return $constraints;
1771  }
1772 
1773  }//end convertConstraints()
1774 
1775 
1786  protected function convertSinglePrimaryKey(array $pk)
1787  {
1788  $sql = 'CONSTRAINT '.$pk['name'].' PRIMARY KEY (';
1789  $sql .= $this->separateFields($pk['COLUMNS']).')';
1790  return $sql;
1791 
1792  }//end convertSinglePrimaryKey()
1793 
1794 
1806  protected function convertSingleForeignKey(array $fk)
1807  {
1808  $sql = 'CONSTRAINT '.$fk['name'].' FOREIGN KEY (';
1809  $cols = array();
1810  $refs = array();
1811  foreach ($fk['COLUMNS'] as $col) {
1812  $cols[] = $col['name'];
1813  $refs[] = $col['references'];
1814  }
1815 
1816  $sql .= $this->separateFields($cols).') ';
1817  $sql .= 'REFERENCES '.$fk['table'].'(';
1818  $sql .= $this->separateFields($refs).')';
1819  if ($fk['on-delete'] !== 'NO ACTION') {
1820  $sql .= ' ON DELETE '.$fk['on-delete'];
1821  }
1822 
1823  return $sql;
1824 
1825  }//end convertSingleForeignKey()
1826 
1827 
1838  protected function convertSingleUnique(array $un)
1839  {
1840  $sql = 'CONSTRAINT '.$un['name'].' UNIQUE (';
1841  $sql .= $this->separateFields($un['COLUMNS']).')';
1842  return $sql;
1843 
1844  }//end convertSingleUnique()
1845 
1846 
1855  protected function convertCreateIndexes(array $table)
1856  {
1857  $sql = '';
1858  $indexes = array();
1859  foreach ($table['INDEXES'] as $index) {
1860  $indexes[] = $this->convertSingleIndex($index, $table['table']);
1861  }
1862 
1863  if (empty($indexes) === FALSE) {
1864  $sql .= implode(";\n", $indexes).';';
1865  }
1866 
1867  return $sql;
1868 
1869  }//end convertCreateIndexes()
1870 
1871 
1883  protected function convertSingleIndex(array $idx, $tableName)
1884  {
1885  $sql = 'CREATE INDEX '.$idx['name'].' ON '.$tableName.' (';
1886  $sql .= $this->separateFields($idx['COLUMNS']).')';
1887  return $sql;
1888 
1889  }//end convertSingleIndex()
1890 
1891 
1900  protected function convertCreateSequences(array $sequences)
1901  {
1902  $sql = '';
1903  $seqs = array();
1904  if (empty($sequences) === FALSE) {
1905  foreach ($sequences as $sequence) {
1906  $seqs[] = $this->convertSingleSequence($sequence);
1907  }
1908 
1909  if (empty($seqs) === FALSE) {
1910  $sql = implode(";\n", $seqs);
1911  }
1912  }
1913 
1914  return $sql;
1915 
1916  }//end convertCreateSequences()
1917 
1918 
1927  protected function convertSingleSequence($sequence)
1928  {
1929  $sql = 'CREATE SEQUENCE ';
1930  $sql .= $sequence;
1931 
1932  return $sql;
1933 
1934  }//end convertSingleSequence()
1935 
1936 
1947  public function convertDropTable($tableName, $cascade=FALSE)
1948  {
1949  $sql = 'DROP TABLE '.$tableName;
1950  if ($cascade === TRUE) {
1951  $sql .= ' CASCADE';
1952  }
1953 
1954  return $sql;
1955 
1956  }//end convertDropTable()
1957 
1958 
1967  public function convertTruncateTable($tableName)
1968  {
1969  $sql = 'delete from '.$tableName;
1970  return $sql;
1971 
1972  }//end convertTruncateTable()
1973 
1974 
1983  public function convertDropSequence($sequenceName)
1984  {
1985  $sql = 'DROP SEQUENCE '.$sequenceName;
1986  return $sql;
1987 
1988  }//end convertDropSequence()
1989 
1990 
1999  public function convertResetSequence($sequenceName)
2000  {
2001  // Need to sort out the min_val from the sequence.
2002  $sql = "SELECT setval('$sequenceName', 1); ";
2003  return $sql;
2004 
2005  }//end convertResetSequence()
2006 
2007 
2016  protected function convertWithQuery(array $withQuery)
2017  {
2018  $sql = 'WITH ';
2019  $sql .= $this->convertSingleFunction($withQuery);
2020  $sql .= "\nAS\n(\n";
2021  $sql .= $this->convertUnions($withQuery);
2022  $sql .= "\n)\n";
2023  $sql .= $this->convertSelectQuery($withQuery['AFTER']);
2024 
2025  return $sql;
2026 
2027  }//end convertWithQuery()
2028 
2029 
2038  protected function convertCallQuery(array $callQuery)
2039  {
2040  $sql = 'CALL ';
2041  $sql .= $this->convertSingleFunction($callQuery);
2042  return $sql;
2043 
2044  }//end convertCallQuery()
2045 
2046 
2056  public function handleFunctionTableExists($tableName, $schema=NULL)
2057  {
2058  if (is_array($tableName) === TRUE) {
2059  $tableName = $tableName[0];
2060  }
2061 
2062  if ($schema === NULL) {
2063  $schema = '\''.DAL::getDbName().'\'';
2064  }
2065 
2066  $sql = 'SELECT count(*) FROM INFORMATION_SCHEMA.tables WHERE TABLE_NAME = '.$tableName.' AND TABLE_SCHEMA = '.$schema;
2067  return $sql;
2068 
2069  }//end handleFunctionTableExists()
2070 
2071 
2080  protected function handleFunctionConcat(array $args)
2081  {
2082  $sql = 'CONCAT('.implode(', ', $args).')';
2083  return $sql;
2084 
2085  }//end handleFunctionConcat()
2086 
2087 
2096  protected function handleFunctionArray(array $args)
2097  {
2098  $sql = 'ARRAY('.$args[0].')';
2099  return $sql;
2100 
2101  }//end handleFunctionArray()
2102 
2103 
2112  protected function convertLikeCondition(array $condition)
2113  {
2114  $compare = $this->convertSingleField($condition['compare']);
2115  $to = $this->convertSingleField($condition['to']);
2116  $sql = $compare.' LIKE '.$to;
2117 
2118  return $sql;
2119 
2120  }//end convertLikeCondition()
2121 
2122 
2131  protected function handleFunctionCast(array $args)
2132  {
2133  $sql = 'CAST('.$args[0].' AS '.$this->getDataType($args[1]).')';
2134  return $sql;
2135 
2136  }//end handleFunctionCast()
2137 
2138 
2149  protected function handleFunctionBindcast(array $args)
2150  {
2151  $sql = $args[0];
2152  return $sql;
2153 
2154  }//end handleFunctionBindcast()
2155 
2156 
2165  protected function handleFunctionLength(array $args)
2166  {
2167  $sql = 'LENGTH('.$this->convertSingleField($args[0]).')';
2168  return $sql;
2169 
2170  }//end handleFunctionLength()
2171 
2172 
2181  protected function handleFunctionCoalesce(array $args)
2182  {
2183  $sql = 'COALESCE(';
2184  $fnArgs = array();
2185  foreach ($args as $arg) {
2186  $fnArgs[] = $this->convertSingleField($arg);
2187  }
2188 
2189  $sql .= implode(',', $fnArgs).')';
2190 
2191  return $sql;
2192 
2193  }//end handleFunctionCoalesce()
2194 
2195 
2204  protected function handleFunctionMax(array $args)
2205  {
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.';
2208  throw new DALConverterException($msg);
2209  }
2210  $sql = 'MAX(';
2211  $fnArg = $this->convertSingleField($args[0]);
2212 
2213  $sql .= $fnArg.')';
2214 
2215  return $sql;
2216 
2217  }//end handleFunctionMax()
2218 
2219 
2228  protected function handleFunctionMin(array $args)
2229  {
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.';
2232  throw new DALConverterException($msg);
2233  }
2234  $sql = 'MIN(';
2235  $fnArg = $this->convertSingleField($args[0]);
2236 
2237  $sql .= $fnArg.')';
2238 
2239  return $sql;
2240 
2241  }//end handleFunctionMin()
2242 
2243 
2252  protected function handleFunctionCount(array $args)
2253  {
2254  if (count($args) != 1) {
2255  $msg = 'The COUNT() aggregate function accepts exactly one parameter.';
2256  throw new DALConverterException($msg);
2257  }
2258 
2259  $sql = 'COUNT(';
2260  $fnArg = $this->convertSingleField($args[0]);
2261 
2262  $sql .= $fnArg.')';
2263 
2264  return $sql;
2265 
2266  }//end handleFunctionCount()
2267 
2268 
2279  protected function handleFunctionSubstring(array $args)
2280  {
2281  // SUBSTRING(input FROM start-position [FOR length])
2282  if (count($args) != 2 && count($args) != 3) {
2283  $msg = 'The SUBSTRING() function only accepts two or three parameters.';
2284  throw new DALConverterException($msg);
2285  }
2286 
2287  $input = $this->convertSingleField($args[0]);
2288  $start = $args[1];
2289  $length = isset($args[2]) ? " FOR $args[2]" : '';
2290  $sql = "SUBSTRING($input FROM $start $length)";
2291 
2292  return $sql;
2293 
2294  }//end handleFunctionSubstring()
2295 
2296 
2305  protected function getComparisonOperators($type=NULL)
2306  {
2307  if ($type !== NULL) {
2308  if (isset($this->_whereConditions[$type]) === TRUE) {
2309  return $this->_whereConditions[$type];
2310  } else {
2311  return '';
2312  }
2313  }
2314 
2315  return $this->_whereConditions;
2316 
2317  }//end getComparisonOperators()
2318 
2319 
2320 }//end class
2321 ?>