<?php /* ** $Id$ ** ** ITools - the Internet Tools Library ** ** Copyright (C) 1995-2003 by the ITools Authors. ** This program is free software; you can redistribute it and/or ** modify it under the terms of either the GNU General Public License ** or the GNU Lesser General Public License, as published by the Free ** Software Foundation. See http://www.gnu.org/licenses/ for details. ** ** it_db.class - Generic Database class, currently using mysql. ** ** This tries to be as efficient as possible by maintaining ** persistent database connections. */ /** * Functions to handle SQL databases * @see it_db_table, it_db_record */ class it_db { /* public */ var $host; /* Database host */ var $host_update=''; /* Optional database host for updates */ var $name; /* Name of database */ var $numtables; /* Number of tables in databasee or 0 if not known */ var $tablenames = array(); /* Array(0..$numtables) of table names */ /* private */ var $link; /* MySQL Link Identifier */ var $username; /* MySQL username (if $updatehost) */ var $password; /* MySQL password (if $updatehost) */ /** * Constructor: connect to MySQL server and select database * @param $databasename name of the database to select or empty for default * @param $username username to connect with * @param $password password to connect with * @param $host Optional name of the host to connect to * @param $host_update Optional name of the host for updates (writes) */ function it_db($databasename, $username, $password, $host='localhost', $host_update='') { if (empty($databasename)) $databasename = strtr(ereg_replace('^www.', '', strtolower(ereg_replace(':.*$', '', getenv('HTTP_HOST')))), '.', '_'); if ($this->link = @mysql_connect($host, $username, $password, true)) { if (mysql_select_db($databasename, $this->link)) { $this->host = $host; $this->name = $databasename; } else internal_error("Can't select database \"$databasename\" on host \"$host\"."); } else internal_error("Can't connect to database server \"$host\" as user \"$username\"."); if ($host_update) { $this->host_update = $host_update; $this->username = $username; $this->password = $password; } } /** * Perform an SQL query. * @see ::safe_sql_query, mysql_query * @param $sql SQL query * @return SQL handle or false in case of failure */ function sql_query($sql) { debug("it_db::sql_query($sql) on {$this->host}", 5); /* ** If we have a special update host, and an update operation is to be ** performed, we switch to this host. And we stay forever and ever and ever... */ if ($this->host_update && eregi('^(UPDATE|INSERT|REPLACE|DELETE|ALTER) ', $sql)) { /*debug('it_db::sql_query(): switching to update host "'.$this->host_update.'"', 3); */ if ($this->link = @mysql_connect($this->host_update, $this->username, $this->password, true)) { if (mysql_select_db($this->name, $this->link)) $this->host = $this->host_update; else internal_error('Error selecting update database "'.$this->name.'" on host "'.$this->host_update.'".'); $this->host_update=''; } else internal_error('Error connecting to update database server "'.$this->host_update.'" as user "'.$this->username.'".'); } return mysql_query($sql, $this->link); } /** * Perform an SQL query. If the query fails, issue an error message * and terminate program execution. No matching rows does not mean failure. * @see ::sql_query, mysql_query * @param $sql SQL query * @return SQL handle */ function safe_sql_query($sql) { /* debug("it_db::safe_sql_query($sql)", 4); */ if ($result = $this->sql_query($sql)) return $result; else { if ($this->errno() == 1062) /* Duplicate entry */ return 0; fail('SQL-Query db "'.$this->name.'" host "'.$this->host."\" failed: \"$sql\":<br>".$this->error().' ('.$this->errno().')'); } } /** * Free resources used by SQL handle * @see mysql_free_result * @param $handle SQL handle * @return */ function free($handle) { return mysql_free_result($handle); } /** * Fetch a row as an array * @see mysql_fetch_array * @param $handle SQL handle * @return numeric & associative array with contents of table row */ function fetch_array($handle) { return mysql_fetch_array($handle); } /** * Fetch a row as an associative array * @see mysql_fetch_array * @param $handle SQL handle * @return associative array with contents of table row */ function fetch_assoc($handle) { return mysql_fetch_assoc($handle); } /** * Return number of rows of a query * @see mysql_num_rows * @param $handle SQL handle * @return number of rows the query returned */ function num_rows($handle) { return mysql_num_rows($handle); } /** * Return number of found rows of a limited query that had SQL_COUNT_FOUND_ROWS set * @return number of rows the query would have returned without LIMIT */ function found_rows() { list($count) = mysql_fetch_row($this->safe_sql_query('SELECT FOUND_ROWS()')); return intval($count); } /* Internal: get information about tables */ function _get_table_info() { if ($this->numtables > 0) /* Already done! */ return; if(($tables = mysql_list_tables($this->name,$this->link)) >= 0) { $this->numtables = mysql_numrows($tables); for ($i=0; $i < $this->numtables; ++$i) { $name = mysql_tablename($tables, $i); $this->tablenames[$i] = $name; } } else internal_error("mysql_list_tables($this->name,$this->link) failed."); } /** * Return a list of all table names of this database * @return array with tablenames of this Database */ function table_names() { $this->_get_table_info(); return $this->tablenames; } /** * Return number of tables in this database */ function num_tables() { $this->_get_table_info(); return $this->numtables; } /** * Return last error number * @see ::sql_query, ::safe_sql_query, mysql_errno * @return last mySQL error number */ function errno() { return mysql_errno($this->link); } /** * Return last error string * @see ::sql_query, ::safe_sql_query, mysql_error * @return last mySQL error message */ function error() { return mysql_error($this->link); } } /* End class it_db */ ?>