<?php namespace Juju { require_once('SQL/query.class.php'); require_once('Data/securestring.class.php'); use \Juju\SQL\Query; use \Juju\Data\SecureString; /** * SQL class. Used for handling SQL connections * * @module sql * @class SQL * @constructor */ class SQL { /** * This is the mysqli connection beneath everything * * @property sql * @type {mysqli} * @private * @required */ private $guid; private $sql; public $queries = []; private static $connections = []; public static function FromDSN(string $dsnstring){ $dsnstring = explode(':', $dsnstring)[1]; $dsn = explode(';', $dsnstring); $dsn = array_reduce($dsn, function($dsn, $item){ $item = explode('=', $item); $dsn[$item[0]] = $item[1]; return $dsn; }); if(!isset($dsn['host'])){ throw new \Exception("DSN {$dsnstring} missing host"); } if(!isset($dsn['dbname'])){ throw new \Exception("DSN {$dsnstring} missing dbname"); } if(!isset($dsn['user'])){ $dsn['user'] = $dsn['dbname']; } if(!isset($dsn['pass'])){ $dsn['pass'] = $dsn['user']; } $dsn['pass'] = SecureString::from($dsn['pass']); return new SQL($dsn['host'], $dsn['user'], $dsn['pass'], $dsn['dbname']); } public function __construct($server,$user,$pass,$db){ $this->guid = uniqid(); $this->sql = new \mysqli('p:'.$server,$user,"{$pass}",$db);; if($this->sql->connect_error){ throw new \Exception('Mysqli Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error); } self::$connections[] = $sql; } public function __destruct(){ $this->sql->rollback(); $this->sql->close(); foreach($this->queries as $query){ unset($query); } self::$connections = array_diff(self::$connections, [$this]); } public function __invoke(){ return $this->sql; } public function __get($name){ switch($name){ case 'error': return $this->sql->error; break; case 'insert_id': return $this->sql->insert_id; break; } } public function __toString(){ return $this->guid; } /** * Returns a Query object based on inputs * * @method query * @param {String} sql The sql expression to run * @param {String=null} [types] A string containing all the types of arguments being passed * @param {Mixed} [bindings]* The bindings to use in the sql statement * @return {Query} Returns the query object */ public function query(...$args){ return new SQL\Query(...array_merge([$this], $args)); } public function escape($s){ return $this->sql->escape_string($s); } public function charset($charset){ return $this->sql->set_charset($charset); } public static function make_referenced(&$arr){ $refs = []; foreach($arr as $key => $value){ $refs[$key] = &$arr[$key]; } return $refs; } public static function shutdown(){ foreach(self::$connections as $sql){ unset($sql); } } } register_shutdown_function(function(){ SQL::shutdown(); }); } ?>