2015-04-13 10:14:59 +00:00
< ? php
/*
* Sakura MySQL Database Engine
*/
2015-06-25 22:35:06 +00:00
namespace Sakura\DBWrapper ;
2015-04-13 10:14:59 +00:00
use PDO ;
use PDOException ;
2015-11-06 22:30:37 +00:00
use \Sakura\Config ;
2015-04-13 10:14:59 +00:00
2015-10-18 19:06:30 +00:00
/**
* Class MySQL
* @ package Sakura\DBWrapper
*/
2015-10-30 16:43:09 +00:00
class mysql
2015-09-14 20:51:23 +00:00
{
2015-04-13 10:14:59 +00:00
// Variable that will contain the SQL connection
// Please refrain from referring to this, unless it's for your personal branch/purpose, despite it being public
// it sort of defeats the "dynamic database system" I want to go for.
2015-05-29 19:27:45 +00:00
public $sql ;
2015-04-13 10:14:59 +00:00
// Constructor
2015-09-14 20:51:23 +00:00
public function __construct ()
{
if ( ! extension_loaded ( 'PDO' )) {
2015-04-13 10:14:59 +00:00
// Return error and die
2015-05-29 19:27:45 +00:00
trigger_error ( 'PDO extension not loaded.' , E_USER_ERROR );
2015-04-13 10:14:59 +00:00
}
// Initialise connection
2015-05-29 19:27:45 +00:00
$this -> initConnect (
2015-04-13 10:14:59 +00:00
(
2015-12-04 14:19:10 +00:00
Config :: local ( 'database' , 'unixsocket' ) ?
2015-05-29 19:27:45 +00:00
$this -> prepareSock (
2015-12-04 14:19:10 +00:00
Config :: local ( 'database' , 'host' ),
Config :: local ( 'database' , 'database' )
2015-04-13 10:14:59 +00:00
) :
2015-05-29 19:27:45 +00:00
$this -> prepareHost (
2015-12-04 14:19:10 +00:00
Config :: local ( 'database' , 'host' ),
Config :: local ( 'database' , 'database' ),
2015-04-13 10:14:59 +00:00
(
2015-12-04 14:19:10 +00:00
Config :: local ( 'database' , 'port' ) !== null ?
Config :: local ( 'database' , 'port' ) :
2015-04-13 10:14:59 +00:00
3306
)
)
),
2015-12-04 14:19:10 +00:00
Config :: local ( 'database' , 'username' ),
Config :: local ( 'database' , 'password' )
2015-04-13 10:14:59 +00:00
);
}
// Regular IP/Hostname connection method prepare function
2015-09-14 20:51:23 +00:00
private function prepareHost ( $dbHost , $dbName , $dbPort = 3306 )
{
$dsn = 'mysql:host=' . $dbHost . ';port=' . $dbPort . ';dbname=' . $dbName ;
2015-04-13 10:14:59 +00:00
2015-09-14 20:51:23 +00:00
return $dsn ;
2015-04-13 10:14:59 +00:00
}
// Unix Socket connection method prepare function
2015-09-14 20:51:23 +00:00
private function prepareSock ( $dbHost , $dbName )
{
$dsn = 'mysql:unix_socket=' . $dbHost . ';dbname=' . $dbName ;
2015-04-13 10:14:59 +00:00
2015-09-14 20:51:23 +00:00
return $dsn ;
2015-04-13 10:14:59 +00:00
}
// Initialise connection using default PDO stuff
2015-09-14 20:51:23 +00:00
private function initConnect ( $dsn , $dbUname , $dbPword )
{
2015-04-13 10:14:59 +00:00
try {
// Connect to SQL server using PDO
2015-09-14 20:51:23 +00:00
$this -> sql = new PDO ( $dsn , $dbUname , $dbPword , [
PDO :: ATTR_EMULATE_PREPARES => false ,
PDO :: ATTR_ERRMODE => PDO :: ERRMODE_WARNING ,
]);
} catch ( PDOException $e ) {
2015-04-13 10:14:59 +00:00
// Catch connection errors
2015-09-14 20:51:23 +00:00
trigger_error ( 'SQL Driver: ' . $e -> getMessage (), E_USER_ERROR );
2015-04-13 10:14:59 +00:00
}
2015-08-19 02:37:45 +00:00
2015-04-13 10:14:59 +00:00
return true ;
}
2015-09-14 20:51:23 +00:00
public function select ( $table , $data = null , $order = null , $limit = null , $group = null , $distinct = false , $column = '*' , $prefix = null )
{
2015-04-13 10:14:59 +00:00
// Begin preparation of the statement
2015-12-04 14:19:10 +00:00
$prepare = 'SELECT ' . ( $distinct ? 'DISTINCT ' : '' ) . ( $column == '*' ? '' : '`' ) . $column . ( $column == '*' ? '' : '`' ) . ' FROM `' . ( $prefix ? $prefix : Config :: local ( 'database' , 'prefix' )) . $table . '`' ;
2015-04-13 10:14:59 +00:00
// If $data is set and is an array continue
2015-09-14 20:51:23 +00:00
if ( is_array ( $data )) {
2015-04-13 10:14:59 +00:00
$prepare .= ' WHERE' ;
2015-09-14 20:51:23 +00:00
foreach ( $data as $key => $value ) {
2015-08-21 22:07:45 +00:00
// Check if there's multiple statements
2015-09-14 20:51:23 +00:00
if ( ! is_array ( $value [ 0 ])) {
2015-08-21 22:07:45 +00:00
$temp = $value ;
unset ( $value );
$value [ 0 ] = $temp ;
}
// Go over each data thing
2015-09-14 20:51:23 +00:00
foreach ( $value as $sub => $val ) {
$prepare .= ' `' . $key . '` ' . $val [ 1 ] . ' :' . $key . '_' . $sub . ( $key == key ( array_slice ( $data , - 1 , 1 , true )) && $sub == key ( array_slice ( $value , - 1 , 1 , true )) ? '' : ' ' . ( isset ( $val [ 2 ]) && $val [ 2 ] ? 'OR' : 'AND' ));
2015-08-21 22:07:45 +00:00
unset ( $sub );
unset ( $val );
}
2015-04-13 10:14:59 +00:00
// Unset variables to be safe
unset ( $key );
unset ( $value );
}
}
// If $group is set and is an array continue
2015-09-14 20:51:23 +00:00
if ( is_array ( $group )) {
2015-04-13 10:14:59 +00:00
$prepare .= ' GROUP BY' ;
2015-09-14 20:51:23 +00:00
foreach ( $group as $key => $value ) {
$prepare .= ' `' . $value . '`' . ( $key == key ( array_slice ( $group , - 1 , 1 , true )) ? '' : ',' );
2015-04-13 10:14:59 +00:00
// Unset variables to be safe
unset ( $key );
unset ( $value );
}
}
2015-07-08 13:09:57 +00:00
// If $order is set and is an array continue
2015-09-14 20:51:23 +00:00
if ( is_array ( $order )) {
$prepare .= ' ORDER BY `' . $order [ 0 ] . '`' . ( ! empty ( $order [ 1 ]) && $order [ 1 ] ? ' DESC' : '' );
2015-07-08 13:09:57 +00:00
}
2015-08-19 02:37:45 +00:00
2015-04-13 10:14:59 +00:00
// If $limit is set and is an array continue
2015-09-14 20:51:23 +00:00
if ( is_array ( $limit )) {
2015-04-13 10:14:59 +00:00
$prepare .= ' LIMIT' ;
2015-09-14 20:51:23 +00:00
foreach ( $limit as $key => $value ) {
$prepare .= ' ' . $value . ( $key == key ( array_slice ( $limit , - 1 , 1 , true )) ? '' : ',' );
2015-04-13 10:14:59 +00:00
// Unset variables to be safe
unset ( $key );
unset ( $value );
}
}
// Add the finishing semicolon
$prepare .= ';' ;
// Actually prepare the preration
2015-05-29 19:27:45 +00:00
$query = $this -> sql -> prepare ( $prepare );
2015-04-13 10:14:59 +00:00
// Bind those parameters if $data is an array that is
2015-09-14 20:51:23 +00:00
if ( is_array ( $data )) {
foreach ( $data as $key => $value ) {
2015-08-21 22:07:45 +00:00
// Check if there's multiple statements
2015-09-14 20:51:23 +00:00
if ( ! is_array ( $value [ 0 ])) {
2015-08-21 22:07:45 +00:00
$temp = $value ;
unset ( $value );
$value [ 0 ] = $temp ;
}
// Go over each data thing
2015-09-14 20:51:23 +00:00
foreach ( $value as $sub => $val ) {
$query -> bindParam ( ':' . $key . '_' . $sub , $val [ 0 ]);
2015-08-21 22:07:45 +00:00
unset ( $sub );
unset ( $val );
}
2015-04-13 10:14:59 +00:00
// Unset variables to be safe
unset ( $key );
unset ( $value );
}
}
// Execute the prepared statements with parameters bound
$query -> execute ();
2015-08-21 22:07:45 +00:00
// Return the query
return $query ;
}
// Fetch array from database
2015-09-14 20:51:23 +00:00
public function fetch ( $table , $fetchAll = true , $data = null , $order = null , $limit = null , $group = null , $distinct = false , $column = '*' , $prefix = null )
{
2015-08-21 22:07:45 +00:00
// Run a select statement
2015-09-14 20:51:23 +00:00
$query = $this -> select ( $table , $data , $order , $limit , $group , $distinct , $column , $prefix );
2015-08-21 22:07:45 +00:00
2015-05-29 19:27:45 +00:00
// Return the output
2015-08-19 02:37:45 +00:00
return $fetchAll ? $query -> fetchAll ( PDO :: FETCH_ASSOC ) : $query -> fetch ( PDO :: FETCH_ASSOC );
2015-04-13 10:14:59 +00:00
}
2015-05-29 19:27:45 +00:00
2015-04-13 10:14:59 +00:00
// Insert data to database
2015-09-14 20:51:23 +00:00
public function insert ( $table , $data , $prefix = null )
{
2015-04-13 10:14:59 +00:00
// Begin preparation of the statement
2015-12-04 14:19:10 +00:00
$prepare = 'INSERT INTO `' . ( $prefix ? $prefix : Config :: local ( 'database' , 'prefix' )) . $table . '` ' ;
2015-04-13 10:14:59 +00:00
// Run the foreach statement twice for (`stuff`) VALUES (:stuff)
2015-09-14 20:51:23 +00:00
for ( $i = 0 ; $i < 2 ; $i ++ ) {
2015-04-13 10:14:59 +00:00
$prepare .= '(' ;
// Do more shit, don't feel like describing this so yeah
2015-09-14 20:51:23 +00:00
foreach ( $data as $key => $value ) {
if ( strlen ( $value )) {
2015-04-13 10:14:59 +00:00
$prepare .= ( $i ? ':' : '`' ) . $key . ( $i ? '' : '`' ) . ( $key == key ( array_slice ( $data , - 1 , 1 , true )) ? '' : ', ' );
2015-09-14 20:51:23 +00:00
}
2015-04-13 10:14:59 +00:00
}
$prepare .= ')' . ( $i ? ';' : ' VALUES ' );
}
// Actually prepare the preration
2015-05-29 19:27:45 +00:00
$query = $this -> sql -> prepare ( $prepare );
2015-04-13 10:14:59 +00:00
// Bind those parameters
2015-09-14 20:51:23 +00:00
foreach ( $data as $key => $value ) {
if ( strlen ( $value )) {
$query -> bindParam ( ':' . $key , $value );
}
2015-04-13 10:14:59 +00:00
// Unset variables to be safe
unset ( $key );
unset ( $value );
}
// Execute the prepared statements with parameters bound
$result = $query -> execute ();
// Return whatever can be returned
return $result ;
}
// Update data in the database
2015-09-14 20:51:23 +00:00
public function update ( $table , $data , $prefix = null )
{
2015-04-13 10:14:59 +00:00
// Begin preparation of the statement
2015-12-04 14:19:10 +00:00
$prepare = 'UPDATE `' . ( $prefix ? $prefix : Config :: local ( 'database' , 'prefix' )) . $table . '`' ;
2015-04-13 10:14:59 +00:00
// Run a foreach on $data and complete the statement
2015-09-14 20:51:23 +00:00
foreach ( $data as $key => $values ) {
2015-04-13 10:14:59 +00:00
// Append WHERE or SET depending on where we are
2015-09-14 20:51:23 +00:00
$prepare .= ' ' . ( $key ? 'WHERE' : 'SET' );
2015-04-13 10:14:59 +00:00
// Do this complicated shit, I barely know what's going on anymore but it works
2015-09-14 20:51:23 +00:00
foreach ( $values as $column => $column_data ) {
$prepare .= ' `' . $column . '` ' . ( $key ? $column_data [ 1 ] : '=' ) . ' :' . ( $key ? 'w' : 's' ) . '_' . $column . ( $column == key ( array_slice ( $values , - 1 , 1 , true )) ? ( $key ? ';' : '' ) : ( $key ? ' ' . ( isset ( $value [ 2 ]) && $value [ 2 ] ? 'OR' : 'AND' ) : ',' ));
}
2015-04-13 10:14:59 +00:00
}
// Actually prepare the preration
2015-05-29 19:27:45 +00:00
$query = $this -> sql -> prepare ( $prepare );
2015-04-13 10:14:59 +00:00
// Seperate the foreaches for the SET and WHERE clauses because it's fucking it up for some odd reason
// Bind Set Clauses
2015-09-14 20:51:23 +00:00
foreach ( $data [ 0 ] as $key => $value ) {
2015-04-13 10:14:59 +00:00
// Do the binding
2015-09-14 20:51:23 +00:00
$query -> bindParam ( ':s_' . $key , $value );
2015-04-13 10:14:59 +00:00
// Unset variables to be safe
unset ( $key );
unset ( $value );
}
// Bind Where Clauses
2015-09-14 20:51:23 +00:00
foreach ( $data [ 1 ] as $key => $values ) {
2015-04-13 10:14:59 +00:00
// Assign the array entry to a variable because fuck strict standards
$value = $values [ 0 ];
// Binding two electrifying memes
2015-09-14 20:51:23 +00:00
$query -> bindParam ( ':w_' . $key , $value );
2015-04-13 10:14:59 +00:00
// Unset variables to be safe
unset ( $key );
unset ( $value );
unset ( $values );
}
// Execute the prepared statements with parameters bound
$result = $query -> execute ();
// Return whatever can be returned
return $result ;
}
2015-04-17 22:14:31 +00:00
// Delete data from the database
2015-09-14 20:51:23 +00:00
public function delete ( $table , $data , $prefix = null )
{
2015-04-17 22:14:31 +00:00
// Begin preparation of the statement
2015-12-04 14:19:10 +00:00
$prepare = 'DELETE FROM `' . ( $prefix ? $prefix : Config :: local ( 'database' , 'prefix' )) . $table . '`' ;
2015-04-17 22:14:31 +00:00
// If $data is set and is an array continue
2015-09-14 20:51:23 +00:00
if ( is_array ( $data )) {
2015-04-17 22:14:31 +00:00
$prepare .= ' WHERE' ;
2015-09-14 20:51:23 +00:00
foreach ( $data as $key => $value ) {
$prepare .= ' `' . $key . '` ' . $value [ 1 ] . ' :' . $key . ( $key == key ( array_slice ( $data , - 1 , 1 , true )) ? '' : ' ' . ( isset ( $value [ 2 ]) && $value [ 2 ] ? 'OR' : 'AND' ));
2015-04-17 22:14:31 +00:00
// Unset variables to be safe
unset ( $key );
unset ( $value );
}
}
// Actually prepare the preration
2015-05-29 19:27:45 +00:00
$query = $this -> sql -> prepare ( $prepare );
2015-04-17 22:14:31 +00:00
// Bind those parameters
2015-09-14 20:51:23 +00:00
foreach ( $data as $key => $value ) {
$query -> bindParam ( ':' . $key , $value [ 0 ]);
2015-04-17 22:14:31 +00:00
// Unset variables to be safe
unset ( $key );
unset ( $value );
}
// Execute the prepared statements with parameters bound
$result = $query -> execute ();
// Return whatever can be returned
return $result ;
}
2015-07-05 00:03:15 +00:00
// Count data from the database
2015-09-14 20:51:23 +00:00
public function count ( $table , $data = null , $prefix = null )
{
2015-07-05 00:03:15 +00:00
// Begin preparation of the statement
2015-12-04 14:19:10 +00:00
$prepare = 'SELECT COUNT(*) FROM `' . ( $prefix ? $prefix : Config :: local ( 'database' , 'prefix' )) . $table . '`' ;
2015-07-05 00:03:15 +00:00
// If $data is set and is an array continue
2015-09-14 20:51:23 +00:00
if ( is_array ( $data )) {
2015-07-05 00:03:15 +00:00
$prepare .= ' WHERE' ;
2015-09-14 20:51:23 +00:00
foreach ( $data as $key => $value ) {
$prepare .= ' `' . $key . '` ' . $value [ 1 ] . ' :' . $key . ( $key == key ( array_slice ( $data , - 1 , 1 , true )) ? '' : ' ' . ( isset ( $value [ 2 ]) && $value [ 2 ] ? 'OR' : 'AND' ));
2015-07-05 00:03:15 +00:00
// Unset variables to be safe
unset ( $key );
unset ( $value );
}
}
// Add the finishing semicolon
$prepare .= ';' ;
// Actually prepare the preration
$query = $this -> sql -> prepare ( $prepare );
// Bind those parameters if $data is an array that is
2015-09-14 20:51:23 +00:00
if ( is_array ( $data )) {
foreach ( $data as $key => $value ) {
$query -> bindParam ( ':' . $key , $value [ 0 ]);
2015-07-05 00:03:15 +00:00
// Unset variables to be safe
unset ( $key );
unset ( $value );
}
}
// Execute the prepared statements with parameters bound
$query -> execute ();
// Return the output
return $query -> fetch ( PDO :: FETCH_BOTH );
}
2015-10-19 21:25:20 +00:00
// Get the ID of the last inserted item
public function lastInsertID ( $name = null )
{
2015-10-30 16:43:09 +00:00
return $this -> sql -> lastInsertID ( $name );
2015-10-19 21:25:20 +00:00
}
2015-04-13 10:14:59 +00:00
}