_debug_file,(($logflushed)?"a":"w") ); $buff = "{$sz}
\n"; fwrite($fl, $buff); fclose($fl); $logflushed = 1; } // // instance // function &get_instance() { return $GLOBALS['db']; } // // escape // function sql_escape($msg) { if (!isset($this) || !$this->db_connect_id) { return @mysql_real_escape_string($msg); } return @mysql_real_escape_string($msg, $this->db_connect_id); } // // Constructor // function sql_db($sqlserver, $sqluser, $sqlpassword, $database, $persistency = true) { $this->cache_path = $GLOBALS['root_path'] . $this->cache_path; $this->_debug_file = $GLOBALS['root_path'] . $this->_debug_file; $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; $this->persistency = $persistency; $this->user = $sqluser; $this->password = $sqlpassword; $this->server = $sqlserver; $this->dbname = $database; $this->prefix = $GLOBALS['table_prefix']; $this->root = $GLOBALS['root_path']; $this->cache_enabled = (isset($GLOBALS['config']['disable_sql_cache'])?false:true); $this->db_connect_id = ($this->persistency) ? @mysql_pconnect($this->server, $this->user, $this->password) : @mysql_connect($this->server, $this->user, $this->password); if( $this->db_connect_id ) { if( $database != "" ) { $this->dbname = $database; $dbselect = mysql_select_db($this->dbname); if( !$dbselect ) { mysql_close($this->db_connect_id); $this->db_connect_id = $dbselect; } } $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return $this->db_connect_id; } else { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return false; } } // // Other base methods // function sql_close() { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; if( $this->db_connect_id ) { // // Commit any remaining transactions // if( $this->in_transaction ) { mysql_query("COMMIT", $this->db_connect_id); } return mysql_close($this->db_connect_id); $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return $result; } else { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return false; } } // function cache_make_id($q){ $data['q']=$q; $table=''; $m=array('','',''); // (?:DELETE|SELECT|) if (preg_match('/^(DELETE|SELECT).*FROM[\s\(]*'.$this->prefix.'([^\s\,\;]+)[\s]*/ims',$q,$m)) $table=@$m[2]; else if (preg_match('/^(MODIFY|INSERT INTO|INSERT|UPDATE|TRUNCATE|DROP|CREATE TABLE)[\s]*'.$this->prefix.'([^\s\,\;]+)[\s]*/ims',$q,$m)) $table=@$m[2]; $this->cache_last_table = $table; # core_c::cprint("[color=blue]{$m[1]} - {$table}[/color]"); return ( $this->dbname . '_' .$table. '_'.sprintf("%u",crc32(serialize($data)))); } /* * CACHE EM ALL! */ var $cache_except_tables = array('sessions','banlist','confirm','users'); //'news_export_news' var $cache_hits = array(); var $cache_last_id; var $cache_last_table; /* make id do this */ /* configs */ var $cache_cache_1items_queries = true; var $cache_ignore_another_tables = true; /* ugnore tables with another prefix */ var $cache; var $cache_table_chains = array( 'blog'=>array('config'), 'blog_com'=>array('blog'), 't_categories'=>array('config') ); /* игнорировать таблицу для кэширования */ function cache_is_ignore($table) { return in_array($table, $this->cache_except_tables); } function cache_fetchrowset($res) { if (!isset($this->cache[$res])) return -1; // inc index $data = $this->cache[$res]['data']; return (!empty($data)?$data:false); } /* -1 - no cache false - out of increment */ function cache_fetchrow($res) { if (!isset($this->cache[$res])) return -1; // inc index $data = $this->cache[$res]['data']; $index = $this->cache[$res]['index']++; return (isset($data[$index])?$data[$index]:false); } /* Вызывается до реального обращения к sql_query Если существует кэш, то он отдается в последствие методом cache_get @return: -1 - cancel cache false - cache not exists true - found */ function cache_check_by_id($id=false) { if ($id===false) $id=$this->cache_last_id; return (isset($this->cache[$id])); } function cache_check($sql) { if (!$this->cache_enabled) return -1; $this->cache_last_id = $this->cache_make_id($sql); $fname = $this->cache_make_fname($this->cache_last_id); // check nasty queries (UPDATE, MODIFY, DELETE, INSERT) if (preg_match('#^(?!SELECT)#i',$sql,$m)) { // skip it #core_c::cprint('SKIP>'.$sql); /* убиваем кэш, если это не селект hack: одиночное изменение */ $single = (preg_match("/WHERE[\s]*id[\s]*=/smi",$sql))?$this->cache_last_id:false; $this->cache_drop(false,$single); return -1; } else { /* skip sone tables, suck as phpbb messages */ if ($this->cache_ignore_another_tables && preg_match('#FROM[\s\(]*([^\s\)]*)#ism',$sql,$m)) { if (substr($m[1],0,strlen($this->prefix))!=$this->prefix) { return -1; } } } // cache hit if (isset($this->cache[$this->cache_last_id]) || file_exists($fname)) { return true; } return false; } /* */ function cache_drop($table=false, $single=false) { if ($table===false) $table = $this->cache_last_table; if (!empty($table) && !$this->cache_is_ignore($table)) { // дропаем $dir = $this->cache_path; $pref_ = $this->dbname . '_' .$table. '_'; /* if ($single!==false) { core_c::cprint('kill single : '.$single); unlink($dir.$single); return true; } */ # core_c::cprint("[DROP] {$pref_}" ); if ($dh = opendir($dir)) { # core_c::cprint('DROP=='.$table); while (($file = readdir($dh)) !== false) { if (preg_match("#^{$pref_}#",$file)) { # core_c::cprint("[SQL DROP] Файл: $file : тип: " . filetype($dir . $file) ); unlink($dir.$file); } } closedir($dh); // } // chain delete if (isset($this->cache_table_chains[$table])) { foreach($this->cache_table_chains[$table] as $t_) { $this->cache_drop($t_); } } } } function cache_rowcount($id=false) { if ($id===false) $id=$this->cache_last_id; return ($this->cache[$id]['count']); } /* cache is exists, get it */ function cache_get($id=false) { if ($id===false) $id=$this->cache_last_id; $fname = $this->cache_make_fname($id); #var_dump('[SET_RES]',$id); if (!isset($this->cache[$id])) { //$data = file_get_contents($fname); //var_dump($data); $data = include($fname); //unserialize($data); $this->cache[$id]=$data; } else { $data = $this->cache[$id]; } // reset! $this->cache[$id]['index']=0; // if fail, return fail query flag! #return ($data['result']) ? $id : false; #core_c::cprint('[cache_get]'); return $id; } /* путь до файла кэша */ function cache_make_fname($t) { return $this->cache_path.$t; } function cache_query($sql,$res) { $this->cache_last_id = $this->cache_make_id($sql); preg_match('/FROM[\s]*'.$this->prefix.'([^\s\,\;]+)[\s]*/i',$sql,$m); $table=@$m[1]; if ($table && $this->cache_is_ignore($table)) { #core_c::cprint("[sql_cache] deny {$table}"); return $res; // do not cache this shit } $data = $this->sql_fetchrowset($res); $cache = array( 'data' => $data, 'result'=> $res, 'table' => $table, 'index' => 0, 'count' => count($data) ); #core_c::cprint('cache write #' .$this->cache_last_id); file_put_contents( $this->cache_make_fname($this->cache_last_id), "" //serialize($cache) ); $this->cache[$this->cache_last_id]=$cache; return $this->cache_last_id; } // // Base query method // function sql_query($query = "", $transaction = FALSE) { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; // // Remove any pre-existing queries // unset($this->query_result); if( $query != "" ) { // core_c::cprint('[color=darkgreen]'.$query.'[/color]'); $cache_ret = $this->cache_check($query); #core_c::cprint("[code type=php]{$query}[/code]"); if ($cache_ret!==true) { $this->num_queries++; if( $transaction == BEGIN_TRANSACTION && !$this->in_transaction ) { $result = mysql_query("BEGIN", $this->db_connect_id); if(!$result) { return false; } $this->in_transaction = TRUE; } $this->query_result = mysql_query($query, $this->db_connect_id); if ($cache_ret!==-1 && ($this->cache_cache_1items_queries || (!$this->cache_cache_1items_queries && $this->sql_numrows($this->query_result)>1)) ) $this->query_result = $this->cache_query($query,$this->query_result); } else { $this->query_result = $this->cache_get(); return $this->query_result; } } else { if( $transaction == END_TRANSACTION && $this->in_transaction ) { $result = mysql_query("COMMIT", $this->db_connect_id); } } if( $this->query_result ) { unset($this->row[$this->query_result]); unset($this->rowset[$this->query_result]); if( $transaction == END_TRANSACTION && $this->in_transaction ) { $this->in_transaction = FALSE; if ( !mysql_query("COMMIT", $this->db_connect_id) ) { mysql_query("ROLLBACK", $this->db_connect_id); return false; } } $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; if (defined('SQL_DEBUG')) { $this->syslog('' . $this->num_queries.') '.htmlspecialchars($query) . ' [' . round($this->sql_time,4) . 'ms]'); // debug code idea by jovani (phpbbguru.net/community/profile.php?mode=viewprofile&u=12) if(strtoupper(substr($query, 0, 6)) == "SELECT") { $x = mysql_query("EXPLAIN $query", $this->db_connect_id); $z = array(); while($y = mysql_fetch_assoc($x)) { $this->syslog ("  » tbl = " . $y['table'] . " type = " . $y['type'] . " possible = " . $y['possible_keys'] . " used = " . $y['key'] . " len = " . $y['key_len'] . " ref = " . $y['ref'] . " rows = " . $y['rows'] . " extra = " . $y['Extra'] ); } mysql_free_result($x); } } return $this->query_result; } else { if( $this->in_transaction ) { mysql_query("ROLLBACK", $this->db_connect_id); $this->in_transaction = FALSE; } $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; if (defined('SQL_DEBUG')) { core_c::cprint('[color=red]MYSQL ERROR : '.$query.'[/color]'); $err = $this->sql_error(); core_c::cprint('[color=red]MYSQL : '.$err['message'].' ('.$err['code'].')[/color]'); } return false; } } // // Other query methods // function sql_numrows($query_id = 0) { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; if( !$query_id ) { $query_id = $this->query_result; } // cache num rows if ($this->cache_check_by_id($query_id)) return $this->cache_rowcount($query_id); $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return ( $query_id ) ? mysql_num_rows($query_id) : false; } function sql_affectedrows() { // cache num rows if ($this->cache_check_by_id()) return $this->cache_rowcount(); $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return ( $this->db_connect_id ) ? mysql_affected_rows($this->db_connect_id) : false; } function sql_numfields($query_id = 0) { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; if( !$query_id ) { $query_id = $this->query_result; } $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return ( $query_id ) ? mysql_num_fields($query_id) : false; } function sql_fieldname($offset, $query_id = 0) { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; if( !$query_id ) { $query_id = $this->query_result; } $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return ( $query_id ) ? mysql_field_name($query_id, $offset) : false; } function sql_fieldtype($offset, $query_id = 0) { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; if( !$query_id ) { $query_id = $this->query_result; } $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return ( $query_id ) ? mysql_field_type($query_id, $offset) : false; } /* SQL: fetchrow */ function sql_fetchrow($query_id = 0) { #core_c::cprint('[FETCHROW] '.$query_id); $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; if( !$query_id ) { $query_id = $this->query_result; } if( $query_id ) { // cached? if (-1!==($tmp_=$this->cache_fetchrow($query_id))) return $tmp_; $this->row[intval($query_id)] = mysql_fetch_assoc($query_id); $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return $this->row[intval($query_id)]; } else { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return false; } } function sql_fetchrowset($query_id = 0) { $result = array(); $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; if( !$query_id ) { $query_id = $this->query_result; } if( $query_id ) { // cached? if (-1!==($tmp_=$this->cache_fetchrowset($query_id))) return $tmp_; unset($this->rowset[$query_id]); unset($this->row[$query_id]); while($this->rowset[intval($query_id)] = mysql_fetch_assoc($query_id)) { $result[] = $this->rowset[$query_id]; } $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return $result; } else { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return false; } } function sql_fetchfield($field, $rownum = -1, $query_id = 0) { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; if( !$query_id ) { $query_id = $this->query_result; } if( $query_id ) { if( $rownum > -1 ) { $result = mysql_result($query_id, $rownum, $field); } else { if( empty($this->row[$query_id]) && empty($this->rowset[$query_id]) ) { if( $this->sql_fetchrow() ) { $result = $this->row[$query_id][$field]; } } else { if( $this->rowset[$query_id] ) { $result = $this->rowset[$query_id][0][$field]; } else if( $this->row[$query_id] ) { $result = $this->row[$query_id][$field]; } } } $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return $result; } else { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return false; } } function sql_rowseek($rownum, $query_id = 0) { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; if( !$query_id ) { $query_id = $this->query_result; } $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return ( $query_id ) ? mysql_data_seek($query_id, $rownum) : false; } function sql_nextid() { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return ( $this->db_connect_id ) ? mysql_insert_id($this->db_connect_id) : false; } function sql_freeresult($query_id = 0) { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; if( !$query_id ) { $query_id = $this->query_result; } if ( $query_id ) { unset($this->row[$query_id]); unset($this->rowset[$query_id]); mysql_free_result($query_id); $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return true; } else { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return false; } } function sql_error() { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; $result['message'] = mysql_error($this->db_connect_id); $result['code'] = mysql_errno($this->db_connect_id); $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $this->sql_time += $endtime - $starttime; return $result; } function get_version() { $version = $this->sql_fetchrow($this->sql_query("SELECT VERSION() as version")); return $version['version']; } } // class sql_db /** * sql cache stuff */ } // if ... define ?>