18 require_once SQ_LIB_PATH.
'/DAL/DALBaker.inc';
19 require_once SQ_LIB_PATH.
'/FileSystem/FileSystem.inc';
20 require_once SQ_LIB_PATH.
'/XML/XML.inc';
55 parent::__construct();
74 $filename = SQ_SYSTEM_ROOT.
'/core/db/queries.xml';
76 if (file_exists($filename)) {
77 self::processQueriesFile(
'core', $filename);
103 $packages = $GLOBALS[
'SQ_SYSTEM']->getInstalledPackages();
104 if (in_array($package, $packages)) {
105 throw new DALBakerException(
'Unable to install queries for package "'.$package.
'"; the package must be installed first.');
108 if ($package ===
'core') {
109 $filename = SQ_CORE_PACKAGE_PATH.
'/queries.xml';
111 $filename = SQ_PACKAGES_PATH.
'/'.$package.
'/queries.xml';
114 if (file_exists($filename)) {
115 self::processQueriesFile($package.
'_package', $filename);
140 if (!$GLOBALS[
'SQ_SYSTEM']->am->installed($assetType)) {
141 throw new DALBakerException(
'Unable to install queries for asset "'.$assetType.
'"; the asset must be installed first.');
144 $dir = $GLOBALS[
'SQ_SYSTEM']->am->getTypeInfo($assetType,
'dir');
145 $filename = SQ_SYSTEM_ROOT.
'/'.$dir.
'/db/queries.xml';
147 if (file_exists($filename)) {
148 self::processQueriesFile($assetType, $filename);
172 if (trim($systemName) ===
'') {
177 $ovenDir = SQ_LIB_PATH.
'/DAL/Oven/'.$systemName;
179 if (file_exists($ovenDir) === FALSE) {
183 $fileName = $ovenDir.
'/'.$systemName.
'Queries.inc';
185 $contents =
'<?'.
"php\n\n";
186 $contents .=
"require_once SQ_LIB_PATH.'/MatrixDAL/MatrixDAL.inc';\n";
187 $contents .=
"class $systemName".
"Queries\n{\n\n";
190 $types = array(
'.xml');
192 foreach ($xmlFiles as $queryName) {
193 $queryName = basename($queryName,
'.xml');
194 if (substr($queryName, -3) !==
'.rb') {
195 $contents .= self::bakeQueryMethod($systemName, $queryName);
199 $contents .=
"\n\n}\n?>";
201 file_put_contents($fileName, $contents);
224 $methodName =
'prepare'.ucwords($queryName).
'Query';
225 $contents =
"public static function $methodName(array \$data, \$bind)\n{\n";
227 $contents .= self::_printPlaceHolderVariables($systemName, $queryName);
229 $contents .=
"try {\n";
232 $assertions = self::_getQueryAssertions($systemName, $queryName);
235 $contents .= self::_printAssertionCalls($assertions);
236 $contents .=
"} catch (ChannelException \$e) {\n";
237 $contents .=
" // Exception thrown in the called channel.\n";
242 if (self::_queryRequiresRollback($systemName, $queryName)) {
243 $contents .=
'if (SQ_ROLLBACK_VIEW) {'.
"\n";
244 $queryBody = self::mergeQuery($systemName, $queryName.
'.rb');
245 $allBindVars = self::findRollbackBindVars($queryBody);
246 $contents .= $queryBody;
247 if (!empty($allBindVars)) {
248 foreach ($allBindVars as $bindVar) {
249 $contents .=
'$query->bind(\''.$bindVar.
'\', $_SESSION[\
'sq_rollback_view\'][\'rollback_time\']);'.
"\n";
252 $contents .=
'$query->bind(\':rbtime\', $_SESSION[\'sq_rollback_view\'][\'rollback_time\']);'.
"\n";
254 $contents .=
'} else {'.
"\n";
255 $queryBody = self::mergeQuery($systemName, $queryName);
256 $contents .= $queryBody;
259 $queryBody = self::mergeQuery($systemName, $queryName);
260 $contents .= $queryBody;
262 $subQueries = self::printSubQueries($systemName, $queryName);
263 $contents .= $subQueries;
264 $contents .= self::_printKeywords($systemName, $queryName);
265 $contents .= self::_printBindings($systemName, $queryName);
266 $contents .=
"\n}//end $methodName()\n";
282 $sqlQuery = preg_match_all(
"/\('(.*)'\)/", $queryBody, $matches);
284 $allBindVars = Array();
285 if (isset($matches[1]) && !empty($matches[1])) {
286 foreach ($matches[1] as $match) {
288 $rollbackBinds = preg_match_all(
'/(:rbtime[0-9]*)\b/i', $query->getSql(), $foundBindVars);
289 if (isset($foundBindVars[1]) && !empty($foundBindVars[1])) {
290 $allBindVars = array_merge($allBindVars, $foundBindVars[1]);
321 protected static function _printBindings($systemName, $queryName, $printBindings=TRUE)
323 $doc = self::getQueryXML($systemName, $queryName);
326 $bindingList = $doc->getElementsByTagName(
'binding');
329 $placeHolders = array();
330 $placeHoldersList = $doc->getElementsByTagName(
'placeholder');
331 foreach ($placeHoldersList as $element) {
332 $varName = $element->getAttribute(
'var_name');
333 $varValue = $element->getAttribute(
'value');
334 $placeHolders[$varName] = $varValue;
337 $usedNames = array();
340 foreach ($bindingList as $binding) {
341 $requiresLob = FALSE;
342 $bindName = $binding->getAttribute(
'name');
344 $columnType = $binding->getAttribute(
'column_type');
345 if ($columnType !==
'') {
348 $column = $binding->getAttribute(
'column');
349 $table = $binding->getAttribute(
'table');
350 $system = $binding->getAttribute(
'system');
353 if (empty($table) === TRUE) {
357 if (array_key_exists($bindName, $placeHolders) === FALSE) {
360 }
else if (self::_fieldRequiresOciClob($table, $column) === TRUE) {
367 $index = substr($bindName, 1);
371 if (isset($placeHolders[$bindName]) === TRUE) {
373 $varName =
'$'.substr($bindName, 1);
377 $varName =
"\$data['$index']";
380 if ($printBindings === TRUE) {
383 if (isset($placeHolders[$bindName]) === FALSE) {
384 $bindCall =
"\nif (array_key_exists('$index',\$data) === TRUE) {\n";
388 if ($requiresLob === TRUE) {
390 $bindCall .=
"\$lob{$lobCount} = oci_new_descriptor(MatrixDAL::getDb(), OCI_D_LOB);\n";
391 $bindCall .=
"\$query->bind('$bindName', \$lob{$lobCount}, PDO::PARAM_LOB);\n";
392 $bindCall .=
"\$lob{$lobCount}->writeTemporary($varName, OCI_TEMP_CLOB);\n";
393 }
else if ($requiresLob === NULL) {
397 $bindCall .=
"if (is_object($varName) && get_class($varName) === 'OCI-Lob') {\n";
398 $bindCall .=
"\$query->bind('$bindName', $varName, PDO::PARAM_LOB);\n";
399 $bindCall .=
"} else {\n";
400 $bindCall .=
"\$query->bind('$bindName', $varName);\n";
403 $bindCall .=
"\$query->bind('$bindName', $varName);\n";
407 $bindCall .=
"\$query->bind('$bindName', $varName);\n";
410 if (isset($placeHolders[$bindName]) === FALSE) {
411 $bindCall .=
"}\n\n";
415 $contents .= $bindCall;
420 $contents .=
"return \$query;\n";
455 $filePath = realpath(SQ_SYSTEM_ROOT).
'/core/lib/DAL/Oven/'.$systemName.
'/'.$queryName.
'.xml';
456 $doc =
new DOMDocument();
457 $doc->load($filePath);
458 $xpath =
new DOMXPath($doc);
459 $nodes = $xpath->query(
'//query/primary/select/from/table');
460 foreach ($nodes as $node) {
461 $table = $node->nodeValue;
462 if (self::_tableRequiresRollback($table)) {
488 if (substr($table, 0, 3) ==
'sq_') {
489 $table = substr($table, 3);
496 $ovenDir = SQ_LIB_PATH.
'/DAL/Oven/core/coreQueries.xml';
499 $packages = $GLOBALS[
'SQ_SYSTEM']->getInstalledPackages();
500 }
catch (Exception $e) {
510 if (empty($packages)) {
512 'code_name' =>
'__core__',
518 foreach ($packages as $_key => $package_details) {
519 $package_name = $package_details[
'code_name'];
521 if ($package_name ===
'__core__') {
522 $dir = SQ_CORE_PACKAGE_PATH;
524 $dir = SQ_PACKAGES_PATH.
'/'.$package_name;
526 $filename = $dir.
'/tables.xml';
528 if (file_exists($filename) === TRUE) {
529 $doc =
new DOMDocument(
'1.0',
'iso-8859-1');
530 $doc->load($filename);
532 $xpath =
new DOMXPath($doc);
533 $count = $xpath->evaluate(
'count(/schema/tables/table[@name="'.$table.
'" and @require_rollback="1"])');
534 if ($count > 0)
return TRUE;
564 if ((empty($table) === TRUE) || (empty($field) === TRUE)) {
571 if (substr($table, 0, 3) ==
'sq_') {
572 $table = substr($table, 3);
576 if (substr($table, 0, 3) ==
'vw_') {
582 if (substr($table, 0, 3) ==
'rb_') {
583 $table = substr($table, 3);
590 $ovenDir = SQ_LIB_PATH.
'/DAL/Oven/core/coreQueries.xml';
593 $packages = $GLOBALS[
'SQ_SYSTEM']->getInstalledPackages();
594 }
catch (Exception $e) {
600 if (empty($packages)) {
601 $packages[] = Array(
'code_name' =>
'__core__');
606 foreach ($packages as $package_name) {
607 $package_name = $package_name[
'code_name'];
608 if ($package_name ===
'__core__') {
609 $dir = SQ_CORE_PACKAGE_PATH;
611 $dir = SQ_PACKAGES_PATH.
'/'.$package_name;
613 $filename = $dir.
'/tables.xml';
615 if (file_exists($filename) === TRUE) {
616 $doc =
new DOMDocument(
'1.0',
'iso-8859-1');
617 $doc->load($filename);
627 $xpath =
new DOMXPath($doc);
628 $count = $xpath->evaluate(
'count(/schema/tables/table[@name="'.$table.
'"]/columns/column[@name="'.$field.
'"])');
632 $nodes = $xpath->query(
'/schema/tables/table[@name="'.$table.
'"]/columns/column[@name="'.$field.
'"]/type_variations/oci');
633 foreach ($nodes as $node) {
634 if (strtoupper($node->nodeValue) ==
'CLOB') {
664 if (file_exists($fileName) === FALSE) {
668 $doc =
new DomDocument();
669 $doc->load($fileName);
670 $queryNode = $doc->getElementsByTagName(
'queries')->item(0);
674 foreach ($queryNode->childNodes as $child) {
675 if ($child->nodeType !== 1) {
681 if ($child->tagName ===
'query') {
682 if ($child->hasAttribute(
'id') === FALSE) {
683 $error =
'ID not specified for query in '.$systemName;
687 if ($child->hasAttribute(
'databases') === TRUE) {
688 $dbString = $child->getAttribute(
'databases');
689 $dbString = str_replace(
' ',
'', $dbString);
690 $dbs = explode(
',', $dbString);
691 if (in_array($currentDbType, $dbs) === FALSE) {
692 $id = $child->getAttribute(
'id');
693 echo
'Skipped Query: '.$id.
" (not for this DB type)\n";
698 if ($child->hasAttribute(
'hookid') === TRUE) {
699 $hookId = $child->getAttribute(
'hookid');
700 if (substr_count($hookId,
'.') === 1) {
702 self::addQueryFragment($systemName, $child);
705 self::addSubQuery($systemName, $child);
709 $id = $child->getAttribute(
'id');
710 self::addQuery($systemName, $child);
711 if (self::_queryRequiresRollback($systemName, $id)) {
712 $rollback_child = self::_createRollbackXML($systemName, $child);
713 $rollback_child->setAttribute(
'id', $id.
'.rb');
714 self::addQuery($systemName, $rollback_child);
735 $doc =
new DOMDocument();
736 $queryNode = $doc->importNode($queryNode, TRUE);
737 $doc->appendChild($queryNode);
738 $xpath =
new DOMXPath($doc);
740 $whereNodes = $xpath->query(
'//query//select/where');
741 if (count($whereNodes) == 0)
745 $whereNode = $whereNodes->item(0);
748 $nodes = $xpath->query(
'//query//select/from/table');
749 foreach ($nodes as $node) {
750 $table = $node->nodeValue;
752 if (self::_tableRequiresRollback($table)) {
756 $fieldNodes = $xpath->query(
'//query//select/fields/field');
757 foreach ($fieldNodes as $fieldNode) {
758 $table = $fieldNode->getAttribute(
'table');
759 if (self::_tableRequiresRollback($table)) {
760 $rbTableName = substr_replace($table,
'sq_rb_', 0, 3);
761 $fieldNode->setAttribute(
'table', $rbTableName);
766 $condNodes = $xpath->query(
'//query//select/where//*');
767 foreach ($condNodes as $condNode) {
768 $table = $condNode->getAttribute(
'table');
769 if (self::_tableRequiresRollback($table)) {
770 $rbTableName = substr_replace($table,
'sq_rb_', 0, 3);
771 $condNode->setAttribute(
'table', $rbTableName);
776 $orderByNodes = $xpath->query(
'//query//select/order-by//*');
777 foreach ($orderByNodes as $orderByNode) {
778 $table = $orderByNode->getAttribute(
'table');
779 if (self::_tableRequiresRollback($table)) {
780 $rbTableName = substr_replace($table,
'sq_rb_', 0, 3);
781 $orderByNode->setAttribute(
'table', $rbTableName);
786 $groupByNodes = $xpath->query(
'//query//select/group-by//*');
787 foreach ($groupByNodes as $groupByNode) {
788 $table = $groupByNode->getAttribute(
'table');
789 if (self::_tableRequiresRollback($table)) {
790 $rbTableName = substr_replace($table,
'sq_rb_', 0, 3);
791 $groupByNode->setAttribute(
'table', $rbTableName);
798 $fromNodes = $xpath->query(
'//query//select/from/table');
800 foreach ($fromNodes as $fromNode) {
801 $table = trim($fromNode->nodeValue);
802 $rollbackTable = substr_replace($table,
'sq_rb_', 0, 3);
804 if (self::_tableRequiresRollback($table)) {
805 $fromNode->nodeValue = substr_replace($table,
'sq_rb_', 0, 3);
808 $selectNode = $fromNode->parentNode->parentNode;
810 foreach ($selectNode->childNodes as $childNode) {
811 if ($childNode->nodeName ==
'where') {
812 $whereNode = $childNode;
818 if (is_null($whereNode)) {
819 $whereNode = $doc->createElement(
'where');
820 $selectNode->appendChild($whereNode);
823 $lessNode = $doc->createElement(
'equal-or-less',
':rbtime'.$count);
825 $lessNode->setAttribute(
'table', $rollbackTable);
826 $lessNode->setAttribute(
'column',
'sq_eff_from');
827 $whereNode->appendChild($lessNode);
829 $orNode = $doc->createElement(
'or');
830 $whereNode->appendChild($orNode);
832 $greaterNode = $doc->createElement(
'equal-or-greater',
':rbtime'.$count);
834 $greaterNode->setAttribute(
'table', $rollbackTable);
835 $greaterNode->setAttribute(
'column',
'sq_eff_to');
836 $orNode->appendChild($greaterNode);
838 $nullNode = $doc->createElement(
'is-null');
839 $nullFieldNode = $doc->createElement(
'field');
840 $nullFieldNode->setAttribute(
'table', $rollbackTable);
841 $nullFieldNode->setAttribute(
'column',
'sq_eff_to');
842 $nullNode->appendChild($nullFieldNode);
843 $orNode->appendChild($nullNode);