1
0

sql.class.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <?php
  2. namespace Juju {
  3. require_once('SQL/query.class.php');
  4. require_once('Data/securestring.class.php');
  5. use \Juju\SQL\Query;
  6. use \Juju\Data\SecureString;
  7. /**
  8. * SQL class. Used for handling SQL connections
  9. *
  10. * @module sql
  11. * @class SQL
  12. * @constructor
  13. */
  14. class SQL {
  15. /**
  16. * This is the mysqli connection beneath everything
  17. *
  18. * @property sql
  19. * @type {mysqli}
  20. * @private
  21. * @required
  22. */
  23. private $guid;
  24. private $sql;
  25. public $queries = [];
  26. private static $connections = [];
  27. public static function FromDSN(string $dsnstring){
  28. $dsnstring = explode(':', $dsnstring)[1];
  29. $dsn = explode(';', $dsnstring);
  30. $dsn = array_reduce($dsn, function($dsn, $item){
  31. $item = explode('=', $item);
  32. $dsn[$item[0]] = $item[1];
  33. return $dsn;
  34. });
  35. if(!isset($dsn['host'])){
  36. throw new \Exception("DSN {$dsnstring} missing host");
  37. }
  38. if(!isset($dsn['dbname'])){
  39. throw new \Exception("DSN {$dsnstring} missing dbname");
  40. }
  41. if(!isset($dsn['user'])){
  42. $dsn['user'] = $dsn['dbname'];
  43. }
  44. if(!isset($dsn['pass'])){
  45. $dsn['pass'] = $dsn['user'];
  46. }
  47. $dsn['pass'] = SecureString::from($dsn['pass']);
  48. return new SQL($dsn['host'], $dsn['user'], $dsn['pass'], $dsn['dbname']);
  49. }
  50. public function __construct($server,$user,$pass,$db){
  51. $this->guid = uniqid();
  52. $this->sql = new \mysqli('p:'.$server,$user,"{$pass}",$db);;
  53. if($this->sql->connect_error){
  54. throw new \Exception('Mysqli Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
  55. }
  56. self::$connections[] = $sql;
  57. }
  58. public function __destruct(){
  59. $this->sql->rollback();
  60. $this->sql->close();
  61. foreach($this->queries as $query){
  62. unset($query);
  63. }
  64. self::$connections = array_diff(self::$connections, [$this]);
  65. }
  66. public function __invoke(){
  67. return $this->sql;
  68. }
  69. public function __get($name){
  70. switch($name){
  71. case 'error':
  72. return $this->sql->error;
  73. break;
  74. case 'insert_id':
  75. return $this->sql->insert_id;
  76. break;
  77. }
  78. }
  79. public function __toString(){
  80. return $this->guid;
  81. }
  82. /**
  83. * Returns a Query object based on inputs
  84. *
  85. * @method query
  86. * @param {String} sql The sql expression to run
  87. * @param {String=null} [types] A string containing all the types of arguments being passed
  88. * @param {Mixed} [bindings]* The bindings to use in the sql statement
  89. * @return {Query} Returns the query object
  90. */
  91. public function query(...$args){
  92. return new SQL\Query(...array_merge([$this], $args));
  93. }
  94. public function escape($s){
  95. return $this->sql->escape_string($s);
  96. }
  97. public function charset($charset){
  98. return $this->sql->set_charset($charset);
  99. }
  100. public static function make_referenced(&$arr){
  101. $refs = [];
  102. foreach($arr as $key => $value){
  103. $refs[$key] = &$arr[$key];
  104. }
  105. return $refs;
  106. }
  107. public static function shutdown(){
  108. foreach(self::$connections as $sql){
  109. unset($sql);
  110. }
  111. }
  112. }
  113. register_shutdown_function(function(){
  114. SQL::shutdown();
  115. });
  116. }
  117. ?>