* @copyright: Copyright (c) 2010, Bunzia Alexander * @version: 1.0 * @license: http://www.gnu.org/copyleft/gpl.html GNU/GPL * @package: HiLo CMS */ /*** * Конструктор sql запросов * * */ class query{ // алиса основной таблицы, переопределяется потомком public $alias; // полное имя основной таблицы, переопределяется потомком public $table; // для сложных sql запросов, можно просто передать код sql private $sql; // ресур возвращаемый из базы данных private $result = ''; // LIMIT $page, ... private $page = false; //количество строк за раз // LIMIT ..., $count_rows private $count_rows = false; // массив условий private $sql_where = array(); // массив сортировок private $sql_order = array(); // сложные условия private $anothe_where = array(); // группировки private $sql_groupby = array(); // вспомогательные таблицы private $sql_tables = array(); // получаемые столбцы private $sql_parametrs = array(); // общее количество полученных столбцов private $_result_count_rows = false; // отладка private $debug; // переопределяемое свойство, содержит последнюю ошибку protected $last_error = FALSE; // сложный запрос сразу заносим, а не генерим public function set_sql($sql){ $this -> sql = $sql; } // сортировка public function set_orderby($key,$value){ if ( !empty($value) && !in_array($value, array('ASC','DESC')) ){ return FALSE; } $this -> sql_order[$key] = $value; return TRUE; } // условия public function set_where($key,$value){ if ( empty($key) ){ return FALSE; } $this -> sql_where[$key] = $value; return TRUE; } public function where_more($key,$value){ return $this -> set_anothe_where( " $key>$value " ); } public function where_less($key,$value){ return $this -> set_anothe_where( " $key<$value " ); } // сложные условия public function set_anothe_where($sql){ $this -> anothe_where[]=$sql; return TRUE; } // группировка результатов public function set_groupby($key){ $this -> sql_groupby[] = $key; return TRUE; } // постраничный вывод public function set_page($page){ $page = intval($page); $this -> page = !empty($page) ? $page : 1; return TRUE; } public function set_limit($page,$count){ $this -> set_count_rows($count); $this -> set_page($page); return TRUE; } // сколько выводить за раз public function set_count_rows($count){ $count = intval($count); // ошибка привидёт к краху запроса, её допускать нельзя if ( empty($count) ){ sys_error('500',E_EMPTY_COUNT_ROWS); return FALSE; } $this -> count_rows = $count; return TRUE; } // отладка запроса public function set_debug($flag){ $this -> debug=$flag; } public function row(){ global $MAIN_DB; $row = $MAIN_DB -> fetch_assoc($this->result); if ( false===$row ){ return false; } $result=array(); $i=0; $f = $this -> fields_get; if ( empty($f) ){ $f = $this; } foreach( $row AS $func=>$value ){ if ( method_exists($f ,$func) ){ $result[$func] =call_user_func( array($f,$func),$value,$row); //$result[$func] = $f :: $func($value,$row); }else{ $result[$func] = $value; } $result[$i] = $result[$func]; $i++; } return $result; } public function make_sql($parametrs,$flag_found_rows=false){ // sql_parametrs - поля которые нужно получить if ( !empty($parametrs) ){ $this -> sql_parametrs[]=$parametrs; } $parametrs = implode(',',$this -> sql_parametrs); // параметры не заданы if ( empty($parametrs) ){ sys_error('500',E_DATABASE_EMPTY_PARAMETRS); return FALSE; } $result = array(); $found_rows = $flag_found_rows ? 'SQL_CALC_FOUND_ROWS' : ''; // условия if ( sizeof($this -> sql_where)>0 || sizeof($this -> anothe_where)>0 ){ $sql_where = array(); foreach( $this -> anothe_where AS $k=>$v){ $sql_where[]=$v; } foreach( $this -> sql_where AS $k=>$v){ if ( empty($k)){ $sql_where[]=$v; continue; } if ( is_array($v) ){ $sql_where[]="$k IN (".implode(',',$v).")"; }else{ $sql_where[]="$k = '".mysql_real_escape_string($v)."'"; } } $sql_where = 'WHERE '.implode(' AND ',$sql_where); }else{ $sql_where=''; } // сортировка $sql_order = ''; if ( sizeof($this -> sql_order)>0 ){ $sql_order = array(); foreach( $this -> sql_order AS $k=>$v){ $sql_order[]="$k $v"; } $sql_order = 'ORDER BY '.implode(' , ',$sql_order); } // groupby $sql_grouby = ''; if ( sizeof($this -> sql_groupby)>0 ){ $sql_grouby = array(); foreach( $this -> sql_groupby AS $k){ $sql_grouby[]="$k"; } $sql_grouby = 'GROUP BY '.implode(' , ',$sql_grouby); } // лимит на выборку $sql_limit = ''; if ( $this -> count_rows!==false && $this -> page !==false ){ $sql_limit = "LIMIT ".(($this -> page-1)*$this -> count_rows).",".$this -> count_rows; } // сборка запроса $sql = "SELECT $found_rows $parametrs FROM ".$this -> table." ".$this -> alias." "; foreach( $this -> sql_tables AS $table_info ){ $sql .= " ".$table_info['join']." ".$table_info['name']." ".$table_info['alias']." USING(".$table_info['key'].")"; } return $sql .= "$sql_where $sql_grouby $sql_order $sql_limit"; } /** * Собираем и выполняем sql запрос * * @var: parametrs str Список получаемых столбцов * @var: flag_found_rows bool Нужно или нет получать общее количество строк без учёта LIMIT * @return: bool */ public function get($parametrs,$flag_found_rows=false){ global $MAIN_DB; $sql = $this -> sql; if ( empty($this -> sql) ){ $sql = $this -> make_sql($parametrs,$flag_found_rows); } if ( $this -> debug ){ HL::ajaxDebug($sql); } $res = $MAIN_DB -> query($sql); if ( $flag_found_rows ){ $sql = 'SELECT FOUND_ROWS()'; list($count) = $MAIN_DB -> fetch_array( $MAIN_DB -> query($sql) ); $this -> _result_count_rows = $count; }else{ $this -> _result_count_rows = $MAIN_DB -> num_rows($res); } return $this->result = $res; } /** * Получаем результат в массив * * */ public function rows(){ $rows = array(); while( $row = $this -> row() ){ $rows[] = $row; } return $rows; } public function get_count_rows(){ return $this -> _result_count_rows; } // получить алиас по названию таблицы protected function get_alias($v){ if ( empty($v) ){ sys_error('500',E_DATABASE_EMPTY_TABLE ); } if ( isset($this ->sql_tables[$v] ) ){ return $this -> sql_tables[$v]['alias']; } if ( $this -> table == $v ){ return $this -> alias; } sys_error('500',sprintf(E_DATABASE_EMPTY_ALIAS_NAME,$v)); return false; } protected function get_table(){ return $this -> table; } // подключаем таблицу для формироания left JOIN protected function include_table($table,$alias,$key,$parametrs=false,$join="LEFT JOIN"){ if ( empty($table) ){ sys_error('500',E_DATABASE_EMPTY_TABLE); return false; } if ( empty($alias) ){ sys_error('500',E_DATABASE_EMPTY_ALIAS); return false; } if ( empty($key) ){ sys_error('500',E_DATABASE_EMPTY_LINK_KEY); return false; } $this -> sql_tables[$table]=array( 'name'=>$table, 'alias'=>$alias, 'key'=>$key, 'join'=>$join ); if ( !empty($parametrs) ){ $this -> sql_parametrs[]=$parametrs; } } // название главной таблицы public function set_table($table){ if ( empty($table) ){ sys_error('500',E_DATABASE_EMPTY_TABLE); } $this -> table = $table; return TRUE; } // алиас для главной таблицы protected function set_alias($alias){ if ( empty($alias) ){ sys_error('500',E_DATABASE_EMPTY_ALIAS); } $this -> alias = $alias; return TRUE; } } ?>