0) && (substr($sql, $nextarg - $escapesCount - 1, 1) == '\\')) $escapesCount++; if (($escapesCount % 2) == 1) $nextarg++; else { $nextchar = substr($sql, $nextarg + 1, 1); if (is_numeric($nextchar)) { $arglength = 0; $arg = ''; // find next non-digit while (preg_match('/^[0-9]{1}/', $nextchar) == 1) { $arg .= $nextchar; $arglength++; $nextchar = substr($sql, $nextarg + $arglength + 1, 1); } // ok ... replace $filtered_sql .= substr($sql, $sqlpos, $nextarg - $sqlpos); $sqlpos = $nextarg + $arglength; if (isset($args[$arg])) { if (is_numeric($args[$arg])) $filtered_sql .= $args[$arg]; else { if ((substr($sql, $sqlpos - $arglength - 1, 1) == '\'') && (substr($sql, $sqlpos + 1, 1) == '\'')) $filtered_sql .= sql_escape($args[$arg]); else if ((substr($sql, $sqlpos - $arglength - 1, 1) == '`') && (substr($sql, $sqlpos + 1, 1) == '`')) $filtered_sql .= sql_escape_backtick($args[$arg]); else sql_error(); } } else { // NULL if ((substr($sql, $sqlpos - $arglength - 1, 1) == '\'') && (substr($sql, $sqlpos + 1, 1) == '\'')) { // strip apostroph and insert NULL $filtered_sql = substr($filtered_sql, 0, strlen($filtered_sql) - 1); $filtered_sql .= 'NULL'; $sqlpos++; } else $filtered_sql .= 'NULL'; } $sqlpos++; } else { $arglength = 0; $arg = ''; // find next non-alphanumeric char while (preg_match('/^[a-zA-Z0-9]{1}/', $nextchar) == 1) { $arg .= $nextchar; $arglength++; $nextchar = substr($sql, $nextarg + $arglength + 1, 1); } // ok ... replace $filtered_sql .= substr($sql, $sqlpos, $nextarg - $sqlpos); if (isset($opt['db']['placeholder'][$arg])) { if (substr($sql, $nextarg - 1, 1) != '`') $filtered_sql .= '`'; $filtered_sql .= sql_escape_backtick($opt['db']['placeholder'][$arg]); if (substr($sql, $nextarg + $arglength + 1, 1) != '`') $filtered_sql .= '`'; } else if (isset($db['temptables'][$arg])) { if (substr($sql, $nextarg - 1, 1) != '`') $filtered_sql .= '`'; $filtered_sql .= sql_escape_backtick($opt['db']['placeholder']['tmpdb']) . '`.`' . sql_escape_backtick($db['temptables'][$arg]); if (substr($sql, $nextarg + $arglength + 1, 1) != '`') $filtered_sql .= '`'; } else sql_error(); $sqlpos = $nextarg + $arglength + 1; } } $nextarg = strpos($sql, '&', $nextarg + 1); } // append the rest $filtered_sql .= substr($sql, $sqlpos); // strip escapes of & $nextarg = strpos($filtered_sql, '\&'); while ($nextarg !== false) { $escapesCount = 0; while ((($nextarg - $escapesCount - 1) > 0) && (substr($filtered_sql, $nextarg - $escapesCount - 1, 1) == '\\')) $escapesCount++; if (($escapesCount % 2) == 0) { // strip escapes of & $filtered_sql = substr($filtered_sql, 0, $nextarg) . '&' . substr($filtered_sql, $nextarg + 2); $nextarg--; } $nextarg = strpos($filtered_sql, '\&', $nextarg + 2); } // // ok ... filtered_sql is ready for usage // /* todo: - errorlogging - LIMIT - block DROP/DELETE */ if (isset($db['debug']) && ($db['debug'] == true)) { require_once($opt['rootpath'] . 'lib2/sqldebugger.class.php'); $result = $sqldebugger->execute($filtered_sql, $dblink, ($dblink===$db['dblink_slave']), $db['slave_server']); if ($result === false) { sql_error(); } } else { // measure time if ($opt['db']['warn']['time'] > 0) { require_once($opt['rootpath'] . 'lib2/bench.inc.php'); $cSqlExecution = new Cbench; $cSqlExecution->start(); } $result = @mysql_query($filtered_sql, $dblink); if ($result === false) { sql_error(); } if ($opt['db']['warn']['time'] > 0) { $cSqlExecution->stop(); if ($cSqlExecution->diff() > $opt['db']['warn']['time']) sql_warn('execution took ' . $cSqlExecution->diff() . ' seconds'); } } return $result; } function sqlf($sql) { global $db; $nOldMode = $db['mode']; $db['mode'] = DB_MODE_FRAMEWORK; $args = func_get_args(); unset($args[0]); $result = sql($sql, $args); $db['mode'] = $nOldMode; return $result; } function sqlf_slave($sql) { global $db; $nOldMode = $db['mode']; $db['mode'] = DB_MODE_FRAMEWORK; $args = func_get_args(); unset($args[0]); $result = sql_slave($sql, $args); $db['mode'] = $nOldMode; return $result; } function sqll($sql) { global $db; $nOldMode = $db['mode']; $db['mode'] = DB_MODE_BUSINESSLAYER; $args = func_get_args(); unset($args[0]); $result = sql($sql, $args); $db['mode'] = $nOldMode; return $result; } function sqlf_value($sql, $default) { global $db; $nOldMode = $db['mode']; $db['mode'] = DB_MODE_FRAMEWORK; $args = func_get_args(); unset($args[0]); unset($args[1]); $result = sql_value($sql, $default, $args); $db['mode'] = $nOldMode; return $result; } function sqll_value($sql, $default) { global $db; $nOldMode = $db['mode']; $db['mode'] = DB_MODE_BUSINESSLAYER; $args = func_get_args(); unset($args[0]); unset($args[1]); $result = sql_value($sql, $default, $args); $db['mode'] = $nOldMode; return $result; } function sql_escape($value) { global $db, $opt; // convert the charset of $value if ($opt['charset']['iconv'] != 'UTF-8') $value = iconv('UTF-8', $opt['charset']['iconv'], $value); // establish db connection if ($db['connected'] != true) sql_connect(); $value = mysql_real_escape_string($value, $db['dblink']); $value = str_replace('&', '\&', $value); return $value; } function sql_escape_backtick($value) { $value = sql_escape($value); $value = str_replace('`', '``', $value); return $value; } function sql_value($sql, $default) { $args = func_get_args(); unset($args[0]); unset($args[1]); if (isset($args[2]) && is_array($args[2])) { $tmp_args = $args[2]; unset($args); // correct indizes $args = array_merge(array(0), $tmp_args); unset($tmp_args); unset($args[0]); } return sql_value_internal(false, $sql, $default, $args); } function sql_value_slave($sql, $default) { $args = func_get_args(); unset($args[0]); unset($args[1]); if (isset($args[2]) && is_array($args[2])) { $tmp_args = $args[2]; unset($args); // correct indizes $args = array_merge(array(0), $tmp_args); unset($tmp_args); unset($args[0]); } return sql_value_internal(true, $sql, $default, $args); } function sql_value_internal($bQuerySlave, $sql, $default) { $args = func_get_args(); unset($args[0]); unset($args[1]); unset($args[2]); /* as an option, you can give as third parameter an array * with all values for the placeholder. The array has to be * with numeric indizes. */ if (isset($args[3]) && is_array($args[3])) { $tmp_args = $args[3]; unset($args); // correct indizes $args = array_merge(array(0), $tmp_args); unset($tmp_args); unset($args[0]); } if ($bQuerySlave == true) $rs = sql_slave($sql, $args); else $rs = sql($sql, $args); $r = sql_fetch_row($rs); sql_free_result($rs); if ($r) { if ($r[0] == null) return $default; else return $r[0]; } else return $default; } /* Replacement for builtin MySQL functions (includes database charset conversion) */ function sql_fetch_array($rs) { global $opt; $retval = mysql_fetch_array($rs); if (is_array($retval)) if ($opt['charset']['iconv'] != 'UTF-8') foreach ($retval AS $k => $v) $retval[$k] = iconv($opt['charset']['iconv'], 'UTF-8', $v); return $retval; } function sql_fetch_assoc($rs) { global $opt; $retval = mysql_fetch_assoc($rs); if (is_array($retval)) if ($opt['charset']['iconv'] != 'UTF-8') foreach ($retval AS $k => $v) $retval[$k] = iconv($opt['charset']['iconv'], 'UTF-8', $v); return $retval; } function sql_fetch_row($rs) { global $opt; $retval = mysql_fetch_row($rs); if (is_array($retval)) if ($opt['charset']['iconv'] != 'UTF-8') foreach ($retval AS $k => $v) $retval[$k] = iconv($opt['charset']['iconv'], 'UTF-8', $v); return $retval; } function sql_affected_rows() { global $db; return mysql_affected_rows($db['dblink']); } function sql_affected_rows_slave() { global $db; return mysql_affected_rows($db['dblink_slave']); } function sql_free_result($rs) { return mysql_free_result($rs); } function sql_insert_id() { global $db; return mysql_insert_id($db['dblink']); } function sql_insert_id_slave() { global $db; return mysql_insert_id($db['dblink_slave']); } function sql_num_rows($rs) { return mysql_num_rows($rs); } function sql_temp_table($table) { global $db, $opt; if ($db['connected'] == false) sql_connect(); if ($opt['db']['pconnect'] == true) { if ($db['temptable_initialized'] == false) { $rs = sqlf("SELECT `threadid`, `name` FROM &db.`sys_temptables` WHERE `threadid`='&1'", mysql_thread_id($db['dblink'])); while ($r = sql_fetch_assoc($rs)) { sqlf("DROP TEMPORARY TABLE IF EXISTS &tmpdb.`&1`", $r['name']); } sql_free_result($rs); sqlf("DELETE FROM &db.`sys_temptables` WHERE `threadid`='&1'", mysql_thread_id($db['dblink'])); $db['temptable_initialized'] = true; } sqlf("INSERT IGNORE INTO &db.`sys_temptables` (`threadid`, `name`) VALUES ('&1', '&2')", mysql_thread_id($db['dblink']), $table); } $db['temptables'][$table] = $table; } function sql_temp_table_slave($table) { global $db, $opt; if ($db['dblink_slave'] === false) sql_connect_anyslave(); if ($opt['db']['pconnect'] == true) sqlf_slave("INSERT IGNORE INTO &db.`sys_temptables` (`threadid`, `name`) VALUES ('&1', '&2')", mysql_thread_id($db['dblink_slave']), $table); $db['temptables'][$table] = $table; $db['temptables_slave'][$table] = $table; } function sql_drop_temp_table($table) { global $db, $opt; sqlf("DROP TEMPORARY TABLE IF EXISTS &tmpdb.`&1`", $table); if ($opt['db']['pconnect'] == true) sqlf("DELETE FROM &db.`sys_temptables` WHERE `threadid`='&1' AND `name`='&2'", mysql_thread_id($db['dblink']), $table); unset($db['temptables'][$table]); } function sql_drop_temp_table_slave($table) { global $db, $opt; sqlf_slave("DROP TEMPORARY TABLE IF EXISTS &tmpdb.`&1`", $table); if ($opt['db']['pconnect'] == true) sqlf_slave("DELETE FROM &db.`sys_temptables` WHERE `threadid`='&1' AND `name`='&2'", mysql_thread_id($db['dblink']), $table); unset($db['temptables'][$table]); unset($db['temptables_slave'][$table]); } //database handling function sql_connect($username=null, $password=null, $raiseError=true) { global $opt, $db; if ($username == null) $username = $opt['db']['username']; if ($password == null) $password = $opt['db']['password']; //connect to the database by the given method - no php error reporting! if ($opt['db']['pconnect'] == true) $db['dblink'] = @mysql_pconnect($opt['db']['servername'], $username, $password); else $db['dblink'] = @mysql_connect($opt['db']['servername'], $username, $password); if ($db['dblink'] !== false) { mysql_query("SET NAMES '" . mysql_real_escape_string($opt['charset']['mysql'], $db['dblink']) . "'", $db['dblink']); //database connection established ... set the used database if (@mysql_select_db($opt['db']['placeholder']['db'], $db['dblink']) == false) { //error while setting the database ... disconnect sql_disconnect(); $db['dblink'] = false; } } // output the error form if there was an error if ($db['dblink'] === false) { if ($raiseError == true) sql_error(); } else $db['connected'] = true; } function sql_slave_exclude() { global $login; if ($login->userid == 0) return; sql("INSERT INTO `sys_repl_exclude` (`user_id`, `datExclude`) VALUES ('&1', NOW()) ON DUPLICATE KEY UPDATE `datExclude`=NOW()", $login->userid); } function sql_connect_anyslave() { global $db, $opt, $login; if ($db['dblink_slave'] !== false) return; $nMaxTimeDiff = $opt['db']['slave']['max_behind']; if ($login->userid != 0) { $nMaxTimeDiff = sql_value("SELECT TIMESTAMP(NOW())-TIMESTAMP(`datExclude`) FROM `sys_repl_exclude` WHERE `user_id`='&1'", $opt['db']['slave']['max_behind'], $login->userid); if ($nMaxTimeDiff > $opt['db']['slave']['max_behind']) $nMaxTimeDiff = $opt['db']['slave']['max_behind']; } $id = sqlf_value("SELECT `id`, `weight`*RAND() AS `w` FROM `sys_repl_slaves` WHERE `active`=1 AND `online`=1 AND (TIMESTAMP(NOW())-TIMESTAMP(`last_check`)+`time_diff`<'&1') ORDER BY `w` DESC LIMIT 1", -1, $nMaxTimeDiff); sql_connect_slave($id); } function sql_connect_master_as_slave() { global $db; // the right slave is connected if ($db['dblink_slave'] !== false) { sql_error(); return; } // use existing master connection $db['slave_id'] = -1; $db['dblink_slave'] = $db['dblink']; $db['slave_server'] = 'master'; } function sql_connect_slave($id) { global $opt, $db; if ($id == -1) { sql_connect_master_as_slave(); return; } // the right slave is connected if ($db['dblink_slave'] !== false) { // TODO: disconnect if other slave is connected if ($db['slave_id'] != $id) sql_error(); return; } $db['slave_id'] = $id; $slave = $opt['db']['slaves'][$id]; // for display in SQL debugger $db['slave_server'] = $slave['server']; if ($opt['db']['pconnect'] == true) $db['dblink_slave'] = @mysql_pconnect($slave['server'], $slave['username'], $slave['password']); else $db['dblink_slave'] = @mysql_connect($slave['server'], $slave['username'], $slave['password']); if ($db['dblink_slave'] !== false) { if (mysql_select_db($opt['db']['placeholder']['db'], $db['dblink_slave']) == false) sql_error(); mysql_query("SET NAMES '" . mysql_real_escape_string($opt['charset']['mysql'], $db['dblink_slave']) . "'", $db['dblink_slave']); // initialize temp tables on slave server $rs = sqlf_slave("SELECT `threadid`, `name` FROM `sys_temptables` WHERE `threadid`='&1'", mysql_thread_id($db['dblink_slave'])); while ($r = sql_fetch_assoc($rs)) { sqlf_slave("DROP TEMPORARY TABLE IF EXISTS &tmpdb.`&1`", $r['name']); } sql_free_result($rs); sqlf_slave("DELETE FROM &db.`sys_temptables` WHERE `threadid`='&1'", mysql_thread_id($db['dblink_slave'])); } else sql_error(); } function sql_connect_root() { global $tpl, $db, $opt; if (file_exists($opt['rootpath'] . 'config2/sqlroot.inc.php')) require($opt['rootpath'] . 'config2/sqlroot.inc.php'); else return false; sql_disconnect(); sql_connect($opt['sqlroot']['username'], $opt['sqlroot']['password'], false); if ($db['dblink'] === false) { sql_disconnect(); sql_connect(); if ($db['connected'] == false) $tpl->error(ERROR_DB_COULD_NOT_RECONNECT); return false; } return true; } //disconnect the databse function sql_disconnect() { global $opt, $db; sql_disconnect_slave(); if (($opt['db']['pconnect'] == true) && ($db['dblink'] !== false)) { if (count($db['temptables']) > 0) { foreach ($db['temptables'] AS $table) sqlf("DROP TEMPORARY TABLE IF EXISTS &tmpdb.`&1`", $table); sqlf("DELETE FROM &db.`sys_temptables` WHERE `threadid`='&1'", mysql_thread_id($db['dblink'])); $db['temptables'] = array(); $db['temptables_slave'] = array(); } } if ($db['dblink'] === $db['dblink_slave']) $db['dblink_slave'] = false; //is connected and no persistent connect used? if (($opt['db']['pconnect'] == false) && ($db['dblink'] !== false)) { mysql_close($db['dblink']); $db['dblink'] = false; $db['connected'] = false; } } //disconnect the databse function sql_disconnect_slave() { global $opt, $db; if ($db['dblink_slave'] === false) return; if (($opt['db']['pconnect'] == true) && ($db['dblink'] !== false)) { if (count($db['temptables']) > 0) { foreach ($db['temptables'] AS $k => $table) { if (isset($db['temptables_slave'][$table])) { sqlf_slave("DROP TEMPORARY TABLE IF EXISTS &tmpdb.`&1`", $table); unset($db['temptables_slave'][$table]); unset($db['temptables'][$k]); } } if (count($db['temptables_slave']) > 0) sqlf_slave("DELETE FROM &db.`sys_temptables` WHERE `threadid`='&1'", mysql_thread_id($db['dblink_slave'])); $db['temptables_slave'] = array(); } } if ($db['dblink'] === $db['dblink_slave']) { $db['dblink_slave'] = false; return; } //is connected and no persistent connect used? if (($opt['db']['pconnect'] == false) && ($db['dblink_slave'] !== false)) mysql_close($db['dblink_slave']); $db['dblink_slave'] = false; } function sql_error() { global $tpl, $opt, $db; global $bSmartyNoTranslate; if ($db['error'] == true) die("sql_error() recursion, aborting!\nCheck if database connect does work.\nMost often, an error mail tried to load translations from database.\nMySQL Error no " . mysql_errno() . "\n"); $db['error'] = true; $errno = mysql_errno(); $error = mysql_error(); if ($db['connected'] == false) $bSmartyNoTranslate = true; if ($opt['db']['error']['mail'] != '') { require_once($opt['rootpath'] . 'lib2/mail.class.php'); $mail = new mail(); $mail->subject = $opt['db']['error']['subject']; $mail->to = $opt['db']['error']['mail']; $mail->name = 'sql_error'; $mail->assign('errno', $errno); $mail->assign('error', $error); $mail->assign('trace', print_r(debug_backtrace(), true)); $mail->send(); $mail = null; } if ($opt['gui'] == GUI_HTML) { if (isset($tpl)) { if ($opt['db']['error']['display'] == true) $tpl->error('MySQL error' . ' (' . $errno . '): ' . $error); else $tpl->error('A database command could not be performed.'); } else { if ($opt['db']['error']['display'] == true) die('' . htmlspecialchars('MySQL error (' .$errno . '): ' . $error) . ''); else die('A database command could not be performed'); } } else { // CLI script, simple text output if ($opt['db']['error']['display'] == true) die('MySQL error' . ' (' . $errno . '): ' . $error . "\n"); else die("A database command could not be performed.\n"); } } function sql_warn($warnmessage) { global $opt; if ($opt['db']['error']['mail'] != '') { require_once($opt['rootpath'] . 'lib2/mail.class.php'); $mail = new mail(); $mail->name = 'sql_warn'; $mail->subject = $opt['db']['warn']['subject']; $mail->to = $opt['db']['warn']['mail']; $mail->assign('warnmessage', $warnmessage); $mail->assign('trace', print_r(debug_backtrace(), true)); $mail->send(); $mail = null; } } function sql_export_recordset($f, $rs, $table, $truncate=true) { fwrite($f, "SET NAMES 'utf8';\n"); if ($truncate == true) fwrite($f, "TRUNCATE TABLE `" . sql_escape($table) . "`;\n"); while ($r = sql_fetch_assoc($rs)) { $fields = array(); $values = array(); foreach ($r AS $k => $v) { $fields[] = '`' . sql_escape($k) . '`'; if ($v === null) $values[] = "NULL"; else $values[] = "'" . sql_escape($v) . "'"; } unset($r); fwrite($f, "INSERT INTO `" . sql_escape($table) . "` (" . implode(', ', $fields) . ") VALUES (" . implode(', ', $values) . ");\n"); } } function sql_export_table($f, $table) { $primary = array(); $rsIndex = sql("SHOW INDEX FROM `&1`", $table); while ($r = sql_fetch_assoc($rsIndex)) { if ($r['Key_name'] == 'PRIMARY') { $primary[] = '`' . sql_escape($r['Column_name']) . '` ASC'; } } sql_free_result($rsIndex); $sql = "SELECT * FROM `" . sql_escape($table) . "`"; if (count($primary) > 0) { $sql .= ' ORDER BY ' . implode(', ', $primary); } $rs = sql($sql); sql_export_recordset($f, $rs, $table); sql_free_result($rs); } function sql_export_tables_to_file($filename, $tables) { $f = fopen($filename, 'w'); fwrite($f, "-- Content of tables:\n"); foreach ($tables AS $t) fwrite($f, "-- $t\n"); fwrite($f, "\n"); foreach ($tables AS $t) { fwrite($f, "-- Table $t\n"); sql_export_table($f, $t); fwrite($f, "\n"); } fclose($f); } function sql_export_table_to_file($filename, $table) { $f = fopen($filename, 'w'); sql_export_table($f, $table); fclose($f); } function sql_export_structure($f, $table) { $rs = sql("SHOW CREATE TABLE `&1`", $table); $r = sql_fetch_array($rs); sql_free_result($rs); $sTableSql = $r[1]; $sTableSql = preg_replace('/ AUTO_INCREMENT=[0-9]{1,} /', ' ', $sTableSql); fwrite($f, "SET NAMES 'utf8';\n"); fwrite($f, "DROP TABLE IF EXISTS `" . sql_escape($table) . "`;\n"); fwrite($f, $sTableSql . " ;\n"); } function sql_export_structure_to_file($filename, $table) { $f = fopen($filename, 'w'); sql_export_structure($f, $table); fclose($f); } ?>