Source for file Oracle_SQLGenerator.class.php

Documentation is available at Oracle_SQLGenerator.class.php

  1. <?php
  2. /**
  3. * @package harmoni.dbc.oracle
  4. *
  5. * @copyright Copyright &copy; 2005, Middlebury College
  6. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License (GPL)
  7. *
  8. * @version $Id: Oracle_SQLGenerator.class.php,v 1.11 2007/09/05 21:39:00 adamfranco Exp $
  9. */
  10. require_once(HARMONI."DBHandler/SQLGenerator.interface.php");
  11.  
  12. /**
  13. * A OracleQueryGenerator class provides the tools to build a Oracle query from a Query object.
  14. *
  15. *
  16. * @package harmoni.dbc.oracle
  17. *
  18. * @copyright Copyright &copy; 2005, Middlebury College
  19. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License (GPL)
  20. *
  21. * @version $Id: Oracle_SQLGenerator.class.php,v 1.11 2007/09/05 21:39:00 adamfranco Exp $
  22. */
  23. class Oracle_SQLGenerator
  24. extends SQLGeneratorInterface
  25. {
  26.  
  27. /**
  28. * Returns a string representing the SQL query corresonding to the specified Query object.
  29. * @param object QueryInterface $query The object from which to generate the SQL string.
  30. * @return mixed Either a string (this would be the case, normally) or an array of strings.
  31. * Each string is corresponding to an SQL query.
  32. * @static
  33. * @access public
  34. */
  35. function generateSQLQuery( Query $query) {
  36.  
  37. switch($query->getType()) {
  38. case INSERT :
  39. return Oracle_SQLGenerator::generateInsertSQLQuery($query);
  40. break;
  41. case UPDATE :
  42. return Oracle_SQLGenerator::generateUpdateSQLQuery($query);
  43. break;
  44. case DELETE :
  45. return Oracle_SQLGenerator::generateDeleteSQLQuery($query);
  46. break;
  47. case SELECT :
  48. return Oracle_SQLGenerator::generateSelectSQLQuery($query);
  49. break;
  50. case GENERIC :
  51. return MySQL_SQLGenerator::generateGenericSQLQuery($query);
  52. break;
  53. default:
  54. throw new DatabaseException("Unsupported query type.");
  55. } // switch
  56. }
  57.  
  58.  
  59.  
  60. /**
  61. * Returns a string representing the SQL query corresonding to this Query object.
  62. * @return string A string representing the SQL query corresonding to this Query object.
  63. * @access public
  64. * @static
  65. */
  66. function generateGenericSQLQuery(GenericSQLQueryInterface $query) {
  67.  
  68. $queries = $query->_sql;
  69.  
  70. if (!is_array($queries) || count($queries) == 0) {
  71. $description = "Cannot generate SQL string for this Query object due to invalid query setup.";
  72. throw new DatabaseException($description);
  73. return null;
  74. }
  75. else if (count($queries) == 1)
  76. return $queries[0];
  77. else
  78. return $queries;
  79. }
  80.  
  81.  
  82.  
  83.  
  84. /**
  85. * Returns a string representing the SQL query corresonding to this Query object.
  86. * @return string A string representing the SQL query corresonding to this Query object.
  87. * @access public
  88. * @static
  89. */
  90. function generateInsertSQLQuery(InsertQueryInterface $query) {
  91.  
  92. if (!$query->_table || count($query->_values) == 0) {
  93. $description = "Cannot generate SQL string for this Query object due to invalid query setup.";
  94. throw new DatabaseException($description);
  95. return null;
  96. }
  97. $count = count($query->_values);
  98. $queries = array();
  99. for ($row = 0; $row < $count; $row++) {
  100. $sql = "";
  101. $sql .= "INSERT INTO ";
  102. $sql .= $query->_table;
  103. if ($query->_columns || $query->_autoIncrementColumn) {
  104. $sql .= "\n\t(";
  105. $columns = $query->_columns;
  106. // include autoincrement column if necessary
  107. if ($query->_autoIncrementColumn)
  108. $columns[] = $query->_autoIncrementColumn;
  109. $sql .= implode(", ", $columns);
  110.  
  111. $sql .= ")";
  112. }
  113. $sql .= "\n\tVALUES";
  114. $rowOfValues = $query->_values[$row];
  115. // make sure that the number of fields matches the number of columns
  116. if (count($rowOfValues) != count($query->_columns)) {
  117. $description = "Cannot generate SQL string for this Query object due to invalid query setup - the number of columns to add does not match the number of values given.";
  118. throw new DatabaseException($description);
  119. return null;
  120. }
  121. // include autoincrement column if necessary
  122. if ($query->_autoIncrementColumn)
  123. $rowOfValues[] = $query->_sequence.".NEXTVAL";
  124. $values = implode(", ", $rowOfValues);
  125. $sql .= "(";
  126. $sql .= $values;
  127. $sql .= ")\n";
  128. $queries[] = $sql;
  129. }
  130. if (count($queries) == 1)
  131. return $queries[0];
  132. else
  133. return $queries;
  134. }
  135.  
  136.  
  137. /**
  138. * Returns a string representing the SQL query corresonding to this Query object.
  139. * @return string A string representing the SQL query corresonding to this Query object.
  140. * @static
  141. * @access public
  142. */
  143. function generateUpdateSQLQuery(UpdateQueryInterface $query) {
  144.  
  145. $sql = "";
  146. if (!$query->_table || count($query->_columns) == 0 || count($query->_values) == 0) {
  147. $description = "Cannot generate SQL string for this Query object due to invalid query setup.";
  148. throw new DatabaseException($description);
  149. return null;
  150. }
  151. $sql .= "UPDATE ";
  152. $sql .= $query->_table;
  153. $sql .= "\nSET\n\t";
  154. // make sure that the number of fields matches the number of columns
  155. if (count($query->_values) != count($query->_columns)) {
  156. $description = "Cannot generate SQL string for this Query object due to invalid query setup.";
  157. throw new DatabaseException($description);
  158. return null;
  159. }
  160.  
  161. $updateExpressions = array(); // will store things like "id = 5" where
  162. // "id" was in the _columns array
  163. // and "5" was in the _values array
  164. // this loop sticks together _columns and _values
  165. foreach ($query->_columns as $key => $column)
  166. $updateExpressions[] = $column." = ".$query->_values[$key];
  167. $sql .= implode(",\n\t", $updateExpressions);
  168. // include the WHERE clause, if necessary
  169. if ($query->_condition) {
  170. $sql .= "\nWHERE";
  171.  
  172. // include join
  173. foreach($query->_condition as $key => $condition) {
  174. // we don't append anything for the first element
  175. if ($key != 0) {
  176. switch ($condition[1]) {
  177. case _AND :
  178. $sql .= "\n\t\tAND";
  179. break;
  180. case _OR :
  181. $sql .= "\n\t\tOR";
  182. break;
  183. default:
  184. throw(new Error("Unsupported logical operator!", "DBHandler", true)); ;
  185. } // switch
  186. }
  187. $sql .= "\n\t";
  188. $sql .= $condition[0];
  189. }
  190. }
  191. $sql .= "\n";
  192. return $sql;
  193. }
  194.  
  195.  
  196. /**
  197. * Returns a string representing the DELETE SQL query corresonding to the Query object.
  198. * @return string A string representing the DELETE SQL query corresonding to the Query object.
  199. * @static
  200. * @access public
  201. */
  202. function generateDeleteSQLQuery(DeleteQueryInterface $query) {
  203.  
  204. $sql = "";
  205. if (!$query->_table) {
  206. $description = "Cannot generate SQL string for this Query object due to invalid query setup.";
  207. throw new DatabaseException($description);
  208. return null;
  209. }
  210. $sql .= "DELETE\nFROM\n\t";
  211. $sql .= $query->_table;
  212. // include the WHERE clause, if necessary
  213. if ($query->_condition) {
  214. $sql .= "\nWHERE";
  215.  
  216. // include join
  217. foreach($query->_condition as $key => $condition) {
  218. // we don't append anything for the first element
  219. if ($key != 0) {
  220. switch ($condition[1]) {
  221. case _AND :
  222. $sql .= "\n\t\tAND";
  223. break;
  224. case _OR :
  225. $sql .= "\n\t\tOR";
  226. break;
  227. default:
  228. throw(new Error("Unsupported logical operator!", "DBHandler", true)); ;
  229. } // switch
  230. }
  231. $sql .= "\n\t";
  232. $sql .= $condition[0];
  233. }
  234. }
  235.  
  236. $sql .= "\n";
  237.  
  238. return $sql;
  239. }
  240.  
  241.  
  242.  
  243. /**
  244. * Returns a string representing the SELECT SQL query corresonding to the Query object.
  245. * @return string A string representing the SELECT SQL query corresonding to the Query object.
  246. * @access public
  247. */
  248. function generateSelectSQLQuery(SelectQueryInterface $query) {
  249.  
  250. $sql = "";
  251. if (count($query->_columns) == 0) {
  252. $description = "Cannot generate SQL string for this Query object due to invalid query setup.";
  253. throw new DatabaseException($description);
  254. return null;
  255. }
  256. $sql .= "SELECT";
  257. // include the DISTINCT keyword, if necessary
  258. if ($query->_distinct) {
  259. $sql .= " DISTINCT";
  260. }
  261. $sql .= "\n\t";
  262. // process any aliases
  263. $columns = array();
  264. foreach ($query->_columns AS $column) {
  265. $str = "";
  266. if ($column[2])
  267. $str .= $column[2].".";
  268. $str .= $column[0];
  269. if ($column[1]) {
  270. $str .= " AS ";
  271. $str .= $column[1];
  272. }
  273. $columns[] = $str;
  274. }
  275. // include columns to select
  276. $columnsList = implode(",\n\t", $columns);
  277. $sql .= $columnsList;
  278. // include FROM clause if necessary
  279. if ($query->_tables) {
  280. $sql .= "\nFROM";
  281.  
  282. // include join
  283. foreach($query->_tables as $key => $table) {
  284. // depending on join type we are appending:
  285. // NO_JOIN: ","
  286. // LEFT_JOIN: "LEFT JOIN"
  287. // INNER_JOIN: "INNER JOIN"
  288. // RIGHT_JOIN: "RIGHT JOIN"
  289. // however, we don't append anything for the first element
  290. if ($key != 0) {
  291. switch ($table[1]) {
  292. case NO_JOIN :
  293. $sql .= ",";
  294. break;
  295. case LEFT_JOIN :
  296. $sql .= "\n\t\tLEFT JOIN";
  297. break;
  298. case INNER_JOIN :
  299. $sql .= "\n\t\tINNER JOIN";
  300. break;
  301. case RIGHT_JOIN :
  302. $sql .= "\n\t\tRIGHT JOIN";
  303. break;
  304. default:
  305. throw new DatabaseException("Unsupported JOIN type!"); ;
  306. } // switch
  307. }
  308.  
  309. $sql .= "\n\t";
  310. // append table name
  311. $sql .= $table[0];
  312. // insert the alias if present
  313. if ($table[3])
  314. $sql .= " ".$table[3];
  315. // now append join condition
  316. if ($key != 0 && $table[1] != NO_JOIN && $table[2]) {
  317. $sql .= "\n\t\tON ";
  318. $sql .= $table[2];
  319. }
  320. }
  321. }
  322. // include the WHERE clause, if necessary
  323. if ($query->_condition) {
  324. $sql .= "\nWHERE";
  325.  
  326. // include join
  327. foreach($query->_condition as $key => $condition) {
  328. // we don't append anything for the first element
  329. if ($key != 0) {
  330. switch ($condition[1]) {
  331. case _AND :
  332. $sql .= "\n\t\tAND";
  333. break;
  334. case _OR :
  335. $sql .= "\n\t\tOR";
  336. break;
  337. default:
  338. throw new DatabaseException("Unsupported logical operator!"); ;
  339. } // switch
  340. }
  341. $sql .= "\n\t";
  342. $sql .= $condition[0];
  343. }
  344. }
  345. // include the GROUP BY and HAVING clauses, if necessary
  346. if ($query->_groupBy) {
  347. $sql .= "\nGROUP BY\n\t";
  348. $sql .= implode(",\n\t", $query->_groupBy);
  349. if ($query->_having) {
  350. $sql .= "\nHAVING\n\t";
  351. $sql .= $query->_having;
  352. }
  353. }
  354.  
  355. // include the ORDER BY clause, if necessary
  356. if ($query->_orderBy) {
  357. $sql .= "\nORDER BY\n\t";
  358. // generate an array for all the columns
  359. $columns = array();
  360. foreach($query->_orderBy as $orderBy) {
  361. $column = $orderBy[0];
  362. $column .= " ";
  363. $column .= ($orderBy[1] === ASCENDING) ? "ASC" : "DESC";
  364. $columns[] = $column;
  365. }
  366. $sql .= implode(",\n\t", $columns);
  367. }
  368. $sql .= "\n";
  369. // ORACLE does not support the LIMIT clause
  370. // need to do some complicated nested queries to implement
  371. // LIMIT functionallity (this could not be tested at the time
  372. // it was written, we had no ORACLE server available to test it on).
  373. if (!$query->_numberOfRows && !$query->_startFromRow)
  374. return $sql;
  375. if ($query->_startFromRow)
  376. $startRow = $query->_startFromRow;
  377. else
  378. $startRow = 1;
  379. if ($query->_numberOfRows)
  380. $endRow = $startRow + $query->_numberOfRows - 1;
  381. else
  382. $endRow = null;
  383. $result = "SELECT *\nFROM (\nSELECT\n\t".$columnsList.",\n\tROWNUM ROW_NUM_UNIQUE_\nFROM (\n";
  384. $result .= $sql;
  385. $result .= ")\nWHERE ";
  386. if ($endRow)
  387. $result .= "ROWNUM < ".($endRow + 1);
  388. $result .= "\n)\nWHERE ROW_NUM_UNIQUE_ >= ".$startRow;
  389. if ($endRow)
  390. $result .= " AND ROW_NUM_UNIQUE_ <= ".$endRow;
  391. $result .= "\n";
  392. return $result;
  393. }
  394.  
  395. }
  396. ?>

Documentation generated on Wed, 19 Sep 2007 10:25:21 -0400 by phpDocumentor 1.3.0RC3