Pdo.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <?php namespace Dever\Store;
  2. use Dever\Debug;
  3. use Dever\Output;
  4. use Dever\Sql;
  5. class Pdo extends Base
  6. {
  7. protected function connect($setting)
  8. {
  9. $this->type = $setting['type'];
  10. $handle = false;
  11. if (strpos($setting['host'], ':') !== false) {
  12. list($setting['host'], $setting['port']) = explode(':', $setting['host']);
  13. }
  14. if (empty($setting['pdo_type'])) {
  15. $setting['pdo_type'] = 'mysql';
  16. }
  17. if (empty($setting['charset'])) {
  18. $setting['charset'] = 'utf8mb4';
  19. }
  20. if (empty($setting['collation'])) {
  21. $setting['collation'] = 'utf8mb4_general_ci';
  22. }
  23. $dsn = $setting['pdo_type'] . ':type='.$setting['type'].';host='.$setting['host'].';port='.$setting['port'].';dbname='.$setting['name'].';collation='.$setting['collation'];
  24. try {
  25. if (empty($setting['persistent'])) {
  26. $persistent = false;
  27. }
  28. $handle = new \PDO($dsn, $setting['user'], $setting['pwd'], array(\PDO::ATTR_PERSISTENT => $persistent));
  29. $handle->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
  30. $handle->setAttribute(\PDO::ATTR_CASE, \PDO::CASE_NATURAL);
  31. $handle->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_ASSOC);
  32. $handle->setAttribute(\PDO::ATTR_STRINGIFY_FETCHES, false);
  33. $handle->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
  34. //$handle->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
  35. //handle->setAttribute(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
  36. Debug::add('db ' . $setting['host'] . ' connected', $setting['type']);
  37. return $handle;
  38. } catch (\PDOException $e) {
  39. if (strstr($e->getMessage(), 'Unknown database')) {
  40. $this->create($setting);
  41. $this->connect($setting);
  42. } else {
  43. Output::error($e->getMessage());
  44. }
  45. }
  46. }
  47. private function create($setting)
  48. {
  49. $method = 'mysql';
  50. if (function_exists('mysqli_connect')) {
  51. $method = 'mysqli';
  52. }
  53. $connect = $method . '_connect';
  54. $query = $method . '_query';
  55. $close = $method . '_close';
  56. $link = $connect($setting['host'] . ':' . $setting['port'], $setting['user'], $setting['pwd']);
  57. if ($link) {
  58. $sql = 'CREATE DATABASE `' . $setting['name'] . '` DEFAULT CHARACTER SET ' . $setting['charset'] . ' COLLATE ' . $setting['collation'];
  59. if ($method == 'mysql') {
  60. $query($sql, $link);
  61. } else {
  62. $query($link, $sql);
  63. }
  64. $close($link);
  65. }
  66. }
  67. public function struct($config, $state = 0)
  68. {
  69. if ($state) {
  70. $sql = Sql::alter($config['table'], $config['struct'], $this->query(Sql::desc($config['table'])));
  71. if ($sql) {
  72. $this->query($sql);
  73. }
  74. } else {
  75. $this->query(Sql::create($config));
  76. }
  77. if (isset($config['default']) && $config['default']) {
  78. $count = $this->count($config['table'], array(), $config['struct']);
  79. if (!$count) {
  80. $this->query(Sql::inserts($config['table'], $config['default']));
  81. }
  82. }
  83. }
  84. public function index($config, $state = 0)
  85. {
  86. $this->query(Sql::index($config['table'], $config['index'], $this->query(Sql::showIndex($config['table']))));
  87. }
  88. public function partition($config, $partition)
  89. {
  90. $this->query(Sql::partition($config['table'], $partition, $this->query(Sql::showIndex($config['table']))));
  91. }
  92. public function query($sql, $bind = array(), $method = 'read')
  93. {
  94. try {
  95. if ($bind) {
  96. $handle = $this->$method->prepare($sql);
  97. $handle->execute($bind);
  98. } else {
  99. $handle = $this->$method->query($sql);
  100. }
  101. } catch (\PDOException $exception) {
  102. $this->error(array('sql' => $sql, 'msg' => $exception->getMessage()));
  103. }
  104. if (Debug::$shell) {
  105. $this->sql($sql, $bind);
  106. $this->log(array('sql' => $sql, 'count' => $handle->rowCount()));
  107. }
  108. return $handle;
  109. }
  110. public function load($table, $param, $set, $field, $lock)
  111. {
  112. $bind = array();
  113. $sql = Sql::select($table, $param, $bind, $set, $field, $lock);
  114. return $this->query($sql, $bind);
  115. }
  116. public function select($table, $param, $set, $field, $lock)
  117. {
  118. return $this->load($table, $param, $set, $field, $lock)->fetchAll();
  119. }
  120. public function find($table, $param, $set, $field, $lock)
  121. {
  122. return $this->load($table, $param, $set, $field, $lock)->fetch();
  123. }
  124. public function count($table, $param, $field)
  125. {
  126. return $this->load($table, $param, array('col'=>'count(*)'), $field, false)->fetch(\PDO::FETCH_NUM)[0];
  127. }
  128. public function insert($table, $data, $field)
  129. {
  130. $bind = array();
  131. $sql = Sql::insert($table, $data, $bind, $field);
  132. $this->query($sql, $bind, 'update');
  133. return $this->update->lastInsertId();
  134. }
  135. public function update($table, $param, $data, $field)
  136. {
  137. $bind = array();
  138. $sql = Sql::update($table, $param, $data, $bind, $field);
  139. return $this->query($sql, $bind, 'update')->rowCount();
  140. }
  141. public function delete($table, $param, $field)
  142. {
  143. $bind = array();
  144. $sql = Sql::delete($table, $param, $bind, $field);
  145. return $this->query($sql, $bind, 'update')->rowCount();
  146. }
  147. public function begin()
  148. {
  149. $this->update->beginTransaction();
  150. }
  151. public function commit()
  152. {
  153. $this->update->commit();
  154. }
  155. public function rollback()
  156. {
  157. $this->update->rollback();
  158. }
  159. public function transaction($class, $param, $msg)
  160. {
  161. if (\Dever::$commit) {
  162. try {
  163. \Dever::$commit = false;
  164. $this->begin();
  165. $result = call_user_func_array($class, $param);
  166. $this->commit();
  167. return $result;
  168. } catch (\Exception $e) {
  169. $this->rollBack();
  170. Output::error($msg);
  171. }
  172. } else {
  173. return call_user_func_array($class, $param);
  174. }
  175. }
  176. }