You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
4.4 KiB

  1. <?php
  2. /**
  3. * @copyright NetMonsters <team@netmonsters.ru>
  4. * @link http://netmonsters.ru
  5. * @package Majestic
  6. * @subpackage db
  7. * @since 2011-11-11
  8. */
  9. abstract class SqlDbDriver extends DbDriver
  10. {
  11. protected $identifier_quote = '`';
  12. public function beginTransaction()
  13. {
  14. $this->connect();
  15. $this->driverBeginTransaction();
  16. return $this;
  17. }
  18. public function commit()
  19. {
  20. $this->connect();
  21. $this->driverCommitTransaction();
  22. return $this;
  23. }
  24. public function rollback()
  25. {
  26. $this->connect();
  27. $this->driverRollbackTransaction();
  28. return $this;
  29. }
  30. /**
  31. * @param string $sql
  32. * @param mixed $params
  33. * @return DbStatement
  34. */
  35. public function query($sql, $params = array())
  36. {
  37. $this->connect();
  38. if (!is_array($params)) {
  39. $params = array($params);
  40. }
  41. $stmt = $this->prepare($sql);
  42. $stmt->execute($params);
  43. return $stmt;
  44. }
  45. /**
  46. * @param string $table
  47. * @param mixed $bind
  48. * @param mixed $on_duplicate
  49. * @return int Affected rows count
  50. */
  51. public function insert($table, $data)
  52. {
  53. $columns = array();
  54. foreach ($data as $col => $val) {
  55. $columns[] = $this->quoteIdentifier($col);
  56. }
  57. $values = array_values($data);
  58. $sql = 'INSERT INTO ' . $this->quoteIdentifier($table)
  59. . ' (' . implode(', ', $columns) . ') VALUES (' . $this->quote($values) . ')';
  60. return $this->query($sql)->affectedRows();
  61. }
  62. /**
  63. * @param string $table
  64. * @param array $bind
  65. * @param mixed $where
  66. * @return int
  67. */
  68. public function update($table, $data, $condition = '')
  69. {
  70. $set = array();
  71. foreach ($data as $col => $val) {
  72. $set[] = $this->quoteIdentifier($col) . '=' . $this->quote($val);
  73. }
  74. $where = $this->whereExpr($condition);
  75. $sql = 'UPDATE ' . $this->quoteIdentifier($table) . ' SET ' . implode(', ', $set)
  76. . (($where) ? (' WHERE ' . $where) : '');
  77. return $this->query($sql)->affectedRows();
  78. }
  79. /**
  80. * @param string $table
  81. * @param mixed $where
  82. * @return int
  83. */
  84. public function delete($table, $condition = '')
  85. {
  86. $where = $this->whereExpr($condition);
  87. $sql = 'DELETE FROM ' . $this->quoteIdentifier($table) . (($where) ? (' WHERE ' . $where) : '');
  88. return $this->query($sql)->affectedRows();
  89. }
  90. /**
  91. * @param mixed $value
  92. * @return string
  93. */
  94. public function quote($value)
  95. {
  96. if ($value instanceof DbExpr) {
  97. return (string) $value;
  98. }
  99. if (is_array($value)) {
  100. foreach ($value as &$val) {
  101. $val = $this->quote($val);
  102. }
  103. return implode(', ', $value);
  104. }
  105. return $this->driverQuote($value);
  106. }
  107. /**
  108. * @param string $ident
  109. * @return string
  110. */
  111. public function quoteIdentifier($ident)
  112. {
  113. $ident = explode('.', $ident);
  114. if (!is_array($ident)) {
  115. $ident = array($ident);
  116. }
  117. foreach ($ident as &$segment) {
  118. $segment = $this->identifier_quote . $segment . $this->identifier_quote;
  119. }
  120. return implode('.', $ident);
  121. }
  122. public function quoteInto($text, $value)
  123. {
  124. $pos = mb_strpos($text, '?');
  125. if ($pos === false) {
  126. return $text;
  127. }
  128. return mb_substr($text, 0, $pos) . $this->quote($value) . mb_substr($text, $pos + 1);
  129. }
  130. /**
  131. * @param mixed $where
  132. * @return string
  133. */
  134. protected function whereExpr($where)
  135. {
  136. if (empty($where)) {
  137. return $where;
  138. }
  139. if (!is_array($where)) {
  140. $where = array($where);
  141. }
  142. foreach ($where as $cond => &$term) {
  143. if (is_int($cond)) {
  144. if ($term instanceof DbExpr) {
  145. $term = (string) $term;
  146. }
  147. } else {
  148. $term = $this->quoteInto($cond, $term);
  149. }
  150. }
  151. return implode(' AND ', $where);
  152. }
  153. /**
  154. * @return DbStatement
  155. */
  156. abstract public function prepare($sql);
  157. abstract protected function driverQuote($value);
  158. abstract protected function driverBeginTransaction();
  159. abstract protected function driverCommitTransaction();
  160. abstract protected function driverRollbackTransaction();
  161. }