собственно для тестов решил дописать database.php для использования mysqli. попутно подправил обработку чисел с плавающей точкой на разных локалях. ответ саппорта как всегда очевиден "В настоящий момент реализация такой задачи в планах не стоит.", а зря. на хостингах с малым количеством памяти пригодилось бы.
было бы неплохо если бы кто-нибудь ещё протестировал.
mysqli используется по умолчанию если доступен соответствующий модуль php[spoiler]
а во собственно и сабж.
было бы неплохо если бы кто-нибудь ещё протестировал.
mysqli используется по умолчанию если доступен соответствующий модуль php[spoiler]
а во собственно и сабж.
<? require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/classes/general/database.php"); /******************************************************************** * MySQL database classes ********************************************************************/ class CDatabase extends CAllDatabase { var $DBName; var $DBHost; var $DBLogin; var $DBPassword; var $bConnected; var $version; var $cntQuery; var $timeQuery; var $column_cache = Array(); var $obSlave; function GetVersion() { if($this->version) return $this->version; $rs = $this->Query("SELECT VERSION() as R", false, "FILE: ".__FILE__."<br> LINE: ".__LINE__); if($ar = $rs->Fetch()) { $version = trim($ar["R"]); preg_match("#[0-9]+\.[0-9]+\.[0-9]+#", $version, $arr); $version = $arr[0]; $this->version = $version; return $version; } else { return false; } } function StartTransaction() { $this->Query("START TRANSACTION"); } function Commit() { $this->Query("COMMIT", true); } function Rollback() { $this->Query("ROLLBACK", true); } //Connect to database function Connect($DBHost, $DBName, $DBLogin, $DBPassword) { $this->type="MYSQL"; $this->DBHost = $DBHost; $this->DBName = $DBName; $this->DBLogin = $DBLogin; $this->DBPassword = $DBPassword; $this->bConnected = false; if (!defined("DBPersistent")) define("DBPersistent",true); if (extension_loaded('mysqli')) define("USE_MYSQLi",true); else define("USE_MYSQLi",false); if(defined("DELAY_DB_CONNECT") && DELAY_DB_CONNECT===true) return true; else return $this->DoConnect(); } function DoConnect() { if($this->bConnected) return; $this->bConnected = true; if (DBPersistent && !$this->bNodeConnection){ if (USE_MYSQLi) $this->db_Conn = @mysqli_connect("p:".$this->DBHost, $this->DBLogin, $this->DBPassword); else $this->db_Conn = @mysql_pconnect($this->DBHost, $this->DBLogin, $this->DBPassword); } else { if (USE_MYSQLi) $this->db_Conn = @mysqli_connect($this->DBHost, $this->DBLogin, $this->DBPassword); else $this->db_Conn = @mysql_connect($this->DBHost, $this->DBLogin, $this->DBPassword, $this->bNodeConnection); } if(!$this->db_Conn) { $s = (DBPersistent && !$this->bNodeConnection? "mysql_pconnect" : "mysql_connect"); if($this->debug || (@session_start() && $_SESSION["SESS_AUTH"]["ADMIN"])){ if (USE_MYSQLi) echo "<br><font color=#ff0000>Error! ".$s."('-', '-', '-')</font><br>".mysqli_error($this->db_Conn)."<br>"; else echo "<br><font color=#ff0000>Error! ".$s."('-', '-', '-')</font><br>".mysql_error()."<br>"; } if (USE_MYSQLi) SendError("Error! ".$s."('-', '-', '-')\n".mysqli_error($this->db_Conn)."\n"); else SendError("Error! ".$s."('-', '-', '-')\n".mysql_error()."\n"); return false; } if (USE_MYSQLi){ if(!mysqli_select_db($this->db_Conn,$this->DBName)) { if($this->debug || (@session_start() && $_SESSION["SESS_AUTH"]["ADMIN"])) echo "<br><font color=#ff0000>Error! mysqli_select_db(".$this->DBName.")</font><br>".mysqli_error($this->db_Conn)."<br>"; SendError("Error! mysqli_select_db(".$this->DBName.")\n".mysqli_error($this->db_Conn)."\n"); return false; } } else { if(!mysql_select_db($this->DBName, $this->db_Conn)) { if($this->debug || (@session_start() && $_SESSION["SESS_AUTH"]["ADMIN"])) echo "<br><font color=#ff0000>Error! mysql_select_db(".$this->DBName.")</font><br>".mysql_error($this->db_Conn)."<br>"; SendError("Error! mysql_select_db(".$this->DBName.")\n".mysql_error($this->db_Conn)."\n"); return false; } } $this->cntQuery = 0; $this->timeQuery = 0; $this->arQueryDebug = array(); global $DB, $USER, $APPLICATION; if(file_exists($_SERVER["DOCUMENT_ROOT"].BX_PERSONAL_ROOT."/php_interface/after_connect.php")) include($_SERVER["DOCUMENT_ROOT"].BX_PERSONAL_ROOT."/php_interface/after_connect.php"); return true; } //This function executes query against database function Query($strSql, $bIgnoreErrors=false, $error_position="", $arOptions=array()) { global $DB; $this->DoConnect(); $this->db_Error=""; if($this->DebugToFile || $DB->ShowSqlStat) { list($usec, $sec) = explode(" ", microtime()); $start_time = ((float)$usec + (float)$sec); } //We track queries for DML statements //and when there is no one we can choose //to run query against master connection //or replicated one static $bSelectOnly = true; if($this->bModuleConnection) { //In case of dedicated module database //were is nothing to do } elseif($DB->bMasterOnly) { //We requested to process all queries //by master connection } elseif(isset($arOptions["fixed_connection"])) { //We requested to process this query //by current connection } elseif($this->bNodeConnection) { //It is node so nothing to do } else { $bSelect = preg_match('/^\s*(select|show)/i', $strSql); if(!$bSelect && !isset($arOptions["ignore_dml"])) $bSelectOnly = false; if($bSelect && $bSelectOnly) { if(!isset($this->obSlave)) $this->obSlave = CDatabase::SlaveConnection(); if(is_object($this->obSlave)) return $this->obSlave->Query($strSql, $bIgnoreErrors, $error_position, $arOptions); } } if (USE_MYSQLi) $result = @mysqli_query($this->db_Conn,$strSql); else $result = @mysql_query($strSql, $this->db_Conn); if($this->DebugToFile || $DB->ShowSqlStat) { list($usec, $sec) = explode(" ",microtime()); $end_time = ((float)$usec + (float)$sec); $exec_time = round($end_time-$start_time, 10); if($DB->ShowSqlStat) { $DB->cntQuery++; $DB->timeQuery+=$exec_time; $DB->arQueryDebug[] = array( "QUERY" =>$strSql, "TIME" =>$exec_time, "TRACE" =>(function_exists("debug_backtrace")? debug_backtrace():false), "BX_STATE" => $GLOBALS["BX_STATE"], ); } if($this->DebugToFile) { $fp = fopen($_SERVER["DOCUMENT_ROOT"]."/mysql_debug.sql","ab+"); $str = "TIME: ".$exec_time." SESSION: ".session_id()." CONN: ".$this->db_Conn."\n"; $str .= $strSql."\n\n"; $str .= "----------------------------------------------------\n\n"; fputs($fp, $str); @fclose($fp); } } if(!$result) { if (USE_MYSQLi) $this->db_Error = mysqli_error($this->db_Conn); else $this->db_Error = mysql_error($this->db_Conn); if(!$bIgnoreErrors) { AddMessage2Log($error_position." MySql Query Error: ".$strSql." [".$this->db_Error."]", "main"); if ($this->DebugToFile) { $fp = fopen($_SERVER["DOCUMENT_ROOT"]."/mysql_debug.sql","ab+"); fputs($fp,"SESSION: ".session_id()." ERROR: ".$this->db_Error."\n\n----------------------------------------------------\n\n"); @fclose($fp); } if($this->debug || (@session_start() && $_SESSION["SESS_AUTH"]["ADMIN"])) echo $error_position."<br><font color=#ff0000>MySQL Query Error: ".htmlspecialchars($strSql)."</font>[".htmlspecialchars($this->db_Error)."]<br>"; $error_position = preg_replace("#<br[^>]*>#i","\n",$error_position); SendError($error_position."\nMySQL Query Error:\n".$strSql." \n [".$this->db_Error."]\n---------------\n\n"); if(file_exists($_SERVER["DOCUMENT_ROOT"].BX_PERSONAL_ROOT."/php_interface/dbquery_error.php")) include($_SERVER["DOCUMENT_ROOT"].BX_PERSONAL_ROOT."/php_interface/dbquery_error.php"); elseif(file_exists($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/dbquery_error.php")) include($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/dbquery_error.php"); else die("MySQL Query Error!"); die(); } return false; } $res = new CDBResult($result); $res->DB = $this; if($DB->ShowSqlStat) $res->SqlTraceIndex = count($DB->arQueryDebug); return $res; } function QueryLong($strSql, $bIgnoreErrors = false) { return $this->Query($strSql, $bIgnoreErrors); } function CurrentTimeFunction() { return "now()"; } function CurrentDateFunction() { return "CURRENT_DATE"; } function DateFormatToDB($format, $field = false) { static $search = array("YYYY", "MM", "DD", "HH", "MI", "SS"); static $replace = array("%Y", "%m", "%d", "%H", "%i", "%s"); $format = str_replace($search, $replace, $format); if($field === false) { return $format; } else { return "DATE_FORMAT(".$field.", '".$format."')"; } } function DateToCharFunction($strFieldName, $strType="FULL", $lang=false, $bSearchInSitesOnly=false) { static $CACHE=array(); $id = $strType.",".$lang.",".$bSearchInSitesOnly; if(!array_key_exists($id,$CACHE)) $CACHE[$id] = $this->DateFormatToDB(CLang::GetDateFormat($strType, $lang, $bSearchInSitesOnly)); return "DATE_FORMAT(".$strFieldName.", '".$CACHE[$id]."')"; } function CharToDateFunction($strValue, $strType="FULL", $lang=false) { return "'".CDatabase::FormatDate($strValue, CLang::GetDateFormat($strType, $lang), ($strType=="SHORT"? "Y-M-D":"Y-M-D H:I:S"))."'"; } // 1 if date1 > date2 // 0 if date1 = date2 // -1 if date1 < date2 function CompareDates($date1, $date2) { $s_date1 = $this->CharToDateFunction($date1); $s_date2 = $this->CharToDateFunction($date2); $strSql = " SELECT if($s_date1 > $s_date2, 1, if ($s_date1 < $s_date2, -1, if ($s_date1 = $s_date2, 0, 'x') )) as RES "; $z = $this->Query($strSql, false, "FILE: ".__FILE__."<br> LINE: ".__LINE__); $zr = $z->Fetch(); return $zr["RES"]; } function LastID() { $this->DoConnect(); if (USE_MYSQLi) return mysqli_insert_id($this->db_Conn); else return mysql_insert_id($this->db_Conn); } //Closes database connection function Disconnect() { if(!DBPersistent && $this->bConnected) { $this->bConnected = false; if (USE_MYSQLi) mysqli_close($this->db_Conn); else mysql_close($this->db_Conn); } foreach(self::$arNodes as $arNode) { if(is_array($arNode) && array_key_exists("DB", $arNode)) { if (USE_MYSQLi) mysqli_close($arNode["DB"]->db_Conn); else mysql_close($arNode["DB"]->db_Conn); unset($arNode["DB"]); } } } function PrepareFields($strTableName, $strPrefix = "str_", $strSuffix = "") { $arColumns = $this->GetTableFields($strTableName); foreach($arColumns as $arColumn) { $column = $arColumn["NAME"]; $type = $arColumn["TYPE"]; global $$column; $var = $strPrefix.$column.$strSuffix; global $$var; switch ($type) { case "int": $$var = IntVal($$column); break; case "real": $$var = self::number2db(DoubleVal(self::number2db($$column))); break; default: $$var = $this->ForSql($$column); } } } function PrepareInsert($strTableName, $arFields, $strFileDir="", $lang=false) { $strInsert1 = ""; $strInsert2 = ""; $arColumns = $this->GetTableFields($strTableName); foreach($arColumns as $strColumnName => $arColumnInfo) { $type = $arColumnInfo["TYPE"]; $value = $arFields[$strColumnName]; if(isset($value)) { if($value === false) { $strInsert1 .= ", `".$strColumnName."`"; $strInsert2 .= ", NULL "; } else { $strInsert1 .= ", `".$strColumnName."`"; switch ($type) { case "datetime": if(strlen($value)<=0) $strInsert2 .= ", NULL "; else $strInsert2 .= ", '".$this->FormatDate($value, CLang::GetDateFormat("FULL", $lang), "Y-M-D H:I:S")."'"; break; case "date": if(strlen($value)<=0) $strInsert2 .= ", NULL "; else $strInsert2 .= ", '".$this->FormatDate($value, CLang::GetDateFormat("SHORT", $lang), "Y-M-D")."'"; break; case "int": $strInsert2 .= ", '".IntVal($value)."'"; break; case "real": $strInsert2 .= ", '".self::number2db(DoubleVal(self::number2db($value)))."'"; break; default: $strInsert2 .= ", '".$this->ForSql($value)."'"; } } } elseif(array_key_exists("~".$strColumnName, $arFields)) { $strInsert1 .= ", `".$strColumnName."`"; $strInsert2 .= ", ".$arFields["~".$strColumnName]; } } if($strInsert1!="") { $strInsert1 = substr($strInsert1, 2); $strInsert2 = substr($strInsert2, 2); } return array($strInsert1, $strInsert2); } function PrepareUpdate($strTableName, $arFields, $strFileDir="", $lang = false) { return $this->PrepareUpdateBind($strTableName, $arFields, $strFileDir, $lang, $arBinds); } function PrepareUpdateBind($strTableName, $arFields, $strFileDir, $lang, &$arBinds) { $arBinds = array(); $strUpdate = ""; $arColumns = $this->GetTableFields($strTableName); foreach($arColumns as $strColumnName => $arColumnInfo) { $type = $arColumnInfo["TYPE"]; $value = $arFields[$strColumnName]; if(isset($value)) { if($value === false) { $strUpdate .= ", `".$strColumnName."` = NULL"; } else { switch ($type) { case "int": $value = IntVal($value); break; case "real": $value = self::number2db(DoubleVal(self::number2db($value))); break; case "datetime": if(strlen($value)<=0) $value = "NULL"; else $value = "'".$this->FormatDate($value, CLang::GetDateFormat("FULL", $lang), "Y-M-D H:I:S")."'"; break; case "date": if(strlen($value)<=0) $value = "NULL"; else $value = "'".$this->FormatDate($value, CLang::GetDateFormat("SHORT", $lang), "Y-M-D")."'"; break; default: $value = "'".$this->ForSql($value)."'"; } $strUpdate .= ", `".$strColumnName."` = ".$value; } } elseif(is_set($arFields, "~".$strColumnName)) { $strUpdate .= ", `".$strColumnName."` = ".$arFields["~".$strColumnName]; } } if($strUpdate!="") $strUpdate = substr($strUpdate, 2); return $strUpdate; } function number2db($value){ $larr = localeconv(); $search = array( $larr['decimal_point'], $larr['mon_decimal_point'], $larr['thousands_sep'], $larr['mon_thousands_sep'], $larr['currency_symbol'], $larr['int_curr_symbol'] ); $replace = array('.', '.', '', '', '', ''); return str_replace($search, $replace, $value); } function Insert($table, $arFields, $error_position="", $DEBUG=false, $EXIST_ID="", $ignore_errors=false) { if(is_array($arFields)) { $str1 = ""; $str2 = ""; foreach($arFields as $field => $value) { $str1 .= ($str1 <> ""? ", ":"")."`".$field."`"; if(strlen($value) <= 0) $str2 .= ($str2 <> ""? ", ":"")."'".$value."'"; else $str2 .= ($str2 <> ""? ", ":"").$value; } if (strlen($EXIST_ID)>0) { $strSql = "INSERT INTO ".$table."(ID,".$str1.") VALUES ('".$this->ForSql($EXIST_ID)."',".$str2.")"; } else { $strSql = "INSERT INTO ".$table."(".$str1.") VALUES (".$str2.")"; } if ($DEBUG) echo "<br>".$strSql."<br>"; $this->Query($strSql, $ignore_errors, $error_position); if (strlen($EXIST_ID)>0) { $ID = $EXIST_ID; } else { $ID = $this->LastID(); } return $ID; } else return false; } function Update($table, $arFields, $WHERE="", $error_position="", $DEBUG=false, $ignore_errors=false, $additional_check=true) { $rows = 0; if(is_array($arFields)) { $str = ""; foreach($arFields as $field => $value) { if (strlen($value)<=0) $str .= "`".$field."` = '', "; else $str .= "`".$field."` = ".$value.", "; } $str = TrimEx($str,","); $strSql = "UPDATE ".$table." SET ".$str." ".$WHERE; if ($DEBUG) echo "<br>".$strSql."<br>"; $w = $this->Query($strSql, $ignore_errors, $error_position); $rows = $w->AffectedRowsCount(); if ($DEBUG) echo "affected_rows = ".$rows."<br>"; if (intval($rows)<=0 && $additional_check) { $w = $this->Query("SELECT 'x' FROM ".$table." ".$WHERE, $ignore_errors, $error_position); if ($w->Fetch()) $rows = $w->SelectedRowsCount(); if ($DEBUG) echo "num_rows = ".$rows."<br>"; } } return $rows; } function Add($tablename, $arFields, $arCLOBFields = Array(), $strFileDir="", $ignore_errors=false, $error_position="", $arOptions=array()) { if(!is_object($this) || !isset($this->type)) { return $GLOBALS["DB"]->Add($tablename, $arFields, $arCLOBFields, $strFileDir, $ignore_errors, $error_position, $arOptions); } else { $arInsert = $this->PrepareInsert($tablename, $arFields, $strFileDir); $strSql = "INSERT INTO ".$tablename."(".$arInsert[0].") ". "VALUES(".$arInsert[1].")"; $this->Query($strSql, $ignore_errors, $error_position, $arOptions); return $this->LastID(); } } function TopSql($strSql, $nTopCount) { $nTopCount = intval($nTopCount); if($nTopCount>0) return $strSql."\nLIMIT ".$nTopCount; else return $strSql; } function ForSql($strValue, $iMaxLength=0) { if(!defined("BX_USE_ESCAPE_FUNC")) { if (USE_MYSQLi){ if(function_exists("mysqli_real_escape_string")) define("BX_USE_ESCAPE_FUNC", 1); else define("BX_USE_ESCAPE_FUNC", 2); } else { if(function_exists("mysql_real_escape_string")) define("BX_USE_ESCAPE_FUNC", 1); else define("BX_USE_ESCAPE_FUNC", 2); } } if($iMaxLength>0) $strValue = substr($strValue, 0, $iMaxLength); if(BX_USE_ESCAPE_FUNC==1) { if(!is_object($this) || !$this->db_Conn) { global $DB; $DB->DoConnect(); if (USE_MYSQLi) return mysqli_real_escape_string($DB->db_Conn,$strValue); else return mysql_real_escape_string($strValue, $DB->db_Conn); } else { $this->DoConnect(); if (USE_MYSQLi) return mysqli_real_escape_string($this->db_Conn,$strValue); else return mysql_real_escape_string($strValue, $this->db_Conn); } } elseif(BX_USE_ESCAPE_FUNC==2){ if (USE_MYSQLi){ if(!is_object($this) || !$this->db_Conn){ global $DB; $DB->DoConnect(); return mysqli_escape_string($DB->db_Conn,$strValue); } else{ $this->DoConnect(); return mysqli_real_escape_string($this->db_Conn,$strValue); } } else return mysql_escape_string($strValue); } //almost unreachable static $aSearch = array("\\", "'", '"'); static $aReplace = array("\\\\", "\'", '\"'); return str_replace($aSearch, $aReplace, $strValue); } function ForSqlLike($strValue, $iMaxLength=0) { if(!defined("BX_USE_ESCAPE_FUNC")) { if (USE_MYSQLi){ if(function_exists("mysqli_real_escape_string")) define("BX_USE_ESCAPE_FUNC", 1); elseif(BX_USE_ESCAPE_FUNC==2) define("BX_USE_ESCAPE_FUNC", 2); } else{ if(function_exists("mysql_real_escape_string")) define("BX_USE_ESCAPE_FUNC", 1); elseif(BX_USE_ESCAPE_FUNC==2) define("BX_USE_ESCAPE_FUNC", 2); } } if($iMaxLength>0) $strValue = substr($strValue, 0, $iMaxLength); if(BX_USE_ESCAPE_FUNC==1) { if(!is_object($this) || !$this->db_Conn) { global $DB; $DB->DoConnect(); if (USE_MYSQLi) return mysqli_real_escape_string($DB->db_Conn,str_replace("\\", "\\\\", $strValue)); else return mysql_real_escape_string(str_replace("\\", "\\\\", $strValue), $DB->db_Conn); } else { $this->DoConnect(); if (USE_MYSQLi) return mysqli_real_escape_string($this->db_Conn,str_replace("\\", "\\\\", $strValue)); else return mysql_real_escape_string(str_replace("\\", "\\\\", $strValue), $this->db_Conn); } } else{ if (USE_MYSQLi){ global $DB; $DB->DoConnect(); return mysqli_escape_string($DB->db_Conn,str_replace("\\", "\\\\", $strValue)); } else return mysql_escape_string(str_replace("\\", "\\\\", $strValue)); } //unreachable return str_replace("'", "\'", str_replace("\\", "\\\\\\\\", $strValue)); } function InitTableVarsForEdit($tablename, $strIdentFrom="str_", $strIdentTo="str_", $strSuffixFrom="", $bAlways=false) { $this->DoConnect(); if (USE_MYSQLi){ $r = mysqli_query($this->db_Conn, "SELECT * FROM ".$tablename." LIMIT 1"); $db_result = mysqli_fetch_fields($r); } else $db_result = mysql_list_fields($this->DBName, $tablename, $this->db_Conn); if($db_result) { if (USE_MYSQLi) $intNumFields = count($db_result); else $intNumFields = mysql_num_fields($db_result); while(--$intNumFields >= 0) { if (USE_MYSQLi) $strColumnName = $db_result[$intNumFields]->name; else $strColumnName = mysql_field_name($db_result, $intNumFields); $varnameFrom=$strIdentFrom.$strColumnName.$strSuffixFrom; $varnameTo=$strIdentTo.$strColumnName; global $$varnameFrom, $$varnameTo; if((isset($$varnameFrom) || $bAlways)) { if(is_array($$varnameFrom)) { $$varnameTo = array(); foreach($$varnameFrom as $k=>$v) $$varnameTo[$k] = htmlspecialchars($v); } else $$varnameTo = htmlspecialchars($$varnameFrom); } } } } function GetTableFieldsList($table) { return array_keys($this->GetTableFields($table)); } function GetTableFields($table) { if(!array_key_exists($table, $this->column_cache)) { $this->column_cache[$table] = array(); $this->DoConnect(); if (USE_MYSQLi){ $r = @mysqli_query($this->db_Conn, "SELECT * FROM ".$table." LIMIT 1"); $rs = @mysqli_fetch_fields($r); } else $rs = @mysql_list_fields($this->DBName, $table, $this->db_Conn); if($rs) { if (USE_MYSQLi) $intNumFields = count($rs); else $intNumFields = mysql_num_fields($rs); while(--$intNumFields >= 0) { if (USE_MYSQLi){ $ar = array("NAME" => $rs[$intNumFields]->name, "TYPE" => 'unknown',); switch ($rs[$intNumFields]->type){ case MYSQLI_TYPE_BIT: $ar["TYPE"]="int";break; case MYSQLI_TYPE_TINY: $ar["TYPE"]="int";break; case MYSQLI_TYPE_SHORT: $ar["TYPE"]="int";break; case MYSQLI_TYPE_LONG: $ar["TYPE"]="int";break; case MYSQLI_TYPE_LONGLONG: $ar["TYPE"]="int";break; case MYSQLI_TYPE_INT24: $ar["TYPE"]="int";break; case MYSQLI_TYPE_FLOAT: $ar["TYPE"]="real";break; case MYSQLI_TYPE_DOUBLE: $ar["TYPE"]="real";break; case MYSQLI_TYPE_DECIMAL: $ar["TYPE"]="real";break; case MYSQLI_TYPE_NEWDECIMAL: $ar["TYPE"]="real";break; case MYSQLI_TYPE_TIMESTAMP: $ar["TYPE"]="timestamp";break; case MYSQLI_TYPE_DATE: $ar["TYPE"]="date";break; case MYSQLI_TYPE_TIME: $ar["TYPE"]="time";break; case MYSQLI_TYPE_DATETIME: $ar["TYPE"]="datetime";break; case MYSQLI_TYPE_YEAR: $ar["TYPE"]="year";break; case MYSQLI_TYPE_NEWDATE: $ar["TYPE"]="date";break; case MYSQLI_TYPE_TINY_BLOB: $ar["TYPE"]="blob";break; case MYSQLI_TYPE_MEDIUM_BLOB: $ar["TYPE"]="blob";break; case MYSQLI_TYPE_LONG_BLOB: $ar["TYPE"]="blob";break; case MYSQLI_TYPE_BLOB: $ar["TYPE"]="blob";break; case MYSQLI_TYPE_VAR_STRING: $ar["TYPE"]="string";break; case MYSQLI_TYPE_STRING: $ar["TYPE"]="string";break; case MYSQLI_TYPE_NULL: $ar["TYPE"]="null";break; } } else $ar = array( "NAME" => mysql_field_name($rs, $intNumFields), "TYPE" => mysql_field_type($rs, $intNumFields), ); $this->column_cache[$table][$ar["NAME"]] = $ar; } } } return $this->column_cache[$table]; } function LockTables($str) { register_shutdown_function(array(&$this, "UnLockTables")); $this->Query("LOCK TABLE ".$str, false, '', array("fixed_connection"=>true)); } function UnLockTables() { $this->Query("UNLOCK TABLES", true, '', array("fixed_connection"=>true)); } function Concat() { $str = ""; $ar = func_get_args(); if (is_array($ar)) $str .= implode(" , ", $ar); if (strlen($str)>0) $str = "concat(".$str.")"; return $str; } function IsNull($expression, $result) { return "ifnull(".$expression.", ".$result.")"; } function Length($field) { return "length($field)"; } function ToChar($expr, $len=0) { return $expr; } function TableExists($tableName) { $tableName = preg_replace("/[^A-Za-z0-9%_]+/i", "", $tableName); $tableName = Trim($tableName); if (strlen($tableName) <= 0) return False; $dbResult = $this->Query("SHOW TABLES LIKE '".$this->ForSql($tableName)."'", false, '', array("fixed_connection"=>true)); if ($arResult = $dbResult->Fetch()) return True; else return False; } function IndexExists($tableName, $arColumns) { if(!is_array($arColumns) || count($arColumns) <= 0) return false; $rs = $this->Query("SHOW INDEX FROM `".$this->ForSql($tableName)."`", true, '', array("fixed_connection"=>true)); if(!$rs) return false; $arIndexes = array(); while($ar = $rs->Fetch()) $arIndexes[$ar["Key_name"]][$ar["Seq_in_index"]-1] = $ar["Column_name"]; $strColumns = implode(",", $arColumns); foreach($arIndexes as $Key_name => $arKeyColumns) { ksort($arKeyColumns); $strKeyColumns = implode(",", $arKeyColumns); if(substr($strKeyColumns, 0, strlen($strColumns)) === $strColumns) return true; } return false; //echo "<pre>",htmlspecialchars(print_r($arIndexes, true)),"</pre><hR>"; } function SlaveConnection() { if(class_exists('cmodule')) { if(CModule::IncludeModule('cluster')) { $arSlaves = CClusterSlave::GetList(); if(!empty($arSlaves)) { $total_weight = 0; foreach($arSlaves as $i=>$slave) { if($slave["ID"] > 1) { $arSlaveStatus = CClusterSlave::GetStatus($slave["ID"], true, false, false); if($arSlaveStatus['Seconds_Behind_Master'] > 10) unset($arSlaves[$i]); else $total_weight += $slave["WEIGHT"]; } else { $total_weight += $slave["WEIGHT"]; } } $found = false; foreach($arSlaves as $slave) { if(mt_rand(0, $total_weight) < $slave["WEIGHT"]) { $found = $slave; break; } } if(!$found || $found["ID"] == 1) return false; //use main connection else { ob_start(); $conn = CDatabase::GetDBNodeConnection($found["ID"], true); ob_end_clean(); if(is_object($conn)) { return $conn; } else { self::$arNodes[$found["ID"]]["ONHIT_ERROR"] = true; CClusterDBNode::SetOffline($found["ID"]); return false; //use main connection } } } } return false; } else { return null; } } } class CDBResult extends CAllDBResult { function CDBResult($res=NULL) { parent::CAllDBResult($res); } //Returns next row of the select result in form of associated array function Fetch() { if($this->bNavStart || $this->bFromArray) { if(!is_array($this->arResult)) $res = false; elseif($res = current($this->arResult)) next($this->arResult); } elseif($this->SqlTraceIndex) { list($usec, $sec) = explode(" ", microtime()); $start_time = ((float)$usec + (float)$sec); if(!$this->arUserMultyFields) { if (USE_MYSQLi) $res = mysqli_fetch_array($this->result, MYSQLI_ASSOC); else $res = mysql_fetch_array($this->result, MYSQL_ASSOC); } else { if (USE_MYSQLi) $res = mysqli_fetch_array($this->result, MYSQLI_ASSOC); else $res = mysql_fetch_array($this->result, MYSQL_ASSOC); if($res) foreach($this->arUserMultyFields as $FIELD_NAME=>$flag) if($res[$FIELD_NAME]) $res[$FIELD_NAME] = unserialize($res[$FIELD_NAME]); } list($usec, $sec) = explode(" ", microtime()); $end_time = ((float)$usec + (float)$sec); $exec_time = round($end_time-$start_time, 10); $GLOBALS["DB"]->arQueryDebug[$this->SqlTraceIndex - 1]["TIME"] += $exec_time; $GLOBALS["DB"]->timeQuery += $exec_time; } else { if(!$this->arUserMultyFields) { if (USE_MYSQLi) $res = mysqli_fetch_array($this->result, MYSQLI_ASSOC); else $res = mysql_fetch_array($this->result, MYSQL_ASSOC); } else { if (USE_MYSQLi) $res = mysqli_fetch_array($this->result, MYSQLI_ASSOC); else $res = mysql_fetch_array($this->result, MYSQL_ASSOC); if($res) foreach($this->arUserMultyFields as $FIELD_NAME=>$flag) if($res[$FIELD_NAME]) $res[$FIELD_NAME] = unserialize($res[$FIELD_NAME]); } } return $res; } function Free(){ if (USE_MYSQLi) return mysqli_free_result($this->result); else return mysql_free_result($this->result); } function SelectedRowsCount() { if($this->nSelectedCount !== false) return $this->nSelectedCount; if (USE_MYSQLi) return mysqli_num_rows($this->result); else return mysql_num_rows($this->result); } function AffectedRowsCount() { if(is_object($this) && is_object($this->DB)) { $this->DB->DoConnect(); if (USE_MYSQLi) return mysqli_affected_rows($this->DB->db_Conn); else return mysql_affected_rows($this->DB->db_Conn); } else { global $DB; $DB->DoConnect(); if (USE_MYSQLi) return mysqli_affected_rows($DB->db_Conn); else return mysql_affected_rows($DB->db_Conn); } } function AffectedRowsCountEx() { if (USE_MYSQLi){ if (intval(@mysqli_num_rows($this->result))>0) return 0; else return mysqli_affected_rows($this->DB->db_Conn); } else{ if (intval(@mysql_num_rows($this->result))>0) return 0; else return mysql_affected_rows($this->DB->db_Conn); } } function FieldsCount() { if (USE_MYSQLi) return count($this->result); else return mysql_num_fields($this->result); } function FieldName($iCol) { if (USE_MYSQLi){ $r = mysqli_fetch_fields($this->result); return $r[$iCol]->name; } else return mysql_field_name($this->result, $iCol); } function DBNavStart() { //total rows count if (USE_MYSQLi) $this->NavRecordCount = mysqli_num_rows($this->result); else $this->NavRecordCount = mysql_num_rows($this->result); if($this->NavRecordCount < 1) return; if($this->NavShowAll) $this->NavPageSize = $this->NavRecordCount; //calculate total pages depend on rows count. start with 1 $this->NavPageCount = floor($this->NavRecordCount/$this->NavPageSize); if($this->NavRecordCount % $this->NavPageSize > 0) $this->NavPageCount++; //page number to display. start with 1 $this->NavPageNomer = ($this->PAGEN < 1 || $this->PAGEN > $this->NavPageCount? ($_SESSION[$this->SESS_PAGEN] < 1 || $_SESSION[$this->SESS_PAGEN] > $this->NavPageCount? 1:$_SESSION[$this->SESS_PAGEN]):$this->PAGEN); //rows to skip $NavFirstRecordShow = $this->NavPageSize * ($this->NavPageNomer-1); $NavLastRecordShow = $this->NavPageSize * $this->NavPageNomer; if($this->SqlTraceIndex) { list($usec, $sec) = explode(" ", microtime()); $start_time = ((float)$usec + (float)$sec); } if (USE_MYSQLi) mysqli_data_seek($this->result, $NavFirstRecordShow); else mysql_data_seek($this->result, $NavFirstRecordShow); $temp_arrray = array(); for($i=$NavFirstRecordShow; $i<$NavLastRecordShow; $i++) { if (USE_MYSQLi) $res = mysqli_fetch_array($this->result, MYSQLI_ASSOC); else $res = mysql_fetch_array($this->result, MYSQL_ASSOC); if($res) { if($this->arUserMultyFields) foreach($this->arUserMultyFields as $FIELD_NAME=>$flag) if($res[$FIELD_NAME]) $res[$FIELD_NAME] = unserialize($res[$FIELD_NAME]); $temp_arrray[] = $res; } else { break; } } if($this->SqlTraceIndex) { list($usec, $sec) = explode(" ", microtime()); $end_time = ((float)$usec + (float)$sec); $exec_time = round($end_time-$start_time, 10); $GLOBALS["DB"]->arQueryDebug[$this->SqlTraceIndex - 1]["TIME"] += $exec_time; $GLOBALS["DB"]->timeQuery += $exec_time; } $this->arResult = $temp_arrray; } function NavQuery($strSql, $cnt, $arNavStartParams) { if(is_set($arNavStartParams, "SubstitutionFunction")) { $arNavStartParams["SubstitutionFunction"]($this, $strSql, $cnt, $arNavStartParams); return; } if(is_set($arNavStartParams, "bShowAll")) $bShowAll = $arNavStartParams["bShowAll"]; else $bShowAll = true; if(is_set($arNavStartParams, "iNumPage")) $iNumPage = $arNavStartParams["iNumPage"]; else $iNumPage = false; if(is_set($arNavStartParams, "bDescPageNumbering")) $bDescPageNumbering = $arNavStartParams["bDescPageNumbering"]; else $bDescPageNumbering = false; $this->InitNavStartVars($arNavStartParams); $this->NavRecordCount = $cnt; if($this->NavShowAll) $this->NavPageSize = $this->NavRecordCount; //calculate total pages depend on rows count. start with 1 $this->NavPageCount = ($this->NavPageSize>0 ? floor($this->NavRecordCount/$this->NavPageSize) : 0); if($bDescPageNumbering) { $makeweight = ($this->NavRecordCount % $this->NavPageSize); if($this->NavPageCount == 0 && $makeweight > 0) $this->NavPageCount = 1; //page number to display //if($iNumPage===false) // $this->PAGEN = $this->NavPageCount; $this->NavPageNomer = ( $this->PAGEN < 1 || $this->PAGEN > $this->NavPageCount ? ($_SESSION[$this->SESS_PAGEN] < 1 || $_SESSION[$this->SESS_PAGEN] > $this->NavPageCount ? $this->NavPageCount : $_SESSION[$this->SESS_PAGEN] ) : $this->PAGEN ); //rows to skip $NavFirstRecordShow = 0; if($this->NavPageNomer != $this->NavPageCount) $NavFirstRecordShow += $makeweight; $NavFirstRecordShow += ($this->NavPageCount - $this->NavPageNomer) * $this->NavPageSize; $NavLastRecordShow = $makeweight + ($this->NavPageCount - $this->NavPageNomer + 1) * $this->NavPageSize; } else { if($this->NavPageSize && ($this->NavRecordCount % $this->NavPageSize > 0)) $this->NavPageCount++; //calculate total pages depend on rows count. start with 1 $this->NavPageNomer = ($this->PAGEN < 1 || $this->PAGEN > $this->NavPageCount? ($_SESSION[$this->SESS_PAGEN] < 1 || $_SESSION[$this->SESS_PAGEN] > $this->NavPageCount? 1:$_SESSION[$this->SESS_PAGEN]):$this->PAGEN); //rows to skip $NavFirstRecordShow = $this->NavPageSize*($this->NavPageNomer-1); $NavLastRecordShow = $this->NavPageSize*$this->NavPageNomer; } if(!$this->NavShowAll) $strSql .= " LIMIT ".$NavFirstRecordShow.", ".($NavLastRecordShow - $NavFirstRecordShow); if(is_object($this->DB)) $res_tmp = $this->DB->Query($strSql); else $res_tmp = $GLOBALS["DB"]->Query($strSql); /* for($i=$NavFirstRecordShow; $i<$NavLastRecordShow; $i++) $temp_arrray[] = mysql_fetch_array($res_tmp->result, MYSQL_ASSOC); */ if($this->SqlTraceIndex) { list($usec, $sec) = explode(" ", microtime()); $start_time = ((float)$usec + (float)$sec); } $temp_arrray = array(); if (USE_MYSQLi) while($ar = mysqli_fetch_array($res_tmp->result, MYSQLI_ASSOC)) { if($this->arUserMultyFields) foreach($this->arUserMultyFields as $FIELD_NAME=>$flag) if($ar[$FIELD_NAME]) $ar[$FIELD_NAME] = unserialize($ar[$FIELD_NAME]); $temp_arrray[] = $ar; } else while($ar = mysql_fetch_array($res_tmp->result, MYSQL_ASSOC)) { if($this->arUserMultyFields) foreach($this->arUserMultyFields as $FIELD_NAME=>$flag) if($ar[$FIELD_NAME]) $ar[$FIELD_NAME] = unserialize($ar[$FIELD_NAME]); $temp_arrray[] = $ar; } if($this->SqlTraceIndex) { list($usec, $sec) = explode(" ", microtime()); $end_time = ((float)$usec + (float)$sec); $exec_time = round($end_time-$start_time, 10); $GLOBALS["DB"]->arQueryDebug[$this->SqlTraceIndex - 1]["TIME"] += $exec_time; $GLOBALS["DB"]->timeQuery += $exec_time; } $this->result = $res_tmp->result; // added for FieldsCount and other compatibility $this->arResult = count($temp_arrray)? $temp_arrray: false; $this->nSelectedCount = $cnt; $this->bDescPageNumbering = $bDescPageNumbering; $this->bFromLimited=true; $this->DB = $res_tmp->DB; } } ?> |