Created
August 16, 2017 11:57
-
-
Save CreeJee/4009500c6b19b044f8b1026bd9f9c88e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
error_reporting(E_ALL); | |
function isListArr($array){ | |
if(is_array($array)){ | |
return array_values($array) === $array; | |
} | |
else{ | |
return false; | |
} | |
}; | |
function isObjectArr($array){ | |
if(is_array($array)){ | |
return array_values($array) !== $array; | |
} | |
else{ | |
return false; | |
} | |
}; | |
function cbListJoin($values,$delimiter,$callback){ | |
if (isListArr($values)) { | |
$valueCount = count($values); | |
$count = 0; | |
$ret = ""; | |
foreach ($values as $v) { | |
if ($callback instanceof Closure) { | |
$ret .= ($v = $callback($v,$count)); | |
} | |
if($count < $valueCount-1){ | |
$count++; | |
$ret .= (!empty($delimiter)) ? $delimiter : ','; | |
} | |
} | |
return $ret; | |
} | |
else{ | |
throw new Exception("list Array only", 99); | |
} | |
} | |
class queryBuilder | |
{ | |
//TODO 호출스택을 따로 만들어서 디버깅하기 용의 하게 하기 | |
//서브쿼리 핸들링 | |
const MYSQL_ERR = -1; | |
const SUCCESS = 0; | |
const QUERY_ERR = 1; | |
const UNKNOWN_TYPE = 11; | |
const SIZE_NOT_MATCHED = 12; | |
function __construct($mysqli){ | |
$this->sql = ""; | |
$this->count = 0; | |
if ($mysqli instanceof Mysqli) { | |
$this->mysqli = $mysqli; | |
} | |
else{ | |
throw new Exception("object is not mysqli", $this::MYSQL_ERR); | |
} | |
$this->result = null; | |
} | |
public function closeDb(){ | |
if ($this->mysqli->ping()) { | |
$this->mysqli->close(); | |
} | |
} | |
private function isTableExist(){ | |
if (empty($this->table)) { | |
throw new Exception("table is not set", $this::QUERY_ERR); | |
} | |
} | |
protected function getSqlResult($sql){ | |
if ($this->mysqli->ping()) { | |
$this->result = ($this->result !== NULL) ? $this->result: $this->mysqli->query($sql); | |
if ($this->mysqli->error) { | |
var_dump($this->mysqli->error); | |
echo "<br>".$this->sql; | |
} | |
if ($this->result) { | |
$ret = array( | |
'db' => $this->result, | |
'status' => $this::SUCCESS | |
); | |
} | |
else{ | |
$ret = array('status' => $this::QUERY_ERR,'info' => $this->mysqli->error); | |
} | |
return $ret; | |
} | |
else{ | |
throw new Exception("Error Connect Mysql [error : ".$this->mysqli->error."]", MYSQL_ERR); | |
} | |
} | |
private function kvCommand($command,$keys,$values,$delimiter){ | |
if (isListArr($keys) && isListArr($values) && !empty($command)){ | |
$this->isTableExist(); | |
$keyCount = count($keys); | |
$valueCount = count($values); | |
$delimiterCount = count($delimiter); | |
if ($keyCount > 0 && $valueCount > 0 && $valueCount <= $keyCount) { | |
$setValues = ""; | |
for ($index = 0,$dli = ""; $index < $keyCount; $index++) { | |
$values[$index] = is_string($values[$index]) ? "".$values[$index]."" : $values[$index]; | |
$dli = (is_array($delimiter)) ? isset($delimiter[$index]) ? $delimiter[$index] : "=" : "="; | |
$setValues .= "".$this->argumentHandle($keys[$index])." ".$dli." ".$values[$index]; | |
if($index < $keyCount - 1){ | |
$setValues .= " AND "; | |
} | |
}; | |
$sql = $command." ".$setValues." "; | |
return $sql; | |
} | |
else{ | |
throw new Exception("Key Value length is Not Matched", $this::SIZE_NOT_MATCHED); | |
} | |
} | |
else if(is_string($keys) && is_string($values) && !empty($command)){ | |
$sql = $command." ".$keys." = ".$values; | |
} | |
else if(!empty($command) && !empty($keys)){ | |
return $command." ".$this->argumentHandle($keys); | |
} | |
else{ | |
throw new Exception("Unknown Type (Array,String)", $this::UNKNOWN_TYPE); | |
} | |
} | |
private function upadteCommand($command,$operator,$keys,$values){ | |
if (isListArr($keys) && isListArr($values) && !empty($command)){ | |
$this->isTableExist(); | |
$keyCount = count($keys); | |
$valueCount = count($values); | |
if ($keyCount > 0 && $valueCount > 0 && $valueCount <= $keyCount) { | |
$setValues = ""; | |
for ($index = 0; $index < $keyCount; $index++) { | |
$values[$index] = is_string($values[$index]) ? "'".$values[$index]."'" : $values[$index]; | |
$setValues .= "`".$keys[$index]."` = ".$values[$index]; | |
if($index <= $keyCount){ | |
$setValues .= ", "; | |
} | |
}; | |
$sql = $command." `".$this->table."` ".$operator." ".$setValues.""; | |
return $sql; | |
} | |
else{ | |
throw new Exception("Key Value length is Not Matched", $this::SIZE_NOT_MATCHED); | |
} | |
} | |
else{ | |
throw new Exception("Unknown Type (Only Array)", $this::UNKNOWN_TYPE); | |
} | |
} | |
private function insertCommand($command,$operator,$keys,$values){ | |
if (isListArr($keys) && isListArr($values) && !empty($command)){ | |
$this->isTableExist(); | |
$keyCount = count($keys); | |
$valueCount = count($values); | |
if ($keyCount > 0 && $valueCount > 0 && $valueCount === $keyCount) { | |
$column = "`".(is_array($keys) ? join($keys,"`,`") : $keys)."`"; | |
$values = cbListJoin($values,",",function($val){ | |
$val = is_string($val) ? '\''.$val.'\'' : $val; | |
$val = ($val === null) ? 'NULL' : $val; | |
return $val; | |
}); | |
$sql = $command." `".$this->table."` (".$column.") ".$operator." (".$values.")"; | |
return $sql; | |
} | |
else{ | |
throw new Exception("Key Value length is Not Matched", $this::SIZE_NOT_MATCHED); | |
} | |
} | |
else{ | |
throw new Exception("Unknown Type (Only Array)", $this::UNKNOWN_TYPE); | |
} | |
} | |
private function argumentHandle($listedArr){ | |
$res = ""; | |
$arg = ""; | |
$arguments = func_get_args(); | |
$suffix = !empty($arguments[1]) ? $arguments[1] : ""; | |
if(isListArr($listedArr)){ | |
$func = array_splice($listedArr,0,1)[0]; | |
$argLen = count($listedArr); | |
for ($i=0; $i < $argLen; $i++) { | |
$arg .= isListArr($listedArr[$i]) ? $this->argumentHandle($listedArr[$i]) : $listedArr[$i]; | |
if ($i < $argLen-1) { | |
$arg .= ","; | |
} | |
} | |
$res = $func."(".$arg.") ".$suffix." "; | |
} | |
else if(is_string($listedArr)){ | |
$res = $listedArr." ".$suffix." "; | |
} | |
return $res; | |
} | |
private function bindFunc($arr){ | |
$arguments = func_get_args(); | |
$res = ""; | |
$prefix = !empty($arguments[1]) ? $arguments[1] : ""; | |
$suffix = !empty($arguments[2]) ? $arguments[2] : ""; | |
if(isListArr($arr)){ | |
$res = $prefix." ".$this->argumentHandle($arr).$suffix." "; | |
} | |
else if($arr instanceof queryBuilder){ | |
$res = $prefix." "."(".$arr->sql.") ".$suffix; | |
} | |
else if(!is_array($arr)){ | |
$res = is_string($arr) ? $arr : $arr; | |
} | |
else{ | |
throw new Exception("Array Attribute Is Wrong [arguments : ".print_r($arr,true)."]", $this::UNKNOWN_TYPE); | |
} | |
return $res; | |
} | |
function query($sql){ | |
$res = $this->getSqlResult($sql); | |
$this->result = null; | |
return $res; | |
} | |
function setTable($table){ | |
$this->table = $table; | |
return $this; | |
} | |
function select(...$column){ | |
$this->isTableExist(); | |
$columnStr = ""; | |
$count = 0; | |
$columnCount = count($column); | |
foreach ($column as $k => $v) { | |
if (isObjectArr($v)) { | |
$preifx = !empty($v['prefix']) ? $v['prefix'] : ""; | |
$suffix = !empty($v['suffix']) ? $v['suffix'] : ""; | |
if (isset($v['query'])) { | |
$columnStr .= $this->bindFunc($v['query'],$preifx,$suffix); | |
} | |
else{ | |
throw new Exception("Error for argumens (empty query)", 1); | |
} | |
} | |
else{ | |
$columnStr .= $this->bindFunc($v); | |
} | |
if ($count < $columnCount-1) { | |
$columnStr .= ","; | |
} | |
$count++; | |
} | |
$columnStr .= ""; | |
$this->sql .= "SELECT ".$columnStr." FROM `".$this->table."` "; | |
$this->mode = "select"; | |
return $this; | |
} | |
function insert($keys,$values){ | |
$this->sql .= $this->insertCommand("INSERT INTO","VALUES",$keys,$values)." "; | |
$this->mode = "insert"; | |
return $this; | |
} | |
function delete(){ | |
$this->isTableExist(); | |
$this->sql .= "DELETE FROM `".$this->table."` "; | |
$this->mode = "delete"; | |
return $this; | |
} | |
function update($keys,$values){ | |
$this->sql .= upadteCommand("UPDATE","SET",$keys,$values)." "; | |
$this->mode = "update"; | |
return $this; | |
} | |
function limit(){ | |
$arg = func_get_args(); | |
$countPreifx = empty($arg[0]) && $arg[0] !== 0 ? "" : ((is_numeric($arg[0]) && $arg[0] >= 0) ? "LIMIT ".$arg[0]." " : ""); | |
$limitPreifx = empty($arg[1]) ? "" : ((is_numeric($arg[1]) && $arg[1] >= 0) ? ", ".$arg[1]." " : ""); | |
$this->sql .= $countPreifx.$limitPreifx; | |
return $this; | |
} | |
function where($keys){ | |
$arg = func_get_args(); | |
$values = is_array($arg) ? !empty($arg[1]) ? $arg[1] : null : null; | |
$delimiter = is_array($arg) ? !empty($arg[2]) ? $arg[2] : null : null; | |
$this->sql .= $this->kvCommand("WHERE",$keys,$values,$delimiter); | |
return $this; | |
} | |
function orderBy(...$data){ | |
//key,value,preifx 로 구성 | |
$sql = "ORDER BY "; | |
$count = count($data); | |
if (isListArr($data)) { | |
for ($index = 0; $index < $count; $index++) { | |
$data[$index]['key'] = !empty($data[$index]['key']) ? $data[$index]['key'] : ""; | |
$data[$index]['suffix'] = !empty($data[$index]['suffix']) ? $data[$index]['suffix'] : ""; | |
$data[$index]['value'] = !empty($data[$index]['value']) ? $data[$index]['value'] : ""; | |
$sql .= "".$this->argumentHandle( | |
$data[$index]['key'], | |
$data[$index]['suffix'] | |
)." ".$data[$index]['value']." "; | |
if ($index < $count - 1) { | |
$sql .= ", "; | |
} | |
} | |
$sql .= " "; | |
$this->sql .= $sql; | |
} | |
else{ | |
throw new Exception("Unknown Column Or Value ", 1); | |
} | |
return $this; | |
} | |
function groupBy(...$column){ | |
$col = '`'.join($column,'`,`').'`'; | |
$this->sql .= "GROUP BY ".$col." "; | |
return $this; | |
} | |
//subquery Handle | |
function subQuery($subBuilder){ | |
if(get_class($subBuilder) === get_class($this)){ | |
$this->sql .= "(".$subBuilder->sql.")"; | |
} | |
} | |
function debug(){ | |
return $this; | |
} | |
function exec(){ | |
$res = $this->getSqlResult($this->sql); | |
$this->result = $this->table = null; | |
return $res; | |
} | |
function clone($cloneObj){ | |
if($cloneObj instanceof queryBuilder){ | |
$this->mode = $cloneObj->mode; | |
$this->sql = $cloneObj->sql; | |
return $this; | |
} | |
else{ | |
throw new Exception("unknown type (Only $this(queryBuilder))", $this::UNKNOWN_TYPE); | |
} | |
} | |
function result(){ | |
$res = $this->getSqlResult($this->sql)['db']; | |
if (!is_bool($res)){ | |
$row = $res->fetch_array(); | |
$row['count'] = $row[2] = ++$this->count; | |
$row['total'] = $res->num_rows; | |
if ($this->count > $row['total']) { | |
$this->count = 0; | |
$this->res = null; | |
} | |
else{ | |
return $row; | |
} | |
} | |
else{ | |
return $res; | |
} | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment