2015-04-13 10:14:59 +00:00
< ? php
2016-02-03 22:22:56 +00:00
/**
* Holds the MySQL / PDO wrapper .
*
* @ package Sakura
*/
2015-06-25 22:35:06 +00:00
namespace Sakura\DBWrapper ;
2015-04-13 10:14:59 +00:00
use PDO ;
use PDOException ;
2016-02-02 21:04:15 +00:00
use PDOStatement ;
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
/**
2016-02-02 21:04:15 +00:00
* Sakura MySQL Wrapper .
*
* @ package Sakura
* @ author Julian van de Groep < me @ flash . moe >
2015-10-18 19:06:30 +00:00
*/
2015-10-30 16:43:09 +00:00
class mysql
2015-09-14 20:51:23 +00:00
{
2016-02-02 21:04:15 +00:00
/**
* Contains the PDO object .
*
* @ var PDO
*/
protected $sql ;
/**
* 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
);
}
2016-02-02 21:04:15 +00:00
/**
* Generates a DSN for a regular hostname : port endpoint .
*
* @ param string $dbHost Database hostname .
* @ param string $dbName Database name .
* @ param int $dbPort Database host port .
*
* @ return string The PDO DSN .
*/
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
}
2016-02-02 21:04:15 +00:00
/**
* Generates a DSN for a unix socket endpoint .
*
* @ param string $dbHost Path to the Unix Socket .
* @ param string $dbName Database name .
*
* @ return string The PDO DSN .
*/
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
}
2016-02-02 21:04:15 +00:00
/**
* Initialise a the database connection .
*
* @ param string $dsn The PDO DSN .
* @ param string $dbUname The database username .
* @ param string $dbPword The database password .
*
* @ return bool Returns true if the connection was successful .
*/
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 ,
]);
2015-12-27 04:37:57 +00:00
} 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 ;
}
2016-02-02 21:04:15 +00:00
/**
* Select table row ( s ) .
*
* @ param string $table The table to select data from .
* @ param array $data The WHERE selectors .
* @ param array $order The order in which the data is returned .
* @ param array $limit The limit of what should be returned .
* @ param array $group The way MySQL will group the data .
* @ param bool $distinct Only return distinct values .
* @ param string $column Only select from this column .
* @ param string $prefix Use a different table prefix than the one from the configuration .
*
* @ return PDOStatement The PDOStatement object for this action .
*/
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 ;
}
2016-02-02 21:04:15 +00:00
/**
* Summary of fetch
*
* @ param string $table The table to select data from .
* @ param bool $fetchAll Whether all result will be returned or just the first one .
* @ param array $data The WHERE selectors .
* @ param array $order The order in which the data is returned .
* @ param array $limit The limit of what should be returned .
* @ param array $group The way MySQL will group the data .
* @ param bool $distinct Only return distinct values .
* @ param string $column Only select from this column .
* @ param string $prefix Use a different table prefix than the one from the configuration .
*
* @ return array The data the database returned .
*/
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
2016-02-02 21:04:15 +00:00
/**
* Insert data into the database .
*
* @ param string $table The table that the data will be inserted into .
* @ param array $data The data that should be stored .
* @ param string $prefix Use a different table prefix than the one from the configuration .
*
* @ return bool Successfulness .
*/
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 ;
}
2016-02-02 21:04:15 +00:00
/**
* Update existing database rows .
*
* @ param string $table The table that the updated data will be inserted into .
* @ param array $data The data that should be stored .
* @ param string $prefix Use a different table prefix than the one from the configuration .
*
* @ return bool Successfulness .
*/
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
2016-02-02 21:04:15 +00:00
/**
* Deleted data from the database .
*
* @ param string $table The table that the data will be removed from .
* @ param array $data The pointers to what should be deleted .
* @ param string $prefix Use a different table prefix than the one from the configuration .
*
* @ return bool Successfulness .
*/
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 ;
}
2016-02-02 21:04:15 +00:00
/**
* Return the amount of rows from a table .
*
* @ param string $table Table to count in .
* @ param array $data Data that should be matched .
* @ param string $prefix Use a different table prefix than the one from the configuration .
*
* @ return array Array containing the SQL result .
*/
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
2016-02-02 21:04:15 +00:00
/**
* Get the id of the item that was last inserted into the database .
*
* @ param string $name Sequence of which the last id should be returned .
*
* @ return string The last inserted id .
*/
2015-10-19 21:25:20 +00:00
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
}