Pdo.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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_EMULATE_PREPARES, false);
  33. //handle->setAttribute(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
  34. Debug::add('db ' . $setting['host'] . ' connected', $setting['type']);
  35. return $handle;
  36. } catch (\PDOException $e) {
  37. if (strstr($e->getMessage(), 'Unknown database')) {
  38. $this->create($setting);
  39. $this->connect($setting);
  40. } else {
  41. Output::error($e->getMessage());
  42. }
  43. }
  44. }
  45. private function create($setting)
  46. {
  47. $method = 'mysql';
  48. if (function_exists('mysqli_connect')) {
  49. $method = 'mysqli';
  50. }
  51. $connect = $method . '_connect';
  52. $query = $method . '_query';
  53. $close = $method . '_close';
  54. $link = $connect($setting['host'] . ':' . $setting['port'], $setting['user'], $setting['pwd']);
  55. if ($link) {
  56. $sql = 'CREATE DATABASE `' . $setting['name'] . '` DEFAULT CHARACTER SET ' . $setting['charset'] . ' COLLATE ' . $setting['collation'];
  57. if ($method == 'mysql') {
  58. $query($sql, $link);
  59. } else {
  60. $query($link, $sql);
  61. }
  62. $close($link);
  63. }
  64. }
  65. public function struct($config, $state = 0)
  66. {
  67. if ($state) {
  68. $sql = Sql::alter($config['table'], $config['struct'], $this->query(Sql::desc($config['table'])));
  69. if ($sql) {
  70. $this->query($sql);
  71. }
  72. } else {
  73. $this->query(Sql::create($config));
  74. }
  75. if (isset($config['default']) && $config['default']) {
  76. $count = $this->count($config['table'], array(), $config['struct']);
  77. if (!$count) {
  78. $this->query(Sql::inserts($config['table'], $config['default']));
  79. }
  80. }
  81. }
  82. public function index($config, $state = 0)
  83. {
  84. $this->query(Sql::index($config['table'], $config['index'], $this->query(Sql::showIndex($config['table']))));
  85. }
  86. public function partition($config, $partition)
  87. {
  88. $this->query(Sql::partition($config['table'], $partition, $this->query(Sql::showIndex($config['table']))));
  89. }
  90. public function query($sql, $bind = array(), $method = 'read')
  91. {
  92. try {
  93. if ($bind) {
  94. $handle = $this->$method->prepare($sql);
  95. $handle->execute($bind);
  96. } else {
  97. $handle = $this->$method->query($sql);
  98. }
  99. } catch (\PDOException $exception) {
  100. $this->error(array('sql' => $sql, 'msg' => $exception->getMessage()));
  101. }
  102. if (Debug::$shell) {
  103. $this->sql($sql, $bind);
  104. $this->log(array('sql' => $sql, 'count' => $handle->rowCount()));
  105. }
  106. return $handle;
  107. }
  108. public function load($table, $param, $set, $field, $lock)
  109. {
  110. $bind = array();
  111. $sql = Sql::select($table, $param, $bind, $set, $field, $lock);
  112. return $this->query($sql, $bind);
  113. }
  114. public function select($table, $param, $set, $field, $lock)
  115. {
  116. return $this->load($table, $param, $set, $field, $lock)->fetchAll();
  117. }
  118. public function find($table, $param, $set, $field, $lock)
  119. {
  120. return $this->load($table, $param, $set, $field, $lock)->fetch();
  121. }
  122. public function count($table, $param, $field)
  123. {
  124. return $this->load($table, $param, array('col'=>'count(*)'), $field, false)->fetch(\PDO::FETCH_NUM)[0];
  125. }
  126. public function insert($table, $data, $field)
  127. {
  128. $bind = array();
  129. $sql = Sql::insert($table, $data, $bind, $field);
  130. $this->query($sql, $bind, 'update');
  131. return $this->update->lastInsertId();
  132. }
  133. public function update($table, $param, $data, $field)
  134. {
  135. $bind = array();
  136. $sql = Sql::update($table, $param, $data, $bind, $field);
  137. return $this->query($sql, $bind, 'update')->rowCount();
  138. }
  139. public function delete($table, $param, $field)
  140. {
  141. $bind = array();
  142. $sql = Sql::delete($table, $param, $bind, $field);
  143. return $this->query($sql, $bind, 'update')->rowCount();
  144. }
  145. public function begin()
  146. {
  147. $this->update->beginTransaction();
  148. }
  149. public function commit()
  150. {
  151. $this->update->commit();
  152. }
  153. public function rollback()
  154. {
  155. $this->update->rollback();
  156. }
  157. public function transaction($class, $param, $msg)
  158. {
  159. if (\Dever::$commit) {
  160. try {
  161. \Dever::$commit = false;
  162. $this->begin();
  163. $result = call_user_func_array($class, $param);
  164. $this->commit();
  165. return $result;
  166. } catch (\Exception $e) {
  167. $this->rollBack();
  168. Output::error($msg);
  169. }
  170. } else {
  171. return call_user_func_array($class, $param);
  172. }
  173. }
  174. }