PaperBag/application/DB.php

141 lines
3.7 KiB
PHP

<?php
class DB {
private static $instance = null;
private $db;
/**
* @throws DatabaseException
*/
private function __construct(){
try {
$this->db = new mysqli(
Config::get('database', 'host'),
Config::get('database', "user"),
Config::get('database', "pass"),
Config::get('database', "database")
);
if($this->db->connect_error){
throw new DatabaseException("Database connection failed: ". $this->db->connect_error);
}
}
catch (mysqli_sql_exception $e){
throw new DatabaseException($e->getMessage(), $e->getCode());
}
}
public static function getInstance(): DB {
if(self::$instance == null){
self::$instance = new DB();
}
return self::$instance;
}
public static function escape($input): string {
return DB::getInstance()->db->real_escape_string($input);
}
/**
* @throws DatabaseException
*/
public static function query($sql, ...$params){
return self::doQuery(0, $sql, ...$params);
}
/**
* @throws DatabaseException
*/
public static function queryTest($sql, ...$params){
return self::doQuery(1, $sql, ...$params);
}
/**
* Never @throws DatabaseException
*/
public static function queryPreview($sql, ...$params){
return self::doQuery(2, $sql, ...$params);
}
/**
* @param integer $mode 0: Execute normally - 1: Execute, but print query - 2: Only print query
* @param string $sql Input SQL as string
* @param mixed ...$params A list or an array of values for the query
* @throws DatabaseException
*/
private static function doQuery(int $mode, string $sql, ...$params){
// Check if query parameters comes as an array, or as individual arguments
if(count($params) == 1 && is_array($params[0])){
$params = $params[0];
}
// Create type-specification for query
$types = "";
foreach($params as $value){
if(is_double($value)){
$types .= "d";
}
elseif(is_integer($value)){
$types .= "i";
}
else {
$types .= "s";
}
}
$db = DB::getInstance();
if($mode >= 1){
printf(str_replace('?', "'%s'", $sql)."\n", ...$params);
}
if($mode >= 2) {
return [];
}
try {
$stmt = $db->db->prepare($sql);
if(
$stmt === false ||
(!empty($params) && $stmt->bind_param($types, ...$params) === false) ||
$stmt->execute() === false
){
throw new DatabaseException($db->db->error);
}
}
catch (mysqli_sql_exception $e){
throw new DatabaseException($e->getMessage(), $e->getCode());
}
return $stmt->get_result();
}
/**
* @throws DatabaseException
*/
public static function multiQuery(...$sql){
$db = DB::getInstance();
foreach ($sql as $s){
try {
$db->db->multi_query($s);
}
catch (mysqli_sql_exception $e){
throw new DatabaseException($e->getMessage(), $e->getCode());
}
}
}
public static function insert_id(){
$db = DB::getInstance();
return $db->db->insert_id;
}
}
class DatabaseException extends Exception {
public function __construct($message = "", $code = 0, Throwable $previous = null){
parent::__construct($message, $code, $previous);
}
}