diff --git a/classes/db/DB.class.php b/classes/db/DB.class.php index 5726ceda7..bab12766c 100644 --- a/classes/db/DB.class.php +++ b/classes/db/DB.class.php @@ -357,13 +357,32 @@ if($source_args) $args = @clone($source_args); - $output = @include($cache_file); + require_once(_XE_PATH_.'classes/xml/xmlquery/DBParser.class.php'); + require_once(_XE_PATH_.'classes/xml/xmlquery/argument/Argument.class.php'); + require_once(_XE_PATH_.'classes/xml/xmlquery/argument/SortArgument.class.php'); + require_once(_XE_PATH_.'classes/xml/xmlquery/argument/ConditionArgument.class.php'); + require_once(_XE_PATH_.'classes/xml/XmlQueryParser.class.php'); + require_once(_XE_PATH_.'classes/db/queryparts/expression/Expression.class.php'); + require_once(_XE_PATH_.'classes/db/queryparts/expression/SelectExpression.class.php'); + require_once(_XE_PATH_.'classes/db/queryparts/expression/InsertExpression.class.php'); + require_once(_XE_PATH_.'classes/db/queryparts/expression/UpdateExpression.class.php'); + require_once(_XE_PATH_.'classes/db/queryparts/table/Table.class.php'); + require_once(_XE_PATH_.'classes/db/queryparts/table/JoinTable.class.php'); + require_once(_XE_PATH_.'classes/db/queryparts/condition/ConditionGroup.class.php'); + require_once(_XE_PATH_.'classes/db/queryparts/condition/Condition.class.php'); + require_once(_XE_PATH_.'classes/db/queryparts/expression/StarExpression.class.php'); + require_once(_XE_PATH_.'classes/db/queryparts/order/OrderByColumn.class.php'); + require_once(_XE_PATH_.'classes/db/queryparts/limit/Limit.class.php'); + require_once(_XE_PATH_.'classes/db/queryparts/Query.class.php'); + require_once(_XE_PATH_.'classes/db/queryparts/Subquery.class.php'); + + + $output = include($cache_file); 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(); - + // execute appropriate query - switch($output->action) { + switch($output->getAction()) { case 'insert' : $this->resetCountCache($output->tables); $output = $this->_executeInsertAct($output); @@ -377,11 +396,12 @@ $output = $this->_executeDeleteAct($output); break; case 'select' : + // TODO Add property for Query object for Arg_columns $output->arg_columns = is_array($arg_columns)?$arg_columns:array(); $output = $this->_executeSelectAct($output); break; } - + if($this->isError()) $output = $this->getError(); else if(!is_a($output, 'Object') && !is_subclass_of($output, 'Object')) $output = new Object(); $output->add('_query', $this->query); @@ -390,232 +410,6 @@ return $output; } - /** - * @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; - - 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)); - 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)); - 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)); - break; - case 'number' : - case 'numbers' : - if(is_array($val)) $val = join(',', $val); - if(!preg_match('/^(-?)[0-9]+(,\-?[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)); - 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)); - break; - } - - return new Object(); - } - - /** - * @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); - return $column_type_list[$name]; - } - - /** - * @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(!in_array($operation,array('in','notin','between')) && $type == 'number') { - if(is_array($value)){ - $value = join(',',$value); - } - if(strpos($value, ',') === false && strpos($value, '(') === false) return (int)$value; - return $value; - } - - if(!is_array($value) && strpos($name, '.') !== false && strpos($value, '.') !== false) { - list($table_name, $column_name) = explode('.', $value); - if($column_type[$column_name]) return $value; - } - - switch($operation) { - case 'like_prefix' : - if(!is_array($value)) $value = preg_replace('/(^\'|\'$){1}/', '', $value); - $value = $value.'%'; - break; - case 'like_tail' : - if(!is_array($value)) $value = preg_replace('/(^\'|\'$){1}/', '', $value); - $value = '%'.$value; - break; - case 'like' : - if(!is_array($value)) $value = preg_replace('/(^\'|\'$){1}/', '', $value); - $value = '%'.$value.'%'; - break; - case 'notin' : - if(is_array($value)) - { - $value = $this->addQuotesArray($value); - if($type=='number') return join(',',$value); - else return "'". join("','",$value)."'"; - } - else - { - return $value; - } - break; - case 'in' : - if(is_array($value)) - { - $value = $this->addQuotesArray($value); - if($type=='number') return join(',',$value); - else return "'". join("','",$value)."'"; - } - else - { - return $value; - } - break; - case 'between' : - if(!is_array($value)) $value = array($value); - $value = $this->addQuotesArray($value); - if($type!='number') - { - foreach($value as $k=>$v) - { - $value[$k] = "'".$v."'"; - } - } - - return $value; - break; - default: - if(!is_array($value)) $value = preg_replace('/(^\'|\'$){1}/', '', $value); - } - - return "'".$this->addQuotes($value)."'"; - } - - /** - * @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) { - case 'equal' : - case 'more' : - case 'excess' : - case 'less' : - case 'below' : - case 'like_tail' : - case 'like_prefix' : - case 'like' : - 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; - break; - case 'between' : - if(!is_array($value)) return; - if(count($value)!=2) return; - - } - - switch($operation) { - case 'equal' : - return $name.' = '.$value; - break; - case 'more' : - return $name.' >= '.$value; - break; - case 'excess' : - return $name.' > '.$value; - break; - case 'less' : - return $name.' <= '.$value; - break; - case 'below' : - return $name.' < '.$value; - break; - case 'like_tail' : - case 'like_prefix' : - case 'like' : - return $name.' like '.$value; - break; - case 'in' : - return $name.' in ('.$value.')'; - break; - case 'notin' : - return $name.' not in ('.$value.')'; - break; - case 'notequal' : - return $name.' <> '.$value; - break; - case 'notnull' : - return $name.' is not null'; - break; - case 'null' : - return $name.' is null'; - break; - case 'between' : - return $name.' between ' . $value[0] . ' and ' . $value[1]; - break; - } - } - - /** - * @brief returns condition key - * @param[in] $output result of query - * @return array of conditions of $output - **/ - function getConditionList($output) { - $conditions = array(); - if(count($output->conditions)) { - foreach($output->conditions as $key => $val) { - if($val['condition']) { - foreach($val['condition'] as $k => $v) { - $conditions[] = $v['column']; - } - } - } - } - - return $conditions; - } /** * @brief returns counter cache data @@ -720,30 +514,260 @@ $this->_query($query); } - function addQuotesArray($arr) - { - if(is_array($arr)) - { - foreach($arr as $k => $v) - { - $arr[$k] = $this->addQuotes($v); - } - } - else - { - $arr = $this->addQuotes($arr); - } + function getSelectSql($query, $with_values = true){ + $select = $query->getSelectString($with_values); + if($select == '') return new Object(-1, "Invalid query"); + $select = 'SELECT ' .$select; - return $arr; + $from = $query->getFromString($with_values); + if($from == '') return new Object(-1, "Invalid query"); + $from = ' FROM '.$from; + + $where = $query->getWhereString($with_values); + if($where != '') $where = ' WHERE ' . $where; + + $groupBy = $query->getGroupByString(); + if($groupBy != '') $groupBy = ' GROUP BY ' . $groupBy; + + $orderBy = $query->getOrderByString(); + if($orderBy != '') $orderBy = ' ORDER BY ' . $orderBy; + + $limit = $query->getLimitString(); + if($limit != '') $limit = ' LIMIT ' . $limit; + + return $select . ' ' . $from . ' ' . $where . ' ' . $groupBy . ' ' . $orderBy . ' ' . $limit; } - /** - * @brief Just like numbers, and operations needed to remove the rest + function getDeleteSql($query, $with_values = true){ + $sql = 'DELETE '; + + // TODO Add support for deleting based on alias, for both simple FROM and multi table join FROM clause + $tables = $query->getTables(); + + $sql .= $tables[0]->getAlias(); + + $from = $query->getFromString($with_values); + if($from == '') return new Object(-1, "Invalid query"); + $sql .= ' FROM '.$from; + + $where = $query->getWhereString($with_values); + if($where != '') $sql .= ' WHERE ' . $where; + + return $sql; + } + + function getUpdateSql($query, $with_values = true){ + $columnsList = $query->getSelectString($with_values); + if($columnsList == '') return new Object(-1, "Invalid query"); + + $tableName = $query->getFirstTableName(); + if($tableName == '') return new Object(-1, "Invalid query"); + + $where = $query->getWhereString($with_values); + if($where != '') $where = ' WHERE ' . $where; + + return "UPDATE $tableName SET $columnsList ".$where; + } + + function getInsertSql($query, $with_values = true){ + $tableName = $query->getFirstTableName(); + $values = $query->getInsertString($with_values); + + return "INSERT INTO $tableName \n $values"; + } + + // HACK This is needed because on installation, the XmlQueryParer is used without any configured database + // TODO Change this or make sure the query cache files created before db.config exists are deleted + function getParser(){ + return new DBParser('"'); + } + + + // TO BE REMOVED - Used for query compare + /** + * @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 _filterNumber(&$value) - { - $value = preg_replace('/[^\d\w\+\-\*\/\.\(\)]/', '', $value); - if(!$value) $value = 0; - } + function getColumnType($column_type_list, $name) { + if(strpos($name, '.') === false) return $column_type_list[$name]; + list($prefix, $name) = explode('.', $name); + return $column_type_list[$name]; + } + /** + * @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(!in_array($operation,array('in','notin','between')) && $type == 'number') { + if(is_array($value)){ + $value = join(',',$value); + } + if(strpos($value, ',') === false && strpos($value, '(') === false) return (int)$value; + return $value; + } + + if(!is_array($value) && strpos($name, '.') !== false && strpos($value, '.') !== false) { + list($table_name, $column_name) = explode('.', $value); + if($column_type[$column_name]) return $value; + } + + switch($operation) { + case 'like_prefix' : + if(!is_array($value)) $value = preg_replace('/(^\'|\'$){1}/', '', $value); + $value = $value.'%'; + break; + case 'like_tail' : + if(!is_array($value)) $value = preg_replace('/(^\'|\'$){1}/', '', $value); + $value = '%'.$value; + break; + case 'like' : + if(!is_array($value)) $value = preg_replace('/(^\'|\'$){1}/', '', $value); + $value = '%'.$value.'%'; + break; + case 'notin' : + if(is_array($value)) + { + $value = $this->addQuotesArray($value); + if($type=='number') return join(',',$value); + else return "'". join("','",$value)."'"; + } + else + { + return $value; + } + break; + case 'in' : + if(is_array($value)) + { + $value = $this->addQuotesArray($value); + if($type=='number') return join(',',$value); + else return "'". join("','",$value)."'"; + } + else + { + return $value; + } + break; + case 'between' : + if(!is_array($value)) $value = array($value); + $value = $this->addQuotesArray($value); + if($type!='number') + { + foreach($value as $k=>$v) + { + $value[$k] = "'".$v."'"; + } + } + + return $value; + break; + default: + if(!is_array($value)) $value = preg_replace('/(^\'|\'$){1}/', '', $value); + } + + return "'".$this->addQuotes($value)."'"; + } + /** + * @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) { + case 'equal' : + case 'more' : + case 'excess' : + case 'less' : + case 'below' : + case 'like_tail' : + case 'like_prefix' : + case 'like' : + 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; + break; + case 'between' : + if(!is_array($value)) return; + if(count($value)!=2) return; + + } + + switch($operation) { + case 'equal' : + return $name.' = '.$value; + break; + case 'more' : + return $name.' >= '.$value; + break; + case 'excess' : + return $name.' > '.$value; + break; + case 'less' : + return $name.' <= '.$value; + break; + case 'below' : + return $name.' < '.$value; + break; + case 'like_tail' : + case 'like_prefix' : + case 'like' : + return $name.' like '.$value; + break; + case 'in' : + return $name.' in ('.$value.')'; + break; + case 'notin' : + return $name.' not in ('.$value.')'; + break; + case 'notequal' : + return $name.' <> '.$value; + break; + case 'notnull' : + return $name.' is not null'; + break; + case 'null' : + return $name.' is null'; + break; + case 'between' : + return $name.' between ' . $value[0] . ' and ' . $value[1]; + break; + } + } + + /** + * @brief returns condition key + * @param[in] $output result of query + * @return array of conditions of $output + **/ + function getConditionList($output) { + $conditions = array(); + if(count($output->conditions)) { + foreach($output->conditions as $key => $val) { + if($val['condition']) { + foreach($val['condition'] as $k => $v) { + $conditions[] = $v['column']; + } + } + } + } + + return $conditions; + } } ?> diff --git a/classes/db/DBCubrid.class.php b/classes/db/DBCubrid.class.php index 06312e12b..6e85d4209 100644 --- a/classes/db/DBCubrid.class.php +++ b/classes/db/DBCubrid.class.php @@ -51,7 +51,7 @@ $this->_setDBInfo(); $this->_connect(); } - + /** * @brief create an instance of this class */ @@ -190,7 +190,7 @@ { if (!$query || !$this->isConnected ()) return; - // Notify to start a query execution + // Notify to start a query execution $this->actStart ($query); // Execute the query @@ -207,16 +207,18 @@ $this->actFinish (); // Return the result - return $result; + return $result; } /** * @brief Fetch the result **/ - function _fetch($result) + function _fetch($result, $arrayIndexEndValue = NULL) { if (!$this->isConnected() || $this->isError() || !$result) return; + // TODO Improve this piece of code + // This code trims values from char type columns $col_types = cubrid_column_types ($result); $col_names = cubrid_column_names ($result); $max = count ($col_types); @@ -234,14 +236,16 @@ } } - $output[] = $tmp; + if($arrayIndexEndValue) $output[$arrayIndexEndValue--] = $tmp; + else $output[] = $tmp; } unset ($char_type_fields); if ($result) cubrid_close_request($result); - if (count ($output) == 1) return $output[0]; + if($arrayIndexEndValue !== null && count($output) == 1) return $output[$arrayIndexEndValue + 1]; + else if (count($output) == 1) return $output[0]; return $output; } @@ -445,7 +449,6 @@ if (!file_exists ($file_name)) return; // read xml file $buff = FileHandler::readFile ($file_name); - return $this->_createTable ($buff); } @@ -561,132 +564,19 @@ } } - /** - * @brief return the condition - **/ - function getCondition ($output) - { - if (!$output->conditions) return; - $condition = $this->_getCondition ($output->conditions, $output->column_type, $output); - if ($condition) $condition = ' where '.$condition; - return $condition; - } - function _getCondition ($conditions, $column_type, &$output) - { - $condition = ''; - - foreach ($conditions as $val) { - $sub_condition = ''; - - foreach ($val['condition'] as $v) { - if (!isset ($v['value'])) continue; - if ($v['value'] === '') continue; - if(!in_array(gettype($v['value']), array('string', 'integer', 'double', 'array'))) continue; - - $name = $v['column']; - $operation = $v['operation']; - $value = $v['value']; - $type = $this->getColumnType ($column_type, $name); - $pipe = $v['pipe']; - $value = $this->getConditionValue ($name, $value, $operation, $type, $column_type); - - if (!$value) { - $value = $v['value']; - if (strpos ($value, '(')) { - $valuetmp = $value; - } - elseif (strpos ($value, ".") === false) { - $valuetmp = $value; - } - else { - $valuetmp = '"'.str_replace('.', '"."', $value).'"'; - } - } - else { - $tmp = explode('.',$value); - - if (count($tmp)==2) { - $table = $tmp[0]; - $column = $tmp[1]; - - if ($column_type[$column] && (in_array ($table, $output->tables) || - array_key_exists($table, $output->tables))) { - $valuetmp = sprintf('"%s"."%s"', $table, $column); - } - else { - $valuetmp = $value; - } - } - else { - $valuetmp = $value; - } - } - - if (strpos ($name, '(') > 0) { - $nametmp = $name; - } - elseif (strpos ($name, ".") === false) { - $nametmp = '"'.$name.'"'; - } - else { - $nametmp = '"'.str_replace('.', '"."', $name).'"'; - } - $str = $this->getConditionPart ($nametmp, $valuetmp, $operation); - if ($sub_condition) $sub_condition .= ' '.$pipe.' '; - $sub_condition .= $str; - } - - if ($sub_condition) { - if ($condition && $val['pipe']) { - $condition .= ' '.$val['pipe'].' '; - } - $condition .= '('.$sub_condition.')'; - } - } - - return $condition; - } /** * @brief handles insertAct **/ - function _executeInsertAct ($output) + function _executeInsertAct($queryObject) { - // tables - foreach ($output->tables as $val) { - $table_list[] = '"'.$this->prefix.$val.'"'; - } - - // columns - foreach ($output->columns as $key => $val) { - $name = $val['name']; - $value = $val['value']; - //if ($this->getColumnType ($output->column_type, $name) != 'number') - if ($output->column_type[$name] != 'number') { - if (!is_null($value)) { - $value = "'" . $this->addQuotes($value) ."'"; - } - else { - if ($val['notnull']=='notnull') { - $value = "''"; - } - else { - //$value = 'null'; - $value = "''"; - } - } - } - else $this->_filterNumber($value); - - $column_list[] = '"'.$name.'"'; - $value_list[] = $value; - } - - $query = sprintf ("insert into %s (%s) values (%s);", implode(',', $table_list), implode(',', $column_list), implode(',', $value_list)); + $query = $this->getInsertSql($queryObject); + if(is_a($query, 'Object')) return; $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf (' '.$this->comment_syntax, $this->query_id):''; + $result = $this->_query ($query); if ($result && !$this->transaction_started) { @cubrid_commit ($this->fd); @@ -698,109 +588,29 @@ /** * @brief handles updateAct **/ - function _executeUpdateAct ($output) + function _executeUpdateAct($queryObject) { - // tables - foreach ($output->tables as $key => $val) { - $table_list[] = '"'.$this->prefix.$val.'" as "'.$key.'"'; - } + $query = $this->getUpdateSql($queryObject); + if(is_a($query, 'Object')) return; - $check_click_count = true; + $result = $this->_query($query); - // columns - foreach ($output->columns as $key => $val) { - if (!isset ($val['value'])) continue; - $name = $val['name']; - $value = $val['value']; - - if (substr ($value, -2) != '+1' || $output->column_type[$name] != 'number') { - $check_click_count = false; - } - - for ($i = 0; $i < $key; $i++) { - // not allows to define the same property repeatedly in a single query in CUBRID - if ($output->columns[$i]['name'] == $name) break; - } - if ($i < $key) continue; // ignore the rest of properties if duplicated property found - - if (strpos ($name, '.') !== false && strpos ($value, '.') !== false) { - $column_list[] = $name.' = '.$value; - } - else { - if ($output->column_type[$name] != 'number') { - $check_column = false; - $value = "'".$this->addQuotes ($value)."'"; - } - else $this->_filterNumber($value); - - $column_list[] = sprintf ("\"%s\" = %s", $name, $value); - } - } - - // conditional clause - $condition = $this->getCondition ($output); - - $check_click_count_condition = false; - if ($check_click_count) { - foreach ($output->conditions as $val) { - if ($val['pipe'] == 'or') { - $check_click_count_condition = false; - break; - } - - foreach ($val['condition'] as $v) { - if ($v['operation'] == 'equal') { - $check_click_count_condition = true; - } - else { - if ($v['operation'] == 'in' && !strpos ($v['value'], ',')) { - $check_click_count_condition = true; - } - else { - $check_click_count_condition = false; - } - } - - if ($v['pipe'] == 'or') { - $check_click_count_condition = false; - break; - } - } - } - } - - if ($check_click_count&& $check_click_count_condition && count ($output->tables) == 1 && count ($output->conditions) > 0 && count ($output->groups) == 0 && count ($output->order) == 0) { - foreach ($output->columns as $v) { - $incr_columns[] = 'incr("'.$v['name'].'")'; - } - - $query = sprintf ('select %s from %s %s', join (',', $incr_columns), implode(',', $table_list), $condition); - } - else { - $query = sprintf ("update %s set %s %s", implode (',', $table_list), implode (',', $column_list), $condition); - } - - $result = $this->_query ($query); if ($result && !$this->transaction_started) @cubrid_commit ($this->fd); return $result; } + /** * @brief handles deleteAct **/ - function _executeDeleteAct ($output) + function _executeDeleteAct($queryObject) { - // tables - foreach ($output->tables as $val) { - $table_list[] = '"'.$this->prefix.$val.'"'; - } + $query = $this->getDeleteSql($queryObject); + if(is_a($query, 'Object')) return; - // Conditional clauses - $condition = $this->getCondition ($output); - - $query = sprintf ("delete from %s %s", implode (',',$table_list), $condition); $result = $this->_query ($query); + if ($result && !$this->transaction_started) @cubrid_commit ($this->fd); return $result; @@ -810,454 +620,73 @@ * @brief Handle selectAct * * to get a specific page list easily in select statement,\n - * a method, navigation, is used + * a method, navigation, is used **/ - function _executeSelectAct ($output) - { - // tables - $table_list = array (); - foreach ($output->tables as $key => $val) { - $table_list[] = '"'.$this->prefix.$val.'" as "'.$key.'"'; - } - $left_join = array (); - // why??? - $left_tables = (array) $output->left_tables; + // TODO Rewrite with Query object as input + function _executeSelectAct($queryObject){ + $query = $this->getSelectSql($queryObject); + if(is_a($query, 'Object')) return; - foreach ($left_tables as $key => $val) { - $condition = $this->_getCondition ($output->left_conditions[$key], $output->column_type, $output); - if ($condition) { - $left_join[] = $val.' "'.$this->prefix.$output->_tables[$key]. '" "'.$key.'" on ('.$condition.')'; - } - } - - $click_count = array(); - if(!$output->columns){ - $output->columns = array(array('name'=>'*')); - } - - $column_list = array (); - foreach ($output->columns as $key => $val) { - $name = $val['name']; - - $click_count = '%s'; - if ($val['click_count'] && count ($output->conditions) > 0) { - $click_count = 'incr(%s)'; - } - - $alias = $val['alias'] ? sprintf ('"%s"', $val['alias']) : null; - $_alias = $val['alias']; - - if ($name == '*') { - $column_list[] = $name; - } - elseif (strpos ($name, '.') === false && strpos ($name, '(') === false) { - $name = sprintf ($click_count,$name); - if ($alias) { - $column_list[$alias] = sprintf('"%s" as %s', $name, $alias); - } - else { - $column_list[] = sprintf ('"%s"', $name); - } - } - else { - if (strpos ($name, '.') != false) { - list ($prefix, $name) = explode('.', $name); - if (($now_matchs = preg_match_all ("/\(/", $prefix, $xtmp)) > 0) { - if ($now_matchs == 1) { - $tmpval = explode ("(", $prefix); - $tmpval[1] = sprintf ('"%s"', $tmpval[1]); - $prefix = implode ("(", $tmpval); - $tmpval = explode (")", $name); - $tmpval[0] = sprintf ('"%s"', $tmpval[0]); - $name = implode (")", $tmpval); - } - } - else { - $prefix = sprintf ('"%s"', $prefix); - $name = ($name == '*') ? $name : sprintf('"%s"',$name); - } - $xtmp = null; - $now_matchs = null; - if($alias) $column_list[$_alias] = sprintf ($click_count, sprintf ('%s.%s', $prefix, $name)) . ($alias ? sprintf (' as %s',$alias) : ''); - else $column_list[] = sprintf ($click_count, sprintf ('%s.%s', $prefix, $name)); - } - elseif (($now_matchs = preg_match_all ("/\(/", $name, $xtmp)) > 0) { - if ($now_matchs == 1 && preg_match ("/[a-zA-Z0-9]*\(\*\)/", $name) < 1) { - $open_pos = strpos ($name, "("); - $close_pos = strpos ($name, ")"); - - if (preg_match ("/,/", $name)) { - $tmp_func_name = sprintf ('%s', substr ($name, 0, $open_pos)); - $tmp_params = sprintf ('%s', substr ($name, $open_pos + 1, $close_pos - $open_pos - 1)); - $tmpval = null; - $tmpval = explode (',', $tmp_params); - - foreach ($tmpval as $tmp_param) { - $tmp_param_list[] = (!is_numeric ($tmp_param)) ? sprintf ('"%s"', $tmp_param) : $tmp_param; - } - - $tmpval = implode (',', $tmp_param_list); - $name = sprintf ('%s(%s)', $tmp_func_name, $tmpval); - } - else { - $name = sprintf ('%s("%s")', substr ($name, 0, $open_pos), substr ($name, $open_pos + 1, $close_pos - $open_pos - 1)); - } - } - - if($alias) $column_list[$_alias] = sprintf ($click_count, $name). ($alias ? sprintf (' as %s', $alias) : ''); - else $column_list[] = sprintf ($click_count, $name); - } - else { - if($alias) $column_list[$_alias] = sprintf($click_count, $name). ($alias ? sprintf(' as %s',$alias) : ''); - else $column_list[] = sprintf($click_count, $name); - } - } - $columns = implode (',', $column_list); - } - - $condition = $this->getCondition ($output); - - $output->column_list = $column_list; - if ($output->list_count && $output->page) { - return ($this->_getNavigationData($table_list, $columns, $left_join, $condition, $output)); - } - - if ($output->order) { - $conditions = $this->getConditionList($output); - //if(in_array('list_order', $conditions) || in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if ($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - //} - } - - - if (count ($output->groups)) { - foreach ($output->groups as $key => $value) { - if (strpos ($value, '.')) { - $tmp = explode ('.', $value); - $tmp[0] = sprintf ('"%s"', $tmp[0]); - $tmp[1] = sprintf ('"%s"', $tmp[1]); - $value = implode ('.', $tmp); - } - elseif (strpos ($value, '(')) { - $value = $value; - } - else { - $value = sprintf ('"%s"', $value); - } - $output->groups[$key] = $value; - - - if(count($output->arg_columns)) - { - if($column_list[$value]) $output->arg_columns[] = $column_list[$value]; - } - } - $groupby_query = sprintf ('group by %s', implode(',', $output->groups)); - } - - - // apply when using list_count - if ($output->list_count['value']) { - $start_count = 0; - $list_count = $output->list_count['value']; - - if ($output->order) { - foreach ($output->order as $val) { - if (strpos ($val[0], '.')) { - $tmpval = explode ('.', $val[0]); - $tmpval[0] = sprintf ('"%s"', $tmpval[0]); - $tmpval[1] = sprintf ('"%s"', $tmpval[1]); - $val[0] = implode ('.', $tmpval); - } - elseif (strpos ($val[0], '(')) $val[0] = $val[0]; - elseif ($val[0] == 'count') $val[0] = 'count (*)'; - else $val[0] = sprintf ('"%s"', $val[0]); - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - } - if (count($index_list)) - $orderby_query = ' order by '.implode(',', $index_list); - $orderby_query = sprintf ('%s for orderby_num() between %d and %d', $orderby_query, $start_count + 1, $list_count + $start_count); - } - else { - if (count ($output->groups)) { - $orderby_query = sprintf ('%s having groupby_num() between %d'. ' and %d', $orderby_query, $start_count + 1, $list_count + $start_count); - } - else { - if ($condition) { - $orderby_query = sprintf ('%s and inst_num() between %d'. ' and %d', $orderby_query, $start_count + 1, $list_count + $start_count); - } - else { - $orderby_query = sprintf ('%s where inst_num() between %d'. ' and %d', $orderby_query, $start_count + 1, $list_count + $start_count); - } - } - } - } - else { - if ($output->order) { - foreach ($output->order as $val) { - if (strpos ($val[0], '.')) { - $tmpval = explode ('.', $val[0]); - $tmpval[0] = sprintf ('"%s"', $tmpval[0]); - $tmpval[1] = sprintf ('"%s"', $tmpval[1]); - $val[0] = implode ('.', $tmpval); - } - elseif (strpos ($val[0], '(')) $val[0] = $val[0]; - elseif ($val[0] == 'count') $val[0] = 'count (*)'; - else $val[0] = sprintf ('"%s"', $val[0]); - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - - if(count($output->arg_columns) && $column_list[$val]) $output->arg_columns[] = $column_list[$key]; - } - - if (count ($index_list)) { - $orderby_query = ' order by '.implode(',', $index_list); - } - } - } - - - if(count($output->arg_columns)) - { - $columns = array(); - foreach($output->arg_columns as $col){ - unset($tmpCol); - $tmpCol = explode('.', $col); - if(isset($tmpCol[1])) $col = $tmpCol[1]; - - if(strpos($col,'"')===false && strpos($col,' ')==false) $col = '"'.$col.'"'; - if(isset($tmpCol[1])) $col = $tmpCol[0].'.'.$col; - - $columns[] = $col; - } - - $columns = join(',',$columns); - } - - $query = sprintf ("select %s from %s %s %s %s", $columns, implode (',',$table_list), implode (' ',$left_join), $condition, $groupby_query.$orderby_query); - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf (' '.$this->comment_syntax, $this->query_id):''; - $result = $this->_query ($query); - if ($this->isError ()) return; - $data = $this->_fetch ($result); - - $buff = new Object (); - $buff->data = $data; - - return $buff; - } - - /** - * @brief displays the current stack trace. Fetch the result - **/ - function backtrace () - { - $output = "
\n"; - $output .= "Backtrace:
\n"; - $backtrace = debug_backtrace (); - - foreach ($backtrace as $bt) { - $args = ''; - foreach ($bt['args'] as $a) { - if (!empty ($args)) { - $args .= ', '; - } - switch (gettype ($a)) { - case 'integer': - case 'double': - $args .= $a; - break; - case 'string': - $a = htmlspecialchars (substr ($a, 0, 64)). - ((strlen ($a) > 64) ? '...' : ''); - $args .= "\"$a\""; - break; - case 'array': - $args .= 'Array ('. count ($a).')'; - break; - case 'object': - $args .= 'Object ('.get_class ($a).')'; - break; - case 'resource': - $args .= 'Resource ('.strstr ($a, '#').')'; - break; - case 'boolean': - $args .= $a ? 'True' : 'False'; - break; - case 'NULL': - $args .= 'Null'; - break; - default: - $args .= 'Unknown'; - } - } - $output .= "
\n"; - $output .= "file: ".$bt['line']." - ". $bt['file']."
\n"; - $output .= "call: ".$bt['class']. $bt['type'].$bt['function'].$args."
\n"; - } - $output .= "
\n"; - return $output; - } - - /** - * @brief paginates when navigation info exists in the query xml - * - * it is convenient although its structure is not good .. -_-; - **/ - function _getNavigationData ($table_list, $columns, $left_join, $condition, $output) { - require_once (_XE_PATH_.'classes/page/PageHandler.class.php'); - - $column_list = $output->column_list; - - $count_condition = count($output->groups) ? sprintf('%s group by %s', $condition, implode(', ', $output->groups)) : $condition; - $count_query = sprintf('select count(*) as "count" from %s %s %s', implode(', ', $table_list), implode(' ', $left_join), $count_condition); - if (count($output->groups)) { - $count_query = sprintf('select count(*) as "count" from (%s) xet', $count_query); - } - - $count_query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf (' '.$this->comment_syntax, $this->query_id):''; - $result = $this->_query($count_query); - $count_output = $this->_fetch($result); - $total_count = (int)$count_output->count; - - $list_count = $output->list_count['value']; - if (!$list_count) $list_count = 20; - $page_count = $output->page_count['value']; - if (!$page_count) $page_count = 10; - $page = $output->page['value']; - if (!$page) $page = 1; - - // total pages - if ($total_count) { - $total_page = (int) (($total_count - 1) / $list_count) + 1; - } - else { - $total_page = 1; - } - - // check the page variables - if ($page > $total_page) $page = $total_page; - $start_count = ($page - 1) * $list_count; - - if ($output->order) { - $conditions = $this->getConditionList($output); - //if(in_array('list_order', $conditions) || in_array('update_order', $conditions)) { - foreach ($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - //} - } - - - if (count ($output->groups)) { - foreach ($output->groups as $key => $value) { - if (strpos ($value, '.')) { - $tmp = explode ('.', $value); - $tmp[0] = sprintf ('"%s"', $tmp[0]); - $tmp[1] = sprintf ('"%s"', $tmp[1]); - $value = implode ('.', $tmp); - } - elseif (strpos ($value, '(')) $value = $value; - else $value = sprintf ('"%s"', $value); - $output->groups[$key] = $value; - } - - $groupby_query = sprintf (' group by %s', implode (',', $output->groups)); - } - - if ($output->order) { - foreach ($output->order as $val) { - if (strpos ($val[0], '.')) { - $tmpval = explode ('.', $val[0]); - $tmpval[0] = sprintf ('"%s"', $tmpval[0]); - $tmpval[1] = sprintf ('"%s"', $tmpval[1]); - $val[0] = implode ('.', $tmpval); - } - elseif (strpos ($val[0], '(')) $val[0] = $val[0]; - elseif ($val[0] == 'count') $val[0] = 'count (*)'; - else $val[0] = sprintf ('"%s"', $val[0]); - $index_list[] = sprintf ('%s %s', $val[0], $val[1]); - } - - if (count ($index_list)) { - $orderby_query = ' order by '.implode(',', $index_list); - } - - $orderby_query = sprintf ('%s for orderby_num() between %d and %d', $orderby_query, $start_count + 1, $list_count + $start_count); - } - else { - if (count($output->groups)) { - $orderby_query = sprintf ('%s having groupby_num() between %d and %d', $orderby_query, $start_count + 1, $list_count + $start_count); - } - else { - if ($condition) { - $orderby_query = sprintf ('%s and inst_num() between %d and %d', $orderby_query, $start_count + 1, $list_count + $start_count); - } - else { - $orderby_query = sprintf('%s where inst_num() between %d and %d', $orderby_query, $start_count + 1, $list_count + $start_count); - } - } - } - - if(count($output->arg_columns)) - { - $columns = array(); - foreach($output->arg_columns as $col){ - unset($tmpCol); - $tmpCol = explode('.', $col); - if(isset($tmpCol[1])) $col = $tmpCol[1]; - - if(strpos($col,'"')===false && strpos($col,' ')==false) $col = '"'.$col.'"'; - if(isset($tmpCol[1])) $col = $tmpCol[0].'.'.$col; - - $columns[] = $col; - } - - $columns = join(',',$columns); - } - - $query = sprintf ("select %s from %s %s %s %s", $columns, implode (',',$table_list), implode (' ',$left_join), $condition, $groupby_query.$orderby_query); - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf (' '.$this->comment_syntax, $this->query_id):''; + $query .= (__DEBUG_QUERY__&1 && $queryObject->query_id)?sprintf (' '.$this->comment_syntax, $this->query_id):''; $result = $this->_query ($query); - if ($this->isError ()) { + if ($this->isError ()) + return $this->queryError($queryObject); + else + return $this->queryPageLimit($queryObject, $result); + } + + function queryError($queryObject){ + if ($queryObject->getLimit() && $queryObject->getLimit()->isPageHandler()){ + $buff = new Object (); + $buff->total_count = 0; + $buff->total_page = 0; + $buff->page = 1; + $buff->data = array (); + $buff->page_navigation = new PageHandler (/*$total_count*/0, /*$total_page*/1, /*$page*/1, /*$page_count*/10);//default page handler values + return $buff; + }else + return; + } + + function queryPageLimit($queryObject, $result){ + if ($queryObject->getLimit() && $queryObject->getLimit()->isPageHandler()) { + // Total count + $count_query = sprintf('select count(*) as "count" %s %s', 'FROM ' . $queryObject->getFromString(), ($queryObject->getWhereString() === '' ? '' : ' WHERE '. $queryObject->getWhereString())); + if ($queryObject->getGroupByString() != '') { + $count_query = sprintf('select count(*) as "count" from (%s) xet', $count_query); + } + + $count_query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf (' '.$this->comment_syntax, $this->query_id):''; + $result_count = $this->_query($count_query); + $count_output = $this->_fetch($result_count); + $total_count = (int)$count_output->count; + + // Total pages + if ($total_count) { + $total_page = (int) (($total_count - 1) / $queryObject->getLimit()->list_count) + 1; + } else $total_page = 1; + + $virtual_no = $total_count - ($queryObject->getLimit()->page - 1) * $queryObject->getLimit()->list_count; + $data = $this->_fetch($result, $virtual_no); + + $buff = new Object (); + $buff->total_count = $total_count; + $buff->total_page = $total_page; + $buff->page = $queryObject->getLimit()->page->getValue(); + $buff->data = $data; + $buff->page_navigation = new PageHandler($total_count, $total_page, $queryObject->getLimit()->page->getValue(), $queryObject->getLimit()->page_count); + }else{ + $data = $this->_fetch($result); $buff = new Object (); - $buff->total_count = 0; - $buff->total_page = 0; - $buff->page = 1; - $buff->data = array (); - - $buff->page_navigation = new PageHandler ($total_count, $total_page, $page, $page_count); - - return $buff; + $buff->data = $data; } - - $virtual_no = $total_count - ($page - 1) * $list_count; - while ($tmp = cubrid_fetch ($result, CUBRID_OBJECT)) { - if ($tmp) { - foreach ($tmp as $k => $v) { - $tmp->{$k} = rtrim($v); - } - } - $data[$virtual_no--] = $tmp; - } - - $buff = new Object (); - $buff->total_count = $total_count; - $buff->total_page = $total_page; - $buff->page = $page; - $buff->data = $data; - - $buff->page_navigation = new PageHandler ($total_count, $total_page, $page, $page_count); - return $buff; } + + function getParser(){ + return new DBParser('"'); + } } return new DBCubrid; diff --git a/classes/db/DBFirebird.class.php b/classes/db/DBFirebird.class.php index f192c6d97..62e2effd8 100644 --- a/classes/db/DBFirebird.class.php +++ b/classes/db/DBFirebird.class.php @@ -291,7 +291,7 @@ // Notify to start a query execution $this->actStart($query); // Execute the query statement - $result = ibase_query($this->fd, $query); + $result = @ibase_query($this->fd, $query); } else { // Notify to start a query execution @@ -592,6 +592,7 @@ } } + if($auto_increment_list) foreach($auto_increment_list as $increment) { $schema = sprintf('CREATE GENERATOR GEN_%s_ID;', $table_name); $output = $this->_query($schema); @@ -616,161 +617,32 @@ } } - /** - * @brief Return conditional clause - **/ - function getCondition($output) { - if(!$output->conditions) return; - $condition = $this->_getCondition($output->conditions,$output->column_type,$output->_tables); - if($condition) $condition = ' where '.$condition; - return $condition; - } - - function getLeftCondition($conditions,$column_type,$tables){ - return $this->_getCondition($conditions,$column_type,$tables); - } - - - function _getCondition($conditions,$column_type,$tables) { - $condition = ''; - foreach($conditions as $val) { - $sub_condition = ''; - foreach($val['condition'] as $v) { - if(!isset($v['value'])) continue; - if($v['value'] === '') continue; - if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue; - - $name = $v['column']; - $operation = $v['operation']; - $value = $v['value']; - $type = $this->getColumnType($column_type,$name); - $pipe = $v['pipe']; - - $value = $this->getConditionValue('"'.$name.'"', $value, $operation, $type, $column_type); - if(!$value) $value = $v['value']; - - $name = $this->autoQuotes($name); - $value = $this->autoValueQuotes($value, $tables); - - $str = $this->getConditionPart($name, $value, $operation); - if($sub_condition) $sub_condition .= ' '.$pipe.' '; - $sub_condition .= $str; - } - if($sub_condition) { - if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; - $condition .= '('.$sub_condition.')'; - } - } - - return $condition; - } /** * @brief Handle the insertAct **/ - function _executeInsertAct($output) { - // tables - foreach($output->tables as $key => $val) { - $table_list[] = '"'.$this->prefix.$val.'"'; - } - // Columns - foreach($output->columns as $key => $val) { - $name = $val['name']; - $value = $val['value']; - - $value = str_replace("'", "`", $value); - - if($output->column_type[$name]=="text" || $output->column_type[$name]=="bigtext"){ - if(!isset($val['value'])) continue; - $blh = ibase_blob_create($this->fd); - ibase_blob_add($blh, $value); - $value = ibase_blob_close($blh); - } - else if($output->column_type[$name]!='number') { -// if(!$value) $value = 'null'; - } - else $this->_filterNumber($value); - - $column_list[] = '"'.$name.'"'; - $value_list[] = $value; - $questions[] = "?"; - } - - $query = sprintf("insert into %s (%s) values (%s);", implode(',',$table_list), implode(',',$column_list), implode(',', $questions)); - - $result = $this->_query($query, $value_list); - if(!$this->transaction_started) @ibase_commit($this->fd); - return $result; + function _executeInsertAct($queryObject) { + $query = $this->getInsertSql($queryObject); + if(is_a($query, 'Object')) return; + return $this->_query($query); } /** * @brief handles updateAct **/ - function _executeUpdateAct($output) { - // Tables - foreach($output->tables as $key => $val) { - $table_list[] = '"'.$this->prefix.$val.'"'; - } - // Columns - foreach($output->columns as $key => $val) { - if(!isset($val['value'])) continue; - $name = $val['name']; - $value = $val['value']; - - $value = str_replace("'", "`", $value); - - if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value; - else { - if($output->column_type[$name]=="text" || $output->column_type[$name]=="bigtext"){ - $blh = ibase_blob_create($this->fd); - ibase_blob_add($blh, $value); - $value = ibase_blob_close($blh); - } - else if($output->column_type[$name]=='number' || - $output->column_type[$name]=='bignumber' || - $output->column_type[$name]=='float') { - // put double-quotes on column name if an expression is entered - preg_match("/(?i)[a-z][a-z0-9_]+/", $value, $matches); - - foreach($matches as $key => $val) { - $value = str_replace($val, "\"".$val."\"", $value); - } - - if($matches != null) { - $column_list[] = sprintf("\"%s\" = %s", $name, $value); - continue; - } - } - - $values[] = $value; - $column_list[] = sprintf('"%s" = ?', $name); - } - } - // conditional clause - $condition = $this->getCondition($output); - - $query = sprintf("update %s set %s %s;", implode(',',$table_list), implode(',',$column_list), $condition); - $result = $this->_query($query, $values); - if(!$this->transaction_started) @ibase_commit($this->fd); - return $result; + function _executeUpdateAct($queryObject) { + $query = $this->getUpdateSql($queryObject); + if(is_a($query, 'Object')) return; + return $this->_query($query); } /** * @brief handles deleteAct **/ - function _executeDeleteAct($output) { - // Tables - foreach($output->tables as $key => $val) { - $table_list[] = '"'.$this->prefix.$val.'"'; - } - // List the conditional clause - $condition = $this->getCondition($output); - - $query = sprintf("delete from %s %s;", implode(',',$table_list), $condition); - - $result = $this->_query($query); - if(!$this->transaction_started) @ibase_commit($this->fd); - return $result; + function _executeDeleteAct($queryObject) { + $query = $this->getDeleteSql($queryObject); + if(is_a($query, 'Object')) return; + return $this->_query($query); } /** @@ -779,265 +651,113 @@ * In order to get a list of pages easily when selecting \n * it supports a method as navigation **/ - function _executeSelectAct($output) { - // Tables - $table_list = array(); - foreach($output->tables as $key => $val) { - $table_list[] = sprintf("\"%s%s\" as \"%s\"", $this->prefix, $val, $key); - } - - $left_join = array(); - // why??? - $left_tables= (array)$output->left_tables; - - foreach($left_tables as $key => $val) { - $condition = $this->getLeftCondition($output->left_conditions[$key],$output->column_type,$output->_tables); - if($condition){ - $left_join[] = $val . ' "'.$this->prefix.$output->_tables[$key].'" as "'.$key.'" on (' . $condition . ')'; - } - } - - $click_count = array(); - if(!$output->columns){ - $output->columns = array(array('name'=>'*')); - } - - $column_list = array(); - foreach($output->columns as $key => $val) { - $name = $val['name']; - $alias = $val['alias']; - if($val['click_count']) $click_count[] = $val['name']; - - if($alias == "") - $column_list[] = $this->autoQuotes($name); - else - $column_list[$alias] = sprintf("%s as \"%s\"", $this->autoQuotes($name), $alias); - } - $columns = implode(',',$column_list); - - $condition = $this->getCondition($output); - - $output->column_list = $column_list; - if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); - // query added in the condition to use an index when ordering by list_order, update_order - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and "%s" < 2100000000 ', $col); - else $condition = sprintf(' where "%s" < 2100000000 ', $col); - } - } - } - // apply when using list_count - if($output->list_count['value']) $limit = sprintf('FIRST %d', $output->list_count['value']); - else $limit = ''; - - - if($output->groups) { - foreach($output->groups as $key => $val) { - $group_list[] = $this->autoQuotes($val); - if($column_list[$val]) $output->arg_columns[] = $column_list[$val]; - } - if(count($group_list)) $groupby_query = sprintf(" group by %s", implode(",",$group_list)); - } - - if($output->order) { - foreach($output->order as $key => $val) { - $index_list[] = sprintf("%s %s", $this->autoQuotes($val[0]), $val[1]); - if(count($output->arg_columns) && $column_list[$val[0]]) $output->arg_columns[] = $column_list[$val[0]]; - } - if(count($index_list)) $orderby_query = sprintf(" order by %s", implode(",",$index_list)); - } - - if(count($output->arg_columns)) - { - $columns = array(); - foreach($output->arg_columns as $col){ - if(strpos($col,'"')===false && strpos($col,' ')==false) $columns[] = '"'.$col.'"'; - else $columns[] = $col; - } - - $columns = join(',',$columns); - } - - $query = sprintf("select %s from %s %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition, $groupby_query.$orderby_query); - $query .= ";"; - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - $result = $this->_query($query); - if($this->isError()) { - if(!$this->transaction_started) @ibase_rollback($this->fd); - return; - } - - $data = $this->_fetch($result, $output); - if(!$this->transaction_started) @ibase_commit($this->fd); - - if(count($click_count)>0 && count($output->conditions)>0){ - $_query = ''; - foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); - $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); - $this->_query($_query); - } - - $buff = new Object(); - $buff->data = $data; - return $buff; + function _executeSelectAct($queryObject) { + $query = $this->getSelectSql($queryObject); + + if(is_a($query, 'Object')) return; + $query .= (__DEBUG_QUERY__&1 && $queryObject->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + $result = $this->_query ($query); + + if ($this->isError ()) return $this->queryError($queryObject); + else return $this->queryPageLimit($queryObject, $result); } + + function queryError($queryObject) { + if ($queryObject->getLimit() && $queryObject->getLimit()->isPageHandler()) { + $buff = new Object (); + $buff->total_count = 0; + $buff->total_page = 0; + $buff->page = 1; + $buff->data = array(); + $buff->page_navigation = new PageHandler(/* $total_count */0, /* $total_page */1, /* $page */1, /* $page_count */10); //default page handler values + }else + return; + } - /** - * @brief paginates when navigation info exists in the query xml - * - * it is convenient although its structure is not good .. -_-; - **/ - function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { - require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); - - $column_list = $output->column_list; - - $query_groupby = ''; - if ($output->groups) { - foreach ($output->groups as $key => $val){ - $group_list[] = $this->autoQuotes($val); - if($column_list[$val]) $output->arg_columns[] = $column_list[$val]; - } - if (count($group_list)) $query_groupby = sprintf(" GROUP BY %s", implode(", ", $group_list)); + function queryPageLimit($queryObject, $result) { + if ($queryObject->getLimit() && $queryObject->getLimit()->isPageHandler()) { + // Total count + $count_query = sprintf('select count(*) as "count" %s %s', 'FROM ' . $queryObject->getFromString(), ($queryObject->getWhereString() === '' ? '' : ' WHERE ' . $queryObject->getWhereString())); + if ($queryObject->getGroupByString() != '') { + $count_query = sprintf('select count(*) as "count" from (%s) xet', $count_query); } - /* - // modified to get the number of rows by SELECT query with group by clause - // activate the commented codes when you confirm it works correctly - // - $count_condition = strlen($query_groupby) ? sprintf('%s group by %s', $condition, $query_groupby) : $condition; - $total_count = $this->getCountCache($output->tables, $count_condition); - if($total_count === false) { - $count_query = sprintf('select count(*) as "count" from %s %s %s', implode(', ', $table_list), implode(' ', $left_join), $count_condition); - if (count($output->groups)) - $count_query = sprintf('select count(*) as "count" from (%s) xet', $count_query); - $result = $this->_query($count_query); - $count_output = $this->_fetch($result); - $total_count = (int)$count_output->count; - $this->putCountCache($output->tables, $count_condition, $total_count); - } - */ - // total number of rows - $count_query = sprintf("select count(*) as \"count\" from %s %s %s", implode(',',$table_list),implode(' ',$left_join), $condition); - $count_query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id . ' count(*)'):''; - $result = $this->_query($count_query); - $count_output = $this->_fetch($result); - if(!$this->transaction_started) @ibase_commit($this->fd); + $count_query .= ( __DEBUG_QUERY__ & 1 && $output->query_id) ? sprintf(' ' . $this->comment_syntax, $this->query_id) : ''; + $result_count = $this->_query($count_query); + $count_output = $this->_fetch($result_count); + $total_count = (int) $count_output->count; - $total_count = (int)$count_output->count; - - $list_count = $output->list_count['value']; - if(!$list_count) $list_count = 20; - $page_count = $output->page_count['value']; - if(!$page_count) $page_count = 10; - $page = $output->page['value']; - if(!$page) $page = 1; - // total pages - if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; - else $total_page = 1; - // check the page variables - if($page > $total_page) $page = $total_page; - $start_count = ($page-1)*$list_count; - // query added in the condition to use an index when ordering by list_order, update_order - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and "%s" < 2100000000 ', $col); - else $condition = sprintf(' where "%s" < 2100000000 ', $col); - } - } - } - - $limit = sprintf('FIRST %d SKIP %d ', $list_count, $start_count); - - - if($output->order) { - foreach($output->order as $key => $val) { - $index_list[] = sprintf("%s %s", $this->autoQuotes($val[0]), $val[1]); - if(count($output->arg_columns) && $column_list[$val[0]]) $output->arg_columns[] = $column_list[$val[0]]; - } - if(count($index_list)) $orderby_query = sprintf(" ORDER BY %s", implode(",",$index_list)); - } - - if(count($output->arg_columns)) - { - $columns = array(); - foreach($output->arg_columns as $col){ - if(strpos($col,'"')===false && strpos($col,' ')==false) $columns[] = '"'.$col.'"'; - else $columns[] = $col; - } - - $columns = join(',',$columns); - } - - $query = sprintf('SELECT %s %s FROM %s %s %s, %s', $limit, $columns, implode(',',$table_list), implode(' ',$left_join), $condition, $groupby_query.$orderby_query); - $query .= ";"; - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - $result = $this->_query($query); - if($this->isError()) { - if(!$this->transaction_started) @ibase_rollback($this->fd); - - $buff = new Object(); - $buff->total_count = 0; - $buff->total_page = 0; - $buff->page = 1; - $buff->data = array(); - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - - $virtual_no = $total_count - ($page-1)*$list_count; - while($tmp = ibase_fetch_object($result)) { - foreach($tmp as $key => $val){ - $type = $output->column_type[$key]; - // $key value is an alias when type value is null. get type by finding the actual column name - if($type == null && $output->columns && count($output->columns)) { - foreach($output->columns as $cols) { - if($cols['alias'] == $key) { - // checks if the format is table.column or a regular expression - preg_match("/\w+[.](\w+)/", $cols['name'], $matches); - if($matches) { - $type = $output->column_type[$matches[1]]; - } - else { - $type = $output->column_type[$cols['name']]; - } - } - } - } - - if(($type == "text" || $type == "bigtext") && $tmp->{$key}) { - $blob_data = ibase_blob_info($tmp->{$key}); - $blob_hndl = ibase_blob_open($tmp->{$key}); - $tmp->{$key} = ibase_blob_get($blob_hndl, $blob_data[0]); - ibase_blob_close($blob_hndl); - } - } + // Total pages + if ($total_count) { + $total_page = (int) (($total_count - 1) / $queryObject->getLimit()->list_count) + 1; + } else + $total_page = 1; + $virtual_no = $total_count - ($queryObject->getLimit()->page - 1) * $queryObject->getLimit()->list_count; + while ($tmp = ibase_fetch_object($result)) $data[$virtual_no--] = $tmp; - } + + if (!$this->transaction_started) + @ibase_commit($this->fd); - if(!$this->transaction_started) @ibase_commit($this->fd); - - $buff = new Object(); + $buff = new Object (); $buff->total_count = $total_count; $buff->total_page = $total_page; - $buff->page = $page; + $buff->page = $queryObject->getLimit()->page->getValue(); + $buff->data = $data; + $buff->page_navigation = new PageHandler($total_count, $total_page, $queryObject->getLimit()->page->getValue(), $queryObject->getLimit()->page_count); + }else { + $data = $this->_fetch($result); + $buff = new Object (); $buff->data = $data; - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; } + return $buff; } + function getParser() { + return new DBParser('"'); + } + + function getSelectSql($query, $with_values = true) { + + if ($query->getLimit()) { + $list_count = $query->getLimit()->list_count->getValue(); + if(!$query->getLimit()->page) $page = 1; + else $page = $query->getLimit()->page->getValue(); + + $start_count = ($page - 1) * $list_count; + $limit = sprintf('SELECT FIRST %d SKIP %d ', $list_count, $start_count); + } + + $select = $query->getSelectString($with_values); + if ($select == '') + return new Object(-1, "Invalid query"); + + if ($query->getLimit()) + $select = $limit . ' ' . $select; + else + $select = 'SELECT ' . $select; + $from = $query->getFromString($with_values); + if ($from == '') + return new Object(-1, "Invalid query"); + $from = ' FROM ' . $from; + + $where = $query->getWhereString($with_values); + if ($where != '') + $where = ' WHERE ' . $where; + + $groupBy = $query->getGroupByString(); + if ($groupBy != '') + $groupBy = ' GROUP BY ' . $groupBy; + + $orderBy = $query->getOrderByString(); + if ($orderBy != '') + $orderBy = ' ORDER BY ' . $orderBy; + + return $select . ' ' . $from . ' ' . $where . ' ' . $groupBy . ' ' . $orderBy; + } + +} + return new DBFireBird; ?> diff --git a/classes/db/DBMssql.class.php b/classes/db/DBMssql.class.php index c5f965875..19294ad33 100644 --- a/classes/db/DBMssql.class.php +++ b/classes/db/DBMssql.class.php @@ -17,7 +17,7 @@ var $prefix = 'xe'; // / _setDBInfo(); $this->_connect(); } - + /** * @brief create an instance of this class */ @@ -70,7 +70,7 @@ $this->password = $db_info->db_password; $this->database = $db_info->db_database; $this->prefix = $db_info->db_table_prefix; - + if(!substr($this->prefix,-1)!='_') $this->prefix .= '_'; } @@ -85,12 +85,11 @@ //sqlsrv_configure( 'LogSeverity', SQLSRV_LOG_SEVERITY_ALL ); //sqlsrv_configure( 'LogSubsystems', SQLSRV_LOG_SYSTEM_ALL ); - $this->conn = sqlsrv_connect( $this->hostname, + $this->conn = sqlsrv_connect( $this->hostname, array( 'Database' => $this->database,'UID'=>$this->userid,'PWD'=>$this->password )); - -// Check connections - + + // Check connections if($this->conn){ $this->is_connected = true; $this->password = md5($this->password); @@ -104,7 +103,7 @@ **/ function close() { if($this->is_connected == false) return; - + $this->commit(); sqlsrv_close($this->conn); $this->conn = null; @@ -113,10 +112,11 @@ /** * @brief handles quatation of the string variables from the query **/ + // TODO See what to do about this function addQuotes($string) { if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string)); //if(!is_numeric($string)) $string = str_replace("'","''",$string); - + return $string; } @@ -126,7 +126,7 @@ function begin() { if($this->is_connected == false || $this->transaction_started) return; if(sqlsrv_begin_transaction( $this->conn ) === false) return; - + $this->transaction_started = true; } @@ -135,7 +135,7 @@ **/ function rollback() { if($this->is_connected == false || !$this->transaction_started) return; - + $this->transaction_started = false; sqlsrv_rollback( $this->conn ); } @@ -145,8 +145,8 @@ **/ function commit($force = false) { if(!$force && ($this->is_connected == false || !$this->transaction_started)) return; - - $this->transaction_started = false; + + $this->transaction_started = false; sqlsrv_commit( $this->conn ); } @@ -159,24 +159,40 @@ * object if a row returned \n * return\n **/ + + // TODO Support array arguments in sql server + /* + * $query_emp="select name from employee where id in (?,?,?)"; + $params_emp= Array(1,2,3); + $res_emp = sqlsrv_query($conn, $query_emp, $params_emp); + * + */ + function _query($query) { if($this->is_connected == false || !$query) return; $_param = array(); - + if(count($this->param)){ foreach($this->param as $k => $o){ - if($o['type'] == 'number'){ - $_param[] = &$o['value']; + if($o->getType() == 'number'){ + $value = $o->getUnescapedValue(); + if(is_array($value)) $_param = array_merge($_param, $value); + else $_param[] = $o->getUnescapedValue(); }else{ - $_param[] = array(&$o['value'], SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8')); + $value = $o->getUnescapedValue(); + if(is_array($value)) { + foreach($value as $v) + $_param[] = array($v, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8')); + } + else $_param[] = array($value, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8')); } - } + } } - + // Notify to start a query execution $this->actStart($query); - + // Run the query statement $result = false; if(count($_param)){ @@ -185,9 +201,9 @@ $result = @sqlsrv_query($this->conn, $query); } // Error Check - + if(!$result) $this->setError(print_r(sqlsrv_errors(),true)); - + // Notify to complete a query execution $this->actFinish(); $this->param = array(); @@ -198,23 +214,27 @@ /** * @brief Fetch results **/ - function _fetch($result) { + function _fetch($result, $arrayIndexEndValue = NULL) { if(!$this->isConnected() || $this->isError() || !$result) return; - + $c = sqlsrv_num_fields($result); $m = null; $output = array(); - + while(sqlsrv_fetch($result)){ if(!$m) $m = sqlsrv_field_metadata($result); unset($row); for($i=0;$i<$c;$i++){ - $row->{$m[$i]['Name']} = sqlsrv_get_field( $result, $i, SQLSRV_PHPTYPE_STRING( 'utf-8' )); + $row->{$m[$i]['Name']} = sqlsrv_get_field( $result, $i, SQLSRV_PHPTYPE_STRING( 'utf-8' )); } - $output[] = $row; + if($arrayIndexEndValue) $output[$arrayIndexEndValue--] = $row; + else $output[] = $row; } - if(count($output)==1) return $output[0]; + if(count($output)==1) { + if(isset($arrayIndexEndValue)) return $output; + else return $output[0]; + } return $output; } @@ -225,12 +245,12 @@ function getNextSequence() { $query = sprintf("insert into %ssequence (seq) values (ident_incr('%ssequence'))", $this->prefix, $this->prefix); $this->_query($query); - + $query = sprintf("select ident_current('%ssequence')+1 as sequence", $this->prefix); $result = $this->_query($query); $tmp = $this->_fetch($result); - + return $tmp->sequence; } @@ -239,9 +259,9 @@ **/ function isTableExists($target_name) { $query = sprintf("select name from sysobjects where name = '%s%s' and xtype='U'", $this->prefix, $this->addQuotes($target_name)); - $result = $this->_query($query); + $result = $this->_query($query); $tmp = $this->_fetch($result); - + if(!$tmp) return false; return true; } @@ -386,11 +406,11 @@ if($unique) $unique_list[$unique][] = $name; else if($index) $index_list[$index][] = $name; } - + $schema = sprintf('create table [%s] (xe_seq int identity(1,1),%s%s)', $this->addQuotes($table_name), "\n", implode($column_schema,",\n")); $output = $this->_query($schema); if(!$output) return false; - + if(count($unique_list)) { foreach($unique_list as $key => $val) { $query = sprintf("create unique index %s on %s (%s);", $key, $table_name, '['.implode('],[',$val).']'); @@ -408,506 +428,143 @@ } } - /** - * @brief Return conditional clause - **/ - function getCondition($output) { - if(!$output->conditions) return; - $condition = $this->_getCondition($output->conditions,$output->column_type); - if($condition) $condition = ' where '.$condition; - return $condition; - } - function getLeftCondition($conditions,$column_type){ - return $this->_getCondition($conditions,$column_type); - } - - - function _getCondition($conditions,$column_type) { - $condition = ''; - - foreach($conditions as $val) { - $sub_condition = ''; - foreach($val['condition'] as $v) { - if(!isset($v['value'])) continue; - if($v['value'] === '') continue; - if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue; - - $name = $v['column']; - if(preg_match('/^substr\(/i',$name)) $name = preg_replace('/^substr\(/i','substring(',$name); - $operation = $v['operation']; - $value = $v['value']; - - $type = $this->getColumnType($column_type,$name); - $pipe = $v['pipe']; - - $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); - if(!$value) $value = $v['value']; - $str = $this->getConditionPart($name, $value, $operation); - if($sub_condition) $sub_condition .= ' '.$pipe.' '; - $sub_condition .= $str; - } - if($sub_condition) { - if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; - $condition .= '('.$sub_condition.')'; - } - } - return $condition; - } - - - function getConditionValue($name, $value, $operation, $type, $column_type) { - - if($type == 'number') { - if(strpos($value,',')===false && strpos($value,'(')===false){ - - if(is_integer($value)){ - $this->param[] = array('type'=>'number','value'=>(int)$value); - return '?'; - }else{ - return $value; - } - } - } - - if(strpos($name,'.')!==false&&strpos($value,'.')!==false) { - list($table_name, $column_name) = explode('.',$value); - if($column_type[$column_name]){ - return $value; - } - } - - switch($operation) { - case 'like_prefix' : - $value = preg_replace('/(^\'|\'$){1}/','',$value); - $this->param[] = array('type'=>$column_type[$name],'value'=>$value); - - $value = "? + '%'"; - break; - case 'like_tail' : - $value = preg_replace('/(^\'|\'$){1}/','',$value); - $this->param[] = array('type'=>$column_type[$name],'value'=>$value); - - $value = "'%' + ?"; - break; - case 'like' : - $value = preg_replace('/(^\'|\'$){1}/','',$value); - $this->param[] = array('type'=>$column_type[$name],'value'=>$value); - - $value = "'%' + ? + '%'"; - break; - case 'notin' : - preg_match_all('/,?\'([^\']*)\'/',$value,$match); - $val = array(); - foreach($match[1] as $k => $v){ - $this->param[] = array('type'=>$column_type[$name],'value'=>trim($v)); - $val[] ='?'; - } - $value = join(',',$val); - break; - case 'in' : - preg_match_all('/,?\'([^\']*)\'/',$value,$match); - $val = array(); - foreach($match[1] as $k => $v){ - $this->param[] = array('type'=>$column_type[$name],'value'=>trim($v)); - $val[] ='?'; - } - $value = join(',',$val); - break; - default: - $value = preg_replace('/(^\'|\'$){1}/','',$value); - $this->param[] = array('type'=>$column_type[$name],'value'=>$value); - $value = '?'; - break; - } - - return $value; - } - /** * @brief Handle the insertAct **/ - function _executeInsertAct($output) { - - // List tables - foreach($output->tables as $key => $val) { - $table_list[] = '['.$this->prefix.$val.']'; - } - // List columns - foreach($output->columns as $key => $val) { - $name = $val['name']; - $value = $val['value']; - - if($output->column_type[$name]!='number') { - $value = $this->addQuotes($value); - if(!$value) $value = ''; - } elseif(is_numeric($value)){ - if(!$value) $value = ''; - $value = (int)$value; - } elseif(!$value){ - $value = ''; - } - // sql injection 문제로 xml 선언이 number인 경우이면서 넘어온 값이 숫자형이 아니면 숫자형으로 강제 형변환 - else $this->_filterNumber($value); - - $column_list[] = '['.$name.']'; - $value_list[] = '?'; - - $this->param[] = array('type'=>$output->column_type[$name], 'value'=>$value); - } - - $query = sprintf("insert into %s (%s) values (%s);", implode(',',$table_list), implode(',',$column_list), implode(',', $value_list)); - + // TODO Lookup _filterNumber against sql injection - see if it is still needed and how to integrate + function _executeInsertAct($queryObject) { + $query = $this->getInsertSql($queryObject, false); + $this->param = $queryObject->getArguments(); return $this->_query($query); } /** * @brief Handle updateAct **/ - function _executeUpdateAct($output) { - // List tables - foreach($output->tables as $key => $val) { - $table_list[] = '['.$this->prefix.$val.']'; - } - -// List columns - - foreach($output->columns as $key => $val) { - if(!isset($val['value'])) continue; - - $name = $val['name']; - $value = $val['value']; - if(strpos($name,'.')!==false&&strpos($value,'.')!==false){ - $column_list[] = $name.' = '.$value; - } else { - if($output->column_type[$name]!='number'){ - $value = $this->addQuotes($value); - if(!$value) $value = ''; - - $this->param[] = array('type'=>$output->column_type[$name], 'value'=>$value); - $column_list[] = sprintf("[%s] = ?", $name); - }elseif(!$value || is_numeric($value)){ - $value = (int)$value; - - $this->param[] = array('type'=>$output->column_type[$name], 'value'=>$value); - $column_list[] = sprintf("[%s] = ?", $name); - }else{ - if(!$value) $value = ''; - $this->_filterNumber($value); - $column_list[] = sprintf("[%s] = %s", $name, $value); - } - } - } - // List the conditional clause - $condition = $this->getCondition($output); - - $query = sprintf("update %s set %s %s", implode(',',$table_list), implode(',',$column_list), $condition); - + function _executeUpdateAct($queryObject) { + $query = $this->getUpdateSql($queryObject, false); + $this->param = $queryObject->getArguments(); return $this->_query($query); } /** * @brief Handle deleteAct **/ - function _executeDeleteAct($output) { - // List tables - foreach($output->tables as $key => $val) { - $table_list[] = '['.$this->prefix.$val.']'; - } - // List the conditional clause - $condition = $this->getCondition($output); - - $query = sprintf("delete from %s %s", implode(',',$table_list), $condition); - + function _executeDeleteAct($queryObject) { + $query = $this->getDeleteSql($queryObject, false); + $this->param = $queryObject->getArguments(); return $this->_query($query); } + function getSelectSql($query){ + $with_value = false; + + //$limitOffset = $query->getLimit()->getOffset(); + //if($limitOffset) + // TODO Implement Limit with offset with subquery + $limit = '';$limitCount = ''; + if($query->getLimit()) + $limitCount = $query->getLimit()->getLimit(); + if($limitCount != '') $limit = 'SELECT TOP ' . $limitCount; + + $select = $query->getSelectString($with_values); + if($select == '') return new Object(-1, "Invalid query"); + if($limit != '') + $select = $limit.' '.$select; + else + $select = 'SELECT ' .$select; + + $from = $query->getFromString($with_values); + if($from == '') return new Object(-1, "Invalid query"); + $from = ' FROM '.$from; + + $where = $query->getWhereString($with_values); + if($where != '') $where = ' WHERE ' . $where; + + $groupBy = $query->getGroupByString(); + if($groupBy != '') $groupBy = ' GROUP BY ' . $groupBy; + + $orderBy = $query->getOrderByString(); + if($orderBy != '') $orderBy = ' ORDER BY ' . $orderBy; + + + + return $select . ' ' . $from . ' ' . $where . ' ' . $groupBy . ' ' . $orderBy; + } + /** * @brief Handle selectAct * * In order to get a list of pages easily when selecting \n * it supports a method as navigation **/ - function _executeSelectAct($output) { - // List tables - $table_list = array(); - foreach($output->tables as $key => $val) { - $table_list[] = '['.$this->prefix.$val.'] as '.$key; - } + function _executeSelectAct($queryObject) { + $query = $this->getSelectSql($queryObject); - $left_join = array(); - // why??? - $left_tables= (array)$output->left_tables; + if(strpos($query, "substr")) $query = str_replace ("substr", "substring", $query); - foreach($left_tables as $key => $val) { - $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); - if($condition){ - $left_join[] = $val . ' ['.$this->prefix.$output->_tables[$key].'] as '.$key . ' on (' . $condition . ')'; - } - } + // TODO Decide if we continue to pass parameters like this + $this->param = $queryObject->getArguments(); - $click_count = array(); - if(!$output->columns){ - $output->columns = array(array('name'=>'*')); - } + $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + $result = $this->_query($query); - $column_list = array(); - foreach($output->columns as $key => $val) { - $name = $val['name']; - if(preg_match('/^substr\(/i',$name)) $name = preg_replace('/^substr\(/i','substring(',$name); - $alias = $val['alias']; - if($val['click_count']) $click_count[] = $val['name']; - - if(substr($name,-1) == '*') { - $column_list[] = $name; - } elseif(strpos($name,'.')===false && strpos($name,'(')===false) { - if($alias) $column_list[$alias] = sprintf('[%s] as [%s]', $name, $alias); - else $column_list[] = sprintf('[%s]',$name); - } else { - if($alias) $column_list[$alias] = sprintf('%s as [%s]', $name, $alias); - else $column_list[] = sprintf('%s',$name); - } - } - $columns = implode(',',$column_list); - - $condition = $this->getCondition($output); - - $output->column_list = $column_list; - if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); - // Add a condition to use an index when sorting in order by list_order, update_order - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - if(count($output->groups)){ - foreach($output->groups as $k => $v ){ - if(preg_match('/^substr\(/i',$v)) $output->groups[$k] = preg_replace('/^substr\(/i','substring(',$v); - if($column_list[$v]) $output->arg_columns[] = $column_list[$v]; - } - $groupby_query = sprintf(' group by %s', implode(',',$output->groups)); - } - - if($output->order && !preg_match('/count\(\*\)/i',$columns) ) { - foreach($output->order as $key => $val) { - if(preg_match('/^substr\(/i',$val[0])) $name = preg_replace('/^substr\(/i','substring(',$val[0]); - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - if(count($output->arg_columns) && $column_list[$val[0]]) $output->arg_columns[] = $column_list[$val[0]]; - } - if(count($index_list)) $orderby_query = ' order by '.implode(',',$index_list); - } - - if(count($output->arg_columns)) - { - $columns = array(); - foreach($output->arg_columns as $col){ - unset($tmpCol); - $tmpCol = explode('.', $col); - if(isset($tmpCol[1])) $col = $tmpCol[1]; - - if(strpos($col,'[')===false && strpos($col,' ')==false) $col = '['.$col.']'; - if(isset($tmpCol[1])) $col = $tmpCol[0].'.'.$col; - - $columns[] = $col; - } - - $columns = join(',',$columns); - } - - $query = sprintf("%s from %s %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition, $groupby_query.$orderby_query); - // Apply when using list_count - if($output->list_count['value']) $query = sprintf('select top %d %s', $output->list_count['value'], $query); - else $query = "select ".$query; - - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - $result = $this->_query($query); - if($this->isError()) return; - - if(count($click_count)>0 && count($output->conditions)>0){ - $_query = ''; - foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); - $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); - $this->_query($_query); - } - - $data = $this->_fetch($result); - - $buff = new Object(); - $buff->data = $data; - return $buff; + if ($this->isError ()) return $this->queryError($queryObject); + else return $this->queryPageLimit($queryObject, $result); } - /** - * @brief Paging is handled if navigation information exists in the query xml - * - * It is quite convenient although its structure is not good at all .. -_-; - **/ - function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { - require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); + function getParser(){ + return new DBParser("[", "]"); + } - $column_list = $output->column_list; + function queryError($queryObject){ + if ($queryObject->getLimit() && $queryObject->getLimit()->isPageHandler()){ + $buff = new Object (); + $buff->total_count = 0; + $buff->total_page = 0; + $buff->page = 1; + $buff->data = array (); + $buff->page_navigation = new PageHandler (/*$total_count*/0, /*$total_page*/1, /*$page*/1, /*$page_count*/10);//default page handler values + return $buff; + }else + return; + } - // Get a total count - if(count($output->groups)){ - foreach($output->groups as $k => $v ){ - if(preg_match('/^substr\(/i',$v)) $output->groups[$k] = preg_replace('/^substr\(/i','substring(',$v); - if($column_list[$v]) $output->arg_columns[] = $column_list[$v]; + function queryPageLimit($queryObject, $result){ + if ($queryObject->getLimit() && $queryObject->getLimit()->isPageHandler()) { + // Total count + $count_query = sprintf('select count(*) as "count" %s %s', 'FROM ' . $queryObject->getFromString(), ($queryObject->getWhereString() === '' ? '' : ' WHERE '. $queryObject->getWhereString())); + if ($queryObject->getGroupByString() != '') { + $count_query = sprintf('select count(*) as "count" from (%s) xet', $count_query); } - $count_condition = sprintf('%s group by %s', $condition, implode(', ', $output->groups)); + + $count_query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf (' '.$this->comment_syntax, $this->query_id):''; + $result_count = $this->_query($count_query); + $count_output = $this->_fetch($result_count); + $total_count = (int)$count_output->count; + + // Total pages + if ($total_count) { + $total_page = (int) (($total_count - 1) / $queryObject->getLimit()->list_count) + 1; + } else $total_page = 1; + + $virtual_no = $total_count - ($queryObject->getLimit()->page - 1) * $queryObject->getLimit()->list_count; + $data = $this->_fetch($result, $virtual_no); + + $buff = new Object (); + $buff->total_count = $total_count; + $buff->total_page = $total_page; + $buff->page = $queryObject->getLimit()->page->getValue(); + $buff->data = $data; + $buff->page_navigation = new PageHandler($total_count, $total_page, $queryObject->getLimit()->page, $queryObject->getLimit()->page_count); }else{ - $count_condition = $condition; + $data = $this->_fetch($result); + $buff = new Object (); + $buff->data = $data; } - - $count_query = sprintf("select count(*) as count from %s %s %s", implode(', ', $table_list), implode(' ', $left_join), $count_condition); - if (count($output->groups)) $count_query = sprintf('select count(*) as count from (%s) xet', $count_query); - - $param = $this->param; - - $count_query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id . ' count(*)'):''; - $result = $this->_query($count_query); - - $this->param = $param; - $count_output = $this->_fetch($result); - - $total_count = (int)$count_output->count; - - $list_count = $output->list_count['value']; - if(!$list_count) $list_count = 20; - $page_count = $output->page_count['value']; - if(!$page_count) $page_count = 10; - $page = $output->page['value']; - if(!$page) $page = 1; - // Get a total page - if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; - else $total_page = 1; - // Check Page variables - if($page > $total_page) $page = $total_page; - $start_count = ($page-1)*$list_count; - // Add a condition to use an index when sorting in order by list_order, update_order - $conditions = $this->getConditionList($output); - if($output->order) { - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' %s < 2100000000 ', $col); - } - } - } - - // Add group by clause - if(count($output->groups)){ - foreach($output->groups as $k => $v ){ - if(preg_match('/^substr\(/i',$v)) $output->groups[$k] = preg_replace('/^substr\(/i','substring(',$v); - if($column_list[$v]) $output->arg_columns[] = $column_list[$v]; - } - - $group = sprintf('group by %s', implode(',',$output->groups)); - } - - // Add order by clause - $order_targets = array(); - if($output->order) { - foreach($output->order as $key => $val) { - if(preg_match('/^substr\(/i',$val[0])) $name = preg_replace('/^substr\(/i','substring(',$val[0]); - $order_targets[$val[0]] = $val[1]; - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - if(count($output->arg_columns) && $column_list[$val[0]]) $output->arg_columns[] = $column_list[$val[0]]; - } - if(count($index_list)) $order .= 'order by '.implode(',',$index_list); - } - if(!count($order_targets)) { - if(in_array('list_order',$conditions)) $order_targets['list_order'] = 'asc'; - else $order_targets['xe_seq'] = 'desc'; - } - - if(count($output->arg_columns)) - { - $columns = array(); - foreach($output->arg_columns as $col){ - unset($tmpCol); - $tmpCol = explode('.', $col); - if(isset($tmpCol[1])) $col = $tmpCol[1]; - - if(strpos($col,'[')===false && strpos($col,' ')==false) $col = '['.$col.']'; - if(isset($tmpCol[1])) $col = $tmpCol[0].'.'.$col; - - $columns[] = $col; - } - - $columns = join(',',$columns); - } - - if($start_count<1) { - $query = sprintf('select top %d %s from %s %s %s %s %s', $list_count, $columns, implode(',',$table_list), implode(' ',$left_join), $condition, $group, $order); - - } else { - foreach($order_targets as $k => $v) { - $first_columns[] = sprintf('%s(%s) as %s', $v=='asc'?'max':'min', $k, $k); - $first_sub_columns[] = $k; - } - - // Fetch values to sort - $param = $this->param; - $first_query = sprintf("select %s from (select top %d %s from %s %s %s %s %s) xet", implode(',',$first_columns), $start_count, implode(',',$first_sub_columns), implode(',',$table_list), implode(' ',$left_join), $condition, $group, $order); - $result = $this->_query($first_query); - $this->param = $param; - $tmp = $this->_fetch($result); - - - - // Re-execute a query by using fetched values - $sub_cond = array(); - foreach($order_targets as $k => $v) { - $sub_cond[] = sprintf("%s %s '%s'", $k, $v=='asc'?'>':'<', $tmp->{$k}); - } - $sub_condition = ' and( '.implode(' and ',$sub_cond).' )'; - - if($condition) $condition .= $sub_condition; - else $condition = ' where '.$sub_condition; - $query = sprintf('select top %d %s from %s %s %s %s %s', $list_count, $columns, implode(',',$table_list), implode(' ',$left_join), $condition, $group, $order); - } - - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - $result = $this->_query($query); - - if($this->isError()) { - $buff = new Object(); - $buff->total_count = 0; - $buff->total_page = 0; - $buff->page = 1; - $buff->data = array(); - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - - $virtual_no = $total_count - ($page-1)*$list_count; - - $output = $this->_fetch($result); - if(!is_array($output)) $output = array($output); - - foreach($output as $k => $v) { - $data[$virtual_no--] = $v; - } - - $buff = new Object(); - $buff->total_count = $total_count; - $buff->total_page = $total_page; - $buff->page = $page; - $buff->data = $data; - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } + return $buff; + } } diff --git a/classes/db/DBMysql.class.php b/classes/db/DBMysql.class.php index 0a2160f86..8a36032d3 100644 --- a/classes/db/DBMysql.class.php +++ b/classes/db/DBMysql.class.php @@ -116,7 +116,7 @@ **/ function addQuotes($string) { if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string)); - if(!is_numeric($string)) $string = @mysql_real_escape_string($string, $this->fd); + if(!is_numeric($string)) $string = @mysql_escape_string($string); return $string; } @@ -152,7 +152,7 @@ // Notify to start a query execution $this->actStart($query); // Run the query statement - $result = @mysql_query($query, $this->fd); + $result = mysql_query($query, $this->fd); // Error Check if(mysql_error($this->fd)) $this->setError(mysql_errno($this->fd), mysql_error($this->fd)); // Notify to complete a query execution @@ -164,12 +164,16 @@ /** * @brief Fetch results **/ - function _fetch($result) { + function _fetch($result, $arrayIndexEndValue = NULL) { if(!$this->isConnected() || $this->isError() || !$result) return; while($tmp = $this->db_fetch_object($result)) { - $output[] = $tmp; + if($arrayIndexEndValue) $output[$arrayIndexEndValue--] = $tmp; + else $output[] = $tmp; + } + if(count($output)==1){ + if(isset($arrayIndexEndValue)) return $output; + else return $output[0]; } - if(count($output)==1) return $output[0]; return $output; } @@ -374,141 +378,46 @@ if(!$output) return false; } - /** - * @brief Return conditional clause - **/ - function getCondition($output) { - if(!$output->conditions) return; - $condition = $this->_getCondition($output->conditions,$output->column_type); - if($condition) $condition = ' where '.$condition; - return $condition; - } - - function getLeftCondition($conditions,$column_type){ - return $this->_getCondition($conditions,$column_type); - } - - - function _getCondition($conditions,$column_type) { - $condition = ''; - foreach($conditions as $val) { - $sub_condition = ''; - foreach($val['condition'] as $v) { - if(!isset($v['value'])) continue; - if($v['value'] === '') continue; - if(!in_array(gettype($v['value']), array('string', 'integer', 'double', 'array'))) continue; - - $name = $v['column']; - $operation = $v['operation']; - $value = $v['value']; - $type = $this->getColumnType($column_type,$name); - $pipe = $v['pipe']; - $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); - if(!$value) $value = $v['value']; - $str = $this->getConditionPart($name, $value, $operation); - if($sub_condition) $sub_condition .= ' '.$pipe.' '; - $sub_condition .= $str; - } - if($sub_condition) { - if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; - $condition .= '('.$sub_condition.')'; - } - } - return $condition; - } - /** * @brief Handle the insertAct **/ - function _executeInsertAct($output) { - // List tables - foreach($output->tables as $key => $val) { - $table_list[] = '`'.$this->prefix.$val.'`'; - } - // List columns - foreach($output->columns as $key => $val) { - $name = $val['name']; - $value = $val['value']; - - if($output->column_type[$name]!='number') { - - if(!is_null($value)){ - $value = "'" . $this->addQuotes($value) ."'"; - }else{ - if($val['notnull']=='notnull') { - $value = "''"; - } else { - //$value = 'null'; - $value = "''"; - } - } - - } - //elseif(!$value || is_numeric($value)) $value = (int)$value; - else $this->_filterNumber($value); - - $column_list[] = '`'.$name.'`'; - $value_list[] = $value; - } - + function _executeInsertAct($queryObject) { + // TODO See what priority does //priority setting - $priority = ''; - if($output->priority) $priority = $output->priority['type'].'_priority'; + //$priority = ''; + //if($output->priority) $priority = $output->priority['type'].'_priority'; - $query = sprintf("insert %s into %s (%s) values (%s);", $priority, implode(',',$table_list), implode(',',$column_list), implode(',', $value_list)); + $query = $this->getInsertSql($queryObject); + if(is_a($query, 'Object')) return; return $this->_query($query); } /** * @brief Handle updateAct **/ - function _executeUpdateAct($output) { - // List tables - foreach($output->tables as $key => $val) { - $table_list[] = '`'.$this->prefix.$val.'` as '.$key; - } - // List columns - foreach($output->columns as $key => $val) { - if(!isset($val['value'])) continue; - $name = $val['name']; - $value = $val['value']; - if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value; - else { - if($output->column_type[$name]!='number') $value = "'".$this->addQuotes($value)."'"; - else $this->_filterNumber($value); - - $column_list[] = sprintf("`%s` = %s", $name, $value); - } - } - // List the conditional clause - $condition = $this->getCondition($output); - + function _executeUpdateAct($queryObject) { + // TODO See what proiority does //priority setting - $priority = ''; - if($output->priority) $priority = $output->priority['type'].'_priority'; - - $query = sprintf("update %s %s set %s %s", $priority, implode(',',$table_list), implode(',',$column_list), $condition); + //$priority = ''; + //if($output->priority) $priority = $output->priority['type'].'_priority'; + $query = $this->getUpdateSql($queryObject); + if(is_a($query, 'Object')) return; return $this->_query($query); } /** * @brief Handle deleteAct **/ - function _executeDeleteAct($output) { - // List tables - foreach($output->tables as $key => $val) { - $table_list[] = '`'.$this->prefix.$val.'`'; - } - // List the conditional clause - $condition = $this->getCondition($output); - - //priority setting - $priority = ''; - if($output->priority) $priority = $output->priority['type'].'_priority'; - - $query = sprintf("delete %s from %s %s", $priority, implode(',',$table_list), $condition); - + function _executeDeleteAct($queryObject) { + $query = $this->getDeleteSql($queryObject); + + if(is_a($query, 'Object')) return; + + //priority setting + // TODO Check what priority does + //$priority = ''; + //if($output->priority) $priority = $output->priority['type'].'_priority'; return $this->_query($query); } @@ -518,261 +427,19 @@ * In order to get a list of pages easily when selecting \n * it supports a method as navigation **/ - function _executeSelectAct($output) { - // List tables - $table_list = array(); - foreach($output->tables as $key => $val) { - $table_list[] = '`'.$this->prefix.$val.'` as '.$key; - } - - $left_join = array(); - // why??? - $left_tables= (array)$output->left_tables; - - foreach($left_tables as $key => $val) { - $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); - if($condition){ - $left_join[] = $val . ' `'.$this->prefix.$output->_tables[$key].'` as '.$key . ' on (' . $condition . ')'; - } - } + function _executeSelectAct($queryObject) { + $query = $this->getSelectSql($queryObject); - $click_count = array(); - if(!$output->columns){ - $output->columns = array(array('name'=>'*')); - } - - $column_list = array(); - foreach($output->columns as $key => $val) - { - $name = $val['name']; - $alias = $val['alias']; - if($val['click_count']) $click_count[] = $val['name']; - - if(substr($name,-1) == '*') - { - $column_list[] = $name; - } - else if(strpos($name,'.')===false && strpos($name,'(')===false) - { - if($alias) - { - $col = sprintf('`%s` as `%s`', $name, $alias); - $column_list[$alias] = $col; - } - else - { - $column_list[] = sprintf('`%s`',$name); - } - } - else - { - if($alias) - { - $col = sprintf('%s as `%s`', $name, $alias); - $column_list[$alias] = $col; - } - else - { - $column_list[] = sprintf('%s',$name); - } - } - } - - $columns = implode(',',$column_list); - $output->column_list = $column_list; - $condition = $this->getCondition($output); - - if(count($output->index_hint)) - $index_hint = sprintf(' %s index (%s) ', $output->index_hint['type'], $output->index_hint['name']); - - if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $index_hint, $condition, $output); - - // Add a condition to use an index when sorting in order by list_order, update_order - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - - if(count($output->groups)) - { - $groupby_query = sprintf(' group by %s', implode(',',$output->groups)); - - if(count($output->arg_columns)) - { - foreach($output->groups as $group) - { - if($column_list[$group]) $output->arg_columns[] = $column_list[$group]; - } - } - } - - if($output->order) { - foreach($output->order as $key => $val) { - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - if(count($output->arg_columns) && $column_list[$val[0]]) $output->arg_columns[] = $column_list[$val[0]]; - } - if(count($index_list)) $orderby_query .= ' order by '.implode(',',$index_list); - } - - if(count($output->arg_columns)) - { - $columns = array(); - foreach($output->arg_columns as $col){ - unset($tmpCol); - $tmpCol = explode('.', $col); - if(isset($tmpCol[1])) $col = $tmpCol[1]; - - if(strpos($col,'`')===false && strpos($col,' ')==false) $col = '`'.$col.'`'; - if(isset($tmpCol[1])) $col = $tmpCol[0].'.'.$col; - - $columns[] = $col; - } - - $columns = join(',',$columns); - } - - $query = sprintf("select %s from %s %s %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $index_hint, $condition, $groupby_query.$orderby_query); - - // Apply when using list_count - if($output->list_count['value']) $query = sprintf('%s limit %d', $query, $output->list_count['value']); - - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - - $result = $this->_query($query); - if($this->isError()) return; - if(count($click_count) && count($output->conditions)){ - $_query = ''; - foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); - $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); - $this->_query($_query); - } - - $data = $this->_fetch($result); - - $buff = new Object(); - $buff->data = $data; - - return $buff; - } - - /** - * @brief Paging is handled if navigation information exists in the query xml - * - * It is quite convenient although its structure is not good at all .. -_-; - **/ - function _getNavigationData($table_list, $columns, $left_join, $index_hint, $condition, $output) { - require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); - - $column_list = $output->column_list; - - // Get a total count - $count_condition = count($output->groups) ? sprintf('%s group by %s', $condition, implode(', ', $output->groups)) : $condition; - $count_query = sprintf("select count(*) as count from %s %s %s", implode(', ', $table_list), implode(' ', $left_join), $count_condition); - if (count($output->groups)) $count_query = sprintf('select count(*) as count from (%s) xet', $count_query); - - $count_query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id . ' count(*)'):''; - $result = $this->_query($count_query); - $count_output = $this->_fetch($result); - $total_count = (int)$count_output->count; - - $list_count = $output->list_count['value']; - if(!$list_count) $list_count = 20; - $page_count = $output->page_count['value']; - if(!$page_count) $page_count = 10; - $page = $output->page['value']; - if(!$page) $page = 1; - // Get a total page - if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; - else $total_page = 1; - // Check Page variables - if($page > $total_page) $page = $total_page; - $start_count = ($page-1)*$list_count; - // Add a condition to use an index when sorting in order by list_order, update_order - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - if(count($output->groups)){ - $groupby_query = sprintf(' group by %s', implode(',',$output->groups)); - - if(count($output->arg_columns)) - { - foreach($output->groups as $group) - { - if($column_list[$group]) $output->arg_columns[] = $column_list[$group]; - } - } - } - - if(count($output->order)) { - foreach($output->order as $key => $val) { - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - if(count($output->arg_columns) && $column_list[$val[0]]) $output->arg_columns[] = $column_list[$val[0]]; - } - if(count($index_list)) $orderby_query = ' order by '.implode(',',$index_list); - } - - if(count($output->arg_columns)) - { - $columns = array(); - foreach($output->arg_columns as $col){ - unset($tmpCol); - $tmpCol = explode('.', $col); - if(isset($tmpCol[1])) $col = $tmpCol[1]; - - if(strpos($col,'`')===false && strpos($col,' ')==false) $col = '`'.$col.'`'; - if(isset($tmpCol[1])) $col = $tmpCol[0].'.'.$col; - - $columns[] = $col; - } - $columns = join(',',$columns); - } - - $query = sprintf("select %s from %s %s %s %s %s", $columns, implode(',',$table_list), implode(' ',$left_join), $index_hint, $condition, $groupby_query.$orderby_query); - $query = sprintf('%s limit %d, %d', $query, $start_count, $list_count); - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - - $result = $this->_query($query); - if($this->isError()) { - $buff = new Object(); - $buff->total_count = 0; - $buff->total_page = 0; - $buff->page = 1; - $buff->data = array(); - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - - $virtual_no = $total_count - ($page-1)*$list_count; - $data = array(); - while($tmp = $this->db_fetch_object($result)) { - $data[$virtual_no--] = $tmp; - } - $buff = new Object(); - $buff->total_count = $total_count; - $buff->total_page = $total_page; - $buff->page = $page; - $buff->data = $data; - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; + if(is_a($query, 'Object')) return; + + $query .= (__DEBUG_QUERY__&1 && $queryObject->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + + // TODO Add support for click count + // TODO Add code for pagination + + $result = $this->_query ($query); + if ($this->isError ()) return $this->queryError($queryObject); + else return $this->queryPageLimit($queryObject, $result); } function db_insert_id() @@ -784,6 +451,58 @@ { return mysql_fetch_object($result); } + + function getParser(){ + return new DBParser('`'); + } + + function queryError($queryObject){ + if ($queryObject->getLimit() && $queryObject->getLimit()->isPageHandler()){ + $buff = new Object (); + $buff->total_count = 0; + $buff->total_page = 0; + $buff->page = 1; + $buff->data = array (); + $buff->page_navigation = new PageHandler (/*$total_count*/0, /*$total_page*/1, /*$page*/1, /*$page_count*/10);//default page handler values + return $buff; + }else + return; + } + + function queryPageLimit($queryObject, $result){ + if ($queryObject->getLimit() && $queryObject->getLimit()->isPageHandler()) { + // Total count + $count_query = sprintf('select count(*) as "count" %s %s', 'FROM ' . $queryObject->getFromString(), ($queryObject->getWhereString() === '' ? '' : ' WHERE '. $queryObject->getWhereString())); + if ($queryObject->getGroupByString() != '') { + $count_query = sprintf('select count(*) as "count" from (%s) xet', $count_query); + } + + $count_query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf (' '.$this->comment_syntax, $this->query_id):''; + $result_count = $this->_query($count_query); + $count_output = $this->_fetch($result_count); + $total_count = (int)$count_output->count; + + // Total pages + if ($total_count) { + $total_page = (int) (($total_count - 1) / $queryObject->getLimit()->list_count) + 1; + } else $total_page = 1; + + $virtual_no = $total_count - ($queryObject->getLimit()->page - 1) * $queryObject->getLimit()->list_count; + $data = $this->_fetch($result, $virtual_no); + + $buff = new Object (); + $buff->total_count = $total_count; + $buff->total_page = $total_page; + $buff->page = $queryObject->getLimit()->page->getValue(); + $buff->data = $data; + $buff->page_navigation = new PageHandler($total_count, $total_page, $queryObject->getLimit()->page->getValue(), $queryObject->getLimit()->page_count); + }else{ + $data = $this->_fetch($result); + $buff = new Object (); + $buff->data = $data; + } + return $buff; + } } return new DBMysql; diff --git a/classes/db/DBPostgresql.class.php b/classes/db/DBPostgresql.class.php index fdaa1a1fe..01eefe729 100644 --- a/classes/db/DBPostgresql.class.php +++ b/classes/db/DBPostgresql.class.php @@ -226,15 +226,19 @@ class DBPostgresql extends DB /** * @brief Fetch results **/ - function _fetch($result) + // TODO This is duplicate code - maybe we can find away to abastract the driver + function _fetch($result, $arrayIndexEndValue = NULL) { if (!$this->isConnected() || $this->isError() || !$result) return; while ($tmp = pg_fetch_object($result)) { - $output[] = $tmp; + if($arrayIndexEndValue) $output[$arrayIndexEndValue--] = $tmp; + else $output[] = $tmp; } - if (count($output) == 1) - return $output[0]; + if(count($output)==1){ + if(isset($arrayIndexEndValue)) return $output; + else return $output[0]; + } return $output; } @@ -493,428 +497,137 @@ class DBPostgresql extends DB } - /** - * @brief Return conditional clause - **/ - function getCondition($output) - { - if (!$output->conditions) - return; - $condition = $this->_getCondition($output->conditions, $output->column_type); - if ($condition) - $condition = ' where ' . $condition; - return $condition; - } - - function getLeftCondition($conditions, $column_type) - { - return $this->_getCondition($conditions, $column_type); - } - - - function _getCondition($conditions, $column_type) - { - $condition = ''; - foreach ($conditions as $val) { - $sub_condition = ''; - foreach ($val['condition'] as $v) { - if (!isset($v['value'])) - continue; - if ($v['value'] === '') - continue; - if(!in_array(gettype($v['value']), array('string', 'integer', 'double', 'array'))) continue; - continue; - - $name = $v['column']; - $operation = $v['operation']; - $value = $v['value']; - $type = $this->getColumnType($column_type, $name); - $pipe = $v['pipe']; - - $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); - if (!$value) - $value = $v['value']; - $str = $this->getConditionPart($name, $value, $operation); - if ($sub_condition) - $sub_condition .= ' ' . $pipe . ' '; - $sub_condition .= $str; - } - if ($sub_condition) { - if ($condition && $val['pipe']) - $condition .= ' ' . $val['pipe'] . ' '; - $condition .= '(' . $sub_condition . ')'; - } - } - return $condition; - } - - + /** * @brief Handle the insertAct **/ - function _executeInsertAct($output) + function _executeInsertAct($queryObject) { - // List tables - foreach ($output->tables as $key => $val) { - $table_list[] = $this->prefix . $val; - } - // List columns - foreach ($output->columns as $key => $val) { - $name = $val['name']; - $value = $val['value']; - if ($output->column_type[$name] != 'number') { - $value = "'" . $this->addQuotes($value) . "'"; - if (!$value) - $value = 'null'; - } - // sql injection 문제로 xml 선언이 number인 경우이면서 넘어온 값이 숫자형이 아니면 숫자형으로 강제 형변환 - // elseif (!$value || is_numeric($value)) $value = (int)$value; - else $this->_filterNumber($value); - - $column_list[] = $name; - $value_list[] = $value; - } - - $query = sprintf("insert into %s (%s) values (%s);", implode(',', $table_list), - implode(',', $column_list), implode(',', $value_list)); + $query = $this->getInsertSql($queryObject); + if(is_a($query, 'Object')) return; + return $this->_query($query); } /** * @brief Handle updateAct **/ - function _executeUpdateAct($output) + function _executeUpdateAct($queryObject) { - // List tables - foreach ($output->tables as $key => $val) { - //$table_list[] = $this->prefix.$val.' as '.$key; - $table_list[] = $this->prefix . $val; - } - // List columns - foreach ($output->columns as $key => $val) { - if (!isset($val['value'])) - continue; - $name = $val['name']; - $value = $val['value']; - if (strpos($name, '.') !== false && strpos($value, '.') !== false) - $column_list[] = $name . ' = ' . $value; - else { - if ($output->column_type[$name] != 'number') - $value = "'" . $this->addQuotes($value) . "'"; - // sql injection 문제로 xml 선언이 number인 경우이면서 넘어온 값이 숫자형이 아니면 숫자형으로 강제 형변환 - else $this->_filterNumber($value); - - $column_list[] = sprintf("%s = %s", $name, $value); - } - } - // List the conditional clause - $condition = $this->getCondition($output); - - $query = sprintf("update %s set %s %s", implode(',', $table_list), implode(',', - $column_list), $condition); - + $query = $this->getUpdateSql($queryObject); + if(is_a($query, 'Object')) return; return $this->_query($query); } /** * @brief Handle deleteAct **/ - function _executeDeleteAct($output) + function _executeDeleteAct($queryObject) { - // List tables - foreach ($output->tables as $key => $val) { - $table_list[] = $this->prefix . $val; - } - // List the conditional clause - $condition = $this->getCondition($output); - - $query = sprintf("delete from %s %s", implode(',', $table_list), $condition); - + $query = $this->getDeleteSql($queryObject); + + if(is_a($query, 'Object')) return; return $this->_query($query); } + /** + * + * override + * @param $queryObject + */ + function getSelectSql($query){ + $select = $query->getSelectString(); + if($select == '') return new Object(-1, "Invalid query"); + $select = 'SELECT ' .$select; + + $from = $query->getFromString(); + if($from == '') return new Object(-1, "Invalid query"); + $from = ' FROM '.$from; + + $where = $query->getWhereString(); + if($where != '') $where = ' WHERE ' . $where; + + $groupBy = $query->getGroupByString(); + if($groupBy != '') $groupBy = ' GROUP BY ' . $groupBy; + + $orderBy = $query->getOrderByString(); + if($orderBy != '') $orderBy = ' ORDER BY ' . $orderBy; + + $limit = $query->getLimitString(); + if($limit != '') $limit = ' LIMIT ' . $query->getLimit()->getLimit() . ' OFFSET ' . $query->getLimit()->getOffset(); + + return $select . ' ' . $from . ' ' . $where . ' ' . $groupBy . ' ' . $orderBy . ' ' . $limit; + } + /** * @brief Handle selectAct * * In order to get a list of pages easily when selecting \n * it supports a method as navigation **/ - function _executeSelectAct($output) + function _executeSelectAct($queryObject) { - // List tables - $table_list = array(); - foreach ($output->tables as $key => $val) { - $table_list[] = $this->prefix . $val . ' as ' . $key; - } - - $left_join = array(); - // why??? - $left_tables = (array )$output->left_tables; - - foreach ($left_tables as $key => $val) { - $condition = $this->_getCondition($output->left_conditions[$key], $output-> - column_type); - if ($condition) { - $left_join[] = $val . ' ' . $this->prefix . $output->_tables[$key] . ' as ' . $key . - ' on (' . $condition . ')'; - } - } - - $click_count = array(); - if(!$output->columns){ - $output->columns = array(array('name'=>'*')); - } - - $column_list = array(); - foreach ($output->columns as $key => $val) { - $name = $val['name']; - $alias = $val['alias']; - if($val['click_count']) $click_count[] = $val['name']; - - if (substr($name, -1) == '*') { - $column_list[] = $name; - } elseif (strpos($name, '.') === false && strpos($name, '(') === false) { - if ($alias) - $column_list[$alias] = sprintf('%s as %s', $name, $alias); - else - $column_list[] = sprintf('%s', $name); - } else { - if ($alias) - $column_list[$alias] = sprintf('%s as %s', $name, $alias); - else - $column_list[] = sprintf('%s', $name); + $query = $this->getSelectSql($queryObject); + + if(is_a($query, 'Object')) return; + + $query .= (__DEBUG_QUERY__&1 && $queryObject->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + + // TODO Add support for click count + // TODO Add code for pagination + + $result = $this->_query ($query); + if ($this->isError ()) { + if ($limit && $output->limit->isPageHandler()){ + $buff = new Object (); + $buff->total_count = 0; + $buff->total_page = 0; + $buff->page = 1; + $buff->data = array (); + $buff->page_navigation = new PageHandler (/*$total_count*/0, /*$total_page*/1, /*$page*/1, /*$page_count*/10);//default page handler values + return $buff; + }else + return; } - } - $columns = implode(',', $column_list); - $condition = $this->getCondition($output); + if ($queryObject->getLimit() && $queryObject->getLimit()->isPageHandler()) { + // Total count + $count_query = sprintf('select count(*) as "count" %s %s', 'FROM ' . $queryObject->getFromString(), ($queryObject->getWhereString() === '' ? '' : ' WHERE '. $queryObject->getWhereString())); + if ($queryObject->getGroupByString() != '') { + $count_query = sprintf('select count(*) as "count" from (%s) xet', $count_query); + } - $output->column_list = $column_list; - if ($output->list_count && $output->page) - return $this->_getNavigationData($table_list, $columns, $left_join, $condition, - $output); - // Add a condition to use an index when sorting in order by list_order, update_order - if ($output->order) { - $conditions = $this->getConditionList($output); - if (!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach ($output->order as $key => $val) { - $col = $val[0]; - if (!in_array($col, array('list_order', 'update_order'))) - continue; - if ($condition) - $condition .= sprintf(' and %s < 2100000000 ', $col); - else - $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } + $count_query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf (' '.$this->comment_syntax, $this->query_id):''; + $result_count = $this->_query($count_query); + $count_output = $this->_fetch($result_count); + $total_count = (int)$count_output->count; + + // Total pages + if ($total_count) { + $total_page = (int) (($total_count - 1) / $queryObject->getLimit()->list_count) + 1; + } else $total_page = 1; + + + $virtual_no = $total_count - ($queryObject->getLimit()->page - 1) * $queryObject->getLimit()->list_count; + $data = $this->_fetch($result, $virtual_no); + $buff = new Object (); + $buff->total_count = $total_count; + $buff->total_page = $total_page; + $buff->page = $queryObject->getLimit()->page->getValue(); + $buff->data = $data; + $buff->page_navigation = new PageHandler($total_count, $total_page, $queryObject->getLimit()->page->getValue(), $queryObject->getLimit()->page_count); + }else{ + $data = $this->_fetch($result); + $buff = new Object (); + $buff->data = $data; + } - if (count($output->groups)) { - /* - var_dump("= column output start = "); - var_dump(sizeof ($output->columns) . " = end length == "); - var_dump($output->columns); - var_dump("= column output end = " . "\n"); - var_dump($output->groups); - var_dump("=== " . "\n"); - var_dump(debug_backtrace()); - - foreach($output->columns as $key => $val) { - $name = $val['name']; - $alias = $val['alias']; - } */ - $group_list = array(); - foreach ($output->groups as $gkey => $gval) { - foreach ($output->columns as $key => $val) { - $name = $val['name']; - $alias = $val['alias']; - if (trim($name) == trim($gval)) { - $group_list[] = $alias; - break; - } - } - - if($column_list[$gval]) $output->arg_columns[] = $column_list[$gval]; - - } - $groupby_query = sprintf(' group by %s', implode(',', $group_list)); - // var_dump($query); - } - - if ($output->order) { - foreach ($output->order as $key => $val) { - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - if(count($output->arg_columns) && $column_list[$val[0]]) $output->arg_columns[] = $column_list[$val[0]]; - } - if (count($index_list)) $orderby_query = ' order by ' . implode(',', $index_list); - } - - if(count($output->arg_columns)) - { - $columns = join(',',$output->arg_columns); - } - - $query = sprintf("select %s from %s %s %s %s", $columns, implode(',', $table_list), implode(' ', $left_join), $condition, $groupby_query.$orderby_query); - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - $result = $this->_query($query); - if ($this->isError()) - return; - - if(count($click_count)>0 && count($output->conditions)>0){ - $_query = ''; - foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); - $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); - $this->_query($_query); - } - - - $data = $this->_fetch($result); - - $buff = new Object(); - $buff->data = $data; - return $buff; + return $buff; } - - /** - * @brief Paging is handled if navigation information exists in the query xml - * - * It is quite convenient although its structure is not good at all .. -_-; - **/ - function _getNavigationData($table_list, $columns, $left_join, $condition, $output) - { - require_once (_XE_PATH_ . 'classes/page/PageHandler.class.php'); - - $column_list = $output->column_list; - /* - // Modified to find total number of SELECT queries having group by clause - // If it works correctly, uncomment the following codes - // - $count_condition = count($output->groups) ? sprintf('%s group by %s', $condition, implode(', ', $output->groups)) : $condition; - $total_count = $this->getCountCache($output->tables, $count_condition); - if ($total_count === false) { - $count_query = sprintf('select count(*) as count from %s %s %s', implode(', ', $table_list), implode(' ', $left_join), $count_condition); - if (count($output->groups)) - $count_query = sprintf('select count(*) as count from (%s) xet', $count_query); - $result = $this->_query($count_query); - $count_output = $this->_fetch($result); - $total_count = (int)$count_output->count; - $this->putCountCache($output->tables, $count_condition, $total_count); - } - */ - - // Get a total count - $count_query = sprintf("select count(*) as count from %s %s %s", implode(',', $table_list), implode(' ', $left_join), $condition); - $count_query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id . ' count(*)'):''; - $result = $this->_query($count_query); - $count_output = $this->_fetch($result); - $total_count = (int)$count_output->count; - - $list_count = $output->list_count['value']; - if (!$list_count) $list_count = 20; - $page_count = $output->page_count['value']; - if (!$page_count) $page_count = 10; - $page = $output->page['value']; - if (!$page) - $page = 1; - - // Get a total page - if ($total_count) $total_page = (int)(($total_count - 1) / $list_count) + 1; - else $total_page = 1; - - // Check Page variables - if ($page > $total_page) $page = $total_page; - $start_count = ($page - 1) * $list_count; - // Add a condition to use an index when sorting in order by list_order, update_order - if ($output->order) { - $conditions = $this->getConditionList($output); - if (!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach ($output->order as $key => $val) { - $col = $val[0]; - if (!in_array($col, array('list_order', 'update_order'))) - continue; - if ($condition) - $condition .= sprintf(' and %s < 2100000000 ', $col); - else - $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - if (count($output->groups)) { - /* - var_dump("= column output start = "); - var_dump(sizeof ($output->columns) . " = end length == "); - var_dump($output->columns); - var_dump("= column output end = " . "\n"); - var_dump($output->groups); - var_dump("=== " . "\n"); - var_dump(debug_backtrace()); - - foreach($output->columns as $key => $val) { - $name = $val['name']; - $alias = $val['alias']; - } */ - $group_list = array(); - foreach ($output->groups as $gkey => $gval) { - foreach ($output->columns as $key => $val) { - $name = $val['name']; - $alias = $val['alias']; - if (trim($name) == trim($gval)) { - $group_list[] = $alias; - break; - } - } - - if($column_list[$gval]) $output->arg_columns[] = $column_list[$gval]; - - } - $groupby_query = sprintf(' group by %s', implode(',', $group_list)); - // var_dump($query); - } - - if ($output->order) { - foreach ($output->order as $key => $val) { - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - if(count($output->arg_columns) && $column_list[$val[0]]) $output->arg_columns[] = $column_list[$val[0]]; - } - if (count($index_list)) $orderby_query = ' order by ' . implode(',', $index_list); - } - - if(count($output->arg_columns)) - { - $columns = join(',',$output->arg_columns); - } - - $query = sprintf("select %s from %s %s %s", $columns, implode(',', $table_list), implode(' ', $left_join), $condition); - $query = sprintf('%s offset %d limit %d', $query, $start_count, $list_count); - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - - $result = $this->_query($query); - if ($this->isError()) { - $buff = new Object(); - $buff->total_count = 0; - $buff->total_page = 0; - $buff->page = 1; - $buff->data = array(); - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - - $virtual_no = $total_count - ($page - 1) * $list_count; - while ($tmp = pg_fetch_object($result)) { - $data[$virtual_no--] = $tmp; - } - - $buff = new Object(); - $buff->total_count = $total_count; - $buff->total_page = $total_page; - $buff->page = $page; - $buff->data = $data; - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; + + function getParser(){ + return new DBParser('"'); } } diff --git a/classes/db/DBSqlite2.class.php b/classes/db/DBSqlite2.class.php index 7802e50e1..93f05c941 100644 --- a/classes/db/DBSqlite2.class.php +++ b/classes/db/DBSqlite2.class.php @@ -425,7 +425,7 @@ } // sql injection 문제로 xml 선언이 number인 경우이면서 넘어온 값이 숫자형이 아니면 숫자형으로 강제 형변환 // elseif(!$value || is_numeric($value)) $value = (int)$value; - else $this->_filterNumber($value); + else $this->_filterNumber(&$value); $column_list[] = $name; $value_list[] = $value; @@ -454,7 +454,7 @@ else { if($output->column_type[$name]!='number') $value = "'".$this->addQuotes($value)."'"; // sql injection 문제로 xml 선언이 number인 경우이면서 넘어온 값이 숫자형이 아니면 숫자형으로 강제 형변환 - else $this->_filterNumber($value); + else $this->_filterNumber(&$value); $column_list[] = sprintf("%s = %s", $name, $value); } @@ -473,7 +473,7 @@ // List the conditional clause $condition = $this->getCondition($output); foreach($table_list as $key => $val) { - $condition = preg_replace('/'.$key.'\\./i', $val.'.', $condition); + $condition = eregi_replace($key.'\\.', $val.'.', $condition); } // List columns foreach($output->columns as $key => $val) { diff --git a/classes/db/DBSqlite3_pdo.class.php b/classes/db/DBSqlite3_pdo.class.php index e8a619c61..ac624f377 100644 --- a/classes/db/DBSqlite3_pdo.class.php +++ b/classes/db/DBSqlite3_pdo.class.php @@ -399,389 +399,118 @@ } } - /** - * @brief Return conditional clause(where) - **/ - function getCondition($output) { - if(!$output->conditions) return; - $condition = $this->_getCondition($output->conditions,$output->column_type); - if($condition) $condition = ' where '.$condition; - return $condition; - } + /** + * @brief insertAct + * */ + function _executeInsertAct($queryObject) { + $query = $this->getInsertSql($queryObject); + if (is_a($query, 'Object')) + return; - function getLeftCondition($conditions,$column_type){ - return $this->_getCondition($conditions,$column_type); - } + $this->_prepare($query); + $val_count = count($val_list); + for ($i = 0; $i < $val_count; $i++) + $this->_bind($val_list[$i]); - function _getCondition($conditions,$column_type) { - $condition = ''; - foreach($conditions as $val) { - $sub_condition = ''; - foreach($val['condition'] as $v) { - if(!isset($v['value'])) continue; - if($v['value'] === '') continue; - if(!in_array(gettype($v['value']), array('string', 'integer', 'double', 'array'))) continue; + return $this->_execute(); + } - $name = $v['column']; - $operation = $v['operation']; - $value = $v['value']; - $type = $this->getColumnType($column_type,$name); - $pipe = $v['pipe']; + /** + * @brief updateAct + * */ + function _executeUpdateAct($queryObject) { + $query = $this->getUpdateSql($queryObject); + if (is_a($query, 'Object')) + return; - $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); - if(!$value) $value = $v['value']; - $str = $this->getConditionPart($name, $value, $operation); - if($sub_condition) $sub_condition .= ' '.$pipe.' '; - $sub_condition .= $str; - } - if($sub_condition) { - if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; - $condition .= '('.$sub_condition.')'; - } - } - return $condition; - } + $this->_prepare($query); + return $this->_execute(); + } - /** - * @brief insertAct - **/ - function _executeInsertAct($output) { - // list tables - foreach($output->tables as $key => $val) { - $table_list[] = $this->prefix.$val; - } - // list columns - foreach($output->columns as $key => $val) { - $name = $val['name']; - $value = $val['value']; + /** + * @brief deleteAct + * */ + function _executeDeleteAct($queryObject) { + $query = $this->getDeleteSql($queryObject); + if (is_a($query, 'Object')) + return; - $key_list[] = $name; + $this->_prepare($query); + return $this->_execute(); + } - if($output->column_type[$name]!='number') $val_list[] = $this->addQuotes($value); - else { - $this->_filterNumber($value); - $val_list[] = $value; - } + /** + * @brief selectAct + * + * To fetch a list of the page conveniently when selecting, \n + * navigation method supported + * */ + function _executeSelectAct($queryObject) { + $query = $this->getSelectSql($queryObject); + if (is_a($query, 'Object')) + return; - $prepare_list[] = '?'; - } + $this->_prepare($query); + $data = $this->_execute(); + if ($this->isError()) + return; - $query = sprintf("INSERT INTO %s (%s) VALUES (%s);", implode(',',$table_list), implode(',',$key_list), implode(',',$prepare_list)); + if ($this->isError()) + return $this->queryError($queryObject); + else + return $this->queryPageLimit($queryObject, $data); + } - $this->_prepare($query); - - $val_count = count($val_list); - for($i=0;$i<$val_count;$i++) $this->_bind($val_list[$i]); - - return $this->_execute(); - } - - /** - * @brief updateAct - **/ - function _executeUpdateAct($output) { - $table_count = count(array_values($output->tables)); - // If a target table is one - if($table_count == 1) { - // list tables - list($target_table) = array_values($output->tables); - $target_table = $this->prefix.$target_table; - // list columns - foreach($output->columns as $key => $val) { - if(!isset($val['value'])) continue; - $name = $val['name']; - $value = $val['value']; - if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value; - else { - if($output->column_type[$name]!='number') $value = "'".$this->addQuotes($value)."'"; - else $this->_filterNumber($value); - - $column_list[] = sprintf("%s = %s", $name, $value); - } - } - // List where cluase - $condition = $this->getCondition($output); - - $query = sprintf("update %s set %s %s", $target_table, implode(',',$column_list), $condition); - // If tables to update are morea than two (In sqlite, it is possible to update a single table only. Let me know if you know a better way) - } elseif($table_count == 2) { - // List tables - foreach($output->tables as $key => $val) { - $table_list[$val] = $this->prefix.$key; - } - list($source_table, $target_table) = array_values($table_list); - // List where cluase - $condition = $this->getCondition($output); - foreach($table_list as $key => $val) { - $condition = preg_replace('/'.$key.'\\./i', $val.'.', $condition); - } - // List columns - foreach($output->columns as $key => $val) { - if(!isset($val['value'])) continue; - $name = $val['name']; - $value = $val['value']; - list($s_prefix, $s_column) = explode('.',$name); - list($t_prefix, $t_column) = explode('.',$value); - - $s_table = $table_list[$s_prefix]; - $t_table = $table_list[$t_prefix]; - $column_list[] = sprintf(' %s = (select %s from %s %s) ', $s_column, $t_column, $t_table, $condition); - } - - $query = sprintf('update %s set %s where exists(select * from %s %s)', $source_table, implode(',', $column_list), $target_table, $condition); - } else { - return; - } - - $this->_prepare($query); - return $this->_execute(); - } - - /** - * @brief deleteAct - **/ - function _executeDeleteAct($output) { - // List tables - foreach($output->tables as $key => $val) { - $table_list[] = $this->prefix.$val; - } - // List the conditional clause - $condition = $this->getCondition($output); - - $query = sprintf("delete from %s %s", implode(',',$table_list), $condition); - - $this->_prepare($query); - return $this->_execute(); - } - - /** - * @brief selectAct - * - * To fetch a list of the page conveniently when selecting, \n - * navigation method supported - **/ - function _executeSelectAct($output) { - // List tables - $table_list = array(); - foreach($output->tables as $key => $val) { - $table_list[] = $this->prefix.$val.' as '.$key; - } - - $left_join = array(); - // why??? - $left_tables= (array)$output->left_tables; - - foreach($left_tables as $key => $val) { - $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); - if($condition){ - $left_join[] = $val . ' '.$this->prefix.$output->_tables[$key].' as '.$key . ' on (' . $condition . ')'; - } - } - - - $click_count = array(); - if(!$output->columns){ - $output->columns = array(array('name'=>'*')); - } - - $column_list = array(); - foreach($output->columns as $key => $val) { - $name = $val['name']; - $alias = $val['alias']; - if($val['click_count']) $click_count[] = $val['name']; - - if(substr($name,-1) == '*') { - $column_list[] = $name; - } elseif(strpos($name,'.')===false && strpos($name,'(')===false) { - if($alias) $column_list[$alias] = sprintf('%s as %s', $name, $alias); - else $column_list[] = sprintf('%s',$name); - } else { - if($alias) $column_list[$alias] = sprintf('%s as %s', $name, $alias); - else $column_list[] = sprintf('%s',$name); - } - } - $columns = implode(',',$column_list); - - $condition = $this->getCondition($output); - - $output->column_list = $column_list; - if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); - // add the condition to the query to use an index for ordering by list_order, update_order - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - if(count($output->groups)){ - $groupby_query = sprintf(' group by %s', implode(',',$output->groups)); - if(count($output->arg_columns)) - { - foreach($output->groups as $group) - { - if($column_list[$group]) $output->arg_columns[] = $column_list[$group]; - } - } - } - - if($output->order) { - foreach($output->order as $key => $val) { - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - if(count($output->arg_columns) && $column_list[$val[0]]) $output->arg_columns[] = $column_list[$val[0]]; - } - if(count($index_list)) $orderby_query = ' order by '.implode(',',$index_list); - } - - if(count($output->arg_columns)) - { - $columns = join(',',$output->arg_columns); - } - - $query = sprintf("select %s from %s %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition, $groupby_query.$orderby_query); - // apply when using list_count - if($output->list_count['value']) $query = sprintf('%s limit %d', $query, $output->list_count['value']); - - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - $this->_prepare($query); - $data = $this->_execute(); - if($this->isError()) return; - - if(count($click_count)>0 && count($output->conditions)>0){ - $_query = ''; - foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); - $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); - $this->_query($_query); - } - - $buff = new Object(); - $buff->data = $data; - return $buff; - } - - /** - * @brief Paging is handled if navigation information exists in the query xml - * - * It is quite convenient although its structure is not good at all .. -_-; - **/ - function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { - require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); - - $column_list = $output->column_list; - /* - // Modified to find total number of SELECT queries having group by clause - // If it works correctly, uncomment the following codes - // - $count_condition = count($output->groups) ? sprintf('%s group by %s', $condition, implode(', ', $output->groups)) : $condition; - $total_count = $this->getCountCache($output->tables, $count_condition); - if($total_count === false) { - $count_query = sprintf("select count(*) as count from %s %s %s", implode(', ', $table_list), implode(' ', $left_join), $count_condition); - if (count($output->groups)) - $count_query = sprintf('select count(*) as count from (%s) xet', $count_query); - $result = $this->_query($count_query); - $count_output = $this->_fetch($result); - $total_count = (int)$count_output->count; - $this->putCountCache($output->tables, $count_condition, $total_count); - } - */ - // Get a total count - $count_query = sprintf("select count(*) as count from %s %s %s", implode(',',$table_list),implode(' ',$left_join), $condition); - $count_query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id . ' count(*)'):''; - $this->_prepare($count_query); - $count_output = $this->_execute(); - $total_count = (int)$count_output->count; - - $list_count = $output->list_count['value']; - if(!$list_count) $list_count = 20; - $page_count = $output->page_count['value']; - if(!$page_count) $page_count = 10; - $page = $output->page['value']; - if(!$page) $page = 1; - // Get a total page - if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; - else $total_page = 1; - // Check Page variables - if($page > $total_page) $page = $total_page; - $start_count = ($page-1)*$list_count; - // Add a condition to use an index when sorting in order by list_order, update_order - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - if(count($output->groups)){ - $groupby_query = sprintf(' group by %s', implode(',',$output->groups)); - if(count($output->arg_columns)) - { - foreach($output->groups as $group) - { - if($column_list[$group]) $output->arg_columns[] = $column_list[$group]; - } - } - } - - if($output->order) { - foreach($output->order as $key => $val) { - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - if(count($output->arg_columns) && $column_list[$val[0]]) $output->arg_columns[] = $column_list[$val[0]]; - } - if(count($index_list)) $orderby_query = ' order by '.implode(',',$index_list); - } - - if(count($output->arg_columns)) - { - $columns = join(',',$output->arg_columns); - } - - // Return the result - $buff = new Object(); + function queryError($queryObject) { + if ($queryObject->getLimit() && $queryObject->getLimit()->isPageHandler()) { + $buff = new Object (); $buff->total_count = 0; $buff->total_page = 0; $buff->page = 1; $buff->data = array(); - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); + $buff->page_navigation = new PageHandler(/* $total_count */0, /* $total_page */1, /* $page */1, /* $page_count */10); //default page handler values + return $buff; + }else + return; + } - // Query Execution - $query = sprintf("select %s from %s %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition, $groupby_query.$orderby_query); - $query = sprintf('%s limit %d, %d', $query, $start_count, $list_count); - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - - $this->_prepare($query); - - if($this->isError()) { - $this->setError($this->handler->errorCode(), print_r($this->handler->errorInfo(),true)); - $this->actFinish(); - return $buff; + function queryPageLimit($queryObject, $data) { + if ($queryObject->getLimit() && $queryObject->getLimit()->isPageHandler()) { + // Total count + $count_query = sprintf('select count(*) as "count" %s %s', 'FROM ' . $queryObject->getFromString(), ($queryObject->getWhereString() === '' ? '' : ' WHERE ' . $queryObject->getWhereString())); + if ($queryObject->getGroupByString() != '') { + $count_query = sprintf('select count(*) as "count" from (%s) xet', $count_query); } - $this->stmt->execute(); + $count_query .= ( __DEBUG_QUERY__ & 1 && $output->query_id) ? sprintf(' ' . $this->comment_syntax, $this->query_id) : ''; + $this->_prepare($count_query); + $count_output = $this->_execute(); + $total_count = (int) $count_output->count; - if($this->stmt->errorCode() != '00000') { - $this->setError($this->stmt->errorCode(), print_r($this->stmt->errorInfo(),true)); + // Total pages + if ($total_count) { + $total_page = (int) (($total_count - 1) / $queryObject->getLimit()->list_count) + 1; + } else + $total_page = 1; + + $this->_prepare($this->getSelectSql($queryObject)); + $this->stmt->execute(); + if ($this->stmt->errorCode() != '00000') { + $this->setError($this->stmt->errorCode(), print_r($this->stmt->errorInfo(), true)); $this->actFinish(); return $buff; } $output = null; - $virtual_no = $total_count - ($page-1)*$list_count; - while($tmp = $this->stmt->fetch(PDO::FETCH_ASSOC)) { + $virtual_no = $total_count - ($queryObject->getLimit()->page - 1) * $queryObject->getLimit()->list_count; + //$data = $this->_fetch($result, $virtual_no); + while ($tmp = $this->stmt->fetch(PDO::FETCH_ASSOC)) { unset($obj); - foreach($tmp as $key => $val) { + foreach ($tmp as $key => $val) { $pos = strpos($key, '.'); - if($pos) $key = substr($key, $pos+1); + if ($pos) + $key = substr($key, $pos + 1); $obj->{$key} = $val; } $data[$virtual_no--] = $obj; @@ -790,16 +519,21 @@ $this->stmt = null; $this->actFinish(); - $buff = new Object(); + $buff = new Object (); $buff->total_count = $total_count; $buff->total_page = $total_page; - $buff->page = $page; + $buff->page = $queryObject->getLimit()->page->getValue(); + $buff->data = $data; + $buff->page_navigation = new PageHandler($total_count, $total_page, $queryObject->getLimit()->page->getValue(), $queryObject->getLimit()->page_count); + }else { + //$data = $this->_fetch($result); + $buff = new Object (); $buff->data = $data; - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; } + return $buff; } +} + return new DBSqlite3_pdo; ?> diff --git a/classes/db/queryparts/Query.class.php b/classes/db/queryparts/Query.class.php new file mode 100644 index 000000000..4943a39a0 --- /dev/null +++ b/classes/db/queryparts/Query.class.php @@ -0,0 +1,296 @@ +queryID = $queryID; + $this->action = $action; + + if(!isset($tables)) return; + $this->columns = $this->setColumns($columns); + $this->tables = $this->setTables($tables); + $this->conditions = $this->setConditions($conditions); + $this->groups = $this->setGroups($groups); + $this->orderby = $this->setOrder($orderby); + $this->limit = $this->setLimit($limit); + } + + function show(){ + return true; + } + + function setQueryId($queryID){ + $this->queryID = $queryID; + } + + function setAction($action){ + $this->action = $action; + } + + function setColumnList($columnList){ + $this->columnList = $columnList; + } + + function setColumns($columns){ + if(!isset($columns) || count($columns) === 0){ + $this->columns = array(new StarExpression()); + return; + } + + if(!is_array($columns)) $columns = array($columns); + + $this->columns = $columns; + } + + function setTables($tables){ + if(!isset($tables) || count($tables) === 0){ + $this->setError(true); + $this->setMessage("You must provide at least one table for the query."); + return; + } + + if(!is_array($tables)) $tables = array($tables); + + $this->tables = $tables; + } + + function setConditions($conditions){ + if(!isset($conditions) || count($conditions) === 0) return; + if(!is_array($conditions)) $conditions = array($conditions); + + $this->conditions = $conditions; + } + + function setGroups($groups){ + if(!isset($groups) || count($groups) === 0) return; + if(!is_array($groups)) $groups = array($groups); + + $this->groups = $groups; + } + + function setOrder($order){ + if(!isset($order) || count($order) === 0) return; + if(!is_array($order)) $order = array($order); + + $this->orderby = $order; + } + + function setLimit($limit = NULL){ + if(!isset($limit)) return; + $this->limit = $limit; + } + + // START Fluent interface + function select($columns= null){ + $this->action = 'select'; + $this->setColumns($columns); + return $this; + } + + function from($tables){ + $this->setTables($tables); + return $this; + } + + function where($conditions){ + $this->setConditions($conditions); + return $this; + } + + function groupBy($groups){ + $this->setGroups($groups); + return $this; + } + + function orderBy($order){ + $this->setOrder($order); + return $this; + } + + function limit($limit){ + $this->setLimit($limit); + return $this; + } + // END Fluent interface + + function getAction(){ + return $this->action; + } + + function getSelectString($with_values = true){ + if(isset($this->columnList)){ + $selectColumns = array(); + $dbParser = XmlQueryParser::getDBParser(); + + foreach($this->columnList as $columnName){ + $columnName = $dbParser->escapeColumn($columnName); + $selectColumns[] = new SelectExpression($columnName); + } + } + else + $selectColumns = $this->columns; + + $select = ''; + foreach($selectColumns as $column){ + if($column->show()) + if(is_a($column, 'Subquery')){ + $select .= $column->toString($with_values) . ' as '. $column->getAlias() .', '; + } + else + $select .= $column->getExpression($with_values) . ', '; + } + if(trim($select) == '') return ''; + $select = substr($select, 0, -2); + return $select; + } + + function getUpdateString($with_values = true){ + return $this->getSelectString($with_values); + } + + function getInsertString($with_values = true){ + $columnsList = ''; + $valuesList = ''; + foreach($this->columns as $column){ + if($column->show()){ + $columnsList .= $column->getColumnName() . ', '; + $valuesList .= $column->getValue($with_values) . ', '; + } + } + $columnsList = substr($columnsList, 0, -2); + $valuesList = substr($valuesList, 0, -2); + + return "($columnsList) \n VALUES ($valuesList)"; + } + + function getTables(){ + return $this->tables; + } + + // from table_a + // from table_a inner join table_b on x=y + // from (select * from table a) as x + // from (select * from table t) as x inner join table y on y.x + function getFromString($with_values = true){ + $from = ''; + $simple_table_count = 0; + foreach($this->tables as $table){ + if($table->isJoinTable() || !$simple_table_count) $from .= $table->toString($with_values) . ' '; + else $from .= ', '.$table->toString($with_values) . ' '; + + if(is_a($table, 'Subquery')) $from .= $table->getAlias() ? ' as ' . $table->getAlias() . ' ' : ' '; + + $simple_table_count++; + } + if(trim($from) == '') return ''; + return $from; + } + + function getWhereString($with_values = true){ + $where = ''; + if(count($this->conditions) > 0){ + $condition_count = 0; + foreach($this->conditions as $conditionGroup){ + $condition_string = $conditionGroup->toString($with_values); + if($condition_string !== '') $condition_count++; + if($condition_count === 1){ + $conditionGroup->setPipe(""); + $condition_string = $conditionGroup->toString($with_values); + } + $where .= $condition_string; + } + if(trim($where) == '') return ''; + + } + return $where; + } + + function getGroupByString(){ + $groupBy = ''; + if($this->groups) if($this->groups[0] !== "") + $groupBy = implode(', ', $this->groups); + return $groupBy; + } + + function getOrderByString(){ + if(count($this->orderby) === 0) return ''; + $orderBy = ''; + foreach($this->orderby as $order){ + $orderBy .= $order->toString() .', '; + } + $orderBy = substr($orderBy, 0, -2); + return $orderBy; + } + + function getLimit(){ + return $this->limit; + } + + function getLimitString(){ + $limit = ''; + if(count($this->limit) > 0){ + $limit = ''; + $limit .= $this->limit->toString(); + } + return $limit; + } + + function getFirstTableName(){ + return $this->tables[0]->getName(); + } + + function getArguments(){ + if(!isset($this->arguments)){ + $this->arguments = array(); + + // Column arguments + if(count($this->columns) > 0){ // The if is for delete statements, all others must have columns + foreach($this->columns as $column){ + if($column->show()){ + $arg = $column->getArgument(); + if($arg) $this->arguments[] = $arg; + } + } + } + + // Condition arguments + if(count($this->conditions) > 0) + foreach($this->conditions as $conditionGroup){ + $args = $conditionGroup->getArguments(); + if(count($args) > 0) $this->arguments = array_merge($this->arguments, $args); + } + + // Navigation arguments + if(count($this->orderby) > 0) + foreach($this->orderby as $order){ + $args = $order->getArguments(); + if(count($args) > 0) $this->arguments = array_merge($this->arguments, $args); + } + } + return $this->arguments; + } + } + + + +?> \ No newline at end of file diff --git a/classes/db/queryparts/Subquery.class.php b/classes/db/queryparts/Subquery.class.php new file mode 100644 index 000000000..3ec2e1a94 --- /dev/null +++ b/classes/db/queryparts/Subquery.class.php @@ -0,0 +1,38 @@ +alias = $alias; + + $this->queryID = null; + $this->action = "select"; + + $this->columns = $columns; + $this->tables = $tables; + $this->conditions = $conditions; + $this->groups = $groups; + $this->orderby = $orderby; + $this->limit = $limit; + $this->join_type = $join_type; + } + + function getAlias(){ + return $this->alias; + } + + function isJoinTable(){ + if($this->join_type) return true; + return false; + } + + function toString($with_values = true){ + $oDB = &DB::getInstance(); + return '(' .$oDB->getSelectSql($this, $with_values) . ')'; + + } + } + +?> \ No newline at end of file diff --git a/classes/db/queryparts/condition/Condition.class.php b/classes/db/queryparts/condition/Condition.class.php new file mode 100644 index 000000000..e9501b516 --- /dev/null +++ b/classes/db/queryparts/condition/Condition.class.php @@ -0,0 +1,140 @@ +column_name = $column_name; + $this->argument = $argument; + $this->operation = $operation; + $this->pipe = $pipe; + if($this->hasArgument()) + $this->_value = $argument->getValue(); + else if(is_a($this->argument, 'Subquery')) + $this->_value = $argument->toString(); + else + $this->_value = $argument; + } + + function hasArgument(){ + return is_a($this->argument, 'Argument'); + } + + function getArgument(){ + if($this->hasArgument()) return $this->argument; + return null; + } + + function toString($withValue = true){ + if(!$this->show()) return ''; + if($withValue) + return $this->toStringWithValue(); + return $this->toStringWithoutValue(); + } + + function toStringWithoutValue(){ + if($this->hasArgument()){ + $value = $this->argument->getUnescapedValue(); + + if(is_array($value)){ + $q = ''; + foreach ($value as $v) $q .= '?,'; + if($q !== '') $q = substr($q, 0, -1); + $q = '(' . $q . ')'; + } + else $q = '?'; + return $this->pipe . ' ' . $this->getConditionPart($q); + } + else return $this->toString(); + } + + function toStringWithValue(){ + return $this->pipe . ' ' . $this->getConditionPart($this->_value); + } + + function setPipe($pipe){ + $this->pipe = $pipe; + } + + function show(){ + if($this->hasArgument() && !$this->argument->isValid()) return false; + if($this->hasArgument() && ($this->_value === '\'\'')) return false; + if(is_array($this->_value) && count($this->_value) === 1 && $this->_value[0] === '') return false; + switch($this->operation) { + case 'equal' : + case 'more' : + case 'excess' : + case 'less' : + case 'below' : + case 'like_tail' : + case 'like_prefix' : + case 'like' : + case 'in' : + case 'notin' : + case 'notequal' : + // if variable is not set or is not string or number, return + if(!isset($this->_value)) return false; + if($this->_value === '') return false; + if(!in_array(gettype($this->_value), array('string', 'integer'))) return false; + break; + case 'between' : + if(!is_array($this->_value)) return false; + if(count($this->_value)!=2) return false; + + } + return true; + } + + function getConditionPart($value) { + $name = $this->column_name; + $operation = $this->operation; + + switch($operation) { + case 'equal' : + return $name.' = '.$value; + break; + case 'more' : + return $name.' >= '.$value; + break; + case 'excess' : + return $name.' > '.$value; + break; + case 'less' : + return $name.' <= '.$value; + break; + case 'below' : + return $name.' < '.$value; + break; + case 'like_tail' : + case 'like_prefix' : + case 'like' : + return $name.' like '.$value; + break; + case 'in' : + return $name.' in '.$value; + break; + case 'notin' : + return $name.' not in '.$value; + break; + case 'notequal' : + return $name.' <> '.$value; + break; + case 'notnull' : + return $name.' is not null'; + break; + case 'null' : + return $name.' is null'; + break; + case 'between' : + return $name.' between ' . $value[0] . ' and ' . $value[1]; + break; + } + } + } + +?> \ No newline at end of file diff --git a/classes/db/queryparts/condition/ConditionGroup.class.php b/classes/db/queryparts/condition/ConditionGroup.class.php new file mode 100644 index 000000000..f801ac63c --- /dev/null +++ b/classes/db/queryparts/condition/ConditionGroup.class.php @@ -0,0 +1,50 @@ +conditions = $conditions; + $this->pipe = $pipe; + } + + function setPipe($pipe){ + $this->pipe = $pipe; + } + + function toString($with_value = true){ + if($this->pipe !== "") + $group = $this->pipe .' ('; + else $group = ''; + + $cond_indx = 0; + + foreach($this->conditions as $condition){ + if($condition->show()){ + if($cond_indx === 0) $condition->setPipe(""); + $group .= $condition->toString($with_value) . ' '; + $cond_indx++; + } + } + // If the group has no conditions in it, return '' + if($cond_indx === 0) return ''; + + if($this->pipe !== "") + $group .= ')'; + + return $group; + } + + function getArguments(){ + $args = array(); + foreach($this->conditions as $condition){ + if($condition->show()){ + $arg = $condition->getArgument(); + if($arg) $args[] = $arg; + } + } + return $args; + } + } +?> \ No newline at end of file diff --git a/classes/db/queryparts/expression/ClickCountExpression.class.php b/classes/db/queryparts/expression/ClickCountExpression.class.php new file mode 100644 index 000000000..a112368e8 --- /dev/null +++ b/classes/db/queryparts/expression/ClickCountExpression.class.php @@ -0,0 +1,33 @@ +click_count = false; + return; + } + $this->click_count = $click_count; + } + + function show() { + return $this->click_count; + } + + function getExpression(){ + return "$this->column_name = $this->column_name + 1"; + } + } + +?> \ No newline at end of file diff --git a/classes/db/queryparts/expression/DeleteExpression.class.php b/classes/db/queryparts/expression/DeleteExpression.class.php new file mode 100644 index 000000000..611510109 --- /dev/null +++ b/classes/db/queryparts/expression/DeleteExpression.class.php @@ -0,0 +1,35 @@ +value = $value; + } + + function getExpression(){ + return "$this->column_name = $this->value"; + } + + function getValue(){ + // TODO Escape value according to column type instead of variable type + if(!is_numeric($this->value)) return "'".$this->value."'"; + return $this->value; + } + + function show(){ + if(!$this->value) return false; + return true; + } + } + + +?> \ No newline at end of file diff --git a/classes/db/queryparts/expression/Expression.class.php b/classes/db/queryparts/expression/Expression.class.php new file mode 100644 index 000000000..bd11929f6 --- /dev/null +++ b/classes/db/queryparts/expression/Expression.class.php @@ -0,0 +1,30 @@ +column_name = $column_name; + } + + function getColumnName(){ + return $this->column_name; + } + + function show() { + return false; + } + + function getExpression() { + } + } \ No newline at end of file diff --git a/classes/db/queryparts/expression/InsertExpression.class.php b/classes/db/queryparts/expression/InsertExpression.class.php new file mode 100644 index 000000000..07c8a14f0 --- /dev/null +++ b/classes/db/queryparts/expression/InsertExpression.class.php @@ -0,0 +1,35 @@ +argument = $argument; + } + + function getValue($with_values = true){ + if($with_values) + return $this->argument->getValue(); + return '?'; + } + + function show(){ + $value = $this->argument->getValue(); + if(!isset($value)) return false; + return true; + } + + function getArgument(){ + return $this->argument; + } + } + +?> \ No newline at end of file diff --git a/classes/db/queryparts/expression/SelectExpression.class.php b/classes/db/queryparts/expression/SelectExpression.class.php new file mode 100644 index 000000000..8a9db88ba --- /dev/null +++ b/classes/db/queryparts/expression/SelectExpression.class.php @@ -0,0 +1,36 @@ +column_alias = $alias; + } + + function getExpression() { + return sprintf("%s%s", $this->column_name, $this->column_alias ? " as ".$this->column_alias : ""); + } + + function show() { + return true; + } + + function getArgument(){ + return null; + } + } +?> \ No newline at end of file diff --git a/classes/db/queryparts/expression/StarExpression.class.php b/classes/db/queryparts/expression/StarExpression.class.php new file mode 100644 index 000000000..eb8d35030 --- /dev/null +++ b/classes/db/queryparts/expression/StarExpression.class.php @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/classes/db/queryparts/expression/UpdateExpression.class.php b/classes/db/queryparts/expression/UpdateExpression.class.php new file mode 100644 index 000000000..eb938dc8b --- /dev/null +++ b/classes/db/queryparts/expression/UpdateExpression.class.php @@ -0,0 +1,56 @@ +argument = $argument; + } + + function getExpression($with_value = true){ + if($with_value) + return $this->getExpressionWithValue(); + return $this->getExpressionWithoutValue(); + } + + function getExpressionWithValue(){ + $value = $this->argument->getValue(); + $operation = $this->argument->getColumnOperation(); + if(isset($operation)) + return "$this->column_name = $this->column_name $operation $value"; + return "$this->column_name = $value"; + } + + function getExpressionWithoutValue(){ + $operation = $this->argument->getColumnOperation(); + if(isset($operation)) + return "$this->column_name = $this->column_name $operation ?"; + return "$this->column_name = ?"; + } + + function getValue(){ + // TODO Escape value according to column type instead of variable type + $value = $this->argument->getValue(); + if(!is_numeric($value)) return "'".$value."'"; + return $value; + } + + function show(){ + if(!$this->argument->getValue()) return false; + return true; + } + + function getArgument(){ + return $this->argument; + } + } + + +?> \ No newline at end of file diff --git a/classes/db/queryparts/limit/Limit.class.php b/classes/db/queryparts/limit/Limit.class.php new file mode 100644 index 000000000..e5fa18a74 --- /dev/null +++ b/classes/db/queryparts/limit/Limit.class.php @@ -0,0 +1,35 @@ +list_count = $list_count; + if ($page){ + $this->start = ($page-1)*$list_count->getValue(); + $this->page_count = $page_count; + $this->page = $page; + } + } + + function isPageHandler(){//in case you choose to use query limit in other cases than page select + if ($this->page)return true; + else return false; + } + + function getOffset(){ + return $this->start; + } + + function getLimit(){ + return $this->list_count->getValue(); + } + + function toString(){ + if ($this->page) return $this->start . ' , ' . $this->list_count->getValue(); + else return $this->list_count->getValue(); + } + } +?> \ No newline at end of file diff --git a/classes/db/queryparts/order/OrderByColumn.class.php b/classes/db/queryparts/order/OrderByColumn.class.php new file mode 100644 index 000000000..8866c057a --- /dev/null +++ b/classes/db/queryparts/order/OrderByColumn.class.php @@ -0,0 +1,27 @@ +column_name = $column_name; + $this->sort_order = $sort_order; + } + + function toString(){ + $result = is_a($this->column_name, 'Argument') ? $this->column_name->getValue() : $this->column_name; + $result .= ' '; + $result .= is_a($this->sort_order, 'Argument') ? $this->sort_order->getValue() : $this->sort_order; + return $result; + } + + function getArguments(){ + $args = array(); + if(is_a($this->column_name, 'Argument')) + $args[]= $this->column_name; + if(is_a($this->sort_order, 'Argument')) + $args[] = $this->sort_order; + } + } + +?> \ No newline at end of file diff --git a/classes/db/queryparts/table/JoinTable.class.php b/classes/db/queryparts/table/JoinTable.class.php new file mode 100644 index 000000000..7738667d1 --- /dev/null +++ b/classes/db/queryparts/table/JoinTable.class.php @@ -0,0 +1,37 @@ +join_type = $join_type; + $this->conditions = $conditions; + } + + function toString($with_value = true){ + $part = $this->join_type . ' ' . $this->name ; + $part .= $this->alias ? ' as ' . $this->alias : ''; + $part .= ' on '; + foreach($this->conditions as $conditionGroup) + $part .= $conditionGroup->toString($with_value); + return $part; + } + + function isJoinTable(){ + return true; + } + } + +?> \ No newline at end of file diff --git a/classes/db/queryparts/table/Table.class.php b/classes/db/queryparts/table/Table.class.php new file mode 100644 index 000000000..3a19d3a97 --- /dev/null +++ b/classes/db/queryparts/table/Table.class.php @@ -0,0 +1,30 @@ +name = $name; + $this->alias = $alias; + } + + function toString(){ + //return $this->name; + return sprintf("%s%s", $this->name, $this->alias ? ' as ' . $this->alias : ''); + } + + function getName(){ + return $this->name; + } + + function getAlias(){ + return $this->alias; + } + + function isJoinTable(){ + return false; + } + } + +?> \ No newline at end of file diff --git a/classes/display/HTMLDisplayHandler.php b/classes/display/HTMLDisplayHandler.php index d32b8cac4..d823ff420 100644 --- a/classes/display/HTMLDisplayHandler.php +++ b/classes/display/HTMLDisplayHandler.php @@ -179,12 +179,10 @@ class HTMLDisplayHandler { if(Context::get('module')=='admin' || strpos(Context::get('act'),'Admin')>0){ if(__DEBUG__) { $oContext->addCSSFile('./modules/admin/tpl/css/admin.css', false, 'all', '', 100000); - //$oContext->addJsFile('./modules/admin/tpl/js/admin.js'); - $oContext->addJsFile('http://svn.xpressengine.com/internal/etc/xeAdmin/js/admin.js'); + $oContext->addJsFile('./modules/admin/tpl/js/admin.js'); } else { $oContext->addCSSFile('./modules/admin/tpl/css/admin.min.css', false, 'all', '',10000); - //$oContext->addJsFile('./modules/admin/tpl/js/admin.js'); - $oContext->addJsFile('http://svn.xpressengine.com/internal/etc/xeAdmin/js/admin.js'); + $oContext->addJsFile('./modules/admin/tpl/js/admin.js'); } } } diff --git a/classes/xml/XmlQueryParser.class.php b/classes/xml/XmlQueryParser.class.php index 27e6692ba..72ac107f1 100644 --- a/classes/xml/XmlQueryParser.class.php +++ b/classes/xml/XmlQueryParser.class.php @@ -1,558 +1,70 @@ db_type = $db_type; + } + + function &getInstance($db_type = NULL){ + static $theInstance = null; + if(!isset($theInstance)){ + $theInstance = new XmlQueryParser($db_type); + } + return $theInstance; + } + function parse($query_id, $xml_file, $cache_file) { - // parse the query xml file. Return if get no result + + // Read xml file + $xml_obj = $this->getXmlFileContent($xml_file); + + // insert, update, delete, select action + $action = strtolower($xml_obj->query->attrs->action); + if(!$action) return; + + $parser = new QueryParser($xml_obj->query); + + FileHandler::writeFile($cache_file, $parser->toString()); + } + + // singleton + function &getDBParser(){ + if(!$self->dbParser){ + is_a($this,'XmlQueryParser')?$self=&$this:$self=&XmlQueryParser::getInstance(); + if(isset($self->db_type)) + $oDB = &DB::getInstance($self->db_type); + else + $oDB = &DB::getInstance(); + $self->dbParser = $oDB->getParser(); + } + return $self->dbParser; + } + + function setDBParser($value){ + $self->dbParser = $value; + } + + function getXmlFileContent($xml_file){ $buff = FileHandler::readFile($xml_file); $xml_obj = parent::parse($buff); if(!$xml_obj) return; unset($buff); - - $id_args = explode('.', $query_id); - if(count($id_args)==2) { - $target = 'modules'; - $module = $id_args[0]; - $id = $id_args[1]; - } elseif(count($id_args)==3) { - $target = $id_args[0]; - if(!in_array($target, array('modules','addons','widgets'))) return; - $module = $id_args[1]; - $id = $id_args[2]; - } - // actions like insert, update, delete, select and so on - $action = strtolower($xml_obj->query->attrs->action); - if(!$action) return; - // get the table list(converting an array code) - $tables = $xml_obj->query->tables->table; - $output->left_tables = array(); - - $left_conditions = array(); - - if(!$tables) return; - if(!is_array($tables)) $tables = array($tables); - foreach($tables as $key => $val) { - // get the name of tables and aliases - $table_name = $val->attrs->name; - $alias = $val->attrs->alias; - if(!$alias) $alias = $table_name; - - $output->tables[$alias] = $table_name; - - if(in_array($val->attrs->type,array('left join','left outer join','right join','right outer join')) && count($val->conditions)){ - $output->left_tables[$alias] = $val->attrs->type; - $left_conditions[$alias] = $val->conditions; - } - // get column properties from the table - $table_file = sprintf('%s%s/%s/schemas/%s.xml', _XE_PATH_, 'modules', $module, $table_name); - if(!file_exists($table_file)) { - $searched_list = FileHandler::readDir(_XE_PATH_.'modules'); - $searched_count = count($searched_list); - for($i=0;$i<$searched_count;$i++) { - $table_file = sprintf('%s%s/%s/schemas/%s.xml', _XE_PATH_, 'modules', $searched_list[$i], $table_name); - if(file_exists($table_file)) break; - } - } - - if(file_exists($table_file)) { - $table_xml = FileHandler::readFile($table_file); - $table_obj = parent::parse($table_xml); - if($table_obj->table) { - if(isset($table_obj->table->column) && !is_array($table_obj->table->column)) - { - $table_obj->table->column = array($table_obj->table->column); - } - - foreach($table_obj->table->column as $k => $v) { - $buff .= sprintf('$output->column_type["%s"] = "%s";%s', $v->attrs->name, $v->attrs->type, "\n"); - } - } - } - } - // Column list - $columns = $xml_obj->query->columns->column; - $out = $this->_setColumn($columns); - $output->columns = $out->columns; - - $conditions = $xml_obj->query->conditions; - $out = $this->_setConditions($conditions); - $output->conditions = $out->conditions; - - foreach($output->left_tables as $key => $val){ - if($left_conditions[$key]){ - $out = $this->_setConditions($left_conditions[$key]); - $output->left_conditions[$key] = $out->conditions; - } - } - - $group_list = $xml_obj->query->groups->group; - $out = $this->_setGroup($group_list); - $output->groups = $out->groups; - - //priority arrange - $priority = $xml_obj->query->priority; - if($priority) $output->priority['type'] = $priority->attrs->type; - - //index hint arrange - $index_hint = $xml_obj->query->index_hint; - if($index_hint) - { - $output->index_hint['name'] = $index_hint->attrs->name; - $output->index_hint['type'] = $index_hint->attrs->type; - } - - // Navigation - $out = $this->_setNavigation($xml_obj); - $output->order = $out->order; - $output->list_count = $out->list_count; - $output->page_count = $out->page_count; - $output->page = $out->page; - - $column_count = count($output->columns); - $priority_count = count($output->priority); - $index_hint_count = count($output->index_hint); - $condition_count = count($output->conditions); - - $buff .= '$output->tables = array( '; - foreach($output->tables as $key => $val) { - if(!array_key_exists($key,$output->left_tables)){ - $buff .= sprintf('"%s"=>"%s",', $key, $val); - } - } - $buff .= ' );'."\n"; - // generates a php script - $buff .= '$output->_tables = array( '; - foreach($output->tables as $key => $val) { - $buff .= sprintf('"%s"=>"%s",', $key, $val); - } - $buff .= ' );'."\n"; - - if(count($output->left_tables)){ - $buff .= '$output->left_tables = array( '; - foreach($output->left_tables as $key => $val) { - $buff .= sprintf('"%s"=>"%s",', $key, $val); - } - $buff .= ' );'."\n"; - } - // column info - if($column_count) { - $buff .= '$output->columns = array ( '; - $buff .= $this->_getColumn($output->columns); - $buff .= ' );'."\n"; - } - - //priority arrange - if($priority_count) { - $priority_str .= '$output->priority = array("type"=>"%s");'."\n"; - $buff .= vsprintf($priority_str, $output->priority); - } - - // index arrange - if($index_hint_count) { - $index_hint_str .= '$output->index_hint = array("name"=>"%s", "type"=>"%s");'."\n"; - $buff .= vsprintf($index_hint_str, $output->index_hint); - } - - // get conditions - if($condition_count) { - $buff .= '$output->conditions = array ( '; - $buff .= $this->_getConditions($output->conditions); - $buff .= ' );'."\n"; - } - // get conditions - if(count($output->left_conditions)) { - $buff .= '$output->left_conditions = array ( '; - foreach($output->left_conditions as $key => $val){ - $buff .= "'{$key}' => array ( "; - $buff .= $this->_getConditions($val); - $buff .= "),\n"; - } - $buff .= ' );'."\n"; - } - - // get arguments - $arg_list = $this->getArguments(); - if($arg_list) - { - foreach($arg_list as $arg) - { - $pre_buff .= 'if(is_object($args->'.$arg.')){ $args->'.$arg.' = array_values(get_method_vars($args->'.$arg.')); }'. "\n"; - $pre_buff .= 'if(is_array($args->'.$arg.') && count($args->'.$arg.')==0){ unset($args->'.$arg.'); };'."\n"; - } - } - - // order - if($output->order) { - $buff .= '$output->order = array('; - foreach($output->order as $key => $val) { - $buff .= sprintf('array($args->%s?$args->%s:"%s",in_array($args->%s,array("asc","desc"))?$args->%s:("%s"?"%s":"asc")),', $val->var, $val->var, $val->default, $val->order, $val->order, $val->order, $val->order); - } - $buff .= ');'."\n"; - } - - // list_count - if($output->list_count) { - $buff .= sprintf('$output->list_count = array("var"=>"%s", "value"=>$args->%s?$args->%s:"%s");%s', $output->list_count->var, $output->list_count->var, $output->list_count->var, $output->list_count->default,"\n"); - } - - // page_count - if($output->page_count) { - $buff .= sprintf('$output->page_count = array("var"=>"%s", "value"=>$args->%s?$args->%s:"%s");%s', $output->page_count->var, $output->page_count->var, $output->page_count->var, $output->list_count->default,"\n"); - } - - // page order - if($output->page) { - $buff .= sprintf('$output->page = array("var"=>"%s", "value"=>$args->%s?$args->%s:"%s");%s', $output->page->var, $output->page->var, $output->page->var, $output->list->default,"\n"); - } - - // group by - if($output->groups) { - $buff .= sprintf('$output->groups = array("%s");%s', implode('","',$output->groups),"\n"); - } - - // minlength check - if(count($minlength_list)) { - foreach($minlength_list as $key => $val) { - $pre_buff .= 'if($args->'.$key.'&&strlen($args->'.$key.')<'.$val.') return new Object(-1, sprintf($lang->filter->outofrange, $lang->'.$key.'?$lang->'.$key.':\''.$key.'\'));'."\n"; - } - } - - // maxlength check - if(count($maxlength_list)) { - foreach($maxlength_list as $key => $val) { - $pre_buff .= 'if($args->'.$key.'&&strlen($args->'.$key.')>'.$val.') return new Object(-1, sprintf($lang->filter->outofrange, $lang->'.$key.'?$lang->'.$key.':\''.$key.'\'));'."\n"; - } - } - - // filter check - if(count($this->filter_list)) { - foreach($this->filter_list as $key => $val) { - $pre_buff .= sprintf('if(isset($args->%s)) { unset($_output); $_output = $this->checkFilter("%s",$args->%s,"%s"); if(!$_output->toBool()) return $_output; } %s',$val->var, $val->var,$val->var,$val->filter,"\n"); - } - } - - // default check - if(count($this->default_list)) { - foreach($this->default_list as $key => $val) { - $pre_buff .= 'if(!isset($args->'.$key.')) $args->'.$key.' = '.$val.';'."\n"; - } - } - - // not null check - if(count($this->notnull_list)) { - foreach($this->notnull_list as $key => $val) { - $pre_buff .= 'if(!isset($args->'.$val.')) return new Object(-1, sprintf($lang->filter->isnull, $lang->'.$val.'?$lang->'.$val.':\''.$val.'\'));'."\n"; - } - } - - $buff = "query_id = "%s";%s', $query_id, "\n") - . sprintf('$output->action = "%s";%s', $action, "\n") - . $pre_buff - . $buff - . 'return $output; ?>'; - - // Save - FileHandler::writeFile($cache_file, $buff); - } - - /** - * @brief transfer given column information to object->columns - * @param[in] column information - * @result Returns $object - */ - - function _setColumn($columns){ - if(!$columns) { - $output->column[] = array("*" => "*"); - } else { - if(!is_array($columns)) $columns = array($columns); - foreach($columns as $key => $val) { - $name = $val->attrs->name; - /* - if(strpos('.',$name)===false && count($output->tables)==1) { - $tmp = array_values($output->tables); - $name = sprintf('%s.%s', $tmp[0], $val->attrs->name); - } - */ - - $output->columns[] = array( - "name" => $name, - "var" => $val->attrs->var, - "default" => $val->attrs->default, - "notnull" => $val->attrs->notnull, - "filter" => $val->attrs->filter, - "minlength" => $val->attrs->minlength, - "maxlength" => $val->attrs->maxlength, - "alias" => $val->attrs->alias, - "click_count" => $val->attrs->click_count, - ); - } - } - return $output; - } - - /** - * @brief transfer condition information to $object->conditions - * @param[in] SQL condition information - * @result Returns $output - */ - function _setConditions($conditions){ - // Conditional clause - $condition = $conditions->condition; - if($condition) { - $obj->condition = $condition; - unset($condition); - $condition = array($obj); - } - $condition_group = $conditions->group; - if($condition_group && !is_array($condition_group)) $condition_group = array($condition_group); - - if($condition && $condition_group) $cond = array_merge($condition, $condition_group); - elseif($condition_group) $cond = $condition_group; - else $cond = $condition; - - if($cond) { - foreach($cond as $key => $val) { - unset($cond_output); - - if($val->attrs->pipe) $cond_output->pipe = $val->attrs->pipe; - else $cond_output->pipe = null; - - if(!$val->condition) continue; - if(!is_array($val->condition)) $val->condition = array($val->condition); - - foreach($val->condition as $k => $v) { - $obj = $v->attrs; - if(!$obj->alias) $obj->alias = $obj->column; - $cond_output->condition[] = $obj; - } - - $output->conditions[] = $cond_output; - } - } - return $output; - } - - /** - * @brief transfer condition information to $object->groups - * @param[in] SQL group information - * @result Returns $output - */ - function _setGroup($group_list){ - // group list - - if($group_list) { - if(!is_array($group_list)) $group_list = array($group_list); - for($i=0;$iattrs->column); - if(!$column) continue; - $group_column_list[] = $column; - } - if(count($group_column_list)) $output->groups = $group_column_list; - } - return $output; - } - - - /** - * @brief transfer pagnation information to $output - * @param[in] $xml_obj xml object containing Navigation information - * @result Returns $output - */ - function _setNavigation($xml_obj){ - $navigation = $xml_obj->query->navigation; - if($navigation) { - $order = $navigation->index; - if($order) { - if(!is_array($order)) $order = array($order); - foreach($order as $order_info) { - $output->order[] = $order_info->attrs; - } - } - - $list_count = $navigation->list_count->attrs; - $output->list_count = $list_count; - - $page_count = $navigation->page_count->attrs; - $output->page_count = $page_count; - - $page = $navigation->page->attrs; - $output->page = $page ; - } - return $output; - } - - /** - * @brief retrieve column information from $output->colums to generate corresponding php code - * @param[in] $column - * @remarks the name of this method is misleading. - * @result Returns string buffer containing php code - */ - function _getColumn($columns){ - $buff = ''; - $str = ''; - $print_vars = array(); - - foreach($columns as $key => $val) { - $str = 'array("name"=>"%s","alias"=>"%s"'; - $print_vars = array(); - $print_vars[] = $val['name']; - $print_vars[] = $val['alias']; - - $val['default'] = $this->getDefault($val['name'], $val['default']); - if($val['var'] && strpos($val['var'],'.')===false) { - - if($val['default']){ - $str .= ',"value"=>$args->%s?$args->%s:%s'; - $print_vars[] = $val['var']; - $print_vars[] = $val['var']; - $print_vars[] = $val['default']; - }else{ - $str .= ',"value"=>$args->%s'; - $print_vars[] = $val['var']; - } - - } else { - if($val['default']){ - $str .= ',"value"=>%s'; - $print_vars[] = $val['default']; - } - } - - if($val['click_count']){ - $str .= ',"click_count"=>$args->%s'; - $print_vars[] = $val['click_count']; - } - - $str .= '),%s'; - $print_vars[] = "\n"; - - $buff .= vsprintf($str, $print_vars); - } - return $buff; - } - - /** - * @brief retrieve condition information from $output->condition to generate corresponding php code - * @param[in] $conditions array containing Query conditions - * @remarks the name of this method is misleading. - * @return Returns string buffer containing php code - */ - function _getConditions($conditions){ - $buff = ''; - foreach($conditions as $key => $val) { - $buff .= sprintf('array("pipe"=>"%s",%s"condition"=>array(', $val->pipe,"\n"); - foreach($val->condition as $k => $v) { - $v->default = $this->getDefault($v->column, $v->default); - if($v->var) { - if(strpos($v->var,".")===false) { - if($v->default) $this->default_list[$v->var] = $v->default; - if($v->filter) $this->filter_list[] = $v; - if($v->notnull) $this->notnull_list[] = $v->var; - if($v->default) $buff .= sprintf('array("column"=>"%s", "value"=>$args->%s?$args->%s:%s,"pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->var, $v->var, $v->default, $v->pipe, $v->operation, "\n"); - else $buff .= sprintf('array("column"=>"%s", "value"=>$args->%s,"pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->var, $v->pipe, $v->operation, "\n"); - - $this->addArguments($v->var); - } else { - $buff .= sprintf('array("column"=>"%s", "value"=>"%s","pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->var, $v->pipe, $v->operation, "\n"); - } - } else { - if($v->default) $buff .= sprintf('array("column"=>"%s", "value"=>%s,"pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->default ,$v->pipe, $v->operation,"\n"); - else $buff .= sprintf('array("column"=>"%s", "pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->pipe, $v->operation,"\n"); - } - } - $buff .= ')),'."\n"; - } - return $buff; - } - - function addArguments($args_name) - { - $this->args[] = $args_name; - } - - function getArguments() - { - return $this->args; - } - - /** - * @brief returns predefined default values correspoding to given parameters - * @param[in] $name - * @param[in] $value - * @return Returns a default value for specified field - */ - function getDefault($name, $value) { - $db_info = Context::getDBInfo (); - if(!isset($value)) return; - $str_pos = strpos($value, '('); - if($str_pos===false) return '"'.$value.'"'; - - $func_name = substr($value, 0, $str_pos); - $args = substr($value, $str_pos+1, strlen($value)-1); - - switch($func_name) { - case 'ipaddress' : - $val = '$_SERVER[\'REMOTE_ADDR\']'; - break; - case 'unixtime' : - $val = 'time()'; - break; - case 'curdate' : - $val = 'date("YmdHis")'; - break; - case 'sequence' : - $val = '$this->getNextSequence()'; - break; - case 'plus' : - $args = abs($args); - if ($db_info->db_type == 'cubrid') { - $val = sprintf ('"\\"%s\\"+%d"', $name, $args); - } else { - $val = sprintf('"%s+%d"', $name, $args); - } - break; - case 'minus' : - $args = abs($args); - if ($db_info->db_type == 'cubrid') { - $val = sprintf ('"\\"%s\\"-%d"', $name, $args); - } else { - $val = sprintf('"%s-%d"', $name, $args); - } - break; - case 'multiply' : - $args = intval($args); - if ($db_info->db_type == 'cubrid') { - $val = sprintf ('"\\"%s\\"*%d"', $name, $args); - } else { - $val = sprintf('"%s*%d"', $name, $args); - } - break; - } - - return $val; + return $xml_obj; } } ?> diff --git a/classes/xml/xmlquery/DBParser.class.php b/classes/xml/xmlquery/DBParser.class.php new file mode 100644 index 000000000..b58e7c028 --- /dev/null +++ b/classes/xml/xmlquery/DBParser.class.php @@ -0,0 +1,108 @@ +escape_char_left = $escape_char_left; + if ($escape_char_right !== "")$this->escape_char_right = $escape_char_right; + else $this->escape_char_right = $escape_char_left; + $this->table_prefix = $table_prefix; + } + + function getEscapeChar($leftOrRight){ + if ($leftOrRight === 'left')return $this->escape_char_left; + else return $this->escape_char_right; + } + + function escape($name){ + return $this->escape_char_left . $name . $this->escape_char_right; + } + + function escapeString($name){ + return "'".$this->escapeStringValue($name)."'"; + } + + function escapeStringValue($value){ + if($value == "*") return $value; + if (is_string($value)) return $value = str_replace("'","''",$value); + return $value; + } + + function parseTableName($name){ + return $this->table_prefix . $name; + } + + function parseColumnName($name){ + return $this->escapeColumn($name); + } + + function escapeColumn($column_name){ + if($this->isUnqualifiedColumnName($column_name)) + return $this->escape($column_name); + if($this->isQualifiedColumnName($column_name)){ + list($table, $column) = explode('.', $column_name); + // $table can also be an alias, so the prefix should not be added + return $this->escape($table).'.'.$this->escape($column); + //return $this->escape($this->parseTableName($table)).'.'.$this->escape($column); + } + } + + function isUnqualifiedColumnName($column_name){ + if(strpos($column_name,'.')===false && strpos($column_name,'(')===false) return true; + return false; + } + + function isQualifiedColumnName($column_name){ + if(strpos($column_name,'.')!==false && strpos($column_name,'(')===false) return true; + return false; + } + + function parseExpression($column_name){ + $functions = preg_split('/([\+\-\*\/\ ])/', $column_name, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); + foreach($functions as &$function){ + if(strlen($function)==1) continue; // skip delimiters + $pos = strrpos("(", $function); + $matches = preg_split('/([a-zA-Z0-9_*]+)/', $function, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); + $total_brackets = substr_count($function, "("); + $brackets = 0; + foreach($matches as &$match){ + if($match == '(') {$brackets++; continue;} + if(strpos($match,')') !== false) continue; + if(in_array($match, array(',', '.'))) continue; + if($brackets == $total_brackets){ + if(!is_numeric($match)) { + $match = $this->escapeColumnExpression($match); + } + } + } + $function = implode('', $matches); + } + return implode('', $functions); + } + + function isStar($column_name){ + if(substr($column_name,-1) == '*') return true; + return false; + } + + /* + * Checks to see if expression is an aggregate star function + * like count(*) + */ + function isStarFunction($column_name){ + if(strpos($column_name, "(*)")!==false) return true; + return false; + } + + function escapeColumnExpression($column_name){ + if($this->isStar($column_name)) return $column_name; + if($this->isStarFunction($column_name)){ + return $column_name; + } + return $this->escapeColumn($column_name); + } + } + + \ No newline at end of file diff --git a/classes/xml/xmlquery/QueryParser.class.php b/classes/xml/xmlquery/QueryParser.class.php new file mode 100644 index 000000000..08fda0f27 --- /dev/null +++ b/classes/xml/xmlquery/QueryParser.class.php @@ -0,0 +1,74 @@ +queryTag = new QueryTag($query, $isSubQuery); + } + + function getTableInfo($query_id, $table_name){ + $column_type = array(); + + $id_args = explode('.', $query_id); + if(count($id_args)==2) { + $target = 'modules'; + $module = $id_args[0]; + $id = $id_args[1]; + } elseif(count($id_args)==3) { + $target = $id_args[0]; + if(!in_array($target, array('modules','addons','widgets'))) return; + $module = $id_args[1]; + $id = $id_args[2]; + } + + // get column properties from the table + $table_file = sprintf('%s%s/%s/schemas/%s.xml', _XE_PATH_, 'modules', $module, $table_name); + if(!file_exists($table_file)) { + $searched_list = FileHandler::readDir(_XE_PATH_.'modules'); + $searched_count = count($searched_list); + for($i=0;$i<$searched_count;$i++) { + $table_file = sprintf('%s%s/%s/schemas/%s.xml', _XE_PATH_, 'modules', $searched_list[$i], $table_name); + if(file_exists($table_file)) break; + } + } + + if(file_exists($table_file)) { + $table_xml = FileHandler::readFile($table_file); + $xml_parser = new XmlParser(); + $table_obj = $xml_parser->parse($table_xml); + if($table_obj->table) { + if(isset($table_obj->table->column) && !is_array($table_obj->table->column)) + { + $table_obj->table->column = array($table_obj->table->column); + } + + foreach($table_obj->table->column as $k => $v) { + $column_type[$v->attrs->name] = $v->attrs->type; + } + } + } + + return $column_type; + } + + function toString(){ + return "queryTag->toString() + . 'return $query; ?>'; + } +} + +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/argument/Argument.class.php b/classes/xml/xmlquery/argument/Argument.class.php new file mode 100644 index 000000000..3d7256eb8 --- /dev/null +++ b/classes/xml/xmlquery/argument/Argument.class.php @@ -0,0 +1,173 @@ +value = $value; + $this->name = $name; + $this->isValid = true; + } + + function getType(){ + if(isset($this->type)) return $this->type; + if(is_string($this->value)) return 'column_name'; + return 'number'; + } + + function setColumnType($value){ + $this->type = $value; + } + + function setColumnOperation($operation){ + $this->column_operation = $operation; + } + + function getName(){ + return $this->name; + } + + function getValue(){ + $value = $this->getEscapedValue(); + return $this->toString($value); + } + + function getColumnOperation(){ + return $this->column_operation; + } + + function getEscapedValue(){ + return $this->escapeValue($this->value); + } + + function getUnescapedValue(){ + return $this->value; + } + + function toString($value){ + if(is_array($value)) return '('.implode(',', $value).')'; + return $value; + } + + function escapeValue($value){ + if($this->getType() == 'column_name'){ + $dbParser = XmlQueryParser::getDBParser(); + return $dbParser->parseExpression($value); + } + if(!isset($value)) return null; + if(in_array($this->type, array('date', 'varchar', 'char','text', 'bigtext'))){ + if(!is_array($value)) + $value = $this->_escapeStringValue ($value); + else { + $total = count($value); + for($i = 0; $i < $total; $i++) + $value[$i] = $this->_escapeStringValue($value[$i]); + //$value[$i] = '\''.$value[$i].'\''; + } + } + return $value; + } + + function _escapeStringValue($value){ + $db = &DB::getInstance(); + $value = $db->addQuotes($value); + return '\''.$value.'\''; + + } + + function isValid(){ + return $this->isValid; + } + + function getErrorMessage(){ + return $this->errorMessage; + } + + function ensureDefaultValue($default_value){ + if(!isset($this->value) || $this->value == '') + $this->value = $default_value; + } + + function checkFilter($filter_type){ + if(isset($this->value) && $this->value != ''){ + $val = $this->value; + $key = $this->name; + 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)) { + $this->isValid = false; + $this->errorMessage = 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)) { + $this->isValid = false; + $this->errorMessage = 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)) { + $this->isValid = false; + $this->errorMessage = new Object(-1, sprintf($lang->filter->invalid_userid, $lang->{$key} ? $lang->{$key} : $key)); + } + break; + case 'number' : + case 'numbers' : + if(is_array($val)) $val = join(',', $val); + if(!preg_match('/^(-?)[0-9]+(,\-?[0-9]+)*$/is', $val)){ + $this->isValid = false; + $this->errorMessage = new Object(-1, sprintf($lang->filter->invalid_number, $lang->{$key} ? $lang->{$key} : $key)); + } + break; + case 'alpha' : + if(!preg_match('/^[a-z]+$/is', $val)) { + $this->isValid = false; + $this->errorMessage = 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)) { + $this->isValid = false; + $this->errorMessage = new Object(-1, sprintf($lang->filter->invalid_alpha_number, $lang->{$key} ? $lang->{$key} : $key)); + } + break; + } + } + } + + function checkMaxLength($length){ + if($this->value && (strlen($this->value) > $length)){ + $this->isValid = false; + $key = $this->name; + $this->errorMessage = new Object(-1, $lang->filter->outofrange, $lang->{$key} ? $lang->{$key} : $key); + } + } + + function checkMinLength($length){ + if($this->value && (strlen($this->value) > $length)){ + $this->isValid = false; + $key = $this->name; + $this->errorMessage = new Object(-1, $lang->filter->outofrange, $lang->{$key} ? $lang->{$key} : $key); + } + } + + function checkNotNull(){ + if(!isset($this->value)){ + $this->isValid = false; + $key = $this->name; + $this->errorMessage = new Object(-1, $lang->filter->isnull, $lang->{$key} ? $lang->{$key} : $key); + } + } + } + + +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/argument/ConditionArgument.class.php b/classes/xml/xmlquery/argument/ConditionArgument.class.php new file mode 100644 index 000000000..42c8f22d0 --- /dev/null +++ b/classes/xml/xmlquery/argument/ConditionArgument.class.php @@ -0,0 +1,56 @@ +operation = $operation; + + if($this->type !== 'date'){ + $dbParser = XmlQueryParser::getDBParser(); + $this->value = $dbParser->escapeStringValue($this->value); + } + } + + function createConditionValue(){ + if(!isset($this->value)) return; + + $name = $this->column_name; + $operation = $this->operation; + $value = $this->value; + + switch($operation) { + case 'like_prefix' : + $this->value = $value.'%'; + break; + case 'like_tail' : + $this->value = '%'.$value; + break; + case 'like' : + $this->value = '%'.$value.'%'; + break; + case 'in': + if(!is_array($value)) $this->value = array($value); + break; + } + } + + function getType(){ + return $this->type; + } + + function setColumnType($column_type){ + if(!isset($this->value)) return; + if($column_type === '') return; + + $this->type = $column_type; + } + + } + +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/argument/SortArgument.class.php b/classes/xml/xmlquery/argument/SortArgument.class.php new file mode 100644 index 000000000..639b10a06 --- /dev/null +++ b/classes/xml/xmlquery/argument/SortArgument.class.php @@ -0,0 +1,11 @@ +getUnescapedValue(); + } + + } + +?> diff --git a/classes/xml/xmlquery/queryargument/DefaultValue.class.php b/classes/xml/xmlquery/queryargument/DefaultValue.class.php new file mode 100644 index 000000000..3ee5d4358 --- /dev/null +++ b/classes/xml/xmlquery/queryargument/DefaultValue.class.php @@ -0,0 +1,97 @@ +column_name = $dbParser->parseColumnName($column_name); + $this->value = $value; + $this->value = $this->_setValue(); + } + + function isString(){ + $str_pos = strpos($this->value, '('); + if($str_pos===false) return true; + return false; + } + + function isSequence(){ + return $this->is_sequence; + } + + function isOperation(){ + return $this->is_operation; + } + + function getOperation(){ + return $this->operation; + } + + function _setValue(){ + if(!isset($this->value)) return; + + // If value contains comma separated values and does not contain paranthesis + // -> default value is an array + if(strpos($this->value, ',') !== false && strpos($this->value, '(') === false) { + return sprintf('array(%s)', $this->value); + } + + $str_pos = strpos($this->value, '('); + // // TODO Replace this with parseExpression + if($str_pos===false) return '\''.$this->value.'\''; + //if($str_pos===false) return $this->value; + + $func_name = substr($this->value, 0, $str_pos); + $args = substr($this->value, $str_pos+1, strlen($value)-1); + + switch($func_name) { + case 'ipaddress' : + $val = '$_SERVER[\'REMOTE_ADDR\']'; + break; + case 'unixtime' : + $val = 'time()'; + break; + case 'curdate' : + $val = 'date("YmdHis")'; + break; + case 'sequence' : + $this->is_sequence = true; + $val = '$sequence'; + break; + case 'plus' : + $args = abs($args); + $this->is_operation = true; + $this->operation = '+'; + $val = sprintf('%d', $args); + break; + case 'minus' : + $args = abs($args); + $this->is_operation = true; + $this->operation = '-'; + $val = sprintf('%d', $args); + break; + case 'multiply' : + $args = intval($args); + $this->is_operation = true; + $this->operation = '*'; + $val = sprintf('%d', $args); + break; + default : + $val = '\'' . $this->value . '\''; + //$val = $this->value; + } + + return $val; + } + + function toString(){ + return $this->value; + } + } + +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/queryargument/QueryArgument.class.php b/classes/xml/xmlquery/queryargument/QueryArgument.class.php new file mode 100644 index 000000000..2dc29878c --- /dev/null +++ b/classes/xml/xmlquery/queryargument/QueryArgument.class.php @@ -0,0 +1,87 @@ +argument_name = $tag->attrs->var; + if(!$this->argument_name) $this->argument_name = $tag->attrs->name; + if(!$this->argument_name) $this->argument_name = str_replace('.', '_',$tag->attrs->column); + + $this->variable_name = $this->argument_name; + + self::$number_of_arguments++; + $this->argument_name .= self::$number_of_arguments; + + $name = $tag->attrs->name; + if(!$name) $name = $tag->attrs->column; + if(strpos($name, '.') === false) $this->column_name = $name; + else { + list($prefix, $name) = explode('.', $name); + $this->column_name = $name; + } + + if($tag->attrs->operation) $this->operation = $tag->attrs->operation; + + require_once(_XE_PATH_.'classes/xml/xmlquery/queryargument/validator/QueryArgumentValidator.class.php'); + $this->argument_validator = new QueryArgumentValidator($tag, $this); + + } + + function getArgumentName(){ + return $this->argument_name; + } + + function getColumnName(){ + return $this->column_name; + } + + function getValidatorString(){ + return $this->argument_validator->toString(); + } + + function isConditionArgument(){ + if($this->operation) return true; + return false; + } + + function toString(){ + if($this->isConditionArgument()) + $arg = sprintf("\n$%s_argument = new ConditionArgument('%s', %s, '%s');\n" + , $this->argument_name + , $this->argument_name + , '$args->'.$this->variable_name + , $this->operation + ); + + else + $arg = sprintf("\n$%s_argument = new Argument('%s', %s);\n" + , $this->argument_name + , $this->argument_name + , '$args->'.$this->variable_name); + + + $arg .= $this->argument_validator->toString(); + + if($this->isConditionArgument()){ + $arg .= sprintf("$%s_argument->createConditionValue();\n" + , $this->argument_name + ); + } + + $arg .= sprintf("if(!$%s_argument->isValid()) return $%s_argument->getErrorMessage();\n" + , $this->argument_name + , $this->argument_name + ); + return $arg; + } + + } + +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/queryargument/SortQueryArgument.class.php b/classes/xml/xmlquery/queryargument/SortQueryArgument.class.php new file mode 100644 index 000000000..60b068f2d --- /dev/null +++ b/classes/xml/xmlquery/queryargument/SortQueryArgument.class.php @@ -0,0 +1,20 @@ +argument_name + , $this->argument_name + , '$args->'.$this->variable_name); + + + $arg .= $this->argument_validator->toString(); + + $arg .= sprintf("if(!$%s_argument->isValid()) return $%s_argument->getErrorMessage();\n" + , $this->argument_name + , $this->argument_name + ); + return $arg; + } + } +?> diff --git a/classes/xml/xmlquery/queryargument/validator/QueryArgumentValidator.class.php b/classes/xml/xmlquery/queryargument/validator/QueryArgumentValidator.class.php new file mode 100644 index 000000000..03816e447 --- /dev/null +++ b/classes/xml/xmlquery/queryargument/validator/QueryArgumentValidator.class.php @@ -0,0 +1,70 @@ +argument = $argument; + $this->argument_name = $this->argument->getArgumentName(); + + $this->default_value = $tag->attrs->default; + $this->notnull = $tag->attrs->notnull; + $this->filter = $tag->attrs->filter; + $this->min_length = $tag->attrs->min_length; + $this->max_length = $tag->attrs->max_length; + } + + function toString(){ + $validator = ''; + if(isset($this->default_value)){ + $this->default_value = new DefaultValue($this->argument_name, $this->default_value); + if($this->default_value->isSequence()) + $validator .= '$db = &DB::getInstance(); $sequence = $db->getNextSequence(); '; + if($this->default_value->isOperation()) + $validator .= sprintf("$%s_argument->setColumnOperation('%s');\n" + , $this->argument_name + , $this->default_value->getOperation() + ); + $validator .= sprintf("$%s_argument->ensureDefaultValue(%s);\n" + , $this->argument_name + , $this->default_value->toString() + ); + } + if($this->notnull){ + $validator .= sprintf("$%s_argument->checkNotNull();\n" + , $this->argument_name + ); + } + if($this->filter){ + $validator .= sprintf("$%s_argument->checkFilter('%s');\n" + , $this->argument_name + , $this->filter + ); + } + if($this->min_length){ + $validator .= sprintf("$%s_argument->checkMinLength(%s);\n" + , $this->argument_name + , $this->min_length + ); + } + if($this->max_length){ + $validator .= sprintf("$%s_argument->checkMaxLength(%s);\n" + , $this->argument_name + , $this->max_length + ); + } + return $validator; + } + } + +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/queryargument/validator/Validator.class.php b/classes/xml/xmlquery/queryargument/validator/Validator.class.php new file mode 100644 index 000000000..6fb7426bc --- /dev/null +++ b/classes/xml/xmlquery/queryargument/validator/Validator.class.php @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/column/ColumnTag.class.php b/classes/xml/xmlquery/tags/column/ColumnTag.class.php new file mode 100644 index 000000000..8ffe77373 --- /dev/null +++ b/classes/xml/xmlquery/tags/column/ColumnTag.class.php @@ -0,0 +1,19 @@ + tag inside an XML Query file + * + * Since the tag supports different attributes depending on + * the type of query (select, update, insert, delete) this is only + * the base class for the classes that will model each type tag. + * + **/ + + class ColumnTag { + var $name; + + function ColumnTag($name){ + $this->name = $name; + } + } \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/column/InsertColumnTag.class.php b/classes/xml/xmlquery/tags/column/InsertColumnTag.class.php new file mode 100644 index 000000000..c34f1bafc --- /dev/null +++ b/classes/xml/xmlquery/tags/column/InsertColumnTag.class.php @@ -0,0 +1,32 @@ + tag inside an XML Query file whose action is 'insert' + * + **/ + + + class InsertColumnTag extends ColumnTag { + var $argument; + + function InsertColumnTag($column) { + parent::ColumnTag($column->attrs->name); + $dbParser = XmlQueryParser::getDBParser(); + $this->name = $dbParser->parseColumnName($this->name); + require_once(_XE_PATH_.'classes/xml/xmlquery/queryargument/QueryArgument.class.php'); + $this->argument = new QueryArgument($column); + } + + function getExpressionString(){ + return sprintf('new InsertExpression(\'%s\', $%s_argument)' + , $this->name + , $this->argument->argument_name); + } + + function getArgument(){ + return $this->argument; + } + + } +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/column/InsertColumnsTag.class.php b/classes/xml/xmlquery/tags/column/InsertColumnsTag.class.php new file mode 100644 index 000000000..a067a6d10 --- /dev/null +++ b/classes/xml/xmlquery/tags/column/InsertColumnsTag.class.php @@ -0,0 +1,49 @@ + tag inside an XML Query file whose action is 'insert' + * + **/ + + require_once(_XE_PATH_.'classes/xml/xmlquery/tags/column/ColumnTag.class.php'); + require_once(_XE_PATH_.'classes/xml/xmlquery/tags/column/InsertColumnTag.class.php'); + + class InsertColumnsTag{ + var $columns; + + function InsertColumnsTag($xml_columns) { + $this->columns = array(); + + if(!$xml_columns) + return; + + if(!is_array($xml_columns)) $xml_columns = array($xml_columns); + + foreach($xml_columns as $column){ + if($column->name === 'query') $this->columns[] = new QueryTag($column, true); + else $this->columns[] = new InsertColumnTag($column); + } + } + + function toString(){ + $output_columns = 'array(' . PHP_EOL; + foreach($this->columns as $column){ + $output_columns .= $column->getExpressionString() . PHP_EOL . ','; + } + $output_columns = substr($output_columns, 0, -1); + $output_columns .= ')'; + return $output_columns; + } + + function getArguments(){ + $arguments = array(); + foreach($this->columns as $column){ + $arguments[] = $column->getArgument(); + } + return $arguments; + } + + } + +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/column/SelectColumnTag.class.php b/classes/xml/xmlquery/tags/column/SelectColumnTag.class.php new file mode 100644 index 000000000..61031dfcc --- /dev/null +++ b/classes/xml/xmlquery/tags/column/SelectColumnTag.class.php @@ -0,0 +1,34 @@ + tag inside an XML Query file whose action is 'select' + * + **/ + + class SelectColumnTag extends ColumnTag{ + var $alias; + var $click_count; + + function SelectColumnTag($column){ + parent::ColumnTag($column->attrs->name); + if(!$this->name) $this->name = "*"; + if($this->name != "*") { + $dbParser = XmlQueryParser::getDBParser(); + $this->name = $dbParser->parseExpression($this->name); + } + + $this->alias = $column->attrs->alias; + $this->click_count = $column->attrs->click_count; + } + + function getExpressionString(){ + if($this->name == '*') return "new StarExpression()"; + if($this->click_count) + return sprintf('new ClickCountExpression(%s, %s, $args->%s)', $this->name, $this->alias,$this->click_count); + $dbParser = XmlQueryParser::getDBParser(); + return sprintf('new SelectExpression(\'%s\'%s)', $this->name, $this->alias ? ', \''.$dbParser->escape($this->alias) .'\'': ''); + } + } +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/column/SelectColumnsTag.class.php b/classes/xml/xmlquery/tags/column/SelectColumnsTag.class.php new file mode 100644 index 000000000..e23c48aed --- /dev/null +++ b/classes/xml/xmlquery/tags/column/SelectColumnsTag.class.php @@ -0,0 +1,60 @@ +column; + $xml_queries = $xml_columns_tag->query; + + $this->columns = array(); + + if(!$xml_columns) { + $this->columns[] = new SelectColumnTag("*"); + return; + } + + if(!is_array($xml_columns)) $xml_columns = array($xml_columns); + + foreach($xml_columns as $column){ + $this->columns[] = new SelectColumnTag($column); + } + + + if(!$xml_queries) { + return; + } + + if(!is_array($xml_queries)) $xml_queries = array($xml_queries); + + foreach($xml_queries as $column){ + $this->columns[] = new QueryTag($column, true); + } + } + + function toString(){ + $output_columns = 'array(' . PHP_EOL; + foreach($this->columns as $column){ + if(is_a($column, 'QueryTag')) + $output_columns .= $column->toString() . PHP_EOL . ','; + else + $output_columns .= $column->getExpressionString() . PHP_EOL . ','; + } + $output_columns = substr($output_columns, 0, -1); + $output_columns .= ')'; + return $output_columns; + } + + function getArguments(){ + $arguments = array(); + foreach($this->columns as $column){ + if(is_a($column, 'QueryTag')) + $arguments = array_merge($arguments, $column->getArguments()); + } + return $arguments; + } + } +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/column/UpdateColumnTag.class.php b/classes/xml/xmlquery/tags/column/UpdateColumnTag.class.php new file mode 100644 index 000000000..9dcf1be9a --- /dev/null +++ b/classes/xml/xmlquery/tags/column/UpdateColumnTag.class.php @@ -0,0 +1,34 @@ + tag inside an XML Query file whose action is 'update' + * + **/ + + + + class UpdateColumnTag extends ColumnTag { + var $argument; + + function UpdateColumnTag($column) { + parent::ColumnTag($column->attrs->name); + $dbParser = XmlQueryParser::getDBParser(); + $this->name = $dbParser->parseColumnName($this->name); + require_once(_XE_PATH_.'classes/xml/xmlquery/queryargument/QueryArgument.class.php'); + $this->argument = new QueryArgument($column); + } + + function getExpressionString(){ + return sprintf('new UpdateExpression(\'%s\', $%s_argument)' + , $this->name + , $this->argument->argument_name); + } + + function getArgument(){ + return $this->argument; + } + } + +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/column/UpdateColumnsTag.class.php b/classes/xml/xmlquery/tags/column/UpdateColumnsTag.class.php new file mode 100644 index 000000000..581f9ad8a --- /dev/null +++ b/classes/xml/xmlquery/tags/column/UpdateColumnsTag.class.php @@ -0,0 +1,47 @@ + tag inside an XML Query file whose action is 'update' + * + **/ + + require_once(_XE_PATH_.'classes/xml/xmlquery/tags/column/ColumnTag.class.php'); + require_once(_XE_PATH_.'classes/xml/xmlquery/tags/column/UpdateColumnTag.class.php'); + + class UpdateColumnsTag{ + var $columns; + + function UpdateColumnsTag($xml_columns) { + $this->columns = array(); + + if(!is_array($xml_columns)) $xml_columns = array($xml_columns); + + foreach($xml_columns as $column){ + if($column->name === 'query') $this->columns[] = new QueryTag($column, true); + else $this->columns[] = new UpdateColumnTag($column); + } + } + + function toString(){ + $output_columns = 'array(' . PHP_EOL; + foreach($this->columns as $column){ + $output_columns .= $column->getExpressionString() . PHP_EOL . ','; + } + $output_columns = substr($output_columns, 0, -1); + $output_columns .= ')'; + return $output_columns; + } + + function getArguments(){ + $arguments = array(); + foreach($this->columns as $column){ + $arguments[] = $column->getArgument(); + } + return $arguments; + } + + } + +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/condition/ConditionGroupTag.class.php b/classes/xml/xmlquery/tags/condition/ConditionGroupTag.class.php new file mode 100644 index 000000000..1ddba44e6 --- /dev/null +++ b/classes/xml/xmlquery/tags/condition/ConditionGroupTag.class.php @@ -0,0 +1,43 @@ +pipe = $pipe; + + if(!is_array($conditions)) $conditions = array($conditions); + if(count($conditions))require_once(_XE_PATH_.'classes/xml/xmlquery/tags/condition/ConditionTag.class.php'); + + foreach($conditions as $condition){ + //if($condition->node_name === 'query') $this->conditions[] = new QueryTag($condition, true); + $this->conditions[] = new ConditionTag($condition); + } + } + + function getConditions(){ + return $this->conditions; + } + + function getConditionGroupString(){ + $conditions_string = 'array('.PHP_EOL; + foreach($this->conditions as $condition){ + $conditions_string .= $condition->getConditionString() . PHP_EOL . ','; + } + $conditions_string = substr($conditions_string, 0, -2);//remove ',' + $conditions_string .= ')'; + + return sprintf("new ConditionGroup(%s%s)", $conditions_string, $this->pipe ? ',\''.$this->pipe . '\'': ''); + } + + function getArguments(){ + $arguments = array(); + foreach($this->conditions as $condition){ + $arguments = array_merge($arguments, $condition->getArguments()); + } + return $arguments; + } + + } +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/condition/ConditionTag.class.php b/classes/xml/xmlquery/tags/condition/ConditionTag.class.php new file mode 100644 index 000000000..38cebf2cc --- /dev/null +++ b/classes/xml/xmlquery/tags/condition/ConditionTag.class.php @@ -0,0 +1,69 @@ + tag inside an XML Query file. Base class. + * + */ + + class ConditionTag { + var $operation; + var $column_name; + + var $pipe; + var $argument_name; + var $argument; + var $default_column; + + var $query; + function ConditionTag($condition){ + $this->operation = $condition->attrs->operation; + $this->pipe = $condition->attrs->pipe; + $dbParser = XmlQueryParser::getDBParser(); + $this->column_name = $dbParser->parseColumnName($condition->attrs->column); + + $isColumnName = strpos($condition->attrs->default, '.'); + $isColumnName = $isColumnName || strpos($condition->attrs->var, '.'); + + if($condition->node_name == 'query'){ + $this->query = new QueryTag($condition, true); + $this->default_column = $this->query->toString(); + } + else if(($condition->attrs->var && !$isColumnName) || $isColumnName === false){ + require_once(_XE_PATH_.'classes/xml/xmlquery/queryargument/QueryArgument.class.php'); + + $this->argument = new QueryArgument($condition); + $this->argument_name = $this->argument->getArgumentName(); + } + else { + if($condition->attrs->default) + $this->default_column = "'" . $dbParser->parseColumnName($condition->attrs->default) . "'" ; + else + $this->default_column = "'" . $dbParser->parseColumnName($condition->attrs->var) . "'" ; + } + } + + function setPipe($pipe){ + $this->pipe = $pipe; + } + + function getArguments(){ + $arguments = array(); + if($this->query) + $arguments = array_merge($arguments, $this->query->getArguments()); + if($this->argument) + $arguments[] = $this->argument; + return $arguments; + } + + function getConditionString(){ + return sprintf("new Condition('%s',%s,%s%s)" + , $this->column_name + , $this->default_column ? $this->default_column: '$' . $this->argument_name . '_argument' + , '"'.$this->operation.'"' + , $this->pipe ? ", '" . $this->pipe . "'" : '' + ); + } + } +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/condition/ConditionsTag.class.php b/classes/xml/xmlquery/tags/condition/ConditionsTag.class.php new file mode 100644 index 000000000..828220b50 --- /dev/null +++ b/classes/xml/xmlquery/tags/condition/ConditionsTag.class.php @@ -0,0 +1,50 @@ +condition_groups = array(); + + $xml_condition_list = array(); + if($xml_conditions->condition) + $xml_condition_list = $xml_conditions->condition; + + if($xml_conditions->query){ + if(!is_array($xml_condition_list)) $xml_condition_list = array($xml_condition_list); + if(!is_array($xml_conditions->query)) $xml_conditions->query = array($xml_conditions->query); + $xml_condition_list = array_merge($xml_condition_list, $xml_conditions->query); + } + if($xml_condition_list){ + require_once(_XE_PATH_.'classes/xml/xmlquery/tags/condition/ConditionGroupTag.class.php'); + $this->condition_groups[] = new ConditionGroupTag($xml_condition_list); + } + + $xml_groups = $xml_conditions->group; + if($xml_groups){ + if(!is_array($xml_groups)) $xml_groups = array($xml_groups); + require_once(_XE_PATH_.'classes/xml/xmlquery/tags/condition/ConditionGroupTag.class.php'); + foreach($xml_groups as $group){ + $this->condition_groups[] = new ConditionGroupTag($group->condition, $group->attrs->pipe); + } + } + } + + function toString(){ + $output_conditions = 'array(' . PHP_EOL; + foreach($this->condition_groups as $condition){ + $output_conditions .= $condition->getConditionGroupString() . PHP_EOL . ','; + } + $output_conditions = substr($output_conditions, 0, -1); + $output_conditions .= ')'; + return $output_conditions; + } + + function getArguments(){ + $arguments = array(); + foreach($this->condition_groups as $condition){ + $arguments = array_merge($arguments, $condition->getArguments()); + } + return $arguments; + } + } +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/condition/JoinConditionsTag.class.php b/classes/xml/xmlquery/tags/condition/JoinConditionsTag.class.php new file mode 100644 index 000000000..3b59989f6 --- /dev/null +++ b/classes/xml/xmlquery/tags/condition/JoinConditionsTag.class.php @@ -0,0 +1,11 @@ +condition_groups[0]->conditions[0]->setPipe(""); + } + } + +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/group/GroupsTag.class.php b/classes/xml/xmlquery/tags/group/GroupsTag.class.php new file mode 100644 index 000000000..19f74fe43 --- /dev/null +++ b/classes/xml/xmlquery/tags/group/GroupsTag.class.php @@ -0,0 +1,35 @@ +groups = array(); + + if($xml_groups) { + if(!is_array($xml_groups)) $xml_groups = array($xml_groups); + + $dbParser = XmlQueryParser::getDBParser(); + for($i=0;$iattrs->column); + if(!$column) continue; + + $column = $dbParser->parseExpression($column); + $this->groups[] = $column; + } + } + } + + function toString(){ + $output = 'array(' . PHP_EOL; + foreach($this->groups as $group){ + $output .= "'" . $group . "' ,"; + } + $output = substr($output, 0, -1); + $output .= ')'; + return $output; + } + } + +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/navigation/IndexTag.class.php b/classes/xml/xmlquery/tags/navigation/IndexTag.class.php new file mode 100644 index 000000000..8fa708576 --- /dev/null +++ b/classes/xml/xmlquery/tags/navigation/IndexTag.class.php @@ -0,0 +1,45 @@ +argument_name = $index->attrs->var; + + // Sort index - column by which to sort + //$dbParser = XmlQueryParser::getDBParser(); + //$index->attrs->default = $dbParser->parseExpression($index->attrs->default); + $this->default = $index->attrs->default; + require_once(_XE_PATH_.'classes/xml/xmlquery/queryargument/QueryArgument.class.php'); + require_once(_XE_PATH_.'classes/xml/xmlquery/queryargument/SortQueryArgument.class.php'); + $this->argument = new QueryArgument($index); + + // Sort order - asc / desc + $this->sort_order = $index->attrs->order; + if(!in_array($this->sort_order, array("asc", "desc"))){ + $arg->attrs->var = $this->sort_order; + $arg->attrs->default = 'asc'; + $this->sort_order_argument = new SortQueryArgument($arg); + $this->sort_order = '$'.$this->sort_order_argument->getArgumentName().'_argument'; + } + else $this->sort_order = '"'.$this->sort_order.'"'; + } + + function toString(){ + return sprintf("new OrderByColumn(\$%s_argument, %s)", $this->argument->getArgumentName(), $this->sort_order); + } + + function getArguments(){ + $arguments = array(); + $arguments[] = $this->argument; + if($this->sort_order_argument) + $arguments[] = $this->sort_order_argument; + return $arguments; + } + } + +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/navigation/LimitTag.class.php b/classes/xml/xmlquery/tags/navigation/LimitTag.class.php new file mode 100644 index 000000000..bb4492045 --- /dev/null +++ b/classes/xml/xmlquery/tags/navigation/LimitTag.class.php @@ -0,0 +1,33 @@ +page->attrs && $index->page_count->attrs){ + $this->page = $index->page->attrs; + $this->page_count = $index->page_count->attrs; + $this->arguments[] = new QueryArgument($index->page); + $this->arguments[] = new QueryArgument($index->page_count); + } + + $this->list_count = new QueryArgument($index->list_count); + $this->arguments[] = $this->list_count; + } + + function toString(){ + $name = $this->list_count->getArgumentName(); + if ($this->page)return sprintf("new Limit(\$%s_argument, \$%s_argument, \$%s_argument)",$name, $name, $name); + else return sprintf("new Limit(\$%s_argument)", $name); + } + + function getArguments(){ + return $this->arguments; + } + } +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/navigation/NavigationTag.class.php b/classes/xml/xmlquery/tags/navigation/NavigationTag.class.php new file mode 100644 index 000000000..1c364643e --- /dev/null +++ b/classes/xml/xmlquery/tags/navigation/NavigationTag.class.php @@ -0,0 +1,62 @@ +order = array(); + if($xml_navigation) { + $order = $xml_navigation->index; + if($order) { + if(!is_array($order)) $order = array($order); + foreach($order as $order_info) { + $this->order[] = new IndexTag($order_info); + } + } + + if($xml_navigation->page->attrs || $xml_navigation->list_count->attrs) + $this->limit = new LimitTag($xml_navigation); + + $list_count = $xml_navigation->list_count->attrs; + $this->list_count = $list_count; + + $page_count = $xml_navigation->page_count->attrs; + $this->page_count = $page_count; + + $page = $xml_navigation->page->attrs; + $this->page = $page ; + } + } + + function getOrderByString(){ + $output = 'array(' . PHP_EOL; + foreach($this->order as $order){ + $output .= $order->toString() . PHP_EOL . ','; + } + $output = substr($output, 0, -1); + $output .= ')'; + return $output; + } + + function getLimitString(){ + if ($this->limit) return $this->limit->toString(); + else return ""; + } + + function getArguments(){ + $arguments = array(); + foreach($this->order as $order){ + $arguments = array_merge($order->getArguments(), $arguments); + } + if($this->limit) $arguments = array_merge($this->limit->getArguments(), $arguments); + return $arguments; + } + } + +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/query/QueryTag.class.php b/classes/xml/xmlquery/tags/query/QueryTag.class.php new file mode 100644 index 000000000..41c7db291 --- /dev/null +++ b/classes/xml/xmlquery/tags/query/QueryTag.class.php @@ -0,0 +1,181 @@ +action = $query->attrs->action; + $this->query_id = $query->attrs->id; + $this->query = $query; + $this->isSubQuery = $isSubQuery; + if($this->isSubQuery) $this->action = 'select'; + $this->alias = $query->attrs->alias; + $this->join_type = $query->attrs->join_type; + + $this->getColumns(); + $tables = $this->getTables(); + $this->setTableColumnTypes($tables); + $this->getConditions(); + $this->getGroups(); + $this->getNavigation(); + $this->getPrebuff(); + $this->getBuff(); + } + + function show(){ + return true; + } + + function getQueryId(){ + return $this->query->attrs->query_id ? $this->query->attrs->query_id : $this->query->attrs->id; + } + + function getAction(){ + return $this->query->attrs->action; + } + + function setTableColumnTypes($tables){ + $query_id = $this->getQueryId(); + if(!isset($this->column_type[$query_id])){ + $table_tags = $tables->getTables(); + $column_type = array(); + foreach($table_tags as $table_tag){ + if(is_a($table_tag, 'TableTag')){ + $tag_column_type = QueryParser::getTableInfo($query_id, $table_tag->getTableName()); + $column_type = array_merge($column_type, $tag_column_type); + } + } + $this->column_type[$query_id] = $column_type; + } + } + + function getColumns(){ + if($this->action == 'select'){ + return $this->columns = new SelectColumnsTag($this->query->columns); + }else if($this->action == 'insert'){ + return $this->columns = new InsertColumnsTag($this->query->columns->column); + }else if($this->action == 'update') { + return $this->columns = new UpdateColumnsTag($this->query->columns->column); + }else if($this->action == 'delete') { + return $this->columns = null; + } + } + + function getPrebuff(){ + // TODO Check if this work with arguments in join clause + $arguments = $this->getArguments(); + + $prebuff = ''; + foreach($arguments as $argument){ + if(isset($argument) && $argument->getArgumentName()){ + $prebuff .= $argument->toString(); + $column_type = $this->column_type[$this->getQueryId()][$argument->getColumnName()]; + if(isset($column_type)) + $prebuff .= sprintf("$%s_argument->setColumnType('%s');\n" + , $argument->getArgumentName() + , $column_type ); + } + } + $prebuff .= "\n"; + + return $this->preBuff = $prebuff; + } + + function getBuff(){ + $buff = ''; + if($this->isSubQuery){ + $buff = 'new Subquery('; + $buff .= "'\"" . $this->alias . '"\', '; + $buff .= ($this->columns ? $this->columns->toString() : 'null' ). ', '.PHP_EOL; + $buff .= $this->tables->toString() .','.PHP_EOL; + $buff .= $this->conditions->toString() .',' .PHP_EOL; + $buff .= $this->groups->toString() . ',' .PHP_EOL; + $buff .= $this->navigation->getOrderByString() .','.PHP_EOL; + $limit = $this->navigation->getLimitString() ; + $buff .= $limit ? $limit : 'null' . PHP_EOL; + $buff .= $this->join_type ? "'" . $this->join_type . "'" : ''; + $buff .= ')'; + + $this->buff = $buff; + return $this->buff; + } + + $buff .= '$query = new Query();'.PHP_EOL; + $buff .= sprintf('$query->setQueryId("%s");%s', $this->query_id, "\n"); + $buff .= sprintf('$query->setAction("%s");%s', $this->action, "\n"); + $buff .= $this->preBuff; + if($this->columns) + $buff .= '$query->setColumns(' . $this->columns->toString() . ');'.PHP_EOL; + + $buff .= '$query->setTables(' . $this->tables->toString() .');'.PHP_EOL; + $buff .= '$query->setConditions('.$this->conditions->toString() .');'.PHP_EOL; + $buff .= '$query->setGroups(' . $this->groups->toString() . ');'.PHP_EOL; + $buff .= '$query->setOrder(' . $this->navigation->getOrderByString() .');'.PHP_EOL; + $buff .= '$query->setLimit(' . $this->navigation->getLimitString() .');'.PHP_EOL; + + $this->buff = $buff; + return $this->buff; + } + + function getTables(){ + return $this->tables = new TablesTag($this->query->tables); + } + + function getConditions(){ + return $this->conditions = new ConditionsTag($this->query->conditions); + } + + function getGroups(){ + return $this->groups = new GroupsTag($this->query->groups->group); + } + + function getNavigation(){ + return $this->navigation = new NavigationTag($this->query->navigation); + } + + function toString(){ + return $this->buff; + } + + function getTableString(){ + return $this->buff; + } + + function getConditionString(){ + return $this->buff; + } + + function getExpressionString(){ + return $this->buff; + } + + + function getArguments(){ + $arguments = array(); + if($this->columns) + $arguments = array_merge($arguments, $this->columns->getArguments()); + $arguments = array_merge($arguments, $this->tables->getArguments()); + $arguments = array_merge($arguments, $this->conditions->getArguments()); + $arguments = array_merge($arguments, $this->navigation->getArguments()); + return $arguments; + } + +} +?> diff --git a/classes/xml/xmlquery/tags/table/TableTag.class.php b/classes/xml/xmlquery/tags/table/TableTag.class.php new file mode 100644 index 000000000..8fe35ff6f --- /dev/null +++ b/classes/xml/xmlquery/tags/table/TableTag.class.php @@ -0,0 +1,88 @@ + tag inside an XML Query file + * + * @abstract + * Example + * + *
+ * Attributes + * name - name of the table - table prefix will be automatically added + * alias - table alias. If no value is specified, the table name will be set as default alias + * join_type - in case the table is part of a join clause, this specifies the type of join: left, right etc. + * - permitted values: 'left join','left outer join','right join','right outer join' + * Children + * Can have children of type + */ + + class TableTag { + var $unescaped_name; + var $name; + var $alias; + var $join_type; + var $conditions; + var $conditionsTag; + /** + * @brief Initialises Table Tag properties + * @param XML
tag $table + */ + function TableTag($table){ + $dbParser = XmlQueryParser::getDBParser(); + + $this->unescaped_name = $table->attrs->name; + $this->name = $dbParser->parseTableName($table->attrs->name); + + $this->alias = $table->attrs->alias; + if(!$this->alias) $this->alias = $table->attrs->name; + + $this->join_type = $table->attrs->type; + + $this->conditions = $table->conditions; + + if($this->isJoinTable()) + $this->conditionsTag = new JoinConditionsTag($this->conditions); + } + + function isJoinTable(){ + if(in_array($this->join_type,array('left join','left outer join','right join','right outer join')) + && count($this->conditions)) return true; + return false; + } + + function getTableAlias(){ + return $this->alias; + } + + function getTableName(){ + return $this->unescaped_name; + } + + /** + * @brief Returns string for printing in PHP query cache file + * The string contains code for instantiation of either + * a Table or a JoinTable object + * @return string + */ + function getTableString(){ + $dbParser = XmlQueryParser::getDBParser(); + if($this->isJoinTable()){ + return sprintf('new JoinTable(\'%s\', \'%s\', "%s", %s)' + , $dbParser->escape($this->name) + , $dbParser->escape($this->alias) + , $this->join_type, $this->conditionsTag->toString()); + } + return sprintf('new Table(\'%s\'%s)' + , $dbParser->escape($this->name) + , $this->alias ? ', \'' . $dbParser->escape($this->alias) .'\'' : ''); + } + + function getArguments(){ + if(!isset($this->conditionsTag)) return array(); + return $this->conditionsTag->getArguments(); + } + } + +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/table/TablesTag.class.php b/classes/xml/xmlquery/tags/table/TablesTag.class.php new file mode 100644 index 000000000..3c1d6fcdb --- /dev/null +++ b/classes/xml/xmlquery/tags/table/TablesTag.class.php @@ -0,0 +1,64 @@ + tag inside an XML Query file + * + * @abstract + * Example + * + *
+ * + * Attributes + * None. + * Children + * Can have children of type
or + */ + + require_once(_XE_PATH_.'classes/xml/xmlquery/tags/table/TableTag.class.php'); + + class TablesTag { + var $tables; + + function TablesTag($xml_tables_tag){ + $this->tables = array(); + + $xml_tables = $xml_tables_tag->table; + if(!is_array($xml_tables)) $xml_tables = array($xml_tables); + + foreach($xml_tables as $tag){ + if($tag->attrs->query == 'true'){ + $this->tables[] = new QueryTag($tag, true); + } + else { + $this->tables[] = new TableTag($tag); + } + } + } + + function getTables(){ + return $this->tables; + } + + function toString(){ + $output_tables = 'array(' . PHP_EOL; + foreach($this->tables as $table){ + if(is_a($table, 'QueryTag')) + $output_tables .= $table->toString() . PHP_EOL . ','; + else + $output_tables .= $table->getTableString() . PHP_EOL . ','; + } + $output_tables = substr($output_tables, 0, -1); + $output_tables .= ')'; + return $output_tables; + } + + function getArguments(){ + $arguments = array(); + foreach($this->tables as $table) + $arguments = array_merge($arguments, $table->getArguments()); + return $arguments; + } + } +?> \ No newline at end of file diff --git a/test-phpUnit/Helper.class.php b/test-phpUnit/Helper.class.php new file mode 100644 index 000000000..597d52ac3 --- /dev/null +++ b/test-phpUnit/Helper.class.php @@ -0,0 +1,23 @@ +getXmlFileContent($xml_file); + } + + } + +?> \ No newline at end of file diff --git a/test-phpUnit/QueryTester.class.php b/test-phpUnit/QueryTester.class.php new file mode 100644 index 000000000..3fc911044 --- /dev/null +++ b/test-phpUnit/QueryTester.class.php @@ -0,0 +1,320 @@ +getXmlFileContent($xml_file); + $parser = new QueryParser($xml_obj->query); + return $parser->toString(); + } + + function getOldParserOutput($query_id, $xml_file){ + $cache_file = _TEST_PATH_ . "cache/".$query_id.'.cache.php'; + $parser = new OldXmlQueryParser(); + $parser->parse($query_id, $xml_file, $cache_file); + $buff = FileHandler::readFile($cache_file); + return $buff; + } + + function cleanOutputAndAddArgs($outputString, $argsString = ''){ + $outputString = str_replace("", "", $outputString); + $outputString = $argsString . $outputString; + return $outputString; + } + + function getXmlFileContent($xml_file){ + return FileHandler::readFile($xml_file); + } + + function printOutput($output){ + if(is_object($output)) { + var_dump($output); return; + } + $output = htmlspecialchars($output); + + $output = preg_replace('/select/i', 'SELECT', $output); + $output = preg_replace('/from/i', '
FROM', $output); + $output = preg_replace('/where/i', '
WHERE', $output); + $output = preg_replace('/group by/i', '
GROUP BY', $output); + $output = preg_replace('/order by/i', '
ORDER BY', $output); + + $output = str_replace("\n", "
", $output); + + echo '
'
+					.$output
+				.'
'; + } + + function getNewParserOutputString($xml_file, $argsString){ + $outputString = ''; + $outputString = $this->getNewParserOutput($xml_file); + $outputString = $this->cleanOutputAndAddArgs($outputString, $argsString); + return $outputString; + } + + function getNewParserQuery($outputString){ + //echo $outputString; + //exit(0); + $output = eval($outputString); + if(is_a($output, 'Object')) + if(!$output->toBool()) return("Date incorecte! Query-ul nu a putut fi executat."); + $db = new DBCubrid(); + if($output->getAction() == 'select') + return $db->getSelectSql($output); + else if($output->getAction() == 'insert') + return $db->getInsertSql($output); + else if($output->getAction() == 'update') + return $db->getUpdateSql($output); + else if($output->getAction() == 'delete') + return $db->getDeleteSql($output); + } + + function testNewParser($xml_file, $escape_char, $argsString, $show_output_string){ + $outputString = $this->getNewParserOutputString($xml_file, $escape_char, $argsString); + $query = $this->getNewParserQuery($outputString); + + echo '
'; + if($show_output_string){ + echo ''; + } + + echo ''; + echo ''; + } + + function getOldParserOutputString($query_id, $xml_file, $argsString){ + $outputString = $this->getOldParserOutput($query_id, $xml_file); + $outputString = $this->cleanOutputAndAddArgs($outputString, $argsString); + return $outputString; + } + + function getOldParserQuery($outputString){ + $output = eval($outputString); + if(is_a($output, 'Object')) + if(!$output->toBool()) exit("Date incorecte! Query-ul nu a putut fi executat."); + + /* SQL Server + * + $db = new DBMssql(false); + if($output->action == "select") + return $db->_executeSelectAct($output); + else if($output->action == "insert") + return $db->_executeInsertAct($output); + else if($output->action == "delete") + return $db->_executeDeleteAct($output); + else if($output->action == "update") + return $db->_executeUpdateAct($output); + */ + + /* + * Mysql + */ + $db = new DBMysql(false); + if($output->action == "select") + $db->_executeSelectAct($output); + else if($output->action == "insert") + $db->_executeInsertAct($output); + else if($output->action == "delete") + $db->_executeDeleteAct($output); + else if($output->action == "update") + $db->_executeUpdateAct($output); + return $db->getLatestQuery(); + } + + function testOldParser($query_id, $xml_file, $argsString, $show_output_string){ + $outputString = $this->getOldParserOutputString($query_id, $xml_file, $argsString); + $query = $this->getOldParserQuery($outputString); + + + echo ''; + if($show_output_string){ + echo ''; + } + + echo ''; + echo ''; + } + + function showXmlInputFile($xml_file){ + echo ''; + echo ''; + } + + function test($query_id, $xml_file, $argsString, $show_output_string, $escape_char = '"'){ + echo "

$query_id

"; + echo '
'; + $this->printOutput($outputString); + echo ''; + $this->printOutput($query); + echo '
'; + $this->printOutput($outputString); + echo ''; + $this->printOutput($query); + echo '
'; + $xml_file_content = $this->getXmlFileContent($xml_file); + $this->printOutput($xml_file_content); + echo '
'; + + $this->showXmlInputFile($xml_file); + + $this->testNewParser($xml_file, $escape_char, $argsString, $show_output_string); + + //$this->testOldParser($query_id, $xml_file, $argsString, $show_output_string); + + echo '
'; + } + + function test_addon_getAddonInfo($show_output_string = false){ + $argsString = '$args->addon = "captcha";'; + $this->test("modules.addon.getAddonInfo" + , $this->getQueryPath("modules", "addon", "getAddonInfo") + , $argsString + , $show_output_string); + } + + function test_addon_getAddons($show_output_string = false){ + $argsString = ''; + $this->test("modules.addon.getAddons" + , $this->getQueryPath("modules", "addon", "getAddons") + , $argsString + , $show_output_string); + } + + function test_admin_getCommentCount($show_output_string = false){ + $argsString = ''; + $this->test("modules.admin.getCommentCount" + , $this->getQueryPath("modules", "admin", "getCommentCount") + , $argsString + , $show_output_string); + } + + function test_admin_getCommentDeclaredStatus($show_output_string = false){ + $argsString = '$args->date = "20110411";'; + $this->test("modules.admin.getCommentDeclaredStatus" + , $this->getQueryPath("modules", "admin", "getCommentDeclaredStatus") + , $argsString + , $show_output_string); + } + + function test_module_getDefaultModules($show_output_string = false){ + $argsString = ''; + $this->test("modules.module.getDefaultModules" + , $this->getQueryPath("modules", "module", "getDefaultModules") + , $argsString + , $show_output_string); + } + + function test_module_getModuleCategories($show_output_string = false){ + $argsString = ''; + $this->test("modules.module.getModuleCategories" + , $this->getQueryPath("modules", "module", "getModuleCategories") + , $argsString + , $show_output_string); + } + + function test_module_getNonuniqueDomains($show_output_string = false){ + $argsString = ''; + $this->test("modules.module.getNonuniqueDomains" + , $this->getQueryPath("modules", "module", "getNonuniqueDomains") + , $argsString + , $show_output_string); + } + + function test_module_getAdminId($show_output_string = false){ + $argsString = '$args->module_srl = 23;'; + $this->test("modules.module.getAdminId" + , $this->getQueryPath("modules", "module", "getAdminId") + , $argsString + , $show_output_string); + } + function test_module_getSiteInfo($show_output_string = false){ + $argsString = '$args->site_srl = 0;'; + $this->test("modules.module.getSiteInfo" + , $this->getQueryPath("modules", "module", "getSiteInfo") + , $argsString + , $show_output_string); + } + function test_module_insertModule($show_output_string = false){ + $argsString = ' $args->module_category_srl = 0; + $args->browser_title = "test"; + $args->layout_srl = 0; + $args->mlayout_srl = 0; + $args->module = "page"; + $args->mid = "test"; + $args->site_srl = 0; + $args->module_srl = 47374;'; + $this->test("modules.module.insertModule" + , $this->getQueryPath("modules", "module", "insertModule") + , $argsString + , $show_output_string); + } + function test_module_updateModule($show_output_string = false){ + $argsString = ' $args->module_category_srl = 0; + $args->browser_title = "test"; + $args->layout_srl = 0; + $args->mlayout_srl = 0; + $args->module = "page"; + $args->mid = "test"; + $args->use_mobile = ""; + $args->site_srl = 0; + $args->module_srl = 47374;'; + $this->test("modules.module.updateModule" + , $this->getQueryPath("modules", "module", "updateModule") + , $argsString + , $show_output_string); + } + function test_admin_deleteActionForward($show_output_string = false){ + $argsString = '$args->module = "page"; + $args->type = "page"; + $args->act = "tata";'; + $this->test("modules.admin.deleteActionForward" + , $this->getQueryPath("modules", "module", "deleteActionForward") + , $argsString + , $show_output_string); + } + + function test_member_getAutologin($show_output_string = false){ + $argsString = '$args->autologin_key = 10;'; + $this->test("modules.member.getAutologin" + , $this->getQueryPath("modules", "member", "getAutologin") + , $argsString + , $show_output_string); + } + + function test_opage_getOpageList($show_output_string = false){ + $argsString = '$args->s_title = "yuhuu"; + $args->module = 12;'; + $this->test("modules.opage.getOpageList" + , $this->getQueryPath("modules", "opage", "getOpageList") + , $argsString + , $show_output_string); + } + function test_getPageList($show_output_string = false){ + $argsString = '$args->sort_index = "module_srl"; + $args->page_count = 10; + $args->s_module_category_srl = 0; + $args->s_mid = "test"; + $args->s_browser_title = "caca";'; + + $this->test("modules.page.getPageList" + , $this->getQueryPath("modules", "page", "getPageList") + , $argsString + , $show_output_string); + } + + + + } +?> \ No newline at end of file diff --git a/test-phpUnit/classes/db/queryparts/condition/ConditionTest.php b/test-phpUnit/classes/db/queryparts/condition/ConditionTest.php new file mode 100644 index 000000000..5b0d54d1a --- /dev/null +++ b/test-phpUnit/classes/db/queryparts/condition/ConditionTest.php @@ -0,0 +1,56 @@ +assertEquals(' "member_srl" = 20', $tag->toString()); + } + + /** + * Checks equal operation + */ + public function testConditionString_Equal_WithPipe_NumericValue() { + $member_srl_argument = new ConditionArgument('"member_srl"', 20, 'equal'); + + $tag = new Condition('"member_srl"', $member_srl_argument, 'equal', 'and'); + + $this->assertEquals('and "member_srl" = 20', $tag->toString()); + } + + /** + * Checks condition returns nothing when argument is not valid + */ + public function testConditionString_InvalidArgument() { + $member_srl_argument = new ConditionArgument('"member_srl"', null, 'equal'); + $member_srl_argument->checkNotNull(); + + $tag = new Condition('"member_srl"', $member_srl_argument, 'equal', 'and'); + + $this->assertEquals('', $tag->toString()); + } + + /** + * Checks "in" operation + */ + public function testConditionString_In_VarcharArray() { + $member_srl_argument = new ConditionArgument('"member_srl"', array('a', 'b', 'c'), 'in'); + $member_srl_argument->createConditionValue(); + $member_srl_argument->setColumnType('varchar'); + + $tag = new Condition('"member_srl"', $member_srl_argument, 'in'); + + $this->assertEquals(' "member_srl" in (\'a\',\'b\',\'c\')', $tag->toString()); + } +} + +?> diff --git a/test-phpUnit/classes/db/queryparts/table/TableTest.php b/test-phpUnit/classes/db/queryparts/table/TableTest.php new file mode 100644 index 000000000..df389a826 --- /dev/null +++ b/test-phpUnit/classes/db/queryparts/table/TableTest.php @@ -0,0 +1,42 @@ +object = new Table('"xe_member"', '"m"'); + } + + protected function tearDown() + { + } + + public function testToString() + { + $this->assertEquals('"xe_member" as "m"', $this->object->toString()); + } + + public function testGetName() + { + $this->assertEquals('"xe_member"', $this->object->getName()); + } + + public function testGetAlias() + { + $this->assertEquals('"m"', $this->object->getAlias()); + } + + public function testIsJoinTable() + { + $this->assertEquals(false, $this->object->isJoinTable()); + } +} +?> diff --git a/test-phpUnit/classes/xml/xmlquery/argument/ArgumentTest.php b/test-phpUnit/classes/xml/xmlquery/argument/ArgumentTest.php new file mode 100644 index 000000000..84293883e --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/argument/ArgumentTest.php @@ -0,0 +1,249 @@ +markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * @todo Implement testSetColumnType(). + */ + public function testSetColumnType() { + // Remove the following lines when you implement this test. + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * @todo Implement testGetName(). + */ + public function testGetName() { + // Remove the following lines when you implement this test. + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * @todo Implement testGetValue(). + */ + public function testGetValue() { + // Remove the following lines when you implement this test. + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * @todo Implement testGetUnescapedValue(). + */ + public function testGetUnescapedValue() { + // Remove the following lines when you implement this test. + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * @todo Implement testToString(). + */ + public function testToString() { + // Remove the following lines when you implement this test. + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * @todo Implement testEscapeValue(). + */ + public function testEscapeValue() { + // Remove the following lines when you implement this test. + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * @todo Implement testIsValid(). + */ + public function testIsValid() { + // Remove the following lines when you implement this test. + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * @todo Implement testGetErrorMessage(). + */ + public function testGetErrorMessage() { + // Remove the following lines when you implement this test. + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * @todo Implement testEnsureDefaultValue(). + */ + public function testEnsureDefaultValue() { + // Remove the following lines when you implement this test. + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * @todo Implement testCheckFilter(). + */ + public function testCheckFilter() { + // Remove the following lines when you implement this test. + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * @todo Implement testCheckMaxLength(). + */ + public function testCheckMaxLength() { + // Remove the following lines when you implement this test. + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * @todo Implement testCheckMinLength(). + */ + public function testCheckMinLength() { + // Remove the following lines when you implement this test. + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * Checks that argument is valid after a notnull check when value is not null + */ + public function testCheckNotNullWhenNotNull() { + $member_srl_argument = new ConditionArgument('member_srl', 20, 'equal'); + $member_srl_argument->checkNotNull(); + + $this->assertEquals(true, $member_srl_argument->isValid()); + } + + /** + * Checks that argument becomes invalid after a notnull check when value is null + */ + public function testCheckNotNullWhenNull() { + $member_srl_argument = new ConditionArgument('member_srl', null, 'equal'); + $member_srl_argument->checkNotNull(); + + $this->assertEquals(false, $member_srl_argument->isValid()); + } + + /** + * Checks that argument value stays the same when both user value and default value are given + */ + public function testCheckDefaultValueWhenNotNull() { + $member_srl_argument = new ConditionArgument('member_srl', 20, 'equal'); + $member_srl_argument->ensureDefaultValue(25); + + $this->assertEquals(20, $member_srl_argument->getValue()); + } + + /** + * Checks that argument value gets set when user value is null and default value is specified + */ + public function testCheckDefaultValueWhenNull() { + $member_srl_argument = new ConditionArgument('member_srl', null, 'equal'); + $member_srl_argument->ensureDefaultValue(25); + + $this->assertEquals(25, $member_srl_argument->getValue()); + } + + /** + * Checks like prefix operation + */ + public function testCreateConditionValue_LikePrefix() { + $member_srl_argument = new ConditionArgument('"mid"', 'forum', 'like_prefix'); + $member_srl_argument->createConditionValue(); + + $this->assertEquals('forum%', $member_srl_argument->getValue()); + } + + /** + * Checks like tail operation + */ + public function testCreateConditionValue_LikeTail() { + $member_srl_argument = new ConditionArgument('"mid"', 'forum', 'like_tail'); + $member_srl_argument->createConditionValue(); + + $this->assertEquals('%forum', $member_srl_argument->getValue()); + } + + /** + * Checks like operation + */ + public function testCreateConditionValue_Like() { + $member_srl_argument = new ConditionArgument('"mid"', 'forum', 'like'); + $member_srl_argument->createConditionValue(); + + $this->assertEquals('%forum%', $member_srl_argument->getValue()); + } + + + /** + * Checks in operation + */ + public function testCreateConditionValue_In_StringValues() { + $member_srl_argument = new ConditionArgument('"mid"', array('forum', 'board'), 'in'); + $member_srl_argument->createConditionValue(); + $member_srl_argument->setColumnType('varchar'); + + $this->assertEquals('(\'forum\',\'board\')', $member_srl_argument->getValue()); + } + + /** + * Checks in operation + */ + public function testCreateConditionValue_In_NumericValues() { + $member_srl_argument = new ConditionArgument('"module_srl"', array(3, 21), 'in'); + $member_srl_argument->setColumnType('number'); + $member_srl_argument->createConditionValue(); + + $this->assertEquals('(3,21)', $member_srl_argument->getValue()); + } + + public function testEnsureDefaultValueWithEmptyString(){ + $homepage_argument = new Argument('homepage', ''); + $homepage_argument->ensureDefaultValue(''); + $homepage_argument->checkFilter('homepage'); + if(!$homepage_argument->isValid()) return $homepage_argument->getErrorMessage(); + $homepage_argument->setColumnType('varchar'); + + + $this->assertEquals('\'\'', $homepage_argument->getValue()); + } + + public function testDefaultValue() { + $default = new DefaultValue("var", ''); + $this->assertEquals('\'\'', $default->toString()); + } +} + +?> diff --git a/test-phpUnit/classes/xml/xmlquery/argument/ConditionArgumentTest.php b/test-phpUnit/classes/xml/xmlquery/argument/ConditionArgumentTest.php new file mode 100644 index 000000000..633e00cfb --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/argument/ConditionArgumentTest.php @@ -0,0 +1,64 @@ +document_srl = 1234; + $document_srl_argument = new ConditionArgument('document_srl', $args->document_srl, 'in'); + $document_srl_argument->checkNotNull(); + $document_srl_argument->createConditionValue(); + if(!$document_srl_argument->isValid()) return $document_srl_argument->getErrorMessage(); + $document_srl_argument->setColumnType('number'); + + $condition = new Condition('"extra_vars"."document_srl"',$document_srl_argument,"in", 'and'); + $this->assertEquals('and "extra_vars"."document_srl" in (1234)', $condition->toString()); + } + + function testZeroValue(){ + $args->site_srl = 0; + $site_srl_argument = new ConditionArgument('site_srl', $args->site_srl, 'equal'); + $site_srl_argument->checkNotNull(); + $site_srl_argument->createConditionValue(); + if(!$site_srl_argument->isValid()) return $site_srl_argument->getErrorMessage(); + $site_srl_argument->setColumnType('number'); + + $condition = new Condition('"sites"."site_srl"',$site_srl_argument,"equal"); + $this->assertEquals(' "sites"."site_srl" = 0', $condition->toString()); + } + + /** + * @todo Implement testCreateConditionValue(). + */ + public function testCreateConditionValue() { + // Remove the following lines when you implement this test. + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * @todo Implement testGetType(). + */ + public function testGetType() { + // Remove the following lines when you implement this test. + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + + /** + * @todo Implement testSetColumnType(). + */ + public function testSetColumnType() { + // Remove the following lines when you implement this test. + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } + +} + +?> diff --git a/test-phpUnit/classes/xml/xmlquery/queryargument/QueryArgumentTest.php b/test-phpUnit/classes/xml/xmlquery/queryargument/QueryArgumentTest.php new file mode 100644 index 000000000..5aed5baa4 --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/queryargument/QueryArgumentTest.php @@ -0,0 +1,15 @@ +xmlPath = str_replace('QueryArgumentTest.php', '', str_replace('\\', '/', __FILE__)) . $this->xmlPath; + } + } + +?> diff --git a/test-phpUnit/classes/xml/xmlquery/queryargument/data/condition1.xml b/test-phpUnit/classes/xml/xmlquery/queryargument/data/condition1.xml new file mode 100644 index 000000000..53decc580 --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/queryargument/data/condition1.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test-phpUnit/classes/xml/xmlquery/queryargument/data/index1.xml b/test-phpUnit/classes/xml/xmlquery/queryargument/data/index1.xml new file mode 100644 index 000000000..6cbf9193a --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/queryargument/data/index1.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test-phpUnit/classes/xml/xmlquery/tags/condition/ConditionTagTest.php b/test-phpUnit/classes/xml/xmlquery/tags/condition/ConditionTagTest.php new file mode 100644 index 000000000..fe8d84f44 --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/tags/condition/ConditionTagTest.php @@ -0,0 +1,87 @@ +xmlPath = str_replace('ConditionTagTest.php', '', str_replace('\\', '/', __FILE__)) . $this->xmlPath; + } + + /** + * Tests a simple tag: + * + */ + function testConditionStringWithArgument(){ + $xml_file = $this->xmlPath . "condition1.xml"; + $xml_obj = Helper::getXmlObject($xml_file); + $tag = new ConditionTag($xml_obj->condition); + $arguments = $tag->getArguments(); + + $expected = "new Condition('\"user_id\"',\$" . $arguments[0]->getArgumentName() . "_argument,\"equal\")"; + $actual = $tag->getConditionString(); + $this->assertEquals($expected, $actual); + + + $this->assertEquals(1, count($arguments)); + } + + /** + * Tests a condition tag for joins - that uses no argument + * + */ + function testConditionStringWithoutArgument(){ + $xml_file = $this->xmlPath . "condition3.xml"; + $xml_obj = Helper::getXmlObject($xml_file); + $tag = new ConditionTag($xml_obj->condition); + + $expected = "new Condition('\"comments\".\"user_id\"','\"member\".\"user_id\"',\"equal\")"; + $actual = $tag->getConditionString(); + $this->assertEquals($expected, $actual); + + $arguments = $tag->getArguments(); + $this->assertEquals(0, count($arguments)); + } + + + /** + * Tests a tag with pipe: + * + */ + function testConditionStringWithPipe(){ + $xml_file = $this->xmlPath . "condition2.xml"; + $xml_obj = Helper::getXmlObject($xml_file); + $tag = new ConditionTag($xml_obj->condition); + $arguments = $tag->getArguments(); + + $expected = "new Condition('\"type\"',\$" . $arguments[0]->getArgumentName() . "_argument,\"equal\", 'and')"; + $actual = $tag->getConditionString(); + $this->assertEquals($expected, $actual); + + + $this->assertEquals(1, count($arguments)); + } + + /** + * Tests that even if the column name is given in the var attribute, it knows it's just a name and not an argument + * + */ + function testConditionStringWithoutArgumentAndDefaultValueInsideVar(){ + $xml_file = $this->xmlPath . "condition4.xml"; + $xml_obj = Helper::getXmlObject($xml_file); + $tag = new ConditionTag($xml_obj->condition); + + $expected = "new Condition('\"modules\".\"module_srl\"','\"documents\".\"module_srl\"',\"equal\", 'and')"; + $actual = $tag->getConditionString(); + $this->assertEquals($expected, $actual); + + $arguments = $tag->getArguments(); + $this->assertEquals(0, count($arguments)); + } + +} + +?> diff --git a/test-phpUnit/classes/xml/xmlquery/tags/condition/data/condition1.xml b/test-phpUnit/classes/xml/xmlquery/tags/condition/data/condition1.xml new file mode 100644 index 000000000..274121640 --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/tags/condition/data/condition1.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test-phpUnit/classes/xml/xmlquery/tags/condition/data/condition2.xml b/test-phpUnit/classes/xml/xmlquery/tags/condition/data/condition2.xml new file mode 100644 index 000000000..7ace26b8d --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/tags/condition/data/condition2.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test-phpUnit/classes/xml/xmlquery/tags/condition/data/condition3.xml b/test-phpUnit/classes/xml/xmlquery/tags/condition/data/condition3.xml new file mode 100644 index 000000000..538d81f3d --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/tags/condition/data/condition3.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test-phpUnit/classes/xml/xmlquery/tags/condition/data/condition4.xml b/test-phpUnit/classes/xml/xmlquery/tags/condition/data/condition4.xml new file mode 100644 index 000000000..ac432b118 --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/tags/condition/data/condition4.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test-phpUnit/classes/xml/xmlquery/tags/table/TableTagTest.php b/test-phpUnit/classes/xml/xmlquery/tags/table/TableTagTest.php new file mode 100644 index 000000000..1e7c86d74 --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/tags/table/TableTagTest.php @@ -0,0 +1,134 @@ +xmlPath = str_replace('TableTagTest.php', '', str_replace('\\', '/', __FILE__)) . $this->xmlPath; + } + + /** + * Tests a simple tag: + *
+ */ + function testTableTagWithName(){ + $xml_file = $this->xmlPath . "table_name.xml"; + $xml_obj = Helper::getXmlObject($xml_file); + $tag = new TableTag($xml_obj->table); + + $expected = "new Table('\"xe_modules\"', '\"modules\"')"; + $actual = $tag->getTableString(); + $this->assertEquals($expected, $actual); + } + + /** + * Tests a
tag with name and alias + *
+ */ + function testTableTagWithNameAndAlias(){ + $xml_file = $this->xmlPath . "table_name_alias.xml"; + $xml_obj = Helper::getXmlObject($xml_file); + + $tag = new TableTag($xml_obj->table); + + $expected = "new Table('\"xe_modules\"', '\"mod\"')"; + $actual = $tag->getTableString(); + $this->assertEquals($expected, $actual); + } + + /** + * Tests a
tag used for joins + *
+ * + * + * + *
+ * + */ + function testTableTagWithJoinCondition(){ + $xml_file = $this->xmlPath . "table_name_alias_type.xml"; + $xml_obj = Helper::getXmlObject($xml_file); + + $tag = new TableTag($xml_obj->table); + + $actual = $tag->getTableString(); + + $expected = 'new JoinTable(\'"xe_module_categories"\', \'"module_categories"\', "left join", array( + new ConditionGroup(array( + new Condition(\'"module_categories"."module_category_srl"\',\'"modules"."module_category_srl"\',"equal") + )) + ))'; + $actual = Helper::cleanString($actual); + $expected = Helper::cleanString($expected); + + $this->assertEquals($expected, $actual); + } + + /** + * If a table tag has the type attribute and condition children + * it means it is meant to be used inside a join + */ + function testTagWithTypeIsJoinTable(){ + $xml_file = $this->xmlPath . "table_name_alias_type.xml"; + $xml_obj = Helper::getXmlObject($xml_file); + + $tag = new TableTag($xml_obj->table); + + $this->assertEquals(true, $tag->isJoinTable()); + } + + /** + * Tests that a simple table tag is not a join table + */ + function testTagWithoutTypeIsNotJoinTable(){ + $xml_file = $this->xmlPath . "table_name_alias.xml"; + $xml_obj = Helper::getXmlObject($xml_file); + + $tag = new TableTag($xml_obj->table); + + $this->assertEquals(false, $tag->isJoinTable()); + } + + /** + * If no alias is specified, test that table name is used + */ + function testTableAliasWhenAliasNotSpecified(){ + $xml_file = $this->xmlPath . "table_name.xml"; + $xml_obj = Helper::getXmlObject($xml_file); + + $tag = new TableTag($xml_obj->table); + + $this->assertEquals("modules", $tag->getTableAlias()); + } + + /** + * If alias is specified, test that it is used + */ + function testTableAliasWhenAliasSpecified(){ + $xml_file = $this->xmlPath . "table_name_alias.xml"; + $xml_obj = Helper::getXmlObject($xml_file); + + $tag = new TableTag($xml_obj->table); + + $this->assertEquals("mod", $tag->getTableAlias()); + } + + /** + * Table name propery should returned unescaped and unprefixed table name + * (The one in the XML file) + */ + function testTableName(){ + $xml_file = $this->xmlPath . "table_name_alias.xml"; + $xml_obj = Helper::getXmlObject($xml_file); + + $tag = new TableTag($xml_obj->table); + + $this->assertEquals("modules", $tag->getTableName()); + } + + } \ No newline at end of file diff --git a/test-phpUnit/classes/xml/xmlquery/tags/table/TablesTagTest.php b/test-phpUnit/classes/xml/xmlquery/tags/table/TablesTagTest.php new file mode 100644 index 000000000..5181cafbd --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/tags/table/TablesTagTest.php @@ -0,0 +1,114 @@ +xmlPath = str_replace('TablesTagTest.php', '', str_replace('\\', '/', __FILE__)) . $this->xmlPath; + } + + /** + * Tests a simple tag: + * + * + * + */ + function testTablesTagWithOneTable(){ + $xml_file = $this->xmlPath . "tables_one_table.xml"; + $xml_obj = Helper::getXmlObject($xml_file); + $tag = new TablesTag($xml_obj->tables); + + $expected = "array(new Table('\"xe_member\"', '\"member\"'))"; + $actual = $tag->toString(); + + $this->_testCachedOutput($expected, $actual); + } + + /** + * Tests a simple tag: + * + *
+ *
+ * + */ + function testTablesTagWithTwoTablesNoJoin(){ + $xml_file = $this->xmlPath . "tables_two_tables_no_join.xml"; + $xml_obj = Helper::getXmlObject($xml_file); + $tag = new TablesTag($xml_obj->tables); + + $expected = "array( + new Table('\"xe_member_group\"', '\"a\"') + ,new Table('\"xe_member_group_member\"', '\"b\"') + )"; + $actual = $tag->toString(); + + $this->_testCachedOutput($expected, $actual); + } + + /** + * Tests a simple tag: + * + *
+ *
+ * + * + * + *
+ *
+ */ + function testTablesTagWithTwoTablesWithJoin(){ + $xml_file = $this->xmlPath . "tables_two_tables_with_join.xml"; + $xml_obj = Helper::getXmlObject($xml_file); + $tag = new TablesTag($xml_obj->tables); + + $expected = "array( + new Table('\"xe_files\"', '\"files\"') + ,new JoinTable('\"xe_member\"' + , '\"member\"' + , \"left join\" + , array( + new ConditionGroup( + array( + new Condition( + '\"files\".\"member_srl\"' + ,'\"member\".\"member_srl\"' + ,\"equal\" + ) + ) + ) + ) + ) + )"; + $actual = $tag->toString(); + + $this->_testCachedOutput($expected, $actual); + } + + /** + * Tests a simple tag: + * + * + *
+ * + * + * + *
+ *
+ */ + function testGetTables(){ + $xml_file = $this->xmlPath . "tables_two_tables_with_join.xml"; + $xml_obj = Helper::getXmlObject($xml_file); + $tag = new TablesTag($xml_obj->tables); + + $tables = $tag->getTables(); + + $this->assertEquals(2, count($tables)); + $this->assertTrue(is_a($tables[0], 'TableTag')); + $this->assertTrue(is_a($tables[1], 'TableTag')); + } + } \ No newline at end of file diff --git a/test-phpUnit/classes/xml/xmlquery/tags/table/data/table_name.xml b/test-phpUnit/classes/xml/xmlquery/tags/table/data/table_name.xml new file mode 100644 index 000000000..6525964f0 --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/tags/table/data/table_name.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test-phpUnit/classes/xml/xmlquery/tags/table/data/table_name_alias.xml b/test-phpUnit/classes/xml/xmlquery/tags/table/data/table_name_alias.xml new file mode 100644 index 000000000..8240d4652 --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/tags/table/data/table_name_alias.xml @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test-phpUnit/classes/xml/xmlquery/tags/table/data/table_name_alias_type.xml b/test-phpUnit/classes/xml/xmlquery/tags/table/data/table_name_alias_type.xml new file mode 100644 index 000000000..6d8e7f1d5 --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/tags/table/data/table_name_alias_type.xml @@ -0,0 +1,5 @@ +
+ + + +
\ No newline at end of file diff --git a/test-phpUnit/classes/xml/xmlquery/tags/table/data/tables_one_table.xml b/test-phpUnit/classes/xml/xmlquery/tags/table/data/tables_one_table.xml new file mode 100644 index 000000000..525df54be --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/tags/table/data/tables_one_table.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/test-phpUnit/classes/xml/xmlquery/tags/table/data/tables_two_tables_no_join.xml b/test-phpUnit/classes/xml/xmlquery/tags/table/data/tables_two_tables_no_join.xml new file mode 100644 index 000000000..cdedcb831 --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/tags/table/data/tables_two_tables_no_join.xml @@ -0,0 +1,4 @@ + +
+
+ \ No newline at end of file diff --git a/test-phpUnit/classes/xml/xmlquery/tags/table/data/tables_two_tables_with_join.xml b/test-phpUnit/classes/xml/xmlquery/tags/table/data/tables_two_tables_with_join.xml new file mode 100644 index 000000000..fd8d8775e --- /dev/null +++ b/test-phpUnit/classes/xml/xmlquery/tags/table/data/tables_two_tables_with_join.xml @@ -0,0 +1,8 @@ + +
+
+ + + +
+
\ No newline at end of file diff --git a/test-phpUnit/config/config.inc.php b/test-phpUnit/config/config.inc.php new file mode 100644 index 000000000..6fc807eed --- /dev/null +++ b/test-phpUnit/config/config.inc.php @@ -0,0 +1,53 @@ + \ No newline at end of file diff --git a/test-phpUnit/db/CubridOnlineTest.php b/test-phpUnit/db/CubridOnlineTest.php new file mode 100644 index 000000000..f3ca80ba4 --- /dev/null +++ b/test-phpUnit/db/CubridOnlineTest.php @@ -0,0 +1,41 @@ +db_type = 'cubrid'; + $db_info->db_port = '33000'; + $db_info->db_hostname = '10.0.0.206'; + $db_info->db_userid = 'dba'; + $db_info->db_password = 'arniarules'; + $db_info->db_database = 'xe15QA'; + $db_info->db_table_prefix = 'xe'; + + $oContext->setDbInfo($db_info); + + // remove cache dir + FileHandler::removeDir( _XE_PATH_ . 'files/cache'); + } + + /** + * Free resources - reset static DB and QueryParser + */ + protected function tearDown() { + unset($GLOBALS['__DB__']); + XmlQueryParser::setDBParser(null); + } + } +?> diff --git a/test-phpUnit/db/CubridTest.php b/test-phpUnit/db/CubridTest.php new file mode 100644 index 000000000..8739f62bd --- /dev/null +++ b/test-phpUnit/db/CubridTest.php @@ -0,0 +1,29 @@ +db_type = 'cubrid'; + $db_info->db_table_prefix = 'xe'; + + $oContext->setDbInfo($db_info); + } + + /** + * Free resources - reset static DB and QueryParser + */ + protected function tearDown() { + unset($GLOBALS['__DB__']); + XmlQueryParser::setDBParser(null); + } + } +?> diff --git a/test-phpUnit/db/DBTest.php b/test-phpUnit/db/DBTest.php new file mode 100644 index 000000000..59f5c4a3f --- /dev/null +++ b/test-phpUnit/db/DBTest.php @@ -0,0 +1,69 @@ +getNewParserOutputString($xml_file, $argsString); + echo $outputString; + $output = eval($outputString); + + if(!is_a($output, 'Query')){ + if(!$output->toBool()) $querySql = "Date incorecte! Query-ul nu a putut fi executat."; + }else { + $db = &DB::getInstance(); + if($columnList) $output->setColumnList($columnList); + $querySql = $db->{$methodName}($output); + + // Remove whitespaces, tabs and all + $querySql = Helper::cleanString($querySql); + $expected = Helper::cleanString($expected); + } + $this->assertEquals($expected, $querySql); + } + + function _testPreparedQuery($xml_file, $argsString, $expected, $methodName, $expectedArgs = NULL){ + echo PHP_EOL . ' ----------------------------------- ' .PHP_EOL; + echo $xml_file; + echo PHP_EOL . ' ----------------------------------- ' .PHP_EOL; + + $tester = new QueryTester(); + $outputString = $tester->getNewParserOutputString($xml_file, $argsString); + echo $outputString; + $output = eval($outputString); + + if(!is_a($output, 'Query')){ + if(!$output->toBool()) $querySql = "Date incorecte! Query-ul nu a putut fi executat."; + }else { + $db = &DB::getInstance(); + $querySql = $db->{$methodName}($output, false); + $queryArguments = $output->getArguments(); + + // Remove whitespaces, tabs and all + $querySql = Helper::cleanString($querySql); + $expected = Helper::cleanString($expected); + } + + // Test + $this->assertEquals($expected, $querySql); + + // Test query arguments + $argCount = count($expectedArgs); + for($i = 0; $i < $argCount; $i++){ + $this->assertEquals($expectedArgs[$i], $queryArguments[$i]->getEscapedValue()); + } + } + + function _testCachedOutput($expected, $actual){ + $expected = Helper::cleanString($expected); + $actual = Helper::cleanString($actual); + + $this->assertEquals($expected, $actual); + + } + } + +?> diff --git a/test-phpUnit/db/ExpressionParserTest.php b/test-phpUnit/db/ExpressionParserTest.php new file mode 100644 index 000000000..09bb8e73f --- /dev/null +++ b/test-phpUnit/db/ExpressionParserTest.php @@ -0,0 +1,110 @@ +dbLeftEscapeChar,$this->dbRightEscapeChar); + $actual = $expressionParser->parseExpression($column_name); + if($alias) $actual .= " as $alias"; + $this->assertEquals($expected, $actual); + } + + function testStarExpressionIsNotEscaped(){ + $this->_test("*", NULL, '*'); + } + + function testSimpleColumnNameGetsEscaped(){ + $this->_test("member_srl", NULL + , $this->dbLeftEscapeChar.'member_srl'.$this->dbRightEscapeChar ); + } + + function testUnqualifiedAliasedColumnNameGetsEscaped(){ + $this->_test("member_srl", "id" + , $this->dbLeftEscapeChar.'member_srl'.$this->dbRightEscapeChar.' as id'); + } + + function testQualifiedColumnNameGetsEscaped(){ + $this->_test("xe_members.member_srl", NULL + , $this->dbLeftEscapeChar.'xe_members'.$this->dbRightEscapeChar.'.'.$this->dbLeftEscapeChar.'member_srl'.$this->dbRightEscapeChar); + } + + function testQualifiedAliasedColumnNameGetsEscaped(){ + $this->_test("xe_members.member_srl","id" + ,$this->dbLeftEscapeChar.'xe_members'.$this->dbRightEscapeChar.'.'.$this->dbLeftEscapeChar.'member_srl'.$this->dbRightEscapeChar.' as id'); + } + + function testCountDoesntGetEscaped(){ + $this->_test("count(*)", NULL, 'count(*)'); + } + + function testAliasedCountDoesntGetEscaped(){ + $this->_test("count(*)", "count", 'count(*) as count'); + } + + function testUnqualifiedColumnExpressionWithOneParameterLessFunction(){ + $this->_test("substring(regdate)", NULL + , 'substring('.$this->dbLeftEscapeChar.'regdate'.$this->dbRightEscapeChar.')'); + } + + function testAliasedUnqualifiedColumnExpressionWithOneParameterLessFunction(){ + $this->_test("substring(regdate)", "regdate" + , 'substring('.$this->dbLeftEscapeChar.'regdate'.$this->dbRightEscapeChar.') as regdate'); + } + + function testQualifiedColumnExpressionWithOneParameterLessFunction(){ + $this->_test("substring(xe_member.regdate)", NULL + , 'substring('.$this->dbLeftEscapeChar.'xe_member'.$this->dbRightEscapeChar.'.'.$this->dbLeftEscapeChar.'regdate'.$this->dbRightEscapeChar.')'); + } + + function testAliasedQualifiedColumnExpressionWithOneParameterLessFunction(){ + $this->_test("substring(xe_member.regdate)", "regdate" + , 'substring('.$this->dbLeftEscapeChar.'xe_member'.$this->dbRightEscapeChar.'.'.$this->dbLeftEscapeChar.'regdate'.$this->dbRightEscapeChar.') as regdate'); + } + + function testUnqualifiedColumnExpressionWithTwoParameterLessFunctions(){ + $this->_test("lpad(rpad(regdate))", NULL + , 'lpad(rpad('.$this->dbLeftEscapeChar.'regdate'.$this->dbRightEscapeChar.'))'); + } + + function testAliasedUnqualifiedColumnExpressionWithTwoParameterLessFunctions(){ + $this->_test("lpad(rpad(regdate))", "regdate" + , 'lpad(rpad('.$this->dbLeftEscapeChar.'regdate'.$this->dbRightEscapeChar.')) as regdate'); + } + + function testQualifiedColumnExpressionWithTwoParameterLessFunctions(){ + $this->_test("lpad(rpad(xe_member.regdate))", NULL + , 'lpad(rpad('.$this->dbLeftEscapeChar.'xe_member'.$this->dbRightEscapeChar.'.'.$this->dbLeftEscapeChar.'regdate'.$this->dbRightEscapeChar.'))'); + } + + function testAliasedQualifiedColumnExpressionWithTwoParameterLessFunctions(){ + $this->_test("lpad(rpad(xe_member.regdate))", "regdate" + , 'lpad(rpad('.$this->dbLeftEscapeChar.'xe_member'.$this->dbRightEscapeChar.'.'.$this->dbLeftEscapeChar.'regdate'.$this->dbRightEscapeChar.')) as regdate'); + } + + function testColumnAddition(){ + $this->_test("score1 + score2", "total" + , $this->dbLeftEscapeChar.'score1'.$this->dbRightEscapeChar.' + '.$this->dbLeftEscapeChar.'score2'.$this->dbRightEscapeChar.' as total'); + } + + function testMultipleParameterFunction(){ + $this->_test("substring(regdate, 1, 8)", NULL + , 'substring('.$this->dbLeftEscapeChar.'regdate'.$this->dbRightEscapeChar.', 1, 8)'); + $this->_test("substring(regdate, 1, 8)", "regdate" + , 'substring('.$this->dbLeftEscapeChar.'regdate'.$this->dbRightEscapeChar.', 1, 8) as regdate'); + $this->_test("substring(xe_member.regdate, 1, 8)", NULL + , 'substring('.$this->dbLeftEscapeChar.'xe_member'.$this->dbRightEscapeChar.'.'.$this->dbLeftEscapeChar.'regdate'.$this->dbRightEscapeChar.', 1, 8)'); + } + + function testFunctionAddition(){ + $this->_test("abs(score) + abs(totalscore)", NULL + , 'abs('.$this->dbLeftEscapeChar.'score'.$this->dbRightEscapeChar.') + abs('.$this->dbLeftEscapeChar.'totalscore'.$this->dbRightEscapeChar.')'); + } + } \ No newline at end of file diff --git a/test-phpUnit/db/MssqlOnlineTest.php b/test-phpUnit/db/MssqlOnlineTest.php new file mode 100644 index 000000000..10cfe0423 --- /dev/null +++ b/test-phpUnit/db/MssqlOnlineTest.php @@ -0,0 +1,41 @@ +db_type = 'mssql'; + $db_info->db_port = '3306'; + $db_info->db_hostname = 'PHENOMII\SQL2008EXPRESS'; + $db_info->db_userid = 'dba'; + $db_info->db_password = 'arniarules'; + $db_info->db_database = 'xe-15-db'; + $db_info->db_table_prefix = 'xe'; + + $oContext->setDbInfo($db_info); + + // remove cache dir + FileHandler::removeDir( _XE_PATH_ . 'files/cache'); + } + + /** + * Free resources - reset static DB and QueryParser + */ + protected function tearDown() { + unset($GLOBALS['__DB__']); + XmlQueryParser::setDBParser(null); + } + } +?> diff --git a/test-phpUnit/db/MssqlTest.php b/test-phpUnit/db/MssqlTest.php new file mode 100644 index 000000000..20de1129d --- /dev/null +++ b/test-phpUnit/db/MssqlTest.php @@ -0,0 +1,24 @@ +db_type = 'mssql'; + $db_info->db_table_prefix = 'xe'; + + $oContext->setDbInfo($db_info); + } + + protected function tearDown() { + unset($GLOBALS['__DB__']); + XmlQueryParser::setDBParser(null); + } + } +?> diff --git a/test-phpUnit/db/xml_query/cubrid/CubridDeleteTest.php b/test-phpUnit/db/xml_query/cubrid/CubridDeleteTest.php new file mode 100644 index 000000000..76fddaa36 --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/CubridDeleteTest.php @@ -0,0 +1,21 @@ +_testQuery($xml_file, $argsString, $expected, 'getDeleteSql'); + } + + function test_module_deleteActionForward(){ + $xml_file = _XE_PATH_ . "modules/module/queries/deleteActionForward.xml"; + $argsString = '$args->module = "page"; + $args->type = "page"; + $args->act = "tata";'; + $expected = 'delete "action_forward" from "xe_action_forward" as "action_forward" + where "module" = \'page\' + and "type" = \'page\' + and "act" = \'tata\''; + $this->_test($xml_file, $argsString, $expected); + } + } \ No newline at end of file diff --git a/test-phpUnit/db/xml_query/cubrid/CubridInsertOnlineTest.php b/test-phpUnit/db/xml_query/cubrid/CubridInsertOnlineTest.php new file mode 100644 index 000000000..f55bd3720 --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/CubridInsertOnlineTest.php @@ -0,0 +1,86 @@ +module_category_srl = 0; + $args->browser_title = "test"; + $args->layout_srl = 0; + $args->mlayout_srl = 0; + $args->module = "page"; + $args->mid = "test"; + $args->site_srl = 0; + $args->module_srl = 47374; + $args->content = "hello \' moto"; + + $output = executeQuery('module.insertModule', $args); + + $this->assertTrue(!$output->error, $output->message); + } + + function test_document_insertDocument_defaultVarcharValue(){ + $args->module_srl = 102; + $args->content = '

yuhuuuuu

'; + $args->document_srl = 9200; + $args->is_secret = 'N'; + $args->allow_comment = 'N'; + $args->lock_comment = 'N'; + $args->allow_trackback = 'N'; + $args->notify_message = 'N'; + $args->ipaddress = '127.0.0.1'; + $args->extra_vars = 'N;'; + $args->readed_count = 0; + $args->list_order = -9201; + $args->update_order = -9201; + $args->member_srl = 4; + $args->user_id = 'admin'; + $args->user_name = 'admin'; + $args->nick_name = 'admin'; + $args->email_address = 'admin@admin.admin'; + $args->homepage = ''; + $args->title = 'yuhuu'; + $args->lang_code; + $output = executeQuery('document.insertDocument', $args); + + $this->assertNotEquals(-225, $output->error); + $this->assertNotEquals('Missing value for attribute "homepage" with the NOT NULL constraint.', $output->message); + } + + function test_communication_addFriendGroup(){ + $args->member_srl = 202; + $args->title = "Grup"; + + $output = executeQuery("communication.addFriendGroup", $args); + $this->assertEquals(0, $output->error, $output->message); + + } + + function test_communication_addFriendGroup_NullId(){ + $args->member_srl = 202; + $args->title = "Grup"; + $args->friend_group_srl = trim(null); + + $output = executeQuery("communication.addFriendGroup", $args); + $this->assertEquals(0, $output->error, $output->message); + + } + + protected function tearDown() { + $db = &DB::getInstance(); + $db->_query("DELETE FROM xe_modules WHERE module_srl = 47374"); + $db->_query("DELETE FROM xe_documents WHERE document_srl = 9200"); + $db->_query("DELETE FROM xe_member_friend_group WHERE member_srl = 202"); + $db->close(); + + parent::tearDown(); + // TODO Delete inserted value + } + + + } \ No newline at end of file diff --git a/test-phpUnit/db/xml_query/cubrid/CubridInsertTest.php b/test-phpUnit/db/xml_query/cubrid/CubridInsertTest.php new file mode 100644 index 000000000..80a658988 --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/CubridInsertTest.php @@ -0,0 +1,128 @@ +_testQuery($xml_file, $argsString, $expected, 'getInsertSql'); + } + + + /** + * Note: this test can fail when comaparing regdate from the $args with + * regdate from the expected string - a few seconds difference + */ + function test_module_insertModule(){ + $xml_file = _XE_PATH_ . "modules/module/queries/insertModule.xml"; + $argsString = ' $args->module_category_srl = 0; + $args->browser_title = "test"; + $args->layout_srl = 0; + $args->mlayout_srl = 0; + $args->module = "page"; + $args->mid = "test"; + $args->site_srl = 0; + $args->module_srl = 47374;'; + $expected = 'insert into "xe_modules" + ("site_srl" + , "module_srl" + , "module_category_srl" + , "mid" + , "browser_title" + , "layout_srl" + , "module" + , "is_default" + , "open_rss" + , "regdate" + , "mlayout_srl" + , "use_mobile") + values + (0 + , 47374 + , 0 + , \'test\' + , \'test\' + , 0 + , \'page\' + , \'n\' + , \'y\' + , \''.date("YmdHis").'\' + , 0 + , \'n\')'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_module_insertSiteTodayStatus(){ + //\''.date("YmdHis").'\' + $xml_file = _XE_PATH_ . "modules/counter/queries/insertTodayStatus.xml"; + $argsString = ' $args->regdate = 0; + $args->unique_visitor = 0; + $args->pageview = 0;'; + $expected = 'insert into "xe_counter_status" + ("regdate" + , "unique_visitor" + , "pageview") + values + ('.date("YmdHis").' + , 0 + , 0)'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_module_insertCounterLog(){ + $xml_file = _XE_PATH_ . "modules/counter/queries/insertCounterLog.xml"; + $argsString = ' $args->site_srl = 0; + $args->regdate = "20110607120619"; + $args->ipaddress = "127.0.0.1"; + $args->user_agent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.77 Safari/534.24";'; + $expected = 'insert into "xe_counter_log" + ("site_srl", "regdate", "ipaddress", "user_agent") + VALUES (0, \'20110607120619\', \'127.0.0.1\', \'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.77 Safari/534.24\') + '; + $this->_test($xml_file, $argsString, $expected); + } + + function test_module_insertMember(){ + $xml_file = _XE_PATH_ . "modules/member/queries/insertMember.xml"; + $argsString = ' $args->member_srl = 203; + $args->user_id = "cacao"; + $args->email_address = "teta@ar.ro"; + $args->password = "23e5484cb88f3c07bcce2920a5e6a2a7"; + $args->email_id = "teta"; + $args->email_host = "ar.ro"; + $args->user_name = "trident"; + $args->nick_name = "aloha"; + $args->homepage = "http://jkgjfk./ww"; + $args->allow_mailing = "Y"; + $args->allow_message = "Y"; + $args->denied = "N"; + $args->regdate = "20110607121952"; + $args->change_password_date = "20110607121952"; + $args->last_login = "20110607121952"; + $args->is_admin = "N"; + $args->extra_vars = "O:8:\"stdClass\":2:{s:4:\"body\";s:0:\"\";s:7:\"_filter\";s:6:\"insert\";}"; + $args->list_order = -203; + '; + $expected = 'INSERT INTO "xe_member" + ("member_srl", "user_id", "email_address", "password", "email_id", "email_host", "user_name", "nick_name", + "homepage", "allow_mailing", "allow_message", "denied", "regdate", "change_password_date", + "last_login", "is_admin", "extra_vars", "list_order") + VALUES (203, \'cacao\', \'teta@ar.ro\', \'23e5484cb88f3c07bcce2920a5e6a2a7\', \'teta\', \'ar.ro\', \'trident\', + \'aloha\', \'http://jkgjfk./ww\', \'Y\', \'Y\', \'N\', \'20110607121952\', \'20110607121952\', + \'20110607121952\', \'N\', \'O:8:"stdClass":2:{s:4:"body";s:0:"";s:7:"_filter";s:6:"insert";}\', -203)'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_module_insertModuleExtraVars(){ + $xml_file = _XE_PATH_ . "modules/module/queries/insertModuleExtraVars.xml"; + $argsString = ' $args->module_srl = 202; + $args->name = "_filter"; + $args->value = "insert_page"; + '; + $expected = 'INSERT INTO "xe_module_extra_vars" + ("module_srl", "name", "value") + VALUES (202, \'_filter\', \'insert_page\') + '; + $this->_test($xml_file, $argsString, $expected); + } + + } \ No newline at end of file diff --git a/test-phpUnit/db/xml_query/cubrid/CubridSelectOnlineTest.php b/test-phpUnit/db/xml_query/cubrid/CubridSelectOnlineTest.php new file mode 100644 index 000000000..1cc4b5e09 --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/CubridSelectOnlineTest.php @@ -0,0 +1,62 @@ +mid = 'test_4l8ci4vv0n'; + $args->site_srl = 0; + $output = executeQuery('module.getMidInfo', $args); + $this->assertNotNull($output); + $this->assertNotNull($output->data, $output->message . PHP_EOL . $output->variables["_query"]); + $this->assertEquals($output->data->module_srl, 111); + } + + function test_module_getInfo(){ + $args->site_srl = 0; + $output = executeQuery('module.getSiteInfo', $args); + $this->assertTrue(is_a($output, 'Object')); + $this->assertEquals(0, $output->error, $output->message . PHP_EOL . $output->variables["_query"]); + } + + function test_document_getDocumentList_pagination(){ + $args->sort_index = 'list_order'; + $args->order_type = 'asc'; + $args->page = 1; + $args->list_count = 30; + $args->page_count = 10; + $args->s_member_srl = 4; + + $output = executeQuery('document.getDocumentList', $args); + $this->assertEquals(0, $output->error, $output->message . PHP_EOL . $output->variables["_query"]); + } + + function test_syndication_getDocumentList(){ + $args->module_srl = NULL; + $args->exclude_module_srl = NULL; + $args->category_srl = NULL; + $args->sort_index = 'list_order'; + $args->order_type = 'asc'; + $args->page = 5; + $args->list_count = 30; + $args->page_count = 10; + $args->start_date = NULL; + $args->end_date = NULL; + $args->member_srl = NULL; + $output = executeQuery('document.getDocumentList', $args); + + $this->assertTrue(is_int($output->page), $output->message . PHP_EOL . $output->variables["_query"]); + } + + function test_member_getMemberList(){ + $args->is_admin = ''; + $args->is_denied = ''; + $args->sort_index = "list_order"; + $args->sort_order = 'asc'; + $args->list_count = 40; + $args->page_count = 10; + + $output = executeQuery('member.getMemberList', $args); + $this->assertEquals(0, $output->error, $output->message . PHP_EOL . $output->variables["_query"]); + } + } +?> diff --git a/test-phpUnit/db/xml_query/cubrid/CubridSelectTest.php b/test-phpUnit/db/xml_query/cubrid/CubridSelectTest.php new file mode 100644 index 000000000..b8fe617db --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/CubridSelectTest.php @@ -0,0 +1,214 @@ +_testQuery($xml_file, $argsString, $expected, 'getSelectSql', $columnList); + } + + function testSelectStar(){ + $xml_file = _XE_PATH_ . "modules/module/queries/getAdminId.xml"; + $argsString = '$args->module_srl = 10;'; + $expected = 'SELECT * FROM "xe_module_admins" as "module_admins" , "xe_member" as "member" WHERE "module_srl" = 10 and "member"."member_srl" = "module_admins"."member_srl"'; + $this->_test($xml_file, $argsString, $expected); + } + + function testRquiredParameter(){ + $xml_file = _XE_PATH_ . "modules/module/queries/getAdminId.xml"; + $argsString = ''; + $expected = 'Date incorecte! Query-ul nu a putut fi executat.'; + $this->_test($xml_file, $argsString, $expected); + } + + function testWithoutCategoriesTag(){ + $xml_file = _XE_PATH_ . "modules/module/queries/getModuleCategories.xml"; + $argsString = ''; + $expected = 'SELECT * FROM "xe_module_categories" as "module_categories" ORDER BY "title" asc'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_module_getDefaultModules(){ + $xml_file = _XE_PATH_ . "modules/module/queries/getDefaultModules.xml"; + $argsString = ''; + $expected = 'SELECT "modules"."site_srl" + , "modules"."module" + , "modules"."mid" + , "modules"."browser_title" + , "module_categories"."title" as "category" + , "modules"."module_srl" + FROM "xe_modules" as "modules" + left join "xe_module_categories" as "module_categories" + on "module_categories"."module_category_srl" = "modules"."module_category_srl" + WHERE "modules"."site_srl" = 0 + ORDER BY "modules"."module" asc, "module_categories"."title" asc, "modules"."mid" asc'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_module_getSiteInfo(){ + $xml_file = _XE_PATH_ . "modules/module/queries/getSiteInfo.xml"; + $argsString = '$args->site_srl = 0;'; + $expected = 'SELECT "modules"."site_srl" as "module_site_srl" + , "modules"."module_srl" as "module_srl" + , "modules"."module" as "module" + , "modules"."module_category_srl" as "module_category_srl" + , "modules"."layout_srl" as "layout_srl" + , "modules"."mlayout_srl" as "mlayout_srl" + , "modules"."use_mobile" as "use_mobile" + , "modules"."menu_srl" as "menu_srl" + , "modules"."mid" as "mid" + , "modules"."skin" as "skin" + , "modules"."mskin" as "mskin" + , "modules"."browser_title" as "browser_title" + , "modules"."description" as "description" + , "modules"."is_default" as "is_default" + , "modules"."content" as "content" + , "modules"."mcontent" as "mcontent" + , "modules"."open_rss" as "open_rss" + , "modules"."header_text" as "header_text" + , "modules"."footer_text" as "footer_text" + , "modules"."regdate" as "regdate" + , "sites"."site_srl" as "site_srl" + , "sites"."domain" as "domain" + , "sites"."index_module_srl" as "index_module_srl" + , "sites"."default_language" as "default_language" + FROM "xe_sites" as "sites" + left join "xe_modules" as "modules" on "modules"."module_srl" = "sites"."index_module_srl" + WHERE "sites"."site_srl" = 0 '; + $this->_test($xml_file, $argsString, $expected); + } + + function test_addon_getAddonInfo(){ + $xml_file = _XE_PATH_ . "modules/addon/queries/getAddonInfo.xml"; + $argsString = '$args->addon = "captcha";'; + $expected = 'SELECT * + FROM "xe_addons" as "addons" + WHERE "addon" = \'captcha\' '; + $this->_test($xml_file, $argsString, $expected); + } + + function test_addon_getAddons(){ + $xml_file = _XE_PATH_ . "modules/addon/queries/getAddons.xml"; + $argsString = ''; + $expected = 'SELECT * + FROM "xe_addons" as "addons" + ORDER BY "addon" asc'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_admin_getCommentCount(){ + $xml_file = _XE_PATH_ . "modules/admin/queries/getCommentCount.xml"; + $argsString = ''; + $expected = 'SELECT count(*) as "count" + FROM "xe_comments" as "comments"'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_admin_getCommentDeclaredStatus(){ + $xml_file = _XE_PATH_ . "modules/admin/queries/getCommentDeclaredStatus.xml"; + $argsString = '$args->date = "20110411";'; + $expected = 'SELECT substr("regdate",1,8) as "date", count(*) as "count" + FROM "xe_comment_declared_log" as "comment_declared_log" + WHERE "regdate" >= \'20110411\' + GROUP BY substr("regdate",1,8) + ORDER BY substr("regdate",1,8) asc limit 2'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_member_getAutoLogin(){ + $xml_file = _XE_PATH_ . "modules/member/queries/getAutoLogin.xml"; + $argsString = '$args->autologin_key = 10;'; + $expected = 'SELECT "member"."user_id" as "user_id" + , "member"."password" as "password" + , "member_autologin"."autologin_key" as "autologin_key" + FROM "xe_member" as "member" , "xe_member_autologin" as "member_autologin" + WHERE "member_autologin"."autologin_key" = \'10\' + and "member"."member_srl" = "member_autologin"."member_srl"'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_opage_getOpageList(){ + $xml_file = _XE_PATH_ . "modules/opage/queries/getOpageList.xml"; + $argsString = '$args->s_title = "yuhuu"; + $args->module = \'opage\';'; + $expected = 'SELECT * + FROM "xe_modules" as "modules" + WHERE "module" = \'opage\' and ("browser_title" like \'%yuhuu%\') + ORDER BY "module_srl" desc + LIMIT 0, 20'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_syndication_getGrantedModules(){ + $xml_file = _XE_PATH_ . "modules/syndication/queries/getGrantedModules.xml"; + $argsString = '$args->module_srl = 12; + $args->name = array(\'access\',\'view\',\'list\');'; + $expected = 'select "module_srl" + from "xe_module_grants" as "module_grants" + where "name" in (\'access\',\'view\',\'list\') + and ("group_srl" >= 1 + or "group_srl" = -1 + or "group_srl" = -2) + group by "module_srl"'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_document_getDocumentList(){ + $xml_file = _XE_PATH_ . "modules/document/queries/getDocumentList.xml"; + $argsString = '$args->sort_index = \'list_order\'; + $args->order_type = \'asc\'; + $args->page = 1; + $args->list_count = 30; + $args->page_count = 10; + $args->s_member_srl = 4;'; + $expected = 'select * + from "xe_documents" as "documents" + where "member_srl" = 4 + order by "list_order" asc + limit 0, 30'; + $this->_test($xml_file, $argsString, $expected); + + + } + + /** + * Test column list + */ + function test_session_getSession(){ + $xml_file = _XE_PATH_ . "modules/session/queries/getSession.xml"; + $argsString = '$args->session_key = \'session_key\';'; + $columnList = array('session_key', 'cur_mid', 'val'); + + $expected = 'select "session_key", "cur_mid", "val" + from "xe_session" as "session" + where "session_key" = \'session_key\''; + + $this->_test($xml_file, $argsString, $expected, $columnList); + } + + function test_module_getModuleInfoByDocument(){ + $xml_file = _XE_PATH_ . "modules/module/queries/getModuleInfoByDocument.xml"; + $argsString = '$args->document_srl = 10;'; + $expected = 'SELECT "modules".* + FROM "xe_modules" as "modules" + , "xe_documents" as "documents" + WHERE "documents"."document_srl" = 10 + and "modules"."module_srl" = "documents"."module_srl"'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_member_getMemberList(){ + $xml_file = _XE_PATH_ . "modules/member/queries/getMemberList.xml"; + $argsString = '$args->is_admin = \'\'; + $args->is_denied = \'\'; + $args->sort_index = "list_order"; + $args->sort_order = \'asc\'; + $args->list_count = 40; + $args->page_count = 10;'; + $expected = 'select * from "xe_member" as "member" + order by "list_order" asc + limit 0, 40'; + $this->_test($xml_file, $argsString, $expected); + } + + } \ No newline at end of file diff --git a/test-phpUnit/db/xml_query/cubrid/CubridSubqueryTest.php b/test-phpUnit/db/xml_query/cubrid/CubridSubqueryTest.php new file mode 100644 index 000000000..81fbcf5b1 --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/CubridSubqueryTest.php @@ -0,0 +1,191 @@ +xmlPath = str_replace('CubridSubqueryTest.php', '', str_replace('\\', '/', __FILE__)) . $this->xmlPath; + } + + function _test($xml_file, $argsString, $expected){ + $this->_testQuery($xml_file, $argsString, $expected, 'getSelectSql'); + } + + function testSelectUncorrelated1(){ + $xml_file = $this->xmlPath . "select_uncorrelated1.xml"; + $argsString = '$args->user_id = 4; + '; + $expected = 'select "column_a" as "value_a" + , (select max("column_b") as "count" + from "xe_table_b" as "table_b" + ) as "value_b" + from "xe_table_a" as "table_a" + where "column_a" = 4'; + $this->_test($xml_file, $argsString, $expected); + } + + function testSelectUncorrelated2(){ + $xml_file = $this->xmlPath . "select_uncorrelated2.xml"; + $argsString = '$args->user_id = 4; + $args->user_name = 7; + '; + $expected = 'SELECT "column_a" as "value_a" + , "column_b" as "value_b" + , "column_c" as "value_c" + , (SELECT max("column_b") as "count" + FROM "xe_table_b" as "table_b" + WHERE "column_ab" = 7) as "value_b" + FROM "xe_table_a" as "table_a" + WHERE "column_a" = 4'; + $this->_test($xml_file, $argsString, $expected); + } + + function testFromUncorrelated1(){ + $xml_file = $this->xmlPath . "from_uncorrelated1.xml"; + $argsString = '$args->user_id = 4; + $args->user_name = 7; + '; + $expected = 'select max("documentcountbymember"."count") as "maxcount" + from ( + select "member_srl" as "member_srl" + , count(*) as "count" + from "xe_documents" as "documents" + group by "member_srl" + ) as "documentcountbymember"'; + $this->_test($xml_file, $argsString, $expected); + } + +// function testFromUncorrelated2(){ +// $xml_file = $this->xmlPath . "from_uncorrelated1.xml"; +// $argsString = '$args->user_id = 4; +// $args->user_name = 7; +// '; +// $expected = 'select max("documentcountbymember"."count") as "maxcount" +// from ( +// select "member_srl" as "member_srl" +// , count(*) as "count" +// from "xe_documents" as "documents" +// group by "member_srl" +// ) as "documentcountbymember"'; +// $this->_test($xml_file, $argsString, $expected); +// } + + function testFromUncorrelated2(){ + $xml_file = $this->xmlPath . "from_uncorrelated2.xml"; + $argsString = '$args->member_srl = 4; + $args->module_srl = 7; + '; + $expected = 'select max("documentcountbymember"."count") as "maxcount" + from ( + select "member_srl" as "member_srl" + , count(*) as "count" + from "xe_documents" as "documents" + where "module_srl" = 7 + group by "member_srl" + ) as "documentcountbymember" + where "member_srl" = 4 + '; + $this->_test($xml_file, $argsString, $expected); + } + + function testSelectCorrelated1(){ + $xml_file = $this->xmlPath . "select_correlated1.xml"; + $argsString = '$args->user_id = 7;'; + $expected = 'select *, + (select count(*) as "count" + from "xe_documents" as "documents" + where "documents"."user_id" = "member"."user_id" + ) as "totaldocumentcount" + from "xe_member" as "member" + where "user_id" = \'7\''; + $this->_test($xml_file, $argsString, $expected); + } + + function testSelectCorrelated2(){ + $xml_file = $this->xmlPath . "select_correlated2.xml"; + $argsString = '$args->user_id = 7; + $args->module_srl = 17; + '; + $expected = 'select *, + (select count(*) as "count" + from "xe_documents" as "documents" + where "documents"."user_id" = "member"."user_id" + and "module_srl" = 17 + ) as "totaldocumentcount" + from "xe_member" as "member" + where "user_id" = \'7\''; + $this->_test($xml_file, $argsString, $expected); + } + + function testWhereCorrelated1(){ + $xml_file = $this->xmlPath . "where_correlated1.xml"; + $argsString = ''; + $expected = 'select * + from "xe_member" as "member" + where "regdate" = ( + select max("regdate") as "maxregdate" + from "xe_documents" as "documents" + where "documents"."user_id" = "member"."user_id" + )'; + $this->_test($xml_file, $argsString, $expected); + } + + function testWhereCorrelated2(){ + $xml_file = $this->xmlPath . "where_correlated2.xml"; + $argsString = '$args->module_srl = 12; $args->member_srl = 19;'; + $expected = 'select * + from "xe_member" as "member" + where "member_srl" = 19 + and "regdate" = ( + select max("regdate") as "maxregdate" + from "xe_documents" as "documents" + where "documents"."user_id" = "member"."user_id" + and "module_srl" = 12 + ) + '; + $this->_test($xml_file, $argsString, $expected); + } + + function testFromCorrelated1(){ + $xml_file = $this->xmlPath . "from_correlated1.xml"; + $argsString = ''; + $expected = 'select "m"."member_srl" + , "m"."nickname" + , "m"."regdate" + , "a"."count" + from ( + select "member_srl" as "member_srl" + , count(*) as "count" + from "xe_documents" as "documents" + group by "member_srl" + ) as "a" + left join "xe_member" as "m" on "m"."member" = "a"."member_srl"'; + $this->_test($xml_file, $argsString, $expected); + } + + function testFromCorrelated2(){ + $xml_file = $this->xmlPath . "from_correlated2.xml"; + $argsString = '$args->module_srl = 12; $args->count = 20;'; + $expected = 'select "m"."member_srl" + , "m"."nickname" + , "m"."regdate" + , "a"."count" + from ( + select "member_srl" as "member_srl" + , count(*) as "count" + from "xe_documents" as "documents" + where "module_srl" = 12 + group by "member_srl" + ) as "a" + left join "xe_member" as "m" on "m"."member" = "a"."member_srl" + where "a"."count" >= 20 +'; + $this->_test($xml_file, $argsString, $expected); + } + } +?> diff --git a/test-phpUnit/db/xml_query/cubrid/CubridUpdateTest.php b/test-phpUnit/db/xml_query/cubrid/CubridUpdateTest.php new file mode 100644 index 000000000..23f19d5c8 --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/CubridUpdateTest.php @@ -0,0 +1,73 @@ +_testQuery($xml_file, $argsString, $expected, 'getUpdateSql'); + } + + function test_module_updateModule(){ + $xml_file = _XE_PATH_ . "modules/module/queries/updateModule.xml"; + $argsString = ' $args->module_category_srl = 0; + $args->browser_title = "test"; + $args->layout_srl = 0; + $args->mlayout_srl = 0; + $args->module = "page"; + $args->mid = "test"; + $args->use_mobile = ""; + $args->site_srl = 0; + $args->module_srl = 47374;'; + $expected = 'UPDATE "xe_modules" + SET "module" = \'page\' + , "mid" = \'test\' + , "browser_title" = \'test\' + , "description" = \'\' + , "is_default" = \'N\' + , "open_rss" = \'Y\' + , "header_text" = \'\' + , "footer_text" = \'\' + , "use_mobile" = \'n\' + WHERE "site_srl" = 0 + AND "module_srl" = 47374'; + $this->_test($xml_file, $argsString, $expected); + } + function test_member_updateLastLogin(){ + $xml_file = _XE_PATH_ . "modules/member/queries/updateLastLogin.xml"; + $argsString = ' $args->member_srl = 4; + $args->last_login = "20110607120549";'; + $expected = 'UPDATE "xe_member" SET "member_srl" = 4, "last_login" = \'20110607120549\' WHERE "member_srl" = 4'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_module_updatePoint(){ + $xml_file = _XE_PATH_ . "modules/point/queries/updatePoint.xml"; + $argsString = ' $args->member_srl = 4; + $args->point = 105;'; + $expected = 'UPDATE "xe_point" SET "point" = 105 WHERE "member_srl" = 4'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_module_updateCounterUnique(){ + $xml_file = _XE_PATH_ . "modules/counter/queries/updateCounterUnique.xml"; + $argsString = '$args->regdate = 20110607; + '; + $expected = 'UPDATE "xe_counter_status" SET "unique_visitor" = "unique_visitor" + 1, + "pageview" = "pageview" + 1 WHERE "regdate" = 20110607 '; + $this->_test($xml_file, $argsString, $expected); + } + + function test_module_updateMenu(){ + $xml_file = _XE_PATH_ . "modules/menu/queries/updateMenu.xml"; + $argsString = '$args->menu_srl = 204; + $args->title = "test_menu"; + '; + $expected = 'UPDATE "xe_menu" SET "title" = \'test_menu\' WHERE "menu_srl" = 204'; + $this->_test($xml_file, $argsString, $expected); + } + +// $queryTester->test_admin_deleteActionForward(); +// $queryTester->test_module_insertModule(); + + + } \ No newline at end of file diff --git a/test-phpUnit/db/xml_query/cubrid/data/from_correlated1.xml b/test-phpUnit/db/xml_query/cubrid/data/from_correlated1.xml new file mode 100644 index 000000000..7c2c27143 --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/data/from_correlated1.xml @@ -0,0 +1,27 @@ + + + + +
+ + + + + + + + +
+ + + + +
+
+ + + + + + +
\ No newline at end of file diff --git a/test-phpUnit/db/xml_query/cubrid/data/from_correlated2.xml b/test-phpUnit/db/xml_query/cubrid/data/from_correlated2.xml new file mode 100644 index 000000000..8dc162154 --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/data/from_correlated2.xml @@ -0,0 +1,33 @@ + + + + +
+ + + + + + + + + + + +
+ + + + +
+
+ + + + + + + + + +
\ No newline at end of file diff --git a/test-phpUnit/db/xml_query/cubrid/data/from_uncorrelated1.xml b/test-phpUnit/db/xml_query/cubrid/data/from_uncorrelated1.xml new file mode 100644 index 000000000..ec83f3f36 --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/data/from_uncorrelated1.xml @@ -0,0 +1,19 @@ + + + + +
+ + + + + + + + +
+
+ + + +
\ No newline at end of file diff --git a/test-phpUnit/db/xml_query/cubrid/data/from_uncorrelated2.xml b/test-phpUnit/db/xml_query/cubrid/data/from_uncorrelated2.xml new file mode 100644 index 000000000..6431b3b90 --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/data/from_uncorrelated2.xml @@ -0,0 +1,25 @@ + + + + +
+ + + + + + + + + + + +
+
+ + + + + + +
\ No newline at end of file diff --git a/test-phpUnit/db/xml_query/cubrid/data/select_correlated1.xml b/test-phpUnit/db/xml_query/cubrid/data/select_correlated1.xml new file mode 100644 index 000000000..797d878e3 --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/data/select_correlated1.xml @@ -0,0 +1,22 @@ + + + + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/test-phpUnit/db/xml_query/cubrid/data/select_correlated2.xml b/test-phpUnit/db/xml_query/cubrid/data/select_correlated2.xml new file mode 100644 index 000000000..85ab25308 --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/data/select_correlated2.xml @@ -0,0 +1,23 @@ + + +
+ + + + + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/test-phpUnit/db/xml_query/cubrid/data/select_uncorrelated1.xml b/test-phpUnit/db/xml_query/cubrid/data/select_uncorrelated1.xml new file mode 100644 index 000000000..00e556e35 --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/data/select_uncorrelated1.xml @@ -0,0 +1,19 @@ + + +
+ + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/test-phpUnit/db/xml_query/cubrid/data/select_uncorrelated2.xml b/test-phpUnit/db/xml_query/cubrid/data/select_uncorrelated2.xml new file mode 100644 index 000000000..a42294bcf --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/data/select_uncorrelated2.xml @@ -0,0 +1,24 @@ + + +
+ + + + + + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/test-phpUnit/db/xml_query/cubrid/data/where_correlated1.xml b/test-phpUnit/db/xml_query/cubrid/data/where_correlated1.xml new file mode 100644 index 000000000..f6115c71f --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/data/where_correlated1.xml @@ -0,0 +1,21 @@ + + +
+ + + + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/test-phpUnit/db/xml_query/cubrid/data/where_correlated2.xml b/test-phpUnit/db/xml_query/cubrid/data/where_correlated2.xml new file mode 100644 index 000000000..2ab45461c --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/data/where_correlated2.xml @@ -0,0 +1,23 @@ + + +
+ + + + + + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/test-phpUnit/db/xml_query/cubrid/data/where_uncorrelated1.xml b/test-phpUnit/db/xml_query/cubrid/data/where_uncorrelated1.xml new file mode 100644 index 000000000..248b63ae9 --- /dev/null +++ b/test-phpUnit/db/xml_query/cubrid/data/where_uncorrelated1.xml @@ -0,0 +1,18 @@ + + +
+ + + + + + + +
+ + + + + + + \ No newline at end of file diff --git a/test-phpUnit/db/xml_query/mssql/MssqlSelectOnlineTest.php b/test-phpUnit/db/xml_query/mssql/MssqlSelectOnlineTest.php new file mode 100644 index 000000000..44867e38f --- /dev/null +++ b/test-phpUnit/db/xml_query/mssql/MssqlSelectOnlineTest.php @@ -0,0 +1,11 @@ +module_srl = 67; + $output = executeQuery("syndication.getGrantedModule", $args); + $this->assertEquals(0, $output->error, $output->error + ' ' + $output->message); + } + } + +?> \ No newline at end of file diff --git a/test-phpUnit/db/xml_query/mssql/MssqlSelectTest.php b/test-phpUnit/db/xml_query/mssql/MssqlSelectTest.php new file mode 100644 index 000000000..5c080b1d5 --- /dev/null +++ b/test-phpUnit/db/xml_query/mssql/MssqlSelectTest.php @@ -0,0 +1,169 @@ +_testPreparedQuery($xml_file, $argsString, $expected, 'getSelectSql', $expectedArgs); + } + + function testSelectStar(){ + $xml_file = _XE_PATH_ . "modules/module/queries/getAdminId.xml"; + $argsString = '$args->module_srl = 10;'; + $expected = 'SELECT * FROM [xe_module_admins] as [module_admins] , [xe_member] as [member] WHERE [module_srl] = ? and [member].[member_srl] = [module_admins].[member_srl]'; + $this->_test($xml_file, $argsString, $expected, array(10)); + } + + function testRquiredParameter(){ + $xml_file = _XE_PATH_ . "modules/module/queries/getAdminId.xml"; + $argsString = ''; + $expected = 'Date incorecte! Query-ul nu a putut fi executat.'; + $this->_test($xml_file, $argsString, $expected); + } + + function testWithoutCategoriesTag(){ + $xml_file = _XE_PATH_ . "modules/module/queries/getModuleCategories.xml"; + $argsString = ''; + $expected = 'SELECT * FROM [xe_module_categories] as [module_categories] ORDER BY [title] asc'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_module_getDefaultModules(){ + $xml_file = _XE_PATH_ . "modules/module/queries/getDefaultModules.xml"; + $argsString = ''; + $expected = 'SELECT [modules].[site_srl] + , [modules].[module] + , [modules].[mid] + , [modules].[browser_title] + , [module_categories].[title] as [category] + , [modules].[module_srl] + FROM [xe_modules] as [modules] + left join [xe_module_categories] as [module_categories] + on [module_categories].[module_category_srl] = [modules].[module_category_srl] + WHERE [modules].[site_srl] = ? + ORDER BY [modules].[module] asc, [module_categories].[title] asc, [modules].[mid] asc'; + $this->_test($xml_file, $argsString, $expected, array(0)); + } + + function test_module_getSiteInfo(){ + $xml_file = _XE_PATH_ . "modules/module/queries/getSiteInfo.xml"; + $argsString = '$args->site_srl = 0;'; + $expected = 'SELECT [modules].[site_srl] as [module_site_srl] + , [modules].[module_srl] as [module_srl] + , [modules].[module] as [module] + , [modules].[module_category_srl] as [module_category_srl] + , [modules].[layout_srl] as [layout_srl] + , [modules].[mlayout_srl] as [mlayout_srl] + , [modules].[use_mobile] as [use_mobile] + , [modules].[menu_srl] as [menu_srl] + , [modules].[mid] as [mid] + , [modules].[skin] as [skin] + , [modules].[mskin] as [mskin] + , [modules].[browser_title] as [browser_title] + , [modules].[description] as [description] + , [modules].[is_default] as [is_default] + , [modules].[content] as [content] + , [modules].[mcontent] as [mcontent] + , [modules].[open_rss] as [open_rss] + , [modules].[header_text] as [header_text] + , [modules].[footer_text] as [footer_text] + , [modules].[regdate] as [regdate] + , [sites].[site_srl] as [site_srl] + , [sites].[domain] as [domain] + , [sites].[index_module_srl] as [index_module_srl] + , [sites].[default_language] as [default_language] + FROM [xe_sites] as [sites] + left join [xe_modules] as [modules] on [modules].[module_srl] = [sites].[index_module_srl] + WHERE [sites].[site_srl] = ? '; + $this->_test($xml_file, $argsString, $expected, array(0)); + } + + function test_addon_getAddonInfo(){ + $xml_file = _XE_PATH_ . "modules/addon/queries/getAddonInfo.xml"; + $argsString = '$args->addon = "captcha";'; + $expected = 'SELECT * + FROM [xe_addons] as [addons] + WHERE [addon] = ? '; + $this->_test($xml_file, $argsString, $expected, array("'captcha'")); + } + + function test_addon_getAddons(){ + $xml_file = _XE_PATH_ . "modules/addon/queries/getAddons.xml"; + $argsString = ''; + $expected = 'SELECT * + FROM [xe_addons] as [addons] + ORDER BY [addon] asc'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_admin_getCommentCount(){ + $xml_file = _XE_PATH_ . "modules/admin/queries/getCommentCount.xml"; + $argsString = ''; + $expected = 'SELECT count(*) as [count] + FROM [xe_comments] as [comments]'; + $this->_test($xml_file, $argsString, $expected); + } + + function test_admin_getCommentDeclaredStatus(){ + $xml_file = _XE_PATH_ . "modules/admin/queries/getCommentDeclaredStatus.xml"; + $argsString = '$args->date = "20110411";'; + $expected = 'SELECT TOP 2 substr([regdate],1,8) as [date], count(*) as [count] + FROM [xe_comment_declared_log] as [comment_declared_log] + WHERE [regdate] >= ? + GROUP BY substr([regdate],1,8) + ORDER BY substr([regdate],1,8) asc'; + $this->_test($xml_file, $argsString, $expected, array("'20110411'")); + } + + function test_member_getAutoLogin(){ + $xml_file = _XE_PATH_ . "modules/member/queries/getAutoLogin.xml"; + $argsString = '$args->autologin_key = 10;'; + $expected = 'SELECT [member].[user_id] as [user_id] + , [member].[password] as [password] + , [member_autologin].[autologin_key] as [autologin_key] + FROM [xe_member] as [member] , [xe_member_autologin] as [member_autologin] + WHERE [member_autologin].[autologin_key] = ? + and [member].[member_srl] = [member_autologin].[member_srl]'; + $this->_test($xml_file, $argsString, $expected, array("'10'")); + } + + function test_opage_getOpageList(){ + $xml_file = _XE_PATH_ . "modules/opage/queries/getOpageList.xml"; + $argsString = '$args->s_title = "yuhuu"; + $args->module = \'opage\';'; + $expected = 'SELECT TOP 20 * + FROM [xe_modules] as [modules] + WHERE [module] = ? and ([browser_title] like ?) + ORDER BY [module_srl] desc'; + $this->_test($xml_file, $argsString, $expected, array("'opage'", "'%yuhuu%'")); + } + + function test_module_getExtraVars(){ + $xml_file = _XE_PATH_ . "modules/module/queries/getModuleExtraVars.xml"; + $argsString = '$args->module_srl = 25;'; + $expected = 'SELECT * FROM [xe_module_extra_vars] as [module_extra_vars] WHERE [module_srl] in (?)'; + $this->_test($xml_file, $argsString, $expected, array(array(25))); + } + + function test_module_getModuleSites(){ + $xml_file = _XE_PATH_ . "modules/module/queries/getModuleSites.xml"; + $argsString = '$args->module_srls = "67, 65";'; + $expected = 'SELECT [modules].[module_srl] as [module_srl], [sites].[domain] as [domain] FROM [xe_modules] as [modules] , [xe_sites] as [sites] WHERE [modules].[module_srl] in (?,?) and [sites].[site_srl] = [modules].[site_srl]'; + $this->_test($xml_file, $argsString, $expected, array(array(67, 65))); + } + + function test_syndication_getGrantedModule(){ + $xml_file = _XE_PATH_ . "modules/syndication/queries/getGrantedModule.xml"; + $argsString = '$args->module_srl = 67;'; + $expected = 'select count(*) as [count] + from [xe_module_grants] as [module_grants] + where [module_srl] = ? + and [name] in (?,?,?) + and ( + [group_srl] >= ? + or [group_srl] = ? + or [group_srl] = ? + )'; + $this->_test($xml_file, $argsString, $expected, array(67, array('\'access\'', '\'view\'', '\'list\''), 1, -1, -2)); + } + } \ No newline at end of file diff --git a/test-phpUnit/db/xml_query/mssql/MssqlUpdateOnlineTest.php b/test-phpUnit/db/xml_query/mssql/MssqlUpdateOnlineTest.php new file mode 100644 index 000000000..bcd57fbb2 --- /dev/null +++ b/test-phpUnit/db/xml_query/mssql/MssqlUpdateOnlineTest.php @@ -0,0 +1,12 @@ +regdate = 20110211; + + $output = executeQuery("counter.updateCounterUnique", $args); + $this->assertEquals(0, $output->error, $output->error + ' ' + $output->message); + } + } + +?> \ No newline at end of file diff --git a/test-phpUnit/db/xml_query/mssql/MssqlUpdateTest.php b/test-phpUnit/db/xml_query/mssql/MssqlUpdateTest.php new file mode 100644 index 000000000..1f2b183a0 --- /dev/null +++ b/test-phpUnit/db/xml_query/mssql/MssqlUpdateTest.php @@ -0,0 +1,17 @@ +_testPreparedQuery($xml_file, $argsString, $expected, 'getUpdateSql', $expectedArgs = NULL); + } + + function test_counter_updateCounterUnique(){ + $xml_file = _XE_PATH_ . "modules/counter/queries/updateCounterUnique.xml"; + $argsString = '$args->regdate = 25;'; + $expected = 'UPDATE [xe_counter_status] SET [unique_visitor] = [unique_visitor] + ?, [pageview] = [pageview] + ? WHERE [regdate] = ?'; + $this->_test($xml_file, $argsString, $expected, array("25", 1, 1)); + } + } +?> \ No newline at end of file diff --git a/test-phpUnit/debug.php b/test-phpUnit/debug.php new file mode 100644 index 000000000..1e788ca03 --- /dev/null +++ b/test-phpUnit/debug.php @@ -0,0 +1,12 @@ +getParser(); + $dbParser = new DBParser('[', ']'); + $parser = new QueryParser($xml_obj->query, $dbParser); + $query_file = $parser->toString(); + var_dump($parser->toString()); + +?> \ No newline at end of file