DbHandle.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <?php
  2. class LtDbHandle
  3. {
  4. public $configHandle;
  5. public $group;
  6. public $node;
  7. public $role = "master";
  8. public $connectionAdapter;
  9. public $connectionResource;
  10. public $sqlAdapter;
  11. protected $connectionManager;
  12. private $servers;
  13. public function __construct()
  14. {
  15. }
  16. public function init()
  17. {
  18. if(empty($this->servers))
  19. {
  20. $this->servers = $this->configHandle->get("db.servers");
  21. }
  22. $this->connectionManager = new LtDbConnectionManager;
  23. $this->connectionManager->configHandle = $this->configHandle;
  24. $this->sqlAdapter = $this->getCurrentSqlAdapter();
  25. $connectionInfo = $this->connectionManager->getConnection($this->group, $this->node, $this->role);
  26. $this->connectionAdapter = $connectionInfo["connectionAdapter"];
  27. $this->connectionResource = $connectionInfo["connectionResource"];
  28. }
  29. /**
  30. * Trancaction methods
  31. */
  32. public function beginTransaction()
  33. {
  34. return $this->connectionAdapter->exec($this->sqlAdapter->beginTransaction(), $this->connectionResource);
  35. }
  36. public function commit()
  37. {
  38. return $this->connectionAdapter->exec($this->sqlAdapter->commit(), $this->connectionResource);
  39. }
  40. public function rollBack()
  41. {
  42. return $this->connectionAdapter->exec($this->sqlAdapter->rollBack(), $this->connectionResource);
  43. }
  44. /**
  45. * Execute an sql query
  46. *
  47. * @param $sql
  48. * @param $bind
  49. * @param $forceUseMaster
  50. * @return false on query failed
  51. * --sql type-- --return value--
  52. * SELECT, SHOW, DESECRIBE, EXPLAIN rowset or NULL when no record found
  53. * INSERT the ID generated for an AUTO_INCREMENT column
  54. * UPDATE, DELETE, REPLACE affected count
  55. * USE, DROP, ALTER, CREATE, SET etc true
  56. * @notice 每次只能执行一条SQL
  57. * 不要通过此接口执行USE DATABASE, SET NAMES这样的语句
  58. */
  59. public function query($sql, $bind = null, $forceUseMaster = false)
  60. {
  61. $sql = trim($sql);
  62. if (empty($sql))
  63. {
  64. trigger_error('Empty the SQL statement');
  65. }
  66. $queryType = $this->sqlAdapter->detectQueryType($sql);
  67. switch ($queryType)
  68. {
  69. case "SELECT":
  70. if (!$forceUseMaster && isset($this->servers[$this->group][$this->node]["slave"]))
  71. {
  72. $this->role = "slave";
  73. }
  74. $queryMethod = "select";
  75. break;
  76. case "INSERT":
  77. $this->role = "master";
  78. $queryMethod = "insert";
  79. break;
  80. case "CHANGE_ROWS":
  81. $this->role = "master";
  82. $queryMethod = "changeRows";
  83. break;
  84. case "SET_SESSION_VAR":
  85. $queryMethod = "setSessionVar";
  86. break;
  87. case "OTHER":
  88. default:
  89. $this->role = "master";
  90. $queryMethod = "other";
  91. break;
  92. }
  93. $connectionInfo = $this->connectionManager->getConnection($this->group, $this->node, $this->role);
  94. $this->connectionAdapter = $connectionInfo["connectionAdapter"];
  95. $this->connectionResource = $connectionInfo["connectionResource"];
  96. if (is_array($bind) && 0 < count($bind))
  97. {
  98. $sql = $this->bindParameter($sql, $bind);
  99. }
  100. return $this->$queryMethod($sql, $this->connectionResource);
  101. }
  102. /**
  103. * function posted by renlu
  104. */
  105. public function escape($str)
  106. {
  107. return $this->connectionAdapter->escape($str, $this->connectionResource);
  108. }
  109. /**
  110. * function posted by renlu
  111. */
  112. public function insertid()
  113. {
  114. return $this->connectionAdapter->lastInsertId($this->connectionResource);
  115. }
  116. /**
  117. * Generate complete sql from sql template (with placeholder) and parameter
  118. *
  119. * @param $sql
  120. * @param $parameter
  121. * @return string
  122. * @todo 兼容pgsql等其它数据库,pgsql的某些数据类型不接受单引号引起来的值
  123. */
  124. public function bindParameter($sql, $parameter)
  125. {
  126. // 注意替换结果尾部加一个空格
  127. $sql = preg_replace("/:([a-zA-Z0-9_\-\x7f-\xff][a-zA-Z0-9_\-\x7f-\xff]*)\s*([,\)]?)/", "\x01\x02\x03\\1\x01\x02\x03\\2 ", $sql);
  128. foreach($parameter as $key => $value)
  129. {
  130. $find[] = "\x01\x02\x03$key\x01\x02\x03";
  131. if ($value instanceof LtDbSqlExpression)
  132. {
  133. $replacement[] = $value->__toString();
  134. }
  135. else
  136. {
  137. $replacement[] = "'" . $this->connectionAdapter->escape($value, $this->connectionResource) . "'";
  138. }
  139. }
  140. $sql = str_replace($find, $replacement, $sql);
  141. return $sql;
  142. }
  143. protected function getCurrentSqlAdapter()
  144. {
  145. $factory = new LtDbAdapterFactory;
  146. $host = key($this->servers[$this->group][$this->node][$this->role]);
  147. return $factory->getSqlAdapter($this->servers[$this->group][$this->node][$this->role][$host]["sql_adapter"]);
  148. }
  149. protected function select($sql, $connResource)
  150. {
  151. $result = $this->connectionAdapter->query($sql, $connResource);
  152. if (empty($result))
  153. {
  154. return null;
  155. }
  156. else
  157. {
  158. return $result;
  159. }
  160. }
  161. protected function insert($sql, $connResource)
  162. {
  163. if ($result = $this->connectionAdapter->exec($sql, $connResource))
  164. {
  165. return $this->connectionAdapter->lastInsertId($connResource);
  166. }
  167. else
  168. {
  169. return $result;
  170. }
  171. }
  172. protected function changeRows($sql, $connResource)
  173. {
  174. return $this->connectionAdapter->exec($sql, $connResource);
  175. }
  176. /**
  177. *
  178. * @todo 更新连接缓存
  179. */
  180. protected function setSessionVar($sql, $connResource)
  181. {
  182. return false === $this->connectionAdapter->exec($sql, $connResource) ? false : true;
  183. }
  184. protected function other($sql, $connResource)
  185. {
  186. return false === $this->connectionAdapter->exec($sql, $connResource) ? false : true;
  187. }
  188. }