PageRenderTime 50ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/Module/DbDependent.php

https://github.com/codeactual/hashmark
PHP | 197 lines | 86 code | 22 blank | 89 comment | 18 complexity | 47f91acc7434551dcd2aa47d7950ab52 MD5 | raw file
  1. <?php
  2. // vim: fenc=utf-8:ft=php:ai:si:ts=4:sw=4:et:
  3. /**
  4. * Hashmark_Module_DbDependent
  5. *
  6. * @filesource
  7. * @copyright Copyright (c) 2008-2011 David Smith
  8. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  9. * @package Hashmark
  10. * @subpackage Hashmark_Module
  11. * @version $Id$
  12. */
  13. require_once dirname(__FILE__) . '/../DbHelper.php';
  14. /**
  15. * Database-dependent module.
  16. *
  17. * Automates SQL template/helper loading and exposes DB properties.
  18. *
  19. * @package Hashmark
  20. * @subpackage Hashmark_Module
  21. */
  22. abstract class Hashmark_Module_DbDependent extends Hashmark_Module
  23. {
  24. /**
  25. * @var Zend_Db_Adapter_* Current instance.
  26. */
  27. protected $_db;
  28. /**
  29. * @var string Database selection in quoted form `<name>` w/ trailing period.
  30. */
  31. protected $_dbName;
  32. /**
  33. * @var Array SQL templates indexed by module base name, then template name
  34. * which is usually the associated function's name.
  35. */
  36. protected static $_sql;
  37. /**
  38. * @param mixed $db Connection object/resource.
  39. * @return boolean False if module could not be initialized and is unusable.
  40. * Hashmark::getModule() will also then return false.
  41. */
  42. public function initModule($db, $partition = '')
  43. {
  44. if (!$db) {
  45. return false;
  46. }
  47. $class = get_class($this);
  48. $this->_db = $db;
  49. // Load SQL templates.
  50. if ($this->_type) {
  51. $templateFile = HASHMARK_ROOT_DIR . "/Sql/{$this->_base}/{$this->_type}.php";
  52. } else {
  53. $templateFile = HASHMARK_ROOT_DIR . "/Sql/{$this->_base}.php";
  54. }
  55. if (!isset(self::$_sql[$this->_base]) && is_readable($templateFile)) {
  56. require $templateFile;
  57. self::$_sql[$this->_base] = $sql;
  58. }
  59. return true;
  60. }
  61. /**
  62. * Public access to $_sql by key.
  63. *
  64. * @param string Template name, usually a function name.
  65. * @return string Template SQL; otherwise false.
  66. */
  67. public function getSql($name)
  68. {
  69. if (isset(self::$_sql[$this->_base][$name])) {
  70. return self::$_sql[$this->_base][$name];
  71. }
  72. return false;
  73. }
  74. /**
  75. * Public access to $_db.
  76. *
  77. * @return Zend_Db_Adapter_* Current instance.
  78. */
  79. public function getDb()
  80. {
  81. return $this->_db;
  82. }
  83. /**
  84. * Public access to $_dbName.
  85. *
  86. * @param boolean $clean If true, back-quotes and period are removed.
  87. * @return mixed
  88. */
  89. public function getDbName($clean = true)
  90. {
  91. if ($clean) {
  92. return str_replace('`', '', str_replace('.', '', $this->_dbName));
  93. }
  94. return $this->_dbName;
  95. }
  96. /**
  97. * Public write access to $_dbName.
  98. *
  99. * @param string $dbName
  100. * @return void
  101. */
  102. public function setDbName($dbName)
  103. {
  104. if ($dbName) {
  105. $this->_dbName = "`{$dbName}`.";
  106. } else {
  107. $this->_dbName = '';
  108. }
  109. }
  110. /**
  111. * Escape strings without quoting them, ex. SQL function names.
  112. *
  113. * @param string $value Raw string.
  114. * @return string Escaped string.
  115. */
  116. public function escape($value)
  117. {
  118. // Use quote() for native escaping but trim quotes.
  119. return preg_replace('/(^\'|\'$)/', '', $this->_db->quote($value));
  120. }
  121. /**
  122. * Expands :name and @name macros. Escapes/quotes mapped values.
  123. *
  124. * @param string $sql Statement with 0 or more macros.
  125. * @param Array $map Assoc. array that maps macro names to their values.
  126. * Use ':' macro prefix to escape and quote the value (if string).
  127. * Use '@' macro prefix to only escape it.
  128. * Prefix is required.
  129. * Each value is escaped and quoted (if string).
  130. * @return string
  131. * @throws Exception if any parameter cannot be converted to a string;
  132. * if query does not produce a valid result object/resource;
  133. * if a macro is missing a valid prefix.
  134. */
  135. public function expandSql($sql, $map)
  136. {
  137. // Ex. prevent macro :name from being being expanded before :nameSuffix.
  138. uksort($map, array('Hashmark_Util', 'sortByStrlenReverse'));
  139. foreach ($map as $macro => $value) {
  140. if (':' == $macro[0]) {
  141. $map[$macro] = $this->_db->quote($value);
  142. } else if ('@' == $macro[0]) {
  143. $map[$macro] = $this->escape($value);
  144. } else {
  145. throw new Exception("Macro '{$macro}' does not have a valid prefix character.",
  146. HASHMARK_EXCEPTION_VALIDATION);
  147. }
  148. }
  149. return str_replace(array_keys($map), array_values($map), $sql);
  150. }
  151. /**
  152. * Return a Hashmark module instance (of the same type as this one)
  153. *
  154. * @param string $name Module name, ex. 'Core', 'Client', 'Agent'.
  155. * @param string $type Ex. 'ScalarValue', implementation in Agent/ScalarValue.php.
  156. * @return mixed New instance.
  157. */
  158. public function getModule($name, $type = '')
  159. {
  160. $args = func_get_args();
  161. // Ensure this omission gets passed to Hashmark::getModule().
  162. if (!$type) {
  163. array_splice($args, 1, 0, '');
  164. }
  165. // Use the current module's DB object/resource.
  166. if (isset($args[2])) {
  167. array_splice($args, 2, 0, array($this->_db));
  168. } else {
  169. $args[] = $this->_db;
  170. }
  171. $inst = call_user_func_array(array('Hashmark', 'getModule'), $args);
  172. $inst->setDbName($this->getDbName());
  173. return $inst;
  174. }
  175. }