心理咨询网
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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <?php
  2. /**
  3. * @copyright (C)2016-2099 Hnaoyun Inc.
  4. * @author XingMeng
  5. * @email hnxsh@foxmail.com
  6. * @date 2017年8月23日
  7. * 数据库Sqlite驱动 ,写入数据时自动启用事务
  8. */
  9. namespace core\database;
  10. use core\basic\Config;
  11. class Sqlite implements Builder
  12. {
  13. protected static $sqlite;
  14. protected $master;
  15. protected $slave;
  16. private $begin = false;
  17. private function __construct()
  18. {}
  19. public function __destruct()
  20. {
  21. if ($this->begin) { // 存在待提交的事务时自动进行提交
  22. $this->master->exec('commit;');
  23. }
  24. }
  25. // 获取单一实例,使用单一实例数据库连接类
  26. public static function getInstance()
  27. {
  28. if (! self::$sqlite) {
  29. self::$sqlite = new self();
  30. }
  31. return self::$sqlite;
  32. }
  33. // 连接数据库,接受数据库连接参数,返回数据库连接对象
  34. public function conn($cfg)
  35. {
  36. if (extension_loaded('SQLite3')) {
  37. try {
  38. $conn = new \SQLite3($cfg);
  39. $conn->busyTimeout(15 * 1000); // 设置繁忙延迟时间
  40. } catch (\Exception $e) {
  41. error("读取数据库文件失败:" . iconv('gbk', 'utf-8', $e->getMessage()));
  42. }
  43. } else {
  44. if (extension_loaded('pdo_sqlite')) {
  45. error('未检测到您服务器环境的sqlite3数据库扩展,请检查php.ini中是否已经开启该扩展!<br>另外,检测到您服务器支持pdo_sqlite扩展,您也可以修改数据库配置连接驱动为pdo_sqlite试试!');
  46. } else {
  47. error('未检测到您服务器环境的sqlite3数据库扩展,请检查php.ini中是否已经开启该扩展!');
  48. }
  49. }
  50. return $conn;
  51. }
  52. // 执行SQL语句,接受完整SQL语句,返回结果集对象
  53. public function query($sql, $type = 'master')
  54. {
  55. $time_s = microtime(true);
  56. if (! $this->master || ! $this->slave) {
  57. $cfg = ROOT_PATH . Config::get('database.dbname');
  58. $conn = $this->conn($cfg);
  59. $this->master = $conn;
  60. $this->slave = $conn;
  61. }
  62. switch ($type) {
  63. case 'master':
  64. if (! $this->begin) { // 存在写入时自动开启显式事务,提高写入性能
  65. $this->master->exec('begin;');
  66. $this->begin = true;
  67. }
  68. $result = $this->master->exec($sql) or $this->error($sql, 'master');
  69. break;
  70. case 'slave':
  71. $result = $this->slave->query($sql) or $this->error($sql, 'slave');
  72. break;
  73. }
  74. return $result;
  75. }
  76. // 数据是否存在模型,接受完整SQL语句,返回boolean数据
  77. public function isExist($sql)
  78. {
  79. $result = $this->query($sql, 'slave');
  80. if ($result->fetchArray()) {
  81. $result->finalize();
  82. return true;
  83. } else {
  84. return false;
  85. }
  86. }
  87. // 获取记录总量模型,接受数据库表名,返回int数据
  88. public function rows($table)
  89. {
  90. $sql = "SELECT count(*) FROM $table";
  91. $result = $this->query($sql, 'slave');
  92. if (! ! $row = $result->fetchArray(2)) {
  93. $result->finalize();
  94. return $row[0];
  95. } else {
  96. return 0;
  97. }
  98. }
  99. // 读取字段数量模型,接受数据库表名,返回int数据
  100. public function fields($table)
  101. {
  102. $sql = "SELECT * FROM $table LIMIT 1";
  103. $result = $this->query($sql, 'slave');
  104. if ($result) {
  105. return $result->numColumns();
  106. } else {
  107. return false;
  108. }
  109. }
  110. /**
  111. * 获取表字段,接受数据库表名,返回表字段数组
  112. *
  113. * @param $table 表名
  114. */
  115. public function tableFields($table)
  116. {
  117. $sql = "pragma table_info($table)";
  118. $result = $this->query($sql, 'slave');
  119. $rows = array();
  120. while (! ! $row = $result->fetchArray(SQLITE3_ASSOC)) {
  121. $rows[] = $row['name'];
  122. }
  123. $result->finalize();
  124. return $rows;
  125. }
  126. // 查询一条数据模型,接受完整SQL语句,有数据返回对象数组,否则空数组
  127. public function one($sql, $type = null)
  128. {
  129. if (! $type) {
  130. $my_type = SQLITE3_ASSOC;
  131. } else {
  132. $my_type = $type;
  133. }
  134. $row = array();
  135. $result = $this->query($sql, 'slave');
  136. if (! ! $row = $result->fetchArray($my_type)) {
  137. if (! $type && $row) {
  138. $out = new \stdClass();
  139. foreach ($row as $key => $value) {
  140. $out->$key = $value;
  141. }
  142. $row = $out;
  143. }
  144. $result->finalize();
  145. }
  146. return $row;
  147. }
  148. // 查询多条数据模型,接受完整SQL语句,有数据返回二维对象数组,否则空数组
  149. public function all($sql, $type = null)
  150. {
  151. if (! $type) {
  152. $my_type = SQLITE3_ASSOC;
  153. } else {
  154. $my_type = $type;
  155. }
  156. $result = $this->query($sql, 'slave');
  157. $rows = array();
  158. while (! ! $row = $result->fetchArray($my_type)) {
  159. if (! $type && $row) {
  160. $out = new \stdClass();
  161. foreach ($row as $key => $value) {
  162. $out->$key = $value;
  163. }
  164. $row = $out;
  165. }
  166. $rows[] = $row;
  167. }
  168. $result->finalize();
  169. return $rows;
  170. }
  171. // 数据增、删、改模型,接受完整SQL语句,返回影响的行数的int数据
  172. public function amd($sql)
  173. {
  174. $result = $this->query($sql, 'master');
  175. if ($result) {
  176. return $result;
  177. } else {
  178. return 0;
  179. }
  180. }
  181. // 最近一次插入数据的自增字段值,返回int数据
  182. public function insertId()
  183. {
  184. return $this->master->lastInsertRowID();
  185. }
  186. // 执行多条SQL模型,成功返回true,否则false
  187. public function multi($sql)
  188. {
  189. $sqls = explode(';', $sql);
  190. foreach ($sqls as $key => $value) {
  191. $result = $this->query($value, 'master');
  192. }
  193. if ($result) {
  194. return true;
  195. } else {
  196. return false;
  197. }
  198. }
  199. // 显示执行错误
  200. protected function error($sql, $conn)
  201. {
  202. $err = '错误:' . $this->$conn->lastErrorMsg();
  203. if ($this->begin) { // 存在显式开启事务时进行回滚
  204. $this->master->exec('rollback;');
  205. $this->begin = false;
  206. }
  207. // error('执行SQL发生错误!' . $err . '语句:' . $sql);
  208. error('执行SQL发生错误!' . $err);
  209. }
  210. }