Viewing file: ibase.php (67.84 KB) -rw-rw-rw- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php // +----------------------------------------------------------------------+ // | PHP Version 4 | // +----------------------------------------------------------------------+ // | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, | // | Stig. S. Bakken, Lukas Smith | // | All rights reserved. | // +----------------------------------------------------------------------+ // | MDB is a merge of PEAR DB and Metabases that provides a unified DB | // | API as well as database abstraction for PHP applications. | // | This LICENSE is in the BSD license style. | // | | // | Redistribution and use in source and binary forms, with or without | // | modification, are permitted provided that the following conditions | // | are met: | // | | // | Redistributions of source code must retain the above copyright | // | notice, this list of conditions and the following disclaimer. | // | | // | Redistributions in binary form must reproduce the above copyright | // | notice, this list of conditions and the following disclaimer in the | // | documentation and/or other materials provided with the distribution. | // | | // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, | // | Lukas Smith nor the names of his contributors may be used to endorse | // | or promote products derived from this software without specific prior| // | written permission. | // | | // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS| // | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY| // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | // | POSSIBILITY OF SUCH DAMAGE. | // +----------------------------------------------------------------------+ // | Author: Lorenzo Alberton <l.alberton@quipo.it> | // +----------------------------------------------------------------------+ // // $Id: ibase.php,v 1.9.4.29 2004/03/31 20:00:55 quipo Exp $
require_once 'MDB/Common.php';
/** * MDB FireBird/InterBase driver * * Notes: * - when fetching in associative mode all keys are lowercased. * * - Currently, the driver relies on the Interbase server to use SQL dialect 3 * that was introduced with Interbase 6. Some versions of Interbase server, * like the Super Server, do not seem to work by default with dialect 3. * This may lead to errors when trying to create tables using Interbase SQL * data types that are only available when using this dialect version. * * - Interbase does not support per field index sorting support. Indexes are * either ascending, descending or both even when they are defined from more * than one field. Currently Metabase Interbase driver uses the index sorting * type given by the first field of the index for which it is specified the * sorting type. * * - The numRows method is emulated by fetching all the rows into memory. * Avoid using it if for queries with large result sets. * * - Interbase does not provide direct support for returning result sets restrictedto a given range. Such support is emulated in the MDB ibase driver. * * - Current Interbase versions do not support altering table field DEFAULT * values and NOT NULL constraint. Text fields' length may only be raised in * increments defined by Interbase, so the Metabase Interbase does not support * altering text field length yet. * * - createDatabase and dropDatabase are not supported * * - MDB creates Interbase blobs before executing a prepared queries to insert * or update large object fields. If such queries fail to execute, MDB * Interbase driver class is not able to reclaim the database space allocated * for the large object values because there is currently no PHP function to do so. * * @package MDB * @category Database * @author Lorenzo Alberton <l.alberton@quipo.it> */
class MDB_ibase extends MDB_Common { var $connection = 0; var $connected_host; var $connected_port; var $selected_database = ''; var $selected_database_file = ''; var $opened_persistent = ''; var $transaction_id = 0;
var $escape_quotes = "'"; var $decimal_factor = 1.0;
var $results = array(); var $current_row = array(); var $columns = array(); var $rows = array(); var $limits = array(); var $row_buffer = array(); var $highest_fetched_row = array(); var $query_parameters = array(); var $query_parameter_values = array();
// }}} // {{{ constructor
/** * Constructor */ function MDB_ibase() { $this->MDB_Common(); $this->phptype = 'ibase'; $this->dbsyntax = 'ibase';
$this->supported['Sequences'] = 1; $this->supported['Indexes'] = 1; $this->supported['SummaryFunctions'] = 1; $this->supported['OrderByText'] = 1; $this->supported['Transactions'] = 1; $this->supported['CurrId'] = 0; $this->supported['AffectedRows'] = 0; $this->supported['SelectRowRanges'] = 1; $this->supported['LOBs'] = 1; $this->supported['Replace'] = 1; $this->supported['SubSelects'] = 1;
$this->decimal_factor = pow(10.0, $this->decimal_places);
$this->options['DatabasePath'] = ''; $this->options['DatabaseExtension'] = '.gdb'; $this->options['DBAUser'] = FALSE; $this->options['DBAPassword'] = FALSE;
$this->errorcode_map = array( -104 => MDB_ERROR_SYNTAX, -150 => MDB_ERROR_ACCESS_VIOLATION, -151 => MDB_ERROR_ACCESS_VIOLATION, -155 => MDB_ERROR_NOSUCHTABLE, 88 => MDB_ERROR_NOSUCHTABLE, -157 => MDB_ERROR_NOSUCHFIELD, -158 => MDB_ERROR_VALUE_COUNT_ON_ROW, -170 => MDB_ERROR_MISMATCH, -171 => MDB_ERROR_MISMATCH, -172 => MDB_ERROR_INVALID, -204 => MDB_ERROR_INVALID, -205 => MDB_ERROR_NOSUCHFIELD, -206 => MDB_ERROR_NOSUCHFIELD, -208 => MDB_ERROR_INVALID, -219 => MDB_ERROR_NOSUCHTABLE, -297 => MDB_ERROR_CONSTRAINT, -530 => MDB_ERROR_CONSTRAINT, -551 => MDB_ERROR_ACCESS_VIOLATION, -552 => MDB_ERROR_ACCESS_VIOLATION, -607 => MDB_ERROR_NOSUCHTABLE, -803 => MDB_ERROR_CONSTRAINT, -913 => MDB_ERROR_DEADLOCK, -922 => MDB_ERROR_NOSUCHDB, -923 => MDB_ERROR_CONNECT_FAILED, -924 => MDB_ERROR_CONNECT_FAILED );
}
// }}} // {{{ errorCode()
/** * Map native error codes to DB's portable ones. Requires that * the DB implementation's constructor fills in the $errorcode_map * property. * * @param $nativecode the native error code, as returned by the backend * database extension (string or integer) * @return int a portable MDB error code, or FALSE if this DB * implementation has no mapping for the given error code. */ function errorCode($errormsg) { // memo for the interbase php module hackers: we need something similar // to mysql_errno() to retrieve error codes instead of this ugly hack if (preg_match('/^([^0-9\-]+)([0-9\-]+)\s+(.*)$/', $errormsg, $match)) { $errno = (int)$match[2]; } else { $errno = NULL; } switch ($errno) { case -204: if (is_int(strpos($match[3], 'Table unknown'))) { return MDB_ERROR_NOSUCHTABLE; } break; default: if (isset($this->errorcode_map[$errno])) { return($this->errorcode_map[$errno]); } static $error_regexps; if (empty($error_regexps)) { $error_regexps = array( '/[tT]able not found/' => MDB_ERROR_NOSUCHTABLE, '/[tT]able unknown/' => MDB_ERROR_NOSUCHTABLE, '/[tT]able .* already exists/' => MDB_ERROR_ALREADY_EXISTS, '/validation error for column .* value "\*\*\* null/' => MDB_ERROR_CONSTRAINT_NOT_NULL, '/violation of [\w ]+ constraint/' => MDB_ERROR_CONSTRAINT, '/conversion error from string/' => MDB_ERROR_INVALID_NUMBER, '/no permission for/' => MDB_ERROR_ACCESS_VIOLATION, '/arithmetic exception, numeric overflow, or string truncation/' => MDB_ERROR_DIVZERO, '/deadlock/' => MDB_ERROR_DEADLOCK, '/attempt to store duplicate value/' => MDB_ERROR_CONSTRAINT ); } foreach ($error_regexps as $regexp => $code) { if (preg_match($regexp, $errormsg)) { return $code; } } } // Fall back to MDB_ERROR if there was no mapping. return MDB_ERROR; }
// }}} // {{{ ibaseRaiseError()
/** * This method is used to communicate an error and invoke error * callbacks etc. Basically a wrapper for MDB::raiseError * that checks for native error msgs. * * @param integer $errno error code * @param string $message userinfo message * @return object a PEAR error object * @access public * @see PEAR_Error */ function ibaseRaiseError($errno = NULL, $message = NULL) { $error = $this->errorNative(); return($this->raiseError($this->errorCode($error), NULL, NULL, $message, $error)); }
// }}} // {{{ errorNative()
/** * Get the native error code of the last error (if any) that * occured on the current connection. * * @access public * @return int native ibase error code */ function errorNative() { return @ibase_errmsg(); }
// }}} // {{{ autoCommit()
/** * Define whether database changes done on the database be automatically * committed. This function may also implicitly start or end a transaction. * * @param boolean $auto_commit flag that indicates whether the database * changes should be committed right after executing every query * statement. If this argument is 0 a transaction implicitly started. * Otherwise, if a transaction is in progress it is ended by committing * any database changes that were pending. * @return mixed MDB_OK on success, a MDB error on failure * @access public */ function autoCommit($auto_commit) { $this->debug('AutoCommit: '.($auto_commit ? 'On' : 'Off')); if ((!$this->auto_commit) == (!$auto_commit)) { return MDB_OK; } if ($this->connection && $auto_commit && MDB::isError($commit = $this->commit())) { return($commit); } $this->auto_commit = $auto_commit; $this->in_transaction = !$auto_commit; return MDB_OK; }
// }}} // {{{ commit()
/** * Commit the database changes done during a transaction that is in * progress. This function may only be called when auto-committing is * disabled, otherwise it will fail. Therefore, a new transaction is * implicitly started after committing the pending changes. * * @return mixed MDB_OK on success, a MDB error on failure * @access public */ function commit() { $this->debug('Commit Transaction'); if ($this->auto_commit) { return($this->raiseError(MDB_ERROR, NULL, NULL, 'Commit: transaction changes are being auto commited')); } return @ibase_commit($this->connection); }
// }}} // {{{ rollback()
/** * Cancel any database changes done during a transaction that is in * progress. This function may only be called when auto-committing is * disabled, otherwise it will fail. Therefore, a new transaction is * implicitly started after canceling the pending changes. * * @return mixed MDB_OK on success, a MDB error on failure * @access public */ function rollback() { $this->debug('Rollback Transaction'); if ($this->auto_commit) { return($this->raiseError(MDB_ERROR, NULL, NULL, 'Rollback: transactions can not be rolled back when changes are auto commited')); }
//return ibase_rollback($this->connection);
if ($this->transaction_id && !@ibase_rollback($this->connection)) { return($this->raiseError(MDB_ERROR, NULL, NULL, 'Rollback: Could not rollback a pending transaction: '.@ibase_errmsg())); } if (!$this->transaction_id = @ibase_trans(IBASE_COMMITTED, $this->connection)) { return($this->raiseError(MDB_ERROR, NULL, NULL, 'Rollback: Could not start a new transaction: '.@ibase_errmsg())); } return MDB_OK; }
// }}} // {{{ getDatabaseFile()
function getDatabaseFile($database_name) { if (isset($this->options['DatabasePath'])) { $this->database_path = $this->options['DatabasePath']; } if (isset($this->options['DatabaseExtension'])) { $this->database_extension = $this->options['DatabaseExtension']; } //$this->database_path = (isset($this->options['DatabasePath']) ? $this->options['DatabasePath'] : ''); //$this->database_extension = (isset($this->options['DatabaseExtension']) ? $this->options['DatabaseExtension'] : '.gdb');
//$database_path = (isset($this->options['DatabasePath']) ? $this->options['DatabasePath'] : ''); //$database_extension = (isset($this->options['DatabaseExtension']) ? $this->options['DatabaseExtension'] : '.gdb'); return $this->database_path.$database_name.$this->database_extension; }
// }}} // {{{ _doConnect()
/** * Does the grunt work of connecting to the database * * @return mixed connection resource on success, MDB_Error on failure * @access private **/ function _doConnect($database_name, $persistent) { $function = ($persistent ? 'ibase_pconnect' : 'ibase_connect'); if (!function_exists($function)) { return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 'doConnect: FireBird/InterBase support is not available in this PHP configuration')); }
$dbhost = $this->host ? ($this->host . ':' . $database_name) : $database_name;
$params = array(); $params[] = $dbhost; $params[] = !empty($this->user) ? $this->user : NULL; $params[] = !empty($this->password) ? $this->password : NULL;
$connection = @call_user_func_array($function, $params); if ($connection > 0) { @ibase_timefmt("%Y-%m-%d %H:%M:%S", IBASE_TIMESTAMP); @ibase_timefmt("%Y-%m-%d", IBASE_DATE); return $connection; } if (isset($php_errormsg)) { $error_msg = $php_errormsg; } else { $error_msg = 'Could not connect to FireBird/InterBase server'; } return($this->raiseError(MDB_ERROR_CONNECT_FAILED, NULL, NULL, 'doConnect: '.$error_msg)); }
// }}} // {{{ connect()
/** * Connect to the database * * @return TRUE on success, MDB_Error on failure * @access public **/ function connect() { $port = (isset($this->options['port']) ? $this->options['port'] : '');
$database_file = $this->getDatabaseFile($this->database_name);
if ($this->connection != 0) { if (!strcmp($this->connected_host, $this->host) && !strcmp($this->connected_port, $port) && !strcmp($this->selected_database_file, $database_file) && ($this->opened_persistent == $this->options['persistent'])) { return MDB_OK; } @ibase_close($this->connection); $this->affected_rows = -1; $this->connection = 0; } $connection = $this->_doConnect($database_file, $this->options['persistent']); if (MDB::isError($connection)) { return $connection; } $this->connection = $connection;
//the if below was added after PEAR::DB. Review me!! if ($this->dbsyntax == 'fbird') { $this->supported['limit'] = 'alter'; }
if (!$this->auto_commit && MDB::isError($trans_result = $this->_doQuery('BEGIN'))) { @ibase_close($this->connection); $this->connection = 0; $this->affected_rows = -1; return $trans_result; } $this->connected_host = $this->host; $this->connected_port = $port; $this->selected_database_file = $database_file; $this->opened_persistent = $this->options['persistent']; return MDB_OK; }
// }}} // {{{ _close() /** * Close the database connection * * @return boolean * @access private **/ function _close() { if ($this->connection != 0) { if (!$this->auto_commit) { $this->_doQuery('END'); } @ibase_close($this->connection); $this->connection = 0; $this->affected_rows = -1;
unset($GLOBALS['_MDB_databases'][$this->database]); return true; } return false; }
// }}} // {{{ _doQuery()
/** * Execute a query * @param string $query the SQL query * @return mixed result identifier if query executed, else MDB_error * @access private **/ function _doQuery($query, $first=0, $limit=0, $prepared_query=0) // function _doQuery($query) { $connection = ($this->auto_commit ? $this->connection : $this->transaction_id); if ($prepared_query && isset($this->query_parameters[$prepared_query]) && count($this->query_parameters[$prepared_query]) > 2) {
$this->query_parameters[$prepared_query][0] = $connection; $this->query_parameters[$prepared_query][1] = $query; $result = @call_user_func_array("ibase_query", $this->query_parameters[$prepared_query]); } else { //Not Prepared Query $result = @ibase_query($connection, $query); while (@ibase_errmsg() == 'Query argument missed') { //ibase_errcode() only available in PHP5 //connection lost, try again... $this->connect(); //rollback the failed transaction to prevent deadlock and execute the query again if ($this->transaction_id) { $this->rollback(); } $result = @ibase_query($this->connection, $query); } } if ($result) { if (!MDB::isManip($query)) { $result_value = intval($result); $this->current_row[$result_value] = -1; if ($limit > 0) { $this->limits[$result_value] = array($first, $limit, 0); } $this->highest_fetched_row[$result_value] = -1; } else { $this->affected_rows = -1; } } else { return ($this->raiseError(MDB_ERROR, NULL, NULL, '_doQuery: Could not execute query ("'.$query.'"): ' . @ibase_errmsg())); } return $result; }
// }}} // {{{ query()
/** * Send a query to the database and return any results * * @param string $query the SQL query * @param array $types array that contains the types of the columns in * the result set * @return mixed result identifier if query executed, else MDB_error * @access public **/ function query($query, $types = NULL) { $this->debug('Query: '.$query); $this->last_query = $query; $first = $this->first_selected_row; $limit = $this->selected_row_limit; $this->first_selected_row = $this->selected_row_limit = 0; $connected = $this->connect(); if (MDB::isError($connected)) { return $connected; }
if (!MDB::isError($result = $this->_doQuery($query, $first, $limit, 0))) { if ($types != NULL) { if (!is_array($types)) { $types = array($types); } if (MDB::isError($err = $this->setResultTypes($result, $types))) { $this->freeResult($result); return $err; } } return $result; } return $this->ibaseRaiseError();
}
// }}} // {{{ _executePreparedQuery()
/** * Execute a prepared query statement. * * @param int $prepared_query argument is a handle that was returned by * the function prepareQuery() * @param string $query query to be executed * @param array $types array that contains the types of the columns in * the result set * @return mixed a result handle or MDB_OK on success, a MDB error on failure * @access private */ function _executePreparedQuery($prepared_query, $query) { $first = $this->first_selected_row; $limit = $this->selected_row_limit; $this->first_selected_row = $this->selected_row_limit = 0; if (MDB::isError($connect = $this->connect())) { return $connect; } return($this->_doQuery($query, $first, $limit, $prepared_query)); }
// }}} // {{{ _skipLimitOffset()
/** * Skip the first row of a result set. * * @param resource $result * @return mixed a result handle or MDB_OK on success, a MDB error on failure * @access private */ function _skipLimitOffset($result) { $result_value = intval($result); $first = $this->limits[$result_value][0]; for (; $this->limits[$result_value][2] < $first; $this->limits[$result_value][2]++) { if (!is_array(@ibase_fetch_row($result))) { $this->limits[$result_value][2] = $first; return($this->raiseError(MDB_ERROR, NULL, NULL, 'Skip first rows: could not skip a query result row')); } } return MDB_OK; }
// }}} // {{{ getColumnNames()
/** * Retrieve the names of columns returned by the DBMS in a query result. * * @param resource $result result identifier * @return mixed an associative array variable * that will hold the names of columns.The * indexes of the array are the column names * mapped to lower case and the values are the * respective numbers of the columns starting * from 0. Some DBMS may not return any * columns when the result set does not * contain any rows. * * a MDB error on failure * @access public */ function getColumnNames($result) { $result_value = intval($result); if (!isset($this->highest_fetched_row[$result_value])) { return($this->raiseError(MDB_ERROR, NULL, NULL, 'Get column names: it was specified an inexisting result set')); } if (!isset($this->columns[$result_value])) { $this->columns[$result_value] = array(); $columns = @ibase_num_fields($result); for ($column=0; $column < $columns; $column++) { $column_info = @ibase_field_info($result, $column); $field_name = $column_info['name']; if ($this->options['optimize'] == 'portability') { $field_name = strtolower($field_name); } $this->columns[$result_value][$field_name] = $column; } } return $this->columns[$result_value]; }
// }}} // {{{ numCols()
/** * Count the number of columns returned by the DBMS in a query result. * * @param resource $result result identifier * @return mixed integer value with the number of columns, a MDB error * on failure * @access public */ function numCols($result) { if (!isset($this->highest_fetched_row[intval($result)])) { return($this->raiseError(MDB_ERROR, NULL, NULL, 'Number of columns: it was specified an inexisting result set')); } return @ibase_num_fields($result); }
// }}} // {{{ endOfResult()
/** * check if the end of the result set has been reached * * @param resource $result result identifier * @return mixed TRUE or FALSE on sucess, a MDB error on failure * @access public */ function endOfResult($result) { $result_value = intval($result); if (!isset($this->current_row[$result_value])) { return($this->raiseError(MDB_ERROR, NULL, NULL, 'End of result: attempted to check the end of an unknown result')); } if (isset($this->results[$result_value]) && end($this->results[$result_value]) === false) { return(($this->highest_fetched_row[$result_value]-1) <= $this->current_row[$result_value]); } if (isset($this->row_buffer[$result_value])) { return(!$this->row_buffer[$result_value]); } if (isset($this->limits[$result_value])) { if (MDB::isError($this->_skipLimitOffset($result)) || ($this->current_row[$result_value]) > $this->limits[$result_value][1] ) { return true; } } if (is_array($this->row_buffer[$result_value] = @ibase_fetch_row($result))) { return false; } $this->row_buffer[$result_value] = false; return true; }
// }}} // {{{ fetch()
/** * fetch value from a result set * * @param resource $result result identifier * @param int $rownum number of the row where the data can be found * @param int $field field number where the data can be found * @return mixed string on success, a MDB error on failure * @access public */ function fetch($result, $rownum, $field) { $fetchmode = is_numeric($field) ? MDB_FETCHMODE_ORDERED : MDB_FETCHMODE_ASSOC; $row = $this->fetchInto($result, $fetchmode, $rownum); if (MDB::isError($row)) { return $row; } if (!array_key_exists($field, $row)) { return null; } return $row[$field]; }
// }}} // {{{ fetchInto()
/** * Fetch a row and return data in an array. * * @param resource $result result identifier * @param int $fetchmode how the array data should be indexed * @param int $rownum the row number to fetch * @return mixed data array or NULL on success, a MDB error on failure * @access public */ function fetchInto($result, $fetchmode=MDB_FETCHMODE_DEFAULT, $rownum=null) { $result_value = intval($result); if (!isset($this->current_row[$result_value])) { return($this->raiseError(MDB_ERROR, NULL, NULL, 'fetchInto: attemped to fetch on an unknown query result')); } if ($fetchmode == MDB_FETCHMODE_DEFAULT) { $fetchmode = $this->fetchmode; } if (is_null($rownum)) { $rownum = $this->current_row[$result_value] + 1; } if (!isset($this->results[$result_value][$rownum]) && (!isset($this->results[$result_value][$this->highest_fetched_row[$result_value]]) || $this->results[$result_value][$this->highest_fetched_row[$result_value]] !== false) ) { if (isset($this->limits[$result_value])) { //upper limit if ($rownum > $this->limits[$result_value][1]) { // are all previous rows fetched so that we can set the end // of the result set and not have any "holes" in between? if ($rownum == 0 || (isset($this->results[$result_value]) && count($this->results[$result_value]) == $rownum) ) { $this->highest_fetched_row[$result_value] = $rownum; $this->current_row[$result_value] = $rownum; $this->results[$result_value][$rownum] = false; } if ($this->options['autofree']) { $this->freeResult($result); } return null; } // offset skipping if (MDB::isError($this->_skipLimitOffset($result))) { $this->current_row[$result_value] = 0; $this->results[$result_value] = array(false); if ($this->options['autofree']) { $this->freeResult($result); } return null; } } if (isset($this->row_buffer[$result_value])) { ++$this->current_row[$result_value]; $this->results[$result_value][$this->current_row[$result_value]] = $this->row_buffer[$result_value]; unset($this->row_buffer[$result_value]); } if (!isset($this->results[$result_value][$rownum]) && (!isset($this->results[$result_value][$this->highest_fetched_row[$result_value]]) || $this->results[$result_value][$this->highest_fetched_row[$result_value]] !== false) ) { while ($this->current_row[$result_value] < $rownum && is_array($buffer = @ibase_fetch_row($result)) ) { ++$this->current_row[$result_value]; $this->results[$result_value][$this->current_row[$result_value]] = $buffer; } // end of result set reached if ($this->current_row[$result_value] < $rownum) { ++$this->current_row[$result_value]; $this->results[$result_value][$this->current_row[$result_value]] = false; } } $this->highest_fetched_row[$result_value] = max($this->highest_fetched_row[$result_value], $this->current_row[$result_value]); } else { ++$this->current_row[$result_value]; } if (isset($this->results[$result_value][$rownum]) && $this->results[$result_value][$rownum] ) { $row = $this->results[$result_value][$rownum]; } else { if ($this->options['autofree']) { $this->freeResult($result); } return null; } foreach ($row as $key => $value_with_space) { if (!is_null($value_with_space)) { $row[$key] = rtrim($value_with_space, ' '); } } if ($fetchmode & MDB_FETCHMODE_ASSOC) { $column_names = $this->getColumnNames($result); foreach ($column_names as $name => $i) { $column_names[$name] = $row[$i]; } $row = $column_names; } if (isset($this->result_types[$result_value])) { $row = $this->convertResultRow($result, $row); } return $row; }
// }}} // {{{ _retrieveLob()
/** * fetch a lob value from a result set * * @param int $lob handle to a lob created by the createLob() function * @return mixed MDB_OK on success, a MDB error on failure * @access private */ function _retrieveLob($lob) { if (!isset($this->lobs[$lob])) { return($this->raiseError(MDB_ERROR, NULL, NULL, 'Retrieve LOB: it was not specified a valid lob')); }
if (!isset($this->lobs[$lob]['Value'])) { $this->lobs[$lob]['Value'] = $this->fetch($this->lobs[$lob]['Result'], $this->lobs[$lob]['Row'], $this->lobs[$lob]['Field']);
if (!$this->lobs[$lob]['Handle'] = @ibase_blob_open($this->lobs[$lob]['Value'])) { unset($this->lobs[$lob]['Value']); return($this->raiseError(MDB_ERROR, NULL, NULL, 'Retrieve LOB: Could not open fetched large object field' . @ibase_errmsg())); } } return MDB_OK; }
// }}} // {{{ endOfResultLob()
/** * Determine whether it was reached the end of the large object and * therefore there is no more data to be read for the its input stream. * * @param int $lob handle to a lob created by the createLob() function * @return mixed TRUE or FALSE on success, a MDB error on failure * @access public */ function endOfResultLob($lob) { if (MDB::isError($lobresult = $this->_retrieveLob($lob))) { return($lobresult); } return(isset($this->lobs[$lob]['EndOfLOB'])); }
// }}} // {{{ _readResultLob()
/** * Read data from large object input stream. * * @param int $lob handle to a lob created by the createLob() function * @param blob $data reference to a variable that will hold data to be * read from the large object input stream * @param int $length integer value that indicates the largest ammount of * data to be read from the large object input stream. * @return mixed length on success, a MDB error on failure * @access private */ function _readResultLob($lob, &$data, $length) { if (MDB::isError($lobresult = $this->_retrieveLob($lob))) { return $lobresult; } $data = @ibase_blob_get($this->lobs[$lob]['Handle'], $length); if (!is_string($data)) { $this->raiseError(MDB_ERROR, NULL, NULL, 'Read Result LOB: ' . @ibase_errmsg()); } if (($length = strlen($data)) == 0) { $this->lobs[$lob]['EndOfLOB'] = 1; } return $length; }
// }}} // {{{ _destroyResultLob()
/** * Free any resources allocated during the lifetime of the large object * handler object. * * @param int $lob handle to a lob created by the createLob() function * @access private */ function _destroyResultLob($lob) { if (isset($this->lobs[$lob])) { if (isset($this->lobs[$lob]['Value'])) { @ibase_blob_close($this->lobs[$lob]['Handle']); } $this->lobs[$lob] = ''; } }
// }}} // {{{ fetchClob()
/** * fetch a clob value from a result set * * @param resource $result result identifier * @param int $row number of the row where the data can be found * @param int $field field number where the data can be found * @return mixed content of the specified data cell, a MDB error on failure, * a MDB error on failure * @access public */ function fetchClob($result, $row, $field) { return $this->fetchLob($result, $row, $field); }
// }}} // {{{ fetchBlob()
/** * fetch a blob value from a result set * * @param resource $result result identifier * @param int $row number of the row where the data can be found * @param int $field field number where the data can be found * @return mixed content of the specified data cell, a MDB error on failure * @access public */ function fetchBlob($result, $row, $field) { return $this->fetchLob($result, $row, $field); }
// }}} // {{{ convertResult()
/** * convert a value to a RDBMS indepdenant MDB type * * @param mixed $value value to be converted * @param int $type constant that specifies which type to convert to * @return mixed converted value or a MDB error on failure * @access public */ function convertResult($value, $type) { switch ($type) { case MDB_TYPE_DECIMAL: return sprintf('%.'.$this->decimal_places.'f', doubleval($value)/$this->decimal_factor); case MDB_TYPE_TIMESTAMP: return substr($value, 0, strlen('YYYY-MM-DD HH:MM:SS')); default: return $this->_baseConvertResult($value, $type); } }
// }}} // {{{ resultIsNull()
/** * Determine whether the value of a query result located in given row and * field is a NULL. * * @param resource $result result identifier * @param int $rownum number of the row where the data can be found * @param int $field field number where the data can be found * @return mixed TRUE or FALSE on success, a MDB error on failure * @access public */ function resultIsNull($result, $rownum, $field) { $value = $this->fetch($result, $rownum, $field); if (MDB::isError($value)) { return $value; } return(!isset($value)); }
// }}} // {{{ numRows()
/** * returns the number of rows in a result object * * @param ressource $result a valid result ressouce pointer * @return mixed MDB_Error or the number of rows * @access public */ function numRows($result) { $result_value = intval($result); if (!isset($this->current_row[$result_value])) { return($this->raiseError(MDB_ERROR, NULL, NULL, 'Number of rows: attemped to obtain the number of rows contained in an unknown query result')); } if (!isset($this->rows[$result_value][$this->highest_fetched_row[$result_value]]) || $this->rows[$result_value][$this->highest_fetched_row[$result_value]] !== false ) { if (isset($this->limits[$result_value])) { if (MDB::isError($skipfirstrow = $this->_skipLimitOffset($result))) { //$this->rows[$result_value] = 0; return $skipfirstrow; } } if (isset($this->row_buffer[$result_value])) { ++$this->highest_fetched_row[$result_value]; $this->results[$result_value][$this->highest_fetched_row[$result_value]] = $this->row_buffer[$result_value]; unset($this->row_buffer[$result_value]); } if (!isset($this->results[$result_value][$this->highest_fetched_row[$result_value]]) || $this->results[$result_value][$this->highest_fetched_row[$result_value]] !== false ) { while((!isset($this->limits[$result_value]) || ($this->highest_fetched_row[$result_value]+1) < $this->limits[$result_value][1] ) && (is_array($buffer = @ibase_fetch_row($result))) ) { ++$this->highest_fetched_row[$result_value]; $this->results[$result_value][$this->highest_fetched_row[$result_value]] = $buffer; } ++$this->highest_fetched_row[$result_value]; $this->results[$result_value][$this->highest_fetched_row[$result_value]] = false; } } return(max(0, $this->highest_fetched_row[$result_value])); }
// }}} // {{{ freeResult()
/** * Free the internal resources associated with $result. * * @param $result result identifier * @return boolean TRUE on success, FALSE if $result is invalid * @access public */ function freeResult($result) { $result_value = intval($result); if (!isset($this->current_row[$result_value])) { return($this->raiseError(MDB_ERROR, NULL, NULL, 'Free result: attemped to free an unknown query result')); } if (isset($this->highest_fetched_row[$result_value])) { unset($this->highest_fetched_row[$result_value]); } if (isset($this->row_buffer[$result_value])) { unset($this->row_buffer[$result_value]); } if (isset($this->limits[$result_value])) { unset($this->limits[$result_value]); } if (isset($this->current_row[$result_value])) { unset($this->current_row[$result_value]); } if (isset($this->results[$result_value])) { unset($this->results[$result_value]); } if (isset($this->columns[$result_value])) { unset($this->columns[$result_value]); } if (isset($this->rows[$result_value])) { unset($this->rows[$result_value]); } if (isset($this->result_types[$result_value])) { unset($this->result_types[$result_value]); } if (is_resource($result)) { return @ibase_free_result($result); } return true; } // }}} // {{{ getTypeDeclaration()
/** * Obtain DBMS specific SQL code portion needed to declare an text type * field to be used in statements like CREATE TABLE. * * @param string $field associative array with the name of the properties * of the field being declared as array indexes. Currently, the types * of supported field properties are as follows: * * length * Integer value that determines the maximum length of the text * field. If this argument is missing the field should be * declared to have the longest length allowed by the DBMS. * * default * Text value to be used as default for this field. * * notnull * Boolean flag that indicates whether this field is constrained * to not be set to null. * @return string DBMS specific SQL code portion that should be used to * declare the specified field. * @access public */ function getTypeDeclaration($field) { switch($field['type']) { case 'text': return('VARCHAR ('.(isset($field['length']) ? $field['length'] : (isset($this->options['DefaultTextFieldLength']) ? $this->options['DefaultTextFieldLength'] : 4000)).')'); case 'clob': return 'BLOB SUB_TYPE 1'; case 'blob': return 'BLOB SUB_TYPE 0'; case 'integer': return 'INTEGER'; case 'boolean': return 'CHAR (1)'; case 'date': return 'DATE'; case 'time': return 'TIME'; case 'timestamp': return 'TIMESTAMP'; case 'float': return 'DOUBLE PRECISION'; case 'decimal': return 'DECIMAL(18,'.$this->decimal_places.')'; } return ''; }
// }}} // {{{ getTextDeclaration()
/** * Obtain DBMS specific SQL code portion needed to declare an text type * field to be used in statements like CREATE TABLE. * * @param string $name name the field to be declared. * @param string $field associative array with the name of the properties * of the field being declared as array indexes. Currently, the types * of supported field properties are as follows: * * length * Integer value that determines the maximum length of the text * field. If this argument is missing the field should be * declared to have the longest length allowed by the DBMS. * * default * Text value to be used as default for this field. * * notnull * Boolean flag that indicates whether this field is constrained * to not be set to NULL. * @return string DBMS specific SQL code portion that should be used to * declare the specified field. * @access public */ function getTextDeclaration($name, $field) { return($name.' '.$this->getTypeDeclaration($field).(isset($field['default']) ? ' DEFAULT '.$this->getTextValue($field['default']) : '').(IsSet($field['notnull']) ? ' NOT NULL' : '')); }
// }}} // {{{ getClobDeclaration()
/** * Obtain DBMS specific SQL code portion needed to declare an character * large object type field to be used in statements like CREATE TABLE. * * @param string $name name the field to be declared. * @param string $field associative array with the name of the properties * of the field being declared as array indexes. Currently, the types * of supported field properties are as follows: * * length * Integer value that determines the maximum length of the large * object field. If this argument is missing the field should be * declared to have the longest length allowed by the DBMS. * * notnull * Boolean flag that indicates whether this field is constrained * to not be set to NULL. * @return string DBMS specific SQL code portion that should be used to * declare the specified field. * @access public */ function getClobDeclaration($name, $field) { return($name.' '.$this->getTypeDeclaration($field).(isset($field['notnull']) ? ' NOT NULL' : '')); }
// }}} // {{{ getBlobDeclaration()
/** * Obtain DBMS specific SQL code portion needed to declare an binary large * object type field to be used in statements like CREATE TABLE. * * @param string $name name the field to be declared. * @param string $field associative array with the name of the properties * of the field being declared as array indexes. Currently, the types * of supported field properties are as follows: * * length * Integer value that determines the maximum length of the large * object field. If this argument is missing the field should be * declared to have the longest length allowed by the DBMS. * * notnull * Boolean flag that indicates whether this field is constrained * to not be set to NULL. * @return string DBMS specific SQL code portion that should be used to * declare the specified field. * @access public */ function getBlobDeclaration($name, $field) { return($name.' '.$this->getTypeDeclaration($field).(isset($field['notnull']) ? ' NOT NULL' : '')); }
// }}} // {{{ getDateDeclaration()
/** * Obtain DBMS specific SQL code portion needed to declare a date type * field to be used in statements like CREATE TABLE. * * @param string $name name the field to be declared. * @param string $field associative array with the name of the properties * of the field being declared as array indexes. Currently, the types * of supported field properties are as follows: * * default * Date value to be used as default for this field. * * notnull * Boolean flag that indicates whether this field is constrained * to not be set to NULL. * @return string DBMS specific SQL code portion that should be used to * declare the specified field. * @access public */ function getDateDeclaration($name, $field) { return($name.' '.$this->getTypeDeclaration($field).(isset($field['default']) ? ' DEFAULT "'.$field['default'].'"' : '').(isset($field['notnull']) ? ' NOT NULL' : '')); }
// }}} // {{{ getTimeDeclaration()
/** * Obtain DBMS specific SQL code portion needed to declare a time * field to be used in statements like CREATE TABLE. * * @param string $name name the field to be declared. * @param string $field associative array with the name of the properties * of the field being declared as array indexes. Currently, the types * of supported field properties are as follows: * * default * Time value to be used as default for this field. * * notnull * Boolean flag that indicates whether this field is constrained * to not be set to NULL. * @return string DBMS specific SQL code portion that should be used to * declare the specified field. * @access public */ function getTimeDeclaration($name, $field) { return($name.' '.$this->getTypeDeclaration($field).(isset($field['default']) ? ' DEFAULT "'.$field['default'].'"' : '').(isset($field['notnull']) ? ' NOT NULL' : '')); }
// }}} // {{{ getFloatDeclaration()
/** * Obtain DBMS specific SQL code portion needed to declare a float type * field to be used in statements like CREATE TABLE. * * @param string $name name the field to be declared. * @param string $field associative array with the name of the properties * of the field being declared as array indexes. Currently, the types * of supported field properties are as follows: * * default * Float value to be used as default for this field. * * notnull * Boolean flag that indicates whether this field is constrained * to not be set to NULL. * @return string DBMS specific SQL code portion that should be used to * declare the specified field. * @access public */ function getFloatDeclaration($name, $field) { return($name.' '.$this->getTypeDeclaration($field).(isset($field['default']) ? ' DEFAULT '.$this->getFloatValue($field['default']) : '').(isset($field['notnull']) ? ' NOT NULL' : '')); }
// }}} // {{{ getDecimalDeclaration()
/** * Obtain DBMS specific SQL code portion needed to declare a decimal type * field to be used in statements like CREATE TABLE. * * @param string $name name the field to be declared. * @param string $field associative array with the name of the properties * of the field being declared as array indexes. Currently, the types * of supported field properties are as follows: * * default * Decimal value to be used as default for this field. * * notnull * Boolean flag that indicates whether this field is constrained * to not be set to NULL. * @return string DBMS specific SQL code portion that should be used to * declare the specified field. * @access public */ function getDecimalDeclaration($name, $field) { return($name.' '.$this->getTypeDeclaration($field).(isset($field['default']) ? ' DEFAULT '.$this->getDecimalValue($field['default']) : '').(isset($field['notnull']) ? ' NOT NULL' : '')); }
// }}} // {{{ _getLobValue()
/** * Convert a text value into a DBMS specific format that is suitable to * compose query statements. * * @param resource $prepared_query query handle from prepare() * @param $parameter * @param $lob * @return string text string that represents the given argument value in * a DBMS specific format. * @access private */ function _getLobValue($prepared_query, $parameter, $lob) { if (MDB::isError($connect = $this->connect())) { return $connect; } $value = ''; // DEAL WITH ME if (!$this->transaction_id = @ibase_trans(IBASE_COMMITTED, $this->connection)) { return($this->raiseError(MDB_ERROR, NULL, NULL, '_getLobValue: Could not start a new transaction: '.@ibase_errmsg())); }
if (($lo = @ibase_blob_create($this->auto_commit ? $this->connection : $this->transaction_id))) { while (!$this->endOfLob($lob)) { if (MDB::isError($result = $this->readLob($lob, $data, $this->options['lob_buffer_length']))) { break; } if (@ibase_blob_add($lo, $data) === false) { $result = $this->raiseError(MDB_ERROR, NULL, NULL, '_getLobValue - Could not add data to a large object: ' . @ibase_errmsg()); break; } } if (MDB::isError($result)) { @ibase_blob_cancel($lo); } else { $value = @ibase_blob_close($lo); } } else { $result = $this->raiseError(MDB_ERROR, NULL, NULL, 'Get LOB field value' . @ibase_errmsg()); } if (!isset($this->query_parameters[$prepared_query])) { $this->query_parameters[$prepared_query] = array(0, ''); $this->query_parameter_values[$prepared_query] = array(); } $query_parameter = count($this->query_parameters[$prepared_query]); $this->query_parameter_values[$prepared_query][$parameter] = $query_parameter; $this->query_parameters[$prepared_query][$query_parameter] = $value; $value = '?';
if (!$this->auto_commit) { $this->commit(); } return $value; }
// }}} // {{{ getClobValue()
/** * Convert a text value into a DBMS specific format that is suitable to * compose query statements. * * @param resource $prepared_query query handle from prepare() * @param $parameter * @param $clob * @return string text string that represents the given argument value in * a DBMS specific format. * @access public */ function getClobValue($prepared_query, $parameter, $clob) { return $this->_getLobValue($prepared_query, $parameter, $clob); }
// }}} // {{{ freeLobValue()
/** * free a large object * * @param resource $prepared_query query handle from prepare() * @param string $lob * @param string $value * @return MDB_OK * @access public */ function freeLobValue($prepared_query, $lob, &$value) { $query_parameter=$this->query_parameter_values[$prepared_query][$lob];
unset($this->query_parameters[$prepared_query][$query_parameter]); unset($this->query_parameter_values[$prepared_query][$lob]); if (count($this->query_parameter_values[$prepared_query]) == 0) { unset($this->query_parameters[$prepared_query]); unset($this->query_parameter_values[$prepared_query]); } unset($value); }
// }}} // {{{ freeClobValue()
/** * free a character large object * * @param resource $prepared_query query handle from prepare() * @param string $clob * @param string $value * @return MDB_OK * @access public */ function freeClobValue($prepared_query, $clob, &$value) { $this->freeLobValue($prepared_query, $clob, $value); }
// }}} // {{{ getBlobValue()
/** * Convert a text value into a DBMS specific format that is suitable to * compose query statements. * * @param resource $prepared_query query handle from prepare() * @param $parameter * @param $blob * @return string text string that represents the given argument value in * a DBMS specific format. * @access public */ function getBlobValue($prepared_query, $parameter, $blob) { return $this->_getLobValue($prepared_query, $parameter, $blob); }
// }}} // {{{ freeBlobValue()
/** * free a binary large object * * @param resource $prepared_query query handle from prepare() * @param string $blob * @param string $value * @return MDB_OK * @access public */ function freeBlobValue($prepared_query, $blob, &$value) { $this->freeLobValue($prepared_query, $blob, $value); }
// }}} // {{{ getFloatValue()
/** * Convert a text value into a DBMS specific format that is suitable to * compose query statements. * * @param string $value text string value that is intended to be converted. * @return string text string that represents the given argument value in * a DBMS specific format. * @access public */ function getFloatValue($value) { return (($value === null) ? 'NULL' : $value); }
// }}} // {{{ getDecimalValue()
/** * Convert a text value into a DBMS specific format that is suitable to * compose query statements. * * @param string $value text string value that is intended to be converted. * @return string text string that represents the given argument value in * a DBMS specific format. * @access public */ function getDecimalValue($value) { return (($value === null) ? 'NULL' : strval(round($value*$this->decimal_factor))); }
// }}} // {{{ affectedRows()
/** * returns the affected rows of a query * * @return mixed MDB Error Object or number of rows * @access public */ function affectedRows() { if (function_exists('ibase_affected_rows')) { //PHP5 only $affected_rows = @ibase_affected_rows($this->connection); if ($affected_rows === false) { return $this->raiseError(MDB_ERROR_NEED_MORE_DATA); } return $affected_rows; } return parent::affectedRows(); }
// }}} // {{{ nextId()
/** * returns the next free id of a sequence * * @param string $seq_name name of the sequence * @param boolean $ondemand when TRUE the seqence is * automatic created, if it * not exists * @return mixed MDB_Error or id * @access public */ function nextId($seq_name, $ondemand = true) { if (MDB::isError($connect = $this->connect())) { return $connect; } //$sequence_name = $this->getSequenceName($seq_name); $sequence_name = strtoupper($this->getSequenceName($seq_name)); $this->expectError(MDB_ERROR_NOSUCHTABLE); $query = "SELECT GEN_ID($sequence_name, 1) as the_value FROM RDB\$DATABASE"; $result = $this->_doQuery($query); $this->popExpect(); if ($ondemand && MDB::isError($result)) { $result = $this->createSequence($seq_name, 1); if (MDB::isError($result)) { return $result; } return $this->nextId($seq_name, false); } return $this->fetchOne($result); }
// }}} // {{{ currId()
/** * returns the current id of a sequence * * @param string $seq_name name of the sequence * @return mixed MDB_Error or id * @access public */ function currId($seq_name) { $sequence_name = strtoupper($this->getSequenceName($seq_name)); //$sequence_name = $this->getSequenceName($seq_name); $query = "SELECT RDB\$GENERATOR_ID FROM RDB\$GENERATORS WHERE RDB\$GENERATOR_NAME='$sequence_name'"; if (MDB::isError($result = $this->queryOne($query))) { return($this->raiseError(MDB_ERROR, NULL, NULL, 'currId: Unable to select from ' . $seqname) ); } if (!is_numeric($result)) { //var_dump($result); ==> null return($this->raiseError(MDB_ERROR, NULL, NULL, 'currId: could not find value in sequence table')); } return $result; }
// }}} // {{{ nextResult()
/** * Move the internal ibase result pointer to the next available result * * @param $result a valid ibase result resource * @return TRUE if a result is available otherwise return FALSE * @access public */ function nextResult($result) { return false; }
// }}} // {{{ tableInfo()
/** * returns meta data about the result set * * @param mixed $resource FireBird/InterBase result identifier or table name * @param mixed $mode depends on implementation * @return array an nested array, or a MDB error * @access public */ function tableInfo($result, $mode = NULL) { $count = 0; $id = 0; $res = array();
/** * depending on $mode, metadata returns the following values: * * - mode is FALSE (default): * $result[]: * [0]['table'] table name * [0]['name'] field name * [0]['type'] field type * [0]['len'] field length * [0]['flags'] field flags * * - mode is MDB_TABLEINFO_ORDER * $result[]: * ['num_fields'] number of metadata records * [0]['table'] table name * [0]['name'] field name * [0]['type'] field type * [0]['len'] field length * [0]['flags'] field flags * ['order'][field name] index of field named 'field name' * The last one is used, if you have a field name, but no index. * Test: if (isset($result['meta']['myfield'])) { ... * * - mode is MDB_TABLEINFO_ORDERTABLE * the same as above. but additionally * ['ordertable'][table name][field name] index of field * named 'field name' * * this is, because if you have fields from different * tables with the same field name * they override each * other with MDB_TABLEINFO_ORDER * * you can combine MDB_TABLEINFO_ORDER and * MDB_TABLEINFO_ORDERTABLE with MDB_TABLEINFO_ORDER | * MDB_TABLEINFO_ORDERTABLE * or with MDB_TABLEINFO_FULL **/
// if $result is a string, then we want information about a // table without a resultset if (is_string($result)) { $id = @ibase_query($this->connection,"SELECT * FROM $result"); if (empty($id)) { return $this->ibaseRaiseError(); } } else { // else we want information about a resultset $id = $result; if (empty($id)) { return $this->ibaseRaiseError(); } }
$count = @ibase_num_fields($id);
// made this IF due to performance (one if is faster than $count if's) if (empty($mode)) { for ($i=0; $i<$count; $i++) { $info = @ibase_field_info($id, $i); //$res[$i]['table'] = (is_string($result)) ? $result : ''; $res[$i]['table'] = (is_string($result)) ? $result : $info['relation']; $res[$i]['name'] = $info['name']; $res[$i]['type'] = $info['type']; $res[$i]['len'] = $info['length']; //$res[$i]['flags'] = (is_string($result)) ? $this->_ibaseFieldFlags($info['name'], $result) : ''; $res[$i]['flags'] = (is_string($result)) ? $this->_ibaseFieldFlags($id, $i, $result) : ''; } } else { // full $res['num_fields'] = $count;
for ($i=0; $i<$count; $i++) { $info = @ibase_field_info($id, $i); //$res[$i]['table'] = (is_string($result)) ? $result : ''; $res[$i]['table'] = (is_string($result)) ? $result : $info['relation']; $res[$i]['name'] = $info['name']; $res[$i]['type'] = $info['type']; $res[$i]['len'] = $info['length']; //$res[$i]['flags'] = (is_string($result)) ? $this->_ibaseFieldFlags($info['name'], $result) : ''; $res[$i]['flags'] = (is_string($result)) ? $this->_ibaseFieldFlags($id, $i, $result) : ''; if ($mode & MDB_TABLEINFO_ORDER) { $res['order'][$res[$i]['name']] = $i; } if ($mode & MDB_TABLEINFO_ORDERTABLE) { $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; } } }
// free the result only if we were called on a table if (is_string($result) && is_resource($id)) { @ibase_free_result($id); } return $res; }
// }}} // {{{ _ibaseFieldFlags()
/** * get the Flags of a Field * * @param int $resource FireBird/InterBase result identifier * @param int $num_field the field number * @return string The flags of the field ('not_null', 'default_xx', 'primary_key', * 'unique' and 'multiple_key' are supported) * @access private **/ function _ibaseFieldFlags($resource, $num_field, $table_name) { $field_name = @ibase_field_info($resource, $num_field); $field_name = @$field_name['name']; $sql = 'SELECT R.RDB$CONSTRAINT_TYPE CTYPE' .' FROM RDB$INDEX_SEGMENTS I' .' JOIN RDB$RELATION_CONSTRAINTS R ON I.RDB$INDEX_NAME=R.RDB$INDEX_NAME' .' WHERE I.RDB$FIELD_NAME=\''.$field_name.'\'' .' AND UPPER(R.RDB$RELATION_NAME)=\''.strtoupper($table_name).'\''; $result = @ibase_query($this->connection, $sql); if (empty($result)) { return $this->ibaseRaiseError(); } $flags = ''; if ($obj = @ibase_fetch_object($result)) { @ibase_free_result($result); if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'PRIMARY KEY') { $flags = 'primary_key '; } if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'UNIQUE') { $flags .= 'unique_key '; } }
$sql = 'SELECT R.RDB$NULL_FLAG AS NFLAG,' .' R.RDB$DEFAULT_SOURCE AS DSOURCE,' .' F.RDB$FIELD_TYPE AS FTYPE,' .' F.RDB$COMPUTED_SOURCE AS CSOURCE' .' FROM RDB$RELATION_FIELDS R ' .' JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME' .' WHERE UPPER(R.RDB$RELATION_NAME)=\''.strtoupper($table_name).'\'' .' AND R.RDB$FIELD_NAME=\''.$field_name.'\''; $result = @ibase_query($this->connection, $sql); if (empty($result)) { return $this->ibaseRaiseError(); } if ($obj = @ibase_fetch_object($result)) { @ibase_free_result($result); if (isset($obj->NFLAG)) { $flags .= 'not_null '; } if (isset($obj->DSOURCE)) { $flags .= 'default '; } if (isset($obj->CSOURCE)) { $flags .= 'computed '; } if (isset($obj->FTYPE) && $obj->FTYPE == 261) { $flags .= 'blob '; } }
return trim($flags); } }
?>
|