<?php
namespace Empire\Legacy;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\PDOStatement;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\Driver\Statement;
use Empire\Core\Core;
use Empire\Core\Entity;
/**
* Class db
* @package Empire\Legacy
* @deprecated Use the Doctrine DBAL instead.
*/
Class db {
/**
* Does a mysqli query
* run this instead of ::prepare and I might kill you
*
* @param string $query
* @return Statement
* @throws \Exception
* @deprecated
*/
static function query($query) {
$mysql = Core::db();
$res = $mysql->query($query);
if(!$res) {
throw new \Exception($mysql->errorInfo() . " -" . $query);
}
return $res;
}
/**
* Returns the number of affected rows
*
* @param Statement $link_identifier
* @return int
*/
static function affectedRows($link_identifier = null) {
if (!is_null($link_identifier)) {
return $link_identifier->rowCount();
}
return -1;
}
/**
* Fetches an object from a result
*
* @param Statement $result
* @param string $class
* @return mixed
*/
static function fetchObject($result, $class = 'stdClass') {
if($result instanceof PDOStatement) {
if (!is_null($class)) {
$obj = $result->fetchObject($class);
if ($obj instanceof Entity) {
$obj->initialize();
}
} else {
return $result->fetchObject();
}
return $obj;
} else {
return null;
}
}
/**
* Fetches an array from a result
*
* @param Statement $result
* @return array
*/
static function fetchArray($result) {
return $result->fetch(FetchMode::ASSOCIATIVE);
}
/**
* @param Statement $result
* @param string $class
* @return array
*/
static function fetchArrayOfObjects($result, $class = 'stdClass') {
$array = array();
if (method_exists($result, 'rowCount') && $result->rowCount() == 0) {
return $array;
}
while ($row = self::fetchObject($result, $class)) {
$array[] = $row;
}
return $array;
}
/**
* Gets the number of rows in a result
*
* @param Statement $result
* @return int
*/
static function numRows($result) {
return $result->rowCount();
}
/**
* Gets the most recent mysqli insert ID
*
* @return int
*/
static function insertID() {
$mysql = Core::db();
return $mysql->lastInsertId();
}
/**
* Escapes a string for mysql
*
* @param mixed $strToBeEscaped
* @return mixed
*/
static function escape($strToBeEscaped) {
$mysql = Core::db();
if(!is_numeric($strToBeEscaped)) {
//return $mysql->real_escape_string($strToBeEscaped);
return $mysql->quote($strToBeEscaped);
} else {
return $strToBeEscaped;
}
}
/**
* Escapes a value with quotes
*
* @param mixed $value
* @return int|string
*/
public static function quoteEscape($value) {
if($value === null){
return 'null';
} else if($value === true){
return 1;
} else if($value === false){
return 0;
} else if ($value === "NOW()") {
return $value;
}
if(is_array($value)){
$value = array_map(array('Empire\Legacy\db', 'quoteEscape'), $value);
return '(' . implode(', ', $value) . ')';
}
if(is_numeric($value)){
return $value;
}
return self::escape($value);
}
/**
* Used as a callback for prepare
*
* @param string $query
* @param array $assoc
* @return array
*/
private static function prepareAssoc($query, array $assoc = array()){
$numeric = 0;
$callback = function($match) use($assoc, &$numeric){
$modifier = $match[1];
$name = $match[2];
if($modifier == '#'){
if($name == 'UNIX_NOW'){
return time();
} else if($name == 'CGT_NOW'){
return cgt::getCGTSeconds();
}
return self::quoteEscape(constant($name));
}
if($modifier == '@'){
if(is_array($assoc[0])){
return self::quoteEscape($assoc[0][$name]);
} else if(is_object($assoc[0])){
return self::quoteEscape($assoc[0]->$name);
}
throw new \Exception('Invalid argument provided as assoc');
}
if($modifier == '!!'){
if(!array_key_exists($numeric, $assoc)){
throw new \Exception('Looking for array argument: ' . $numeric . ' but not found');
}
return $assoc[$numeric++];
}
if($modifier == '?'){
if(!array_key_exists($numeric, $assoc)){
throw new \Exception('Looking for array argument: ' . $numeric . ' but not found.');
}
return self::quoteEscape($assoc[$numeric++]);
}
if($modifier == '&&') {
return $assoc[$numeric++];
}
throw new \Exception('Invalid query modified provided.');
};
return preg_replace_callback('/([@#?]|!!|&&)(\w*)/', $callback, $query);
}
/**
* Prepares a sql query, uses various args as needed
*
* ? = any arg, gets quote-escaped
* # = a constant, also accepts UNIX_TIME and CGT_TIME
* @ = named replacement
* !! = raw injection
* && = raw injection, can be empty/ignored
*
* @return Statement self::query
* @throws \Exception
*/
public static function prepare(){
$intArgs = func_num_args() - 1;
$arrArgs = func_get_args();
//some initial checking
if($intArgs == -1){
throw new \Exception('prepare called with no arguments');
}
//wildcard query string
$query = array_shift($arrArgs);
//fill in the query
$query = self::prepareAssoc($query, $arrArgs);
//run the generated query
return self::query($query);
}
/**
* Inserts associative $array into $table. Field names are DB field names and values are values.
*
* @param string $table table name
* @param array $array associative array of fields
* @param array $duplicate associative array of fields for duplicate key handling
* @return int insert ID
* @throws \Exception
*/
public static function insert($table, $array, $duplicate = array()) {
if(empty($array)){
throw new \Exception('Array is empty');
}
$sets = array();
foreach($array as $key=>$value){
$sets[] = '`' . $key . '` = ' . self::quoteEscape($value);
}
$sql = 'INSERT INTO `' . $table . '` SET ' . implode(', ', $sets);
if(count($duplicate) > 0) {
$dupes = array();
foreach($duplicate as $key=>$value){
$dupes[] = '`' . $key . '` = ' . self::quoteEscape($value);
}
$sql .= ' ON DUPLICATE KEY UPDATE ' . implode(', ', $dupes);
}
self::query($sql);
return self::insertID();
}
}