0byt3m1n1
Path:
/
data
/
applications
/
aps.bak
/
webcalendar
/
1.2.0-4
/
standard
/
htdocs
/
includes
/
[
Home
]
File: dbi4php.php
<?php /* dbi4php - Generic database access for PHP * * The functions defined in this file are meant to provide a single API to the * different PHP database APIs. Unfortunately, this is necessary since PHP does * not yet have a common db API. The value of <var>$GLOBALS['db_type']</var> * should be defined somewhere to one of the following: * - mysql * - mysqli * - mssql * - oracle (This uses the Oracle8 OCI API, so Oracle 8 libs are required) * - postgresql * - odbc * - ibase (Interbase) * - sqlite * - ibm_db2 * * <b>Limitations:</b> * - This assumes a single connection to a single database for the sake of * simplicity. Do not make a new connection until you are completely * finished with the previous one. However, you can execute more than query * at the same time. * - Rather than use the associative arrays returned with xxx_fetch_array (), * normal arrays are used with xxx_fetch_row (). (Some db APIs don't support * xxx_fetch_array ().) * * @author Craig Knudsen <cknudsen@cknudsen.com> * @copyright Craig Knudsen, <cknudsen@cknudsen.com>, http://www.k5n.us/cknudsen * @license http://www.gnu.org/licenses/lgpl.html GNU LGPL * @version $Id: dbi4php.php,v 1.26.2.4 2007/10/31 19:39:29 umcesrjones Exp $ * @package WebCalendar * * History: * See ChangeLog * * License: * Copyright (C) 2006 Craig Knudsen * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, * or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301, USA */ /* Opens up a database connection. * * Use a pooled connection if the db supports it and * the <var>db_persistent</var> setting is enabled. * * <b>Notes:</b> * - The database type is determined by the global variable * <var>db_type</var> * - For ODBC, <var>$host</var> is ignored, <var>$database</var> = DSN * - For Oracle, <var>$database</var> = tnsnames name * - Use the {@link dbi_error ()} function to get error information * if the connection fails. * * @param string $host Hostname of database server * @param string $login Database login * @param string $password Database login password * @param string $database Name of database * @param string $lazy Wait until a query to connect? * * @return resource The connection */ function dbi_connect ( $host, $login, $password, $database, $lazy = true ) { global $db_cache_count, $db_connection_info, $db_query_count, $old_textlimit, $old_textsize, $db_sqlite_error_str; $db_cache_count = $db_query_count = 0; if ( ! isset ( $db_connection_info ) ) $db_connection_info = array (); $db_connection_info['connected'] = false; $db_connection_info['connection'] = 0; $db_connection_info['database'] = $database; $db_connection_info['host'] = $host; $db_connection_info['login'] = $login; $db_connection_info['password'] = $password; // mysqli requires $db_connection_info['connection'] to be set if ( strcmp ( $GLOBALS['db_type'], 'mysqli' ) == 0 ) $lazy == false; // Lazy connections... do not connect until 1st call to dbi_query. if ( $lazy ) // echo "<!-- Waiting on db connection made (lazy) -->\nRETURN!<br />"; return true; if ( strcmp ( $GLOBALS['db_type'], 'mysql' ) == 0 ) { $c = ( $GLOBALS['db_persistent'] ? mysql_pconnect ( $host, $login, $password ) : mysql_connect ( $host, $login, $password ) ); if ( $c ) { if ( ! mysql_select_db ( $database ) ) return false; $db_connection_info['connected'] = true; $db_connection_info['connection'] = $c; return $c; } else return false; } elseif ( strcmp ( $GLOBALS['db_type'], 'mysqli' ) == 0 ) { $c = new mysqli( $host, $login, $password, $database ); if ( $c ) { if ( mysqli_connect_errno() && ! empty ( $database ) ) return false; $db_connection_info['connected'] = true; $db_connection_info['connection'] = $GLOBALS['db_connection'] = $c; return $c; } else return false; } elseif ( strcmp ( $GLOBALS['db_type'], 'mssql' ) == 0 ) { static $old_textlimit, $old_textsize; $old_textlimit = ini_get ( 'mssql.textlimit' ); $old_textsize = ini_get ( 'mssql.textsize' ); ini_set ( 'mssql.textlimit', '2147483647' ); ini_set ( 'mssql.textsize', '2147483647' ); $c = ( $GLOBALS['db_persistent'] ? mssql_pconnect ( $host, $login, $password ) : mssql_connect ( $host, $login, $password ) ); if ( $c ) { if ( ! mssql_select_db ( $database ) ) return false; $db_connection_info['connected'] = true; $db_connection_info['connection'] = $c; return $c; } else return false; } elseif ( strcmp ( $GLOBALS['db_type'], 'oracle' ) == 0 ) { $_ora_conn_func = 'OCI' . ( $GLOBALS['db_persistent'] ? 'P' : '' ) . 'Logon'; $c = $_ora_conn_func ( $login, $password, ( strlen ( $host ) && strcmp ( $host, 'localhost' ) ? '(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP) (HOST = ' . $host . ' ) (PORT = 1521))) (CONNECT_DATA = (SID = ' . $database . ' )))' : $database ) ); unset ( $_ora_conn_func ); $db_connection_info['connected'] = true; $db_connection_info['connection'] = $GLOBALS['oracle_connection'] = $c; return $c; } elseif ( strcmp ( $GLOBALS['db_type'], 'postgresql' ) == 0 ) { $dbargs = ( strlen ( $host ) ? 'host=' . "$host " : '' ) . 'dbname=' . $database . ' user=' . $login . ( strlen ( $password ) ? ' password=' . $password : '' ); $c = ( $GLOBALS['db_persistent'] ? pg_pconnect ( $dbargs ) : pg_connect ( $dbargs ) ); $GLOBALS['postgresql_connection'] = $c; if ( ! $c ) return false; $db_connection_info['connected'] = true; $db_connection_info['connection'] = $c; return $c; } elseif ( strcmp ( $GLOBALS['db_type'], 'odbc' ) == 0 ) { $c = ( $GLOBALS['db_persistent'] ? odbc_pconnect ( $database, $login, $password ) : odbc_connect ( $database, $login, $password ) ); $db_connection_info['connected'] = true; $db_connection_info['connection'] = $GLOBALS['odbc_connection'] = $c; return $c; } elseif ( strcmp ( $GLOBALS['db_type'], 'ibm_db2' ) == 0 ) { $c = ( $GLOBALS['db_persistent'] ? db2_pconnect ( $database, $login, $password ) : db2_connect ( $database, $login, $password ) ); $db_connection_info['connected'] = true; $db_connection_info['connection'] = $GLOBALS['ibm_db2_connection'] = $c; return $c; } elseif ( strcmp ( $GLOBALS['db_type'], 'ibase' ) == 0 ) { $host = $host . ':' . $database; $c = ( $GLOBALS['db_persistent'] ? ibase_pconnect ( $host, $login, $password ) : ibase_connect ( $host, $login, $password ) ); $db_connection_info['connected'] = true; $db_connection_info['connection'] = $c; return $c; } elseif ( strcmp ( $GLOBALS['db_type'], 'sqlite' ) == 0 ) { $c = ( $GLOBALS['db_persistent'] ? sqlite_popen ( $database, 0666, $db_sqlite_error_str ) : sqlite_open ( $database, 0666, $db_sqlite_error_str ) ); if ( ! $c ) { echo translate ( 'Error connecting to database' ) . ": " . $db_sqlite_error_str . ".\n"; exit; } $db_connection_info['connected'] = true; $db_connection_info['connection'] = $GLOBALS['sqlite_c'] = $c; return $c; } else dbi_fatal_error ( 'dbi_connect (): ' . ( empty ( $GLOBALS['db_type'] ) ? translate ( 'db_type not defined.' ) : translate ( 'invalid db_type' ) . ' ' . $GLOBALS['db_type'] . '.' ) ); } /* Closes a database connection. * * This is not necessary for any database that uses pooled connections, such as * MySQL, but a good programming practice. * * @param resource $conn The database connection. * * @return bool True on success, false on error. */ function dbi_close ( $conn ) { global $db_connection_info, $db_query_count, $old_textlimit, $old_textsize, $SQLLOG; if ( is_array ( $db_connection_info ) ) { if ( ! $db_connection_info['connected'] ) // never connected // echo '<!-- No db connection made (cached) -->' . "\n"; return true; else { $conn = $db_connection_info['connection']; $db_connection_info['connected'] = false; $db_connection_info['connection'] = 0; // echo '<!-- Closing lazy db connection made after ' $db_query_count . " queries -->\n"; } } if ( strcmp ( $GLOBALS['db_type'], 'mysql' ) == 0 ) return mysql_close ( $conn ); elseif ( strcmp ( $GLOBALS['db_type'], 'mysqli' ) == 0 ) return $conn->close(); elseif ( strcmp ( $GLOBALS['db_type'], 'mssql' ) == 0 ) { if ( ! empty ( $old_textlimit ) ) { ini_set ( 'mssql.textlimit', $old_textlimit ); ini_set ( 'mssql.textsize', $old_textsize ); } return mssql_close ( $conn ); } elseif ( strcmp ( $GLOBALS['db_type'], 'oracle' ) == 0 ) return OCILogOff ( $conn ); elseif ( strcmp ( $GLOBALS['db_type'], 'postgresql' ) == 0 ) return pg_close ( $GLOBALS['postgresql_connection'] ); elseif ( strcmp ( $GLOBALS['db_type'], 'odbc' ) == 0 ) return odbc_close ( $GLOBALS['odbc_connection'] ); elseif ( strcmp ( $GLOBALS['db_type'], 'ibm_db2' ) == 0 ) return db2_close ( $GLOBALS['ibm_db2_connection'] ); elseif ( strcmp ( $GLOBALS['db_type'], 'ibase' ) == 0 ) return ibase_close ( $conn ); elseif ( strcmp ( $GLOBALS['db_type'], 'sqlite' ) == 0 ) return sqlite_close ( $conn ); else dbi_fatal_error ( 'dbi_close (): ' . translate ( 'db_type not defined.' ) ); } /* Return the number of database queries that were executed. * (This does not included cached queries.) */ function dbi_num_queries () { global $db_query_count; return $db_query_count; } /* Return the number of queries that were cached. */ function dbi_num_cached_queries () { global $db_cache_count; return $db_cache_count; } /* Executes an SQL query. * * <b>Note:</b> Use the {@link dbi_error ()} function to get error information * if the connection fails. * * @param string $sql SQL of query to execute. * @param bool $fatalOnError Abort execution if there is a database error? * @param bool $showError Display error to user (including possibly the * SQL) if there is a database error? * * @return mixed The query result resource on queries (which can then be * passed to the {@link dbi_fetch_row ()} function to obtain the * results), or true/false on insert or delete queries. */ function dbi_query ( $sql, $fatalOnError = true, $showError = true ) { global $c, $db_connection_info, $db_query_count, $phpdbiVerbose, $SQLLOG; if ( ! isset ( $SQLLOG ) && ! empty ( $db_connection_info['debug'] ) ) $SQLLOG = array (); if ( ! empty ( $db_connection_info['debug'] ) ) $SQLLOG[] = $sql; // echo "dbi_query!: " . htmlentities ( $sql ) . "<br />"; // Connect now if not connected. if ( is_array ( $db_connection_info ) && ! $db_connection_info['connected'] ) { $c = dbi_connect ( $db_connection_info['host'], $db_connection_info['login'], $db_connection_info['password'], $db_connection_info['database'], false// * not lazy ); $db_connection_info['connected'] = true; $db_connection_info['connection'] = $c; // echo '<!-- Created delayed db connection (lazy) -->' . "\n"; } $db_query_count++; // If caching is enabled, then clear out the cache for any request // that may update the datatabase. if ( ! empty ( $db_connection_info['cachedir'] ) ) { if ( ! preg_match ( '/^select/i', $sql ) ) { dbi_clear_cache (); if ( ! empty ( $db_connection_info['debug'] ) ) $SQLLOG[] = translate ( 'Cache cleared from previous SQL!' ); } } // do_debug ( "SQL:" . $sql); $found_db_type = false; if ( strcmp ( $GLOBALS['db_type'], 'mysql' ) == 0 ) { $found_db_type = true; $res = mysql_query ( $sql, $db_connection_info['connection'] ); } elseif ( strcmp ( $GLOBALS['db_type'], 'mysqli' ) == 0 ) { $found_db_type = true; $res = $GLOBALS['db_connection']->query( $sql ); } elseif ( strcmp ( $GLOBALS['db_type'], 'mssql' ) == 0 ) { $found_db_type = true; $res = mssql_query ( $sql ); } elseif ( strcmp ( $GLOBALS['db_type'], 'oracle' ) == 0 ) { if ( false === $GLOBALS['oracle_statement'] = OCIParse ( $GLOBALS['oracle_connection'], $sql ) ) dbi_fatal_error ( translate ( 'Error executing query.' ) . $phpdbiVerbose ? ( dbi_error () . "\n\n<br />\n" . $sql ) : '' . '', $fatalOnError, $showError ); return OCIExecute ( $GLOBALS['oracle_statement'], OCI_COMMIT_ON_SUCCESS ); } elseif ( strcmp ( $GLOBALS['db_type'], 'postgresql' ) == 0 ) { $found_db_type = true; $res = pg_exec ( $GLOBALS['postgresql_connection'], $sql ); } elseif ( strcmp ( $GLOBALS['db_type'], 'odbc' ) == 0 ) return odbc_exec ( $GLOBALS['odbc_connection'], $sql ); elseif ( strcmp ( $GLOBALS['db_type'], "ibm_db2" ) == 0 ) { $found_db_type = true; $res = db2_exec ( $GLOBALS['ibm_db2_connection'], $sql ); } elseif ( strcmp ( $GLOBALS['db_type'], 'ibase' ) == 0 ) { $found_db_type = true; $res = ibase_query ( $sql ); } elseif ( strcmp ( $GLOBALS['db_type'], 'sqlite' ) == 0 ) { $found_db_type = true; $res = sqlite_query ( $GLOBALS['sqlite_c'], $sql, SQLITE_NUM ); } if ( $found_db_type ) { if ( ! $res ) dbi_fatal_error ( translate ( 'Error executing query.' ) . ( $phpdbiVerbose ? ( dbi_error () . "\n\n<br />\n" . $sql ) : '' ), $fatalOnError, $showError ); return $res; } else dbi_fatal_error ( 'dbi_query (): ' . translate ( 'db_type not defined.' ) ); } /* Retrieves a single row from the database and returns it as an array. * * <b>Note:</b> We don't use the more useful xxx_fetch_array because not all * databases support this function. * * <b>Note:</b> Use the {@link dbi_error ()} function to get error information * if the connection fails. * * @param resource $res The database query resource returned from * the {@link dbi_query ()} function. * * @return mixed An array of database columns representing a single row in * the query result or false on an error. */ function dbi_fetch_row ( $res ) { if ( strcmp ( $GLOBALS['db_type'], 'mysql' ) == 0 ) return mysql_fetch_array ( $res, MYSQL_NUM ); elseif ( strcmp ( $GLOBALS['db_type'], 'mysqli' ) == 0 ) return $res->fetch_array( MYSQLI_NUM ); elseif ( strcmp ( $GLOBALS['db_type'], 'mssql' ) == 0 ) return mssql_fetch_array ( $res ); elseif ( strcmp ( $GLOBALS['db_type'], 'oracle' ) == 0 ) return ( OCIFetchInto ( $GLOBALS['oracle_statement'], $row, OCI_NUM + OCI_RETURN_NULLS ) ? $row : 0 ); elseif ( strcmp ( $GLOBALS['db_type'], 'postgresql' ) == 0 ) { // Note: row became optional in PHP 4.1.0. $r = pg_fetch_array ( $res, null, PGSQL_NUM ); return ( ! $r ? false : $r ); } elseif ( strcmp ( $GLOBALS['db_type'], 'odbc' ) == 0 ) return ( ! odbc_fetch_into ( $res, $ret ) ? false : $ret ); elseif ( strcmp ( $GLOBALS['db_type'], 'ibm_db2' ) == 0 ) return db2_fetch_array ( $res ); elseif ( strcmp ( $GLOBALS['db_type'], 'ibase' ) == 0 ) return ibase_fetch_row ( $res ); elseif ( strcmp ( $GLOBALS['db_type'], 'sqlite' ) == 0 ) return sqlite_fetch_array ( $res ); else dbi_fatal_error ( 'dbi_fetch_row (): ' . translate ( 'db_type not defined.' ) ); } /* Returns the number of rows affected by the last INSERT, UPDATE or DELETE. * * <b>Note:</b> Use the {@link dbi_error ()} function to get error information * if the connection fails. * * @param resource $conn The database connection * @param resource $res The database query resource returned from the * {@link dbi_query ()} function. * * @return int The number or database rows affected. */ function dbi_affected_rows ( $conn, $res ) { if ( strcmp ( $GLOBALS['db_type'], 'mysql' ) == 0 ) return mysql_affected_rows ( $conn ); elseif ( strcmp ( $GLOBALS['db_type'], 'mysqli' ) == 0 ) return $conn->affected_rows; elseif ( strcmp ( $GLOBALS['db_type'], 'mssql' ) == 0 ) return mssql_rows_affected ( $conn ); elseif ( strcmp ( $GLOBALS['db_type'], 'oracle' ) == 0 ) return ( $GLOBALS['oracle_statement'] >= 0 ? OCIRowCount ( $GLOBALS['oracle_statement'] ) : -1 ); elseif ( strcmp ( $GLOBALS['db_type'], 'postgresql' ) == 0 ) return pg_affected_rows ( $res ); elseif ( strcmp ( $GLOBALS['db_type'], 'odbc' ) == 0 ) return odbc_num_rows ( $res ); elseif ( strcmp ( $GLOBALS['db_type'], 'ibm_db2' ) == 0 ) return db2_num_rows ( $res ); elseif ( strcmp ( $GLOBALS['db_type'], 'ibase' ) == 0 ) return ibase_affected_rows ( $conn ); elseif ( strcmp ( $GLOBALS['db_type'], 'sqlite' ) == 0 ) return sqlite_changes ( $conn ); else dbi_fatal_error ( 'dbi_free_result (): ' . translate ( 'db_type not defined.' ) ); } /* Update a BLOB (binary large object) in the database with the contents * of the specified file. * A BLOB field should be created in a separete INSERT statement using * NULL as the initial value prior to this call. * * @param resource $table the table name that contains the blob * @param resource $column the table column name for the blob * @param resource $key the key for updating the table row * @param resource $data the data to insert * * @return bool True on success */ function dbi_update_blob ( $table, $column, $key, $data ) { global $unavail_DBI_Update_blob; $unavail_DBI_Update_blob = str_replace ( 'XXX', '"dbi_update_blob"', translate ( 'Unfortunately, XXX is not implemented for' ) ) . ' (' . $GLOBALS['db_type'] . ').'; assert ( '! empty ( $table )' ); assert ( '! empty ( $column )' ); assert ( '! empty ( $key )' ); assert ( '! empty ( $data )' ); $sql = 'UPDATE ' . $table . ' SET ' . $column; if ( strcmp ( $GLOBALS['db_type'], 'mysql' ) == 0 ) { return dbi_execute ( $sql . ' = \'' . ( function_exists ( 'mysql_real_escape_string' ) ? mysql_real_escape_string ( $data ) : addslashes ( $data ) ) . '\' WHERE ' . $key ); } elseif ( strcmp ( $GLOBALS['db_type'], 'sqlite' ) == 0 ) return dbi_execute ( $sql . ' = \'' . sqlite_udf_encode_binary ( $data ) . '\' WHERE ' . $key ); elseif ( strcmp ( $GLOBALS['db_type'], 'mssql' ) == 0 ) return dbi_execute ( $sql . ' = 0x' . bin2hex ( $data ) . ' WHERE ' . $key ); elseif ( strcmp ( $GLOBALS['db_type'], 'postgresql' ) == 0 ) return dbi_execute ( $sql . ' = \'' . pg_escape_bytea ( $data ) . '\' WHERE ' . $key ); else // TODO! die_miserable_death ( $unavail_DBI_Update_blob ); } /* Get a BLOB (binary large object) from the database. * * @param resource $table the table name that contains the blob * @param resource $column the table column name for the blob * @param resource $key the key for updating the table row * * @return bool True on success */ function dbi_get_blob ( $table, $column, $key ) { global $unavail_DBI_Update_blob; assert ( '! empty ( $table )' ); assert ( '! empty ( $column )' ); assert ( '! empty ( $key )' ); $res = dbi_execute ( 'SELECT ' . $column . ' FROM ' . $table . ' WHERE ' . $key ); if ( ! $res ) return false; $ret = ''; if ( $row = dbi_fetch_row ( $res ) ) { if ( strcmp ( $GLOBALS['db_type'], 'mysql' ) == 0 || strcmp ( $GLOBALS['db_type'], 'mssql' ) == 0 ) $ret = $row[0]; elseif ( strcmp ( $GLOBALS['db_type'], 'sqlite' ) == 0 ) $ret = sqlite_udf_decode_binary ( $row[0] ); elseif ( strcmp ( $GLOBALS['db_type'], 'postgresql' ) == 0 ) $ret = pg_unescape_bytea ( $row[0] ); else // TODO! die_miserable_death ( $unavail_DBI_Update_blob ); } dbi_free_result ( $res ); return $ret; } /* Frees a result set. * * @param resource $res The database query resource returned from * the {@link dbi_query ()} function. * * @return bool True on success */ function dbi_free_result ( $res ) { if ( $res === true ) // Not needed for UPDATE, DELETE, etc return; if ( strcmp ( $GLOBALS['db_type'], 'mysql' ) == 0 ) return mysql_free_result ( $res ); elseif ( strcmp ( $GLOBALS['db_type'], 'mysqli' ) == 0 ) return mysqli_free_result ( $res ); elseif ( strcmp ( $GLOBALS['db_type'], 'mssql' ) == 0 ) return mssql_free_result ( $res ); elseif ( strcmp ( $GLOBALS['db_type'], 'oracle' ) == 0 ) { // Not supported. Ingore. if ( $GLOBALS['oracle_statement'] >= 0 ) { OCIFreeStatement ( $GLOBALS['oracle_statement'] ); $GLOBALS['oracle_statement'] = -1; } } elseif ( strcmp ( $GLOBALS['db_type'], 'postgresql' ) == 0 ) return pg_freeresult ( $res ); elseif ( strcmp ( $GLOBALS['db_type'], 'odbc' ) == 0 ) return odbc_free_result ( $res ); elseif ( strcmp ( $GLOBALS['db_type'], 'ibm_db2' ) == 0 ) return db2_free_result ( $res ); elseif ( strcmp ( $GLOBALS['db_type'], 'ibase' ) == 0 ) return ibase_free_result ( $res ); elseif ( strcmp ( $GLOBALS['db_type'], 'sqlite' ) == 0 ) { // Not supported } else dbi_fatal_error ( 'dbi_free_result (): ' . translate ( 'db_type not defined.' ) ); } /* Gets the latest database error message. * * @return string The text of the last database error. (The type of information * varies depending on which type of database is being used.) */ function dbi_error () { if ( strcmp ( $GLOBALS['db_type'], 'mysql' ) == 0 ) $ret = mysql_error (); elseif ( strcmp ( $GLOBALS['db_type'], 'mysqli' ) == 0 ) $ret = $GLOBALS['db_connection']->error; elseif ( strcmp ( $GLOBALS['db_type'], 'mssql' ) == 0 ) // No real mssql_error function. This is as good as it gets. $ret = mssql_get_last_message (); elseif ( strcmp ( $GLOBALS['db_type'], 'oracle' ) == 0 ) $ret = OCIError ( $GLOBALS['oracle_connection'] ); elseif ( strcmp ( $GLOBALS['db_type'], 'postgresql' ) == 0 ) $ret = pg_errormessage ( $GLOBALS['postgresql_connection'] ); elseif ( strcmp ( $GLOBALS['db_type'], 'odbc' ) == 0 ) // No way to get error from ODBC API. $ret = translate ( 'Unknown ODBC error.' ); elseif ( strcmp ( $GLOBALS['db_type'], 'ibase' ) == 0 ) $ret = ibase_errmsg (); elseif ( strcmp ( $GLOBALS['db_type'], "ibm_db2" ) == 0 ) { $ret = db2_conn_errormsg (); if ( $ret == '' ) $ret = db2_stmt_errormsg (); } elseif ( strcmp ( $GLOBALS['db_type'], 'sqlite' ) == 0 ) { if ( empty ( $GLOBALS['db_sqlite_error_str'] ) ) { $ret = sqlite_last_error ( $GLOBALS['sqlite_c'] ); } else { $ret = $GLOBALS['db_sqlite_error_str']; $GLOBALS['db_sqlite_error_str'] = ''; } } else $ret = 'dbi_error (): ' . translate ( 'db_type not defined.' ); return ( strlen ( $ret ) ? $ret : translate ( 'Unknown error.' ) ); } /* Displays a fatal database error and aborts execution. * * @param string $msg The database error message. * @param bool $doExit Abort execution? * @param bool $showError Show the details of the error (possibly including * the SQL that caused the error)? */ function dbi_fatal_error ( $msg, $doExit = true, $showError = true ) { if ( $showError ) { echo '<h2>' . translate ( 'Error' ) . '</h2> <!--begin_error (dbierror)--> ' . $msg . ' <!--end_error--> '; } if ( $doExit ) exit; } /* Escapes a string accordingly to the DB type. * * @param string $string SQL of query to execute * * @return string The escaped string */ function dbi_escape_string ( $string ) { global $db_connection_info; // Return the string in original form; all possible escapings by // magic_quotes_gpc (and possibly magic_quotes_sybase) will be rolled back. // But, also, we may roll back escaping we have done ourselves. // (maybe this should be removed) // if ( get_magic_quotes_gpc () ) $string = stripslashes ( $string ); switch ( $GLOBALS['db_type'] ) { case 'mysql': // MySQL requires an active connection. return ( empty ( $db_connection_info['connected'] ) ? addslashes ( $string ) : ( version_compare ( phpversion (), '4.3.0' ) >= 0 ? mysql_real_escape_string ( $string, $db_connection_info['connection'] ) : mysql_escape_string ( $string ) ) ); case 'mysqli': return ( empty ( $db_connection_info['connected'] ) ? addslashes ( $string ) : $db_connection_info['connection']->real_escape_string ( $string ) ); case 'ibase': case 'mssql': case 'oracle': return str_replace ( "'", "''", $string ); case 'postgresql': return pg_escape_string ( $string ); case 'sqlite': return sqlite_escape_string ( $string ); case 'ibm_db2': case 'odbc': default: return addslashes ( $string ); } } /* Executes a SQL query, supporting parameter binding in the ?-style * * <b>Note:</b> Use the {@link dbi_error ()} function to get error information * if the connection fails. * * @param string $sql SQL of query to execute. * May contain ?-placeholders * @param array $params An array containing the values to put in * placeolders. These values will be escaped with * dbi_escape_string () and will be put in single * quotes. A NULL param will be replaced with NULL * without quotes around it. * @param bool $fatalOnError Abort execution if there is a database error? * @param bool $showError Display error to user (including possibly the * SQL) if there is a database error? * * @return mixed The query result resource on queries (which can then be passed * to the {@link dbi_fetch_row ()} function to obtain the * results), or true/false on insert or delete queries. */ function dbi_execute ( $sql, $params = array (), $fatalOnError = true, $showError = true ) { if ( count ( $params ) == 0 ) return dbi_query ( $sql, $fatalOnError, $showError ); $prepared = ''; $offset = $phindex = 0; while ( ( $pos = strpos ( $sql, '?', $offset ) ) !== false ) { $prepared .= substr ( $sql, $offset, $pos - $offset ) . ( ( is_null ( $params[ $phindex ] ) ) ? "NULL" : ( "'" . dbi_escape_string ( $params[ $phindex ] ) . "'" ) ); $offset = $pos + 1; $phindex++; } $prepared .= substr ( $sql, $offset ); return dbi_query ( $prepared, $fatalOnError, $showError ); } /* Execute a SQL query. First, look to see if the results of this query are in * a cache. If they are, then return them. If not, then run the query and store * them in the cache. Of course, caching is only performed for SELECT queries. * Anything other than that will clear out the entire cache * (until we add more intelligent caching logic). */ function dbi_get_cached_rows ( $sql, $params = array (), $fatalOnError = true, $showError = true ) { global $db_cache_count, $db_connection_info; $file = ''; $save_query = false; if ( ! empty ( $db_connection_info['cachedir'] ) && function_exists ( 'file_get_contents' ) ) { // Cache enabled. Add some sire specific info to avoid cross-site data //sharing $hash = md5 ( $db_connection_info['database'] . $db_connection_info['password'] .$sql . serialize ( $params ) ); $file = $db_connection_info['cachedir'] . '/' . $hash . '.dat'; if ( file_exists ( $file ) ) { $db_cache_count++; return unserialize ( file_get_contents ( $file ) ); } $save_query = true; } $res = dbi_execute ( $sql, $params, $fatalOnError, $showError ); if ( $res ) { $rows = array (); while ( $row = dbi_fetch_row ( $res ) ) { $rows[] = $row; } dbi_free_result ( $res ); // Serialize and save in cache for later use. if ( ! empty ( $file ) && $save_query ) { $fd = @fopen ( $file, 'w+b', false ); if ( empty ( $fd ) ) { if ( function_exists ( "translate" ) ) { dbi_fatal_error ( translate ( 'Cache error' ) . ': ' . str_replace ( 'XXX', translate ( 'write' ), translate ( 'Could not XXX file' ) ) . " $file." ); } else { dbi_fatal_error ( 'Cache error' . ': ' . str_replace ( 'XXX', 'write', 'Could not XXX file' ) . " $file." ); } } fwrite ( $fd, serialize ( $rows ) ); fclose ( $fd ); chmod ( $file, 0666 ); } return $rows; } else return false; } /* Specify the location of the cache directory. * This directory will need to world-writable if this is a web-based application. */ function dbi_init_cache ( $dir ) { global $db_connection_info; if ( ! isset ( $db_connection_info ) ) $db_connection_info = array (); $db_connection_info['cachedir'] = $dir; } /* Enable SQL debugging. * This will keep an array of all SQL queries in the global variable $SQLLOG. */ function dbi_set_debug ( $status = false ) { global $db_connection_info; if ( ! isset ( $db_connection_info ) ) $db_connection_info = array (); $db_connection_info['debug'] = $status; } /* Get the SQL debug status. */ function dbi_get_debug () { global $db_connection_info; return ( ! isset ( $db_connection_info ) ? false : ( ! empty ( $db_connection_info['debug'] ) ) ); } /* Clear out the db cache. * Return the number of files deleted. */ function dbi_clear_cache () { global $db_connection_info; if ( empty ( $db_connection_info['cachedir'] ) ) return 0; $cnt = 0; $fd = @opendir ( $db_connection_info['cachedir'] ); if ( empty ( $fd ) ) dbi_fatal_error ( translate ( 'Error opening cache dir' ) . ': ' . $db_connection_info['cachedir'] ); $b = 0; while ( false !== ( $file = readdir ( $fd ) ) ) { if ( preg_match ( '/^\S\S\S\S\S\S\S\S\S\S+.dat$/', $file ) ) { // echo 'Deleting ' . $file . '<br />'; $cnt++; $fullpath = $db_connection_info['cachedir'] . '/' . $file; $b += filesize ( $fullpath ); if ( ! unlink ( $fullpath ) ) echo '<!-- ' . translate ( 'Error' ) . ': ' . str_replace ( 'XXX', translate ( 'delete' ), translate ( 'Could not XXX file' ) ) . " $file. -->\n"; // TODO: log this somewhere??? } } return $cnt; } ?>