query.class.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <?php
  2. namespace Juju\SQL;
  3. /**
  4. * Query class. Returned by \SQL::query()
  5. *
  6. * @class Query
  7. * @constructor
  8. */
  9. class Query {
  10. private $query;
  11. private $sql;
  12. private $_result = false;
  13. public function __construct($sql, $source, $types=null, ...$args){
  14. $sql->queries[] = $this;
  15. $args = array_merge([$types], $args);
  16. $this->sql = $sql();
  17. $this->query = $this->sql->stmt_init();
  18. if(!$this->query->prepare($source)){
  19. throw new \RuntimeException($this->query->error);
  20. }
  21. if(!is_null($types)){
  22. if(!$this->query->bind_param(...\Juju\SQL::make_referenced($args))){
  23. throw new \RuntimeException("Unable to bind parameter {$this->query->error}");
  24. }
  25. }
  26. }
  27. public function __destruct(){
  28. if($this->_result){
  29. $this->_result = false;
  30. $this->query->free_result();
  31. }
  32. if($this->query){
  33. $this->query->close();
  34. }
  35. $sql->queries = array_diff($sql->queries, [$this]);
  36. }
  37. public function __invoke(){
  38. return $this->query;
  39. }
  40. public function execute(){
  41. if($this->query){
  42. $this->query->free_result();
  43. $this->_result = false;
  44. $this->query->reset();
  45. $r = $this->query->execute();
  46. $this->sql->commit();
  47. return $r;
  48. }else{
  49. return false;
  50. }
  51. }
  52. public function each_assoc(callable $fn){
  53. if($this->query){
  54. $r = $this->results;
  55. while($row = $r->fetch_assoc()){
  56. $fn($row);
  57. }
  58. }else{
  59. return false;
  60. }
  61. }
  62. public function each_num(callable $fn){
  63. if($this->query){
  64. $r = $this->results;
  65. while($row = $r->fetch_num()){
  66. $fn($row);
  67. }
  68. }else{
  69. return false;
  70. }
  71. }
  72. public function __get($name){
  73. switch($name){
  74. /**
  75. * Returns the mysqli::results object for the
  76. * query
  77. *
  78. * @property results
  79. * @type {mysqli::results}
  80. * @public
  81. */
  82. case 'results':
  83. if(!$this->_result && $this->query){
  84. $this->execute();
  85. $this->_result = $this->query->get_result();
  86. $this->query->close();
  87. }
  88. return $this->_result;
  89. break;
  90. /**
  91. * Returns an associative array of the query resulsts
  92. *
  93. * @property assoc_results
  94. * @type {Array}
  95. * @public
  96. */
  97. /**
  98. * Returns an associative array of the query resulsts
  99. *
  100. * @property resulsts_assoc
  101. * @type {Array}
  102. * @public
  103. */
  104. case 'assoc_results':case 'results_assoc':
  105. if($this->query){
  106. $a = [];
  107. $r = $this->results;
  108. while($row = $r->fetch_assoc()){
  109. array_push($a,$row);
  110. }
  111. return $a;
  112. }else{
  113. return false;
  114. }
  115. break;
  116. /**
  117. * Returns a numbered array of the query results
  118. *
  119. * @property num_results
  120. * @type {Array}
  121. * @public
  122. */
  123. /**
  124. * Returns a numbered array of the query results
  125. *
  126. * @property resulsts_num
  127. * @type {Array}
  128. * @public
  129. */
  130. case 'num_results':case 'results_num':
  131. if($this->query){
  132. $a = [];
  133. $r = $this->results;
  134. while($row = $r->fetch_num()){
  135. array_push($a,$row);
  136. }
  137. return $a;
  138. }else{
  139. return false;
  140. }
  141. break;
  142. case 'assoc_result':case 'result_assoc':
  143. if($this->query){
  144. $r = $this->results;
  145. return $r?$r->fetch_assoc():false;
  146. }else{
  147. return false;
  148. }
  149. break;
  150. case 'num_result':case 'result_num':
  151. if($this->query){
  152. $r = $this->results;
  153. return $r?$r->fetch_num():false;
  154. }else{
  155. return false;
  156. }
  157. break;
  158. case 'insert_id':
  159. return $this->sql->insert_id;
  160. break;
  161. case 'affected_rows':
  162. return $this->query->affected_rows;
  163. break;
  164. }
  165. }
  166. }
  167. ?>