SqlQuery.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. <?php
  2. namespace KarmaFW\Database\Sql;
  3. class SqlQuery
  4. {
  5. protected $db;
  6. protected $duration = null;
  7. protected $error = null;
  8. protected $recordset = null;
  9. protected $status = 'ready';
  10. protected $query = null;
  11. protected $results_rows_count = null;
  12. protected $affected_rows_count = null;
  13. public function __construct($db, $query=null)
  14. {
  15. $this->db = $db;
  16. $this->query = $query;
  17. }
  18. public function __toString()
  19. {
  20. return $this->getQuery();
  21. }
  22. public function __debugInfo() {
  23. return [
  24. //'db:protected' => get_class($this->db) ." Object",
  25. 'db:protected' => $this->db,
  26. 'status:protected' => $this->status,
  27. 'error:protected' => $this->error,
  28. 'query:protected' => $this->query,
  29. 'duration:protected' => $this->duration,
  30. //'recordset:protected' => get_class($this->recordset) ." Object",
  31. 'recordset:protected' => $this->recordset,
  32. 'results_rows_count:protected' => $this->results_rows_count,
  33. 'affected_rows_count:protected' => $this->affected_rows_count,
  34. ];
  35. }
  36. public function fetchColumn($column_name)
  37. {
  38. if ($this->status == 'ready') {
  39. $this->execute();
  40. }
  41. return $this->recordset->fetchColumn($column_name);
  42. }
  43. public function fetchOne()
  44. {
  45. if ($this->status == 'ready') {
  46. $this->execute();
  47. }
  48. return $this->recordset->fetchOne();
  49. }
  50. public function fetchAll()
  51. {
  52. if ($this->status == 'ready') {
  53. $this->execute();
  54. }
  55. return $this->recordset->fetchAll();
  56. }
  57. public function getQuery()
  58. {
  59. return $this->query;
  60. }
  61. public function getStatus()
  62. {
  63. return $this->status;
  64. }
  65. public function execute($query=null, $params=[])
  66. {
  67. if (empty($query)) {
  68. $query = $this->query;
  69. }
  70. if (! empty($params)) {
  71. $parts = explode('?', $query);
  72. $query = array_shift($parts);
  73. $i = 1;
  74. foreach ($params as $param) {
  75. if (empty($parts)) {
  76. throw new \Exception('SqlQuery::execute() => params error (1) [QUERY: ' . preg_replace('/\s+/', ' ', $query) . ' ]');
  77. }
  78. $param = $this->db->escape($param);
  79. $query .= $param;
  80. $query .= array_shift($parts);
  81. $i++;
  82. }
  83. if (! empty($parts)) {
  84. throw new \Exception('SqlQuery::execute() => params error (2) [QUERY: ' . preg_replace('/\s+/', ' ', $query) . ' ]');
  85. }
  86. }
  87. $this->query = preg_replace('/\s+/', ' ', $query);
  88. $this->status = 'running';
  89. $ts_start = microtime(true);
  90. //echo $query . "<hr />";
  91. $rs = $this->db->getDriver()->execute($query);
  92. //pre($rs);
  93. $ts_end = microtime(true);
  94. $this->duration = $ts_end - $ts_start;
  95. $this->recordset = $rs;
  96. $this->db->setLastQuery($this);
  97. $error_code = $this->db->getDriver()->getConn()->errno;
  98. if ($error_code !== 0) {
  99. // query error
  100. $error_msg = $this->db->getDriver()->getConn()->error;
  101. $this->error = $error_msg;
  102. $this->status = 'error';
  103. if ($this->db->throwOnSqlError) {
  104. throw new \Exception('SqlQuery::execute() => DB error [' . $error_code . '] : ' . $error_msg . PHP_EOL . '[QUERY: ' . preg_replace('/\s+/', ' ', $query) . ' ]');
  105. }
  106. //return null;
  107. } else {
  108. $this->status = 'success';
  109. }
  110. $this->results_rows_count = $rs->getRowsCount();
  111. $this->affected_rows_count = $this->db->getDriver()->getAffectedRowsCount();
  112. if (strpos($query, "SQL_CALC_FOUND_ROWS")) {
  113. $found_rows = $this->execute('SELECT FOUND_ROWS() AS found_rows')->oneField('found_rows');
  114. } else {
  115. $found_rows = null;
  116. }
  117. return $this;
  118. }
  119. public function executeSelect($query, $params=[])
  120. {
  121. // Alias of executeSelectAll
  122. return $this->executeSelectAll($query, $params);
  123. }
  124. public function executeSelectOne($query, $params=[])
  125. {
  126. return $this->execute($query, $params)->fetchOne();
  127. }
  128. public function executeSelectAll($query, $params=[])
  129. {
  130. return $this->execute($query, $params)->fetchAll();
  131. }
  132. public function executeInsert($query, $params=[])
  133. {
  134. $this->execute($query, $params);
  135. return $this->insert_id();
  136. }
  137. public function executeInsertAll($query, $params=[])
  138. {
  139. return $this->execute($query, $params);
  140. }
  141. public function executeUpdate($query, $params=[])
  142. {
  143. $this->execute($query, $params);
  144. return $this->affected_rows_count;
  145. }
  146. public function executeDelete($query, $params=[])
  147. {
  148. $this->execute($query, $params);
  149. return $this->affected_rows_count;
  150. }
  151. /* ### */
  152. public function tableSelect($table_name, $where=[], $options=[])
  153. {
  154. // Alias of tableSelectAll
  155. return $this->tableSelectAll($table_name, $where, $options)->all();
  156. }
  157. public function tableSelectAll($table_name, $where=[], $options=[])
  158. {
  159. $table = new SqlTable($this->db, $table_name);
  160. $query = $table->buildQuery($where, $options);
  161. return $this->executeSelectAll($query);
  162. }
  163. public function tableSelectOne($table_name, $where=[], $options=[])
  164. {
  165. if (empty($options)) {
  166. $options = [];
  167. }
  168. $options['limit'] = 1;
  169. return $this->tableSelect($table_name, $where, $options)->one();
  170. }
  171. public function tableInsert($table_name, $values=[], $options=[])
  172. {
  173. $this->tableInsertAll($table_name, [$values], $options);
  174. return $this->db->getInsertId();
  175. }
  176. public function tableInsertAll($table_name, $inserts=[], $options=[])
  177. {
  178. $table = new SqlTable($this->db, $table_name);
  179. return $table->insertAll($inserts, $options);
  180. }
  181. public function tableUpdate($table_name, $updates=[], $where=[], $options=[])
  182. {
  183. $table = new SqlTable($this->db, $table_name);
  184. return $table->update($updates, $where, $options);
  185. }
  186. public function tableDelete($table_name, $where=[], $options=[])
  187. {
  188. $table = new SqlTable($this->db, $table_name);
  189. return $table->delete($where, $options);
  190. }
  191. }