* @since 06 Mar 2006 16:41:32
*/
public function escapeString($string)
{
if (!$this->_connected) {
return false;
}
return mysql_real_escape_string($string, $this->dbh);
}
/**
* A wrapper for mysql_query. Allows us to set the database link_identifier,
* to trap errors and ease debugging.
*
* @param string $query The SQL query to execute
* @param bool $debug If true, prints debugging info
* @return resource Query identifier
*/
public function query($query, $debug=false)
{
$app =& App::getInstance();
if (!$this->_connected) {
return false;
}
$this->_query_count++;
$debugqry = preg_replace('/\n[\t ]+/' . $app->getParam('preg_u'), "\n", $query);
if ($this->getParam('db_always_debug') || $debug) {
if ($debug > 1) {
dump($debugqry, true, SC_DUMP_PRINT_R, __FILE__, __LINE__);
} else {
echo "\n";
}
}
// Ensure we have an active connection.
// If we continue on a dead connection we might experience a "MySQL server has gone away" error.
// http://dev.mysql.com/doc/refman/5.0/en/gone-away.html
if (!mysql_ping($this->dbh)) {
$app->logMsg(sprintf('MySQL ping failed; reconnecting… ("%s")', truncate(trim($debugqry), 150)), LOG_DEBUG, __FILE__, __LINE__);
$this->reconnect();
}
// Execute!
$qid = mysql_query($query, $this->dbh);
// Error checking.
if (!$qid || mysql_error($this->dbh)) {
$app->logMsg(sprintf('MySQL error %s: %s in query: %s', mysql_errno($this->dbh), mysql_error($this->dbh), $debugqry), LOG_EMERG, __FILE__, __LINE__);
if ($this->getParam('db_debug')) {
if (!$app->isCLI()) {
echo '' . wordwrap(mysql_error($this->dbh)) . '
' . htmlspecialchars($debugqry) . '
';
}
}
// Die if db_die_on_failure = true, or just continue without connection
return $this->_fail();
}
return $qid;
}
/**
* Loads a list of tables in the current database into an array, and returns
* true if the requested table is found. Use this function to enable/disable
* functionality based upon the current available db tables or to dynamically
* create tables if missing.
*
* @param string $table The name of the table to search.
* @param bool $use_cached_results Get fresh table info (in case DB changed).
* @return bool true if given $table exists.
*/
public function tableExists($table, $use_cached_results=true)
{
$app =& App::getInstance();
if (!$this->_connected) {
return false;
}
if (is_null(self::$existing_tables) || !$use_cached_results) {
self::$existing_tables = array();
$qid = $this->query("SHOW TABLES");
while (list($row) = mysql_fetch_row($qid)) {
self::$existing_tables[] = $row;
}
}
if (in_array($table, self::$existing_tables)) {
return true;
} else {
$app->logMsg(sprintf('Nonexistent DB table: %s.%s', $this->getParam('db_name'), $table), LOG_INFO, __FILE__, __LINE__);
return false;
}
}
/**
* Tests if the given array of columns exists in the specified table.
*
* @param string $table The name of the table to search.
* @param array $columns An array of column names.
* @param bool $strict Exact schema match. If TRUE, test if *only* the given columns exist. If FALSE, test if given columns exist (possibly amongst others).
* @param bool $use_cached_results Get fresh table info (in case DB changed).
* @return bool true if column(s) exist.
*/
public function columnExists($table, $columns, $strict=true, $use_cached_results=true)
{
$app =& App::getInstance();
if (!$this->_connected) {
$app->logMsg(sprintf('No DB connection to run %s', __METHOD__), LOG_NOTICE, __FILE__, __LINE__);
return false;
}
// Ensure the table exists.
if (!$this->tableExists($table, $use_cached_results)) {
$app->logMsg(sprintf('Table does not exist: %s', $table), LOG_NOTICE, __FILE__, __LINE__);
return false;
}
// For single-value columns.
if (!is_array($columns)) {
$columns = array($columns);
}
if (!isset(self::$table_columns[$table]) || !$use_cached_results) {
// Populate and cache array of current columns for this table.
self::$table_columns[$table] = array();
$qid = $this->query("DESCRIBE $table");
while ($row = mysql_fetch_row($qid)) {
self::$table_columns[$table][] = $row[0];
}
}
if ($strict) {
// Do an exact comparison of table schemas.
sort($columns);
sort(self::$table_columns[$table]);
return self::$table_columns[$table] == $columns;
} else {
// Only check that the specified columns are available in the table.
$match_columns = array_intersect(self::$table_columns[$table], $columns);
sort($columns);
sort($match_columns);
return $match_columns == $columns;
}
}
/*
* Return the total number of queries executed thus far.
*
* @access public
* @return int Number of queries
* @author Quinn Comendant
* @version 1.0
* @since 15 Jun 2006 11:46:05
*/
public function numQueries()
{
return $this->_query_count;
}
/**
* Reset cached items.
*
* @access public
* @author Quinn Comendant
* @since 28 Aug 2005 22:10:50
*/
public function resetCache()
{
self::$existing_tables = null;
self::$table_columns = null;
}
/**
* Returns the values of an ENUM or SET column, returning them as an array.
*
* @param string $db_table database table to lookup
* @param string $db_col database column to lookup
* @param bool $sort Sort the output.
* @return array Array of the set/enum values on success, false on failure.
*/
public function getEnumValues($db_table, $db_col, $sort=false)
{
$app =& App::getInstance();
$qid = $this->query("SHOW COLUMNS FROM " . $this->escapeString($db_table) . " LIKE '" . $this->escapeString($db_col) . "'", false);
$row = mysql_fetch_row($qid);
if (preg_match('/^enum|^set/i', $row[1]) && preg_match_all("/'([^']*)'/", $row[1], $matches)) {
if ($sort) {
natsort($matches[1]);
}
return $matches[1];
} else {
$app->logMsg(sprintf('No set or enum fields found in %s.%s', $db_table, $db_col), LOG_ERR, __FILE__, __LINE__);
return false;
}
}
} // End.