diff --git a/classes/db/DB.class.php b/classes/db/DB.class.php index e8f12b7d4..c2d80a200 100644 --- a/classes/db/DB.class.php +++ b/classes/db/DB.class.php @@ -2,22 +2,22 @@ /** * @class DB * @author zero (zero@nzeo.com) - * @brief DB*의 상위 클래스 + * @brief base class of db* classes * @version 0.1 * - * XE의 DB 사용은 xml을 이용하여 이루어짐을 원칙으로 한다. - * xml의 종류에는 query xml, schema xml이 있다. - * query xml의 경우 DB::executeQuery() method를 이용하여 xml파일을 php code로 compile한 후에 실행이 된다. - * query xml은 고유한 query id를 가지며 생성은 module에서 이루어진다. + * usage of db in XE is via xml + * there are 2 types of xml - query xml, schema xml + * in case of query xml, DB::executeQuery() method compiles xml file into php code and then execute it + * query xml has unique query id, and will be created in module * - * queryid = 모듈.쿼리명 + * queryid = module_name.query_name **/ class DB { var $count_cache_path = 'files/cache/db'; - var $cond_operation = array( ///< 조건문에서 조건을 등호로 표시하는 변수 + var $cond_operation = array( ///< operations for condition 'equal' => '=', 'more' => '>=', 'excess' => '>', @@ -32,28 +32,30 @@ var $result = NULL; ///< result - var $errno = 0; ///< 에러 발생시 에러 코드 (0이면 에러가 없다고 정의) - var $errstr = ''; ///< 에러 발생시 에러 메세지 - var $query = ''; ///< 가장 최근에 수행된 query string - var $elapsed_time = 0; ///< 가장 최근에 수행된 query 의 실행시간 + var $errno = 0; ///< error code (0 means no error) + var $errstr = ''; ///< error message + var $query = ''; ///< query string of latest executed query + var $elapsed_time = 0; ///< elapsed time of latest executed query - var $transaction_started = false; ///< 트랙잭션 처리 flag + var $transaction_started = false; ///< transaction flag - var $is_connected = false; ///< DB에 접속이 되었는지에 대한 flag + var $is_connected = false; ///< is db connected - var $supported_list = array(); ///< 지원하는 DB의 종류, classes/DB/DB***.class.php 를 이용하여 동적으로 작성됨 + var $supported_list = array(); ///< list of supported db, (will be written by classes/DB/DB***.class.php) - var $cache_file = 'files/cache/queries/'; ///< query cache파일의 위치 + var $cache_file = 'files/cache/queries/'; ///< location of query cache /** - * @brief DB를 상속받는 특정 db type의 instance를 생성 후 return + * @brief returns instance of certain db type + * @param[in] $db_type type of db + * @return instance **/ function &getInstance($db_type = NULL) { if(!$db_type) $db_type = Context::getDBType(); if(!$db_type && Context::isInstalled()) return new Object(-1, 'msg_db_not_setted'); if(!$GLOBALS['__DB__']) { - $class_name = sprintf("DB%s%s", strtoupper(substr($db_type,0,1)), strtolower(substr($db_type,1))); + $class_name = sprintf("DB%s%s", strtoupper(substr($db_type, 0, 1)), strtolower(substr($db_type,1))); $class_file = sprintf("%sclasses/db/%s.class.php", _XE_PATH_, $class_name); if(!file_exists($class_file)) new Object(-1, 'msg_db_not_setted'); @@ -67,6 +69,7 @@ /** * @brief constructor + * @return none **/ function DB() { $this->count_cache_path = _XE_PATH_.$this->count_cache_path; @@ -74,7 +77,8 @@ } /** - * @brief 지원 가능한 DB 목록을 return + * @brief returns list of supported db + * @return list of supported db **/ function getSupportedList() { $oDB = new DB(); @@ -82,7 +86,8 @@ } /** - * @brief 지원 가능한 DB 목록을 return + * @brief returns list of supported db + * @return list of supported db **/ function _getSupportedList() { $db_classes_path = _XE_PATH_."classes/db/"; @@ -90,8 +95,8 @@ $supported_list = FileHandler::readDir($db_classes_path, $filter, true); sort($supported_list); - // 구해진 클래스의 객체 생성후 isSupported method를 통해 지원 여부를 판단 - for($i=0;$idb_type = $db_type; - $obj->enable = $oDB->isSupported()?true:false; + $obj->enable = $oDB->isSupported() ? true : false; $this->supported_list[] = $obj; } @@ -118,7 +123,9 @@ } /** - * @brief 지원하는 DB인지에 대한 check + * @brief check if the db_type is supported + * @param[in] $db_type type of db to check + * @return true: is supported, false: is not supported **/ function isSupported($db_type) { $supported_list = DB::getSupportedList(); @@ -126,24 +133,30 @@ } /** - * @brief 접속되었는지 return + * @brief check if is connected + * @return true: connected, false: not connected **/ function isConnected() { - return $this->is_connected?true:false; + return $this->is_connected ? true : false; } /** - * @brief 로그 남김 + * @brief start recording log + * @return none **/ function actStart($query) { - $this->setError(0,'success'); + $this->setError(0, 'success'); $this->query = $query; $this->act_start = getMicroTime(); $this->elapsed_time = 0; } + /** + * @brief finish recording log + * @return none + **/ function actFinish() { - if(!$this->query ) return; + if(!$this->query) return; $this->act_finish = getMicroTime(); $elapsed_time = $this->act_finish - $this->act_start; $this->elapsed_time = $elapsed_time; @@ -152,7 +165,7 @@ $log['query'] = $this->query; $log['elapsed_time'] = $elapsed_time; - // 에러 발생시 에러 로그를 남김 (__DEBUG_DB_OUTPUT__이 지정되어 있을경우) + // leave error log if an error occured (if __DEBUG_DB_OUTPUT__ is defined) if($this->isError()) { $log['result'] = 'Failed'; $log['errno'] = $this->errno; @@ -173,7 +186,7 @@ } $GLOBALS['__db_queries__'][] = $log; - // __LOG_SLOW_QUERY__ 가 정해져 있다면 시간 체크후 쿼리 로그 남김 + // if __LOG_SLOW_QUERY__ if defined, check elapsed time and leave query log if(__LOG_SLOW_QUERY__>0 && $elapsed_time > __LOG_SLOW_QUERY__) { $buff = ''; $log_file = _XE_PATH_.'files/_db_slow_query.php'; @@ -181,7 +194,7 @@ $buff = ''."\n"; } $buff .= sprintf("%s\t%s\n\t%0.6f sec\n\n", date("Y-m-h H:i"), $this->query, $elapsed_time); - if($fp = fopen($log_file,'a')) { + if($fp = fopen($log_file, 'a')) { fwrite($fp, $buff); fclose($fp); } @@ -190,7 +203,10 @@ } /** - * @brief 에러발생시 에러 메세지를 남기고 debug 모드일때는 GLOBALS 변수에 에러 로깅 + * @brief set error + * @param[in] $errno error code + * @param[in] $errstr error message + * @return none **/ function setError($errno = 0, $errstr = 'success') { $this->errno = $errno; @@ -198,14 +214,16 @@ } /** - * @brief 오류가 발생하였는지 return + * @brief check if an error occured + * @return true: error, false: no error **/ function isError() { - return $this->errno===0?false:true; + return $this->errno===0 ? false : true; } /** - * @brief 에러결과를 Object 객체로 return + * @brief returns object of error info + * @return object of error **/ function getError() { return new Object($this->errno, $this->errstr); @@ -213,19 +231,20 @@ /** * @brief query xml 파일을 실행하여 결과를 return - * - * query_id = module.queryname - * query_id에 해당하는 xml문(or 캐싱파일)을 찾아서 컴파일 후 실행 + * @param[in] $query_id query id (module.queryname + * @param[in] $args arguments for query + * @return result of query + * @remarks this function finds xml file or cache file of $query_id, compiles it and then execute it **/ function executeQuery($query_id, $args = NULL) { if(!$query_id) return new Object(-1, 'msg_invalid_queryid'); $id_args = explode('.', $query_id); - if(count($id_args)==2) { + if(count($id_args) == 2) { $target = 'modules'; $module = $id_args[0]; $id = $id_args[1]; - } elseif(count($id_args)==3) { + } elseif(count($id_args) == 3) { $target = $id_args[0]; if(!in_array($target, array('addons','widgets'))) return; $module = $id_args[1]; @@ -236,37 +255,45 @@ $xml_file = sprintf('%s%s/%s/queries/%s.xml', _XE_PATH_, $target, $module, $id); if(!file_exists($xml_file)) return new Object(-1, 'msg_invalid_queryid'); - // 캐쉬파일을 찾아 본다 - $cache_file = $this->checkQueryCacheFile($query_id,$xml_file); + // look for cache file + $cache_file = $this->checkQueryCacheFile($query_id, $xml_file); - // 쿼리를 실행한다 + // execute query return $this->_executeQuery($cache_file, $args, $query_id); } /** - * @brief 캐쉬파일을 찾아 본다 - * + * @brief look for cache file + * @param[in] $query_id query id for finding + * @param[in] $xml_file original xml query file + * @return cache file **/ function checkQueryCacheFile($query_id,$xml_file){ - // 일단 cache 파일을 찾아본다 + // first try finding cache file $cache_file = sprintf('%s%s%s.cache.php', _XE_PATH_, $this->cache_file, $query_id); + if(file_exists($cache_file)) $cache_time = filemtime($cache_file); else $cache_time = -1; - // 캐시 파일이 없거나 시간 비교하여 최근것이 아니면 원본 쿼리 xml파일을 찾아서 파싱을 한다 - if($cache_timeparse($query_id, $xml_file, $cache_file); } + return $cache_file; } /** - * @brief 쿼리문을 실행하고 결과를 return한다 + * @brief execute query and return the result + * @param[in] $cache_file cache file of query + * @param[in] $source_args arguments for query + * @param[in] $query_id query id + * @return result of query **/ function _executeQuery($cache_file, $source_args, $query_id) { global $lang; @@ -277,10 +304,10 @@ $output = @include($cache_file); - if( (is_a($output, 'Object')||is_subclass_of($output,'Object'))&&!$output->toBool()) return $output; + if( (is_a($output, 'Object') || is_subclass_of($output, 'Object')) && !$output->toBool()) return $output; $output->_tables = ($output->_tables && is_array($output->_tables)) ? $output->_tables : array(); - // action값에 따라서 쿼리 생성으로 돌입 + // execute appropriate query switch($output->action) { case 'insert' : $this->resetCountCache($output->tables); @@ -302,14 +329,18 @@ if($this->errno != 0 ) $output = new Object($this->errno, $this->errstr); else if(!is_a($output, 'Object') && !is_subclass_of($output, 'Object')) $output = new Object(); $output->add('_query', $this->query); - $output->add('_elapsed_time', sprintf("%0.5f",$this->elapsed_time)); + $output->add('_elapsed_time', sprintf("%0.5f", $this->elapsed_time)); return $output; } /** - * @brief $val을 $filter_type으로 검사 - * XmlQueryParser에서 사용하도록 함 + * @brief check $val with $filter_type + * @param[in] $key key value + * @param[in] $val value of $key + * @param[in] $filter_type type of filter to check $val + * @return object + * @remarks this function is to be used from XmlQueryParser **/ function checkFilter($key, $val, $filter_type) { global $lang; @@ -317,24 +348,24 @@ switch($filter_type) { case 'email' : case 'email_address' : - if(!preg_match('/^[_0-9a-z-]+(\.[_0-9a-z-]+)*@[0-9a-z-]+(\.[0-9a-z-]+)*$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_email, $lang->{$key}?$lang->{$key}:$key)); + if(!preg_match('/^[_0-9a-z-]+(\.[_0-9a-z-]+)*@[0-9a-z-]+(\.[0-9a-z-]+)*$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_email, $lang->{$key} ? $lang->{$key} : $key)); break; case 'homepage' : - if(!preg_match('/^(http|https)+(:\/\/)+[0-9a-z_-]+\.[^ ]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_homepage, $lang->{$key}?$lang->{$key}:$key)); + if(!preg_match('/^(http|https)+(:\/\/)+[0-9a-z_-]+\.[^ ]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_homepage, $lang->{$key} ? $lang->{$key} : $key)); break; case 'userid' : case 'user_id' : - if(!preg_match('/^[a-zA-Z]+([_0-9a-zA-Z]+)*$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_userid, $lang->{$key}?$lang->{$key}:$key)); + if(!preg_match('/^[a-zA-Z]+([_0-9a-zA-Z]+)*$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_userid, $lang->{$key} ? $lang->{$key} : $key)); break; case 'number' : case 'numbers' : - if(!preg_match('/^(-?)[0-9,]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_number, $lang->{$key}?$lang->{$key}:$key)); + if(!preg_match('/^(-?)[0-9,]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_number, $lang->{$key} ? $lang->{$key} : $key)); break; case 'alpha' : - if(!preg_match('/^[a-z]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_alpha, $lang->{$key}?$lang->{$key}:$key)); + if(!preg_match('/^[a-z]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_alpha, $lang->{$key} ? $lang->{$key} : $key)); break; case 'alpha_number' : - if(!preg_match('/^[0-9a-z]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_alpha_number, $lang->{$key}?$lang->{$key}:$key)); + if(!preg_match('/^[0-9a-z]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_alpha_number, $lang->{$key} ? $lang->{$key} : $key)); break; } @@ -342,32 +373,41 @@ } /** - * @brief 컬럼의 타입을 구해옴 - * 컬럼의 경우 a.b 와 같이 되어 있는 경우가 있어서 별도 함수가 필요 + * @brief returns type of column + * @param[in] $column_type_list list of column type + * @param[in] $name name of column type + * @return column type of $name + * @remarks columns are usually like a.b, so it needs another function **/ function getColumnType($column_type_list, $name) { - if(strpos($name,'.')===false) return $column_type_list[$name]; - list($prefix, $name) = explode('.',$name); + if(strpos($name, '.') === false) return $column_type_list[$name]; + list($prefix, $name) = explode('.', $name); return $column_type_list[$name]; } /** - * @brief 이름, 값, operation, type으로 값을 변경 - * like, like_prefix의 경우 value자체가 변경됨 - * type == number가 아니면 addQuotes()를 하고 ' ' 로 묶음 + * @brief returns the value of condition + * @param[in] $name name of condition + * @param[in] $value value of condition + * @param[in] $operation operation this is used in condition + * @param[in] $type type of condition + * @param[in] $column_type type of column + * @return well modified $value + * @remarks if $operation is like or like_prefix, $value itself will be modified + * @remarks if $type is not 'number', call addQuotes() and wrap with ' ' **/ function getConditionValue($name, $value, $operation, $type, $column_type) { if($type == 'number') { - if(strpos($value,',')===false && strpos($value,'(')===false) return (int)$value; + if(strpos($value, ',') === false && strpos($value, '(') === false) return (int)$value; return $value; } - if(strpos($name,'.')!==false&&strpos($value,'.')!==false) { - list($table_name, $column_name) = explode('.',$value); + if(strpos($name, '.') !== false && strpos($value, '.') !== false) { + list($table_name, $column_name) = explode('.', $value); if($column_type[$column_name]) return $value; } - $value = preg_replace('/(^\'|\'$){1}/','',$value); + $value = preg_replace('/(^\'|\'$){1}/', '', $value); switch($operation) { case 'like_prefix' : @@ -391,8 +431,11 @@ } /** - * @brief 이름, 값, operation으로 조건절 작성 - * 조건절을 완성하기 위해 세부 조건절 마다 정리를 해서 return + * @brief returns part of condition + * @param[in] $name name of condition + * @param[in] $value value of condition + * @param[in] $operation operation that is used in condition + * @return detail condition **/ function getConditionPart($name, $value, $operation) { switch($operation) { @@ -407,7 +450,7 @@ case 'in' : case 'notin' : case 'notequal' : - // 변수가 세팅되지 않고, 문자열이나 숫자형이 아니면 리턴 + // if variable is not set or is not string or number, return if(!isset($value)) return; if($value === '') return; if(!in_array(gettype($value), array('string', 'integer'))) return; @@ -453,7 +496,9 @@ } /** - * @brief condition key를 return + * @brief returns condition key + * @param[in] $output result of query + * @return array of conditions of $output **/ function getConditionList($output) { $conditions = array(); @@ -471,7 +516,10 @@ } /** - * @brief 카운터 캐시 데이터 얻어오기 + * @brief returns counter cache data + * @param[in] $tables tables to get data + * @param[in] $condition condition to get data + * @return count of cache data **/ function getCountCache($tables, $condition) { return false; @@ -502,7 +550,11 @@ } /** - * @brief 카운터 캐시 데이터 저장 + * @brief save counter cache data + * @param[in] $tables tables to save data + * @param[in] $condition condition to save data + * @param[in] $count count of cache data to save + * @return none **/ function putCountCache($tables, $condition, $count = 0) { return false; @@ -523,7 +575,9 @@ } /** - * @brief 카운터 캐시 리셋 + * @brief reset counter cache data + * @param[in] $tables tables to reset cache data + * @return true: success, false: failed **/ function resetCountCache($tables) { return false; @@ -534,14 +588,19 @@ foreach($tables as $alias => $table) { $filename = sprintf('%s/cache.%s%s', $this->count_cache_path, $this->prefix, $table); FileHandler::removeFile($filename); - FileHandler::writeFile( $filename, '' ); + FileHandler::writeFile($filename, ''); } return true; } + /** + * @brief returns supported database list + * @return list of supported database + **/ function getSupportedDatabase(){ $result = array(); + if(function_exists('mysql_connect')) $result[] = 'MySQL'; if(function_exists('cubrid_connect')) $result[] = 'Cubrid'; if(function_exists('ibase_connect')) $result[] = 'FireBird'; @@ -549,6 +608,7 @@ if(function_exists('sqlite_open')) $result[] = 'sqlite2'; if(function_exists('mssql_connect')) $result[] = 'MSSQL'; if(function_exists('PDO')) $result[] = 'sqlite3(PDO)'; + return $result; }