mirror of
https://github.com/atlanticbiomedical/portal-legacy.git
synced 2025-07-02 01:47:28 -04:00
initial commit
This commit is contained in:
135
lib/symfony/vendor/creole/CallableStatement.php
vendored
Executable file
135
lib/symfony/vendor/creole/CallableStatement.php
vendored
Executable file
@ -0,0 +1,135 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: CallableStatement.php,v 1.7 2004/03/20 04:16:49 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/PreparedStatement.php';
|
||||
|
||||
/**
|
||||
* Interface for callable statements.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.7 $
|
||||
* @package creole
|
||||
*/
|
||||
interface CallableStatement extends PreparedStatement {
|
||||
|
||||
/**
|
||||
* Register a parameter as an output param.
|
||||
* @param string $paramIndex The stored procedure param name (e.g. @val1).
|
||||
* @param int $sqlType The type of the parameter (e.g. Type::BIT)
|
||||
* @param int $maxLength The maximum expected length (size) of output parameter.
|
||||
*/
|
||||
public function registerOutParameter($paramIndex, $sqlType, $maxLength = null);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mixed $paramIndex Parameter name (e.g. "@var1").
|
||||
* @return array
|
||||
* @throws SQLException if $paramIndex was not bound as output variable.
|
||||
*/
|
||||
public function getArray($paramIndex);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mixed $paramIndex Parameter name (e.g. "@var1").
|
||||
* @return boolean
|
||||
* @throws SQLException if $paramIndex was not bound as output variable.
|
||||
*/
|
||||
public function getBoolean($paramIndex);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mixed $paramIndex Parameter name (e.g. "@var1").
|
||||
* @return Blob blob object
|
||||
* @throws SQLException if $paramIndex was not bound as output variable.
|
||||
*/
|
||||
public function getBlob($paramIndex);
|
||||
|
||||
/**
|
||||
* @param mixed $paramIndex Column name (string) or index (int).
|
||||
* @return Clob clob object.
|
||||
*/
|
||||
public function getClob($paramIndex);
|
||||
|
||||
/**
|
||||
* Return a formatted date.
|
||||
*
|
||||
* The default format for dates returned is preferred (in your locale, as specified using setlocale())
|
||||
* format w/o time (i.e. strftime("%x", $val)). Override this by specifying a format second parameter. You
|
||||
* can also specify a date()-style formatter; if you do, make sure there are no "%" symbols in your format string.
|
||||
*
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1 (if ResultSet::FETCHMODE_NUM was used).
|
||||
* @param string $format Date formatter for use w/ strftime() or date() (it will choose based on examination of format string)
|
||||
* If format is NULL, then the integer unix timestamp will be returned (no formatting performed).
|
||||
* @return mixed Formatted date, or integer unix timestamp (using 00:00:00 for time) if $format was null.
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getDate($column, $format = '%x');
|
||||
|
||||
/**
|
||||
* @param mixed $paramIndex Column name (string) or index (int).
|
||||
* @return float
|
||||
*/
|
||||
public function getFloat($paramIndex);
|
||||
|
||||
/**
|
||||
* @param mixed $paramIndex Column name (string) or index (int).
|
||||
* @return int
|
||||
*/
|
||||
public function getInt($paramIndex);
|
||||
|
||||
/**
|
||||
* @param mixed $paramIndex Column name (string) or index (int).
|
||||
* @return string
|
||||
*/
|
||||
public function getString($paramIndex);
|
||||
|
||||
/**
|
||||
* Return a formatted time.
|
||||
*
|
||||
* The default format for times returned is preferred (in your locale, as specified using setlocale())
|
||||
* format w/o date (i.e. strftime("%X", $val)). Override this by specifying a format second parameter. You
|
||||
* can also specify a date()-style formatter; if you do, make sure there are no "%" symbols in your format string.
|
||||
*
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1 (if ResultSet::FETCHMODE_NUM was used).
|
||||
* @param string $format Date formatter for use w/ strftime() or date() (it will choose based on examination of format string)
|
||||
* If format is NULL, then the integer unix timestamp will be returned (no formatting performed).
|
||||
* @return mixed Formatted time, or integer unix timestamp (using today's date) if $format was null.
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getTime($column, $format = '%X');
|
||||
|
||||
/**
|
||||
* Return a formatted timestamp.
|
||||
*
|
||||
* The default format for timestamp is ISO standard YYYY-MM-DD HH:MM:SS (i.e. date('Y-m-d H:i:s', $val).
|
||||
* Override this by specifying a format second parameter. You can also specify a strftime()-style formatter.
|
||||
*
|
||||
* Hint: if you want to get the unix timestamp use the "U" formatter string.
|
||||
*
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1 (if ResultSet::FETCHMODE_NUM was used).
|
||||
* @param string $format Date formatter for use w/ strftime() or date() (it will choose based on examination of format string)
|
||||
* If format is NULL, then the integer unix timestamp will be returned (no formatting performed).
|
||||
* @return mixed Formatted timestamp, or integer unix timestamp (if $format was null)
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getTimestamp($column, $format = 'Y-m-d H:i:s');
|
||||
|
||||
}
|
||||
220
lib/symfony/vendor/creole/Connection.php
vendored
Executable file
220
lib/symfony/vendor/creole/Connection.php
vendored
Executable file
@ -0,0 +1,220 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: Connection.php,v 1.29 2005/10/17 19:03:50 dlawson_mi Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
include_once 'creole/ResultSet.php'; // we need this for the fetchmode ResultSet flags (constants) that are passed to executeQuery()
|
||||
|
||||
/**
|
||||
* Connection is an abstract base class for DB dialect implementations, and must be
|
||||
* inherited by all such.
|
||||
*
|
||||
* Developer notes:
|
||||
* (1) Make sure that your Connection class can be serialized. See the ConnectionCommon __sleep() and __wakeup() implimentation.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.29 $
|
||||
* @package creole
|
||||
*/
|
||||
interface Connection {
|
||||
|
||||
// Constants that define transaction isolation levels.
|
||||
// [We don't have any code using these yet, so there's no need
|
||||
// to initialize these values at this point.]
|
||||
// const TRANSACTION_NONE = 0;
|
||||
// const TRANSACTION_READ_UNCOMMITTED = 1;
|
||||
// const TRANSACTION_READ_COMMITTED = 2;
|
||||
// const TRANSACTION_REPEATABLE_READ = 3;
|
||||
// const TRANSACTION_SERIALIZABLE = 4;
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param array $dsn The PEAR-style data source hash.
|
||||
* @param int $flags (optional) Flags for connection (e.g. Creole::PERSISTENT). These flags
|
||||
* may apply to any of the driver classes.
|
||||
*/
|
||||
public function connect($dsn, $flags = false);
|
||||
|
||||
/**
|
||||
* Get the PHP native resource for the database connection/link.
|
||||
* @return resource
|
||||
*/
|
||||
public function getResource();
|
||||
|
||||
/**
|
||||
* Get any flags that were passed to connection.
|
||||
* @return int
|
||||
*/
|
||||
public function getFlags();
|
||||
|
||||
/**
|
||||
* Get the DSN array used by connect() method to connect to database.
|
||||
* @see connect()
|
||||
* @return array
|
||||
*/
|
||||
public function getDSN();
|
||||
|
||||
/**
|
||||
* Gets a DatabaseInfo class for the current database.
|
||||
*
|
||||
* This is not modeled on the JDBC MetaData class, but provides a possibly more
|
||||
* useful metadata system. All the same, there may eventually be a getMetaData()
|
||||
* which returns a class that behaves like JDBC's DatabaseMetaData.
|
||||
*
|
||||
* @return DatabaseInfo
|
||||
*/
|
||||
public function getDatabaseInfo();
|
||||
|
||||
/**
|
||||
* Loads and returns an IdGenerator object for current RDBMS.
|
||||
* @return IdGenerator
|
||||
*/
|
||||
public function getIdGenerator();
|
||||
|
||||
/**
|
||||
* Prepares a query for multiple execution with execute().
|
||||
*
|
||||
* With some database backends, this is emulated.
|
||||
* prepare() requires a generic query as string like
|
||||
* "INSERT INTO numbers VALUES(?,?,?)". The ? are placeholders.
|
||||
*
|
||||
* IMPORTANT: All occurrences of the placeholder (?) will be assumed
|
||||
* to be a parameter. Therefore be sure not to have ? anywhere else in
|
||||
* the query.
|
||||
*
|
||||
* So, ... DO NOT MIX WILDCARDS WITH ALREADY-PREPARED QUERIES
|
||||
*
|
||||
* INCORRECT:
|
||||
* SELECT * FROM mytable WHERE id = ? AND title = 'Where are you?' and body LIKE ?
|
||||
*
|
||||
* CORRECT:
|
||||
* SELECT * FROM mytable WHERE id = ? AND title = ? and body LIKE ?
|
||||
*
|
||||
* @param string $sql The query to prepare.
|
||||
* @return PreparedStatement
|
||||
* @throws SQLException
|
||||
* @see PreparedStatement::execute()
|
||||
*/
|
||||
public function prepareStatement($sql);
|
||||
|
||||
/**
|
||||
* Creates a new empty Statement.
|
||||
* @return Statement
|
||||
*/
|
||||
public function createStatement();
|
||||
|
||||
/**
|
||||
* If RDBMS supports native LIMIT/OFFSET then query SQL is modified
|
||||
* so that no emulation is performed in ResultSet.
|
||||
*
|
||||
* @param string &$sql The query that will be modified.
|
||||
* @param int $offset
|
||||
* @param int $limit
|
||||
* @return void
|
||||
* @throws SQLException - if unable to modify query for any reason.
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit);
|
||||
|
||||
/**
|
||||
* Executes the SQL query in this PreparedStatement object and returns the resultset.
|
||||
*
|
||||
* @param string $sql The SQL statement.
|
||||
* @param int $fetchmode
|
||||
* @return object ResultSet
|
||||
* @throws SQLException if a database access error occurs.
|
||||
*/
|
||||
public function executeQuery($sql, $fetchmode = null);
|
||||
|
||||
/**
|
||||
* Executes the SQL INSERT, UPDATE, or DELETE statement.
|
||||
*
|
||||
* @param string $sql This method may optionally be called with the SQL statement.
|
||||
* @return int Number of affected rows (or 0 for drivers that return nothing).
|
||||
* @throws SQLException if a database access error occurs.
|
||||
*/
|
||||
public function executeUpdate($sql);
|
||||
|
||||
/**
|
||||
* Creates a CallableStatement object for calling database stored procedures.
|
||||
*
|
||||
* @param string $sql
|
||||
* @return CallableStatement
|
||||
*/
|
||||
public function prepareCall($sql);
|
||||
|
||||
/**
|
||||
* Free the db resources.
|
||||
* @return void
|
||||
*/
|
||||
public function close();
|
||||
|
||||
/**
|
||||
* Returns false if connection is closed.
|
||||
* @return boolean
|
||||
*/
|
||||
public function isConnected();
|
||||
|
||||
/**
|
||||
* Get auto-commit status.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getAutoCommit();
|
||||
|
||||
/**
|
||||
* Enable/disable automatic commits.
|
||||
*
|
||||
* Pushes SQLWarning onto $warnings stack if the autocommit value is being changed mid-transaction. This function
|
||||
* is overridden by driver classes so that they can perform the necessary begin/end transaction SQL.
|
||||
*
|
||||
* If auto-commit is being set to TRUE, then the current transaction will be committed immediately.
|
||||
*
|
||||
* @param boolean $bit New value for auto commit.
|
||||
* @return void
|
||||
*/
|
||||
public function setAutoCommit($bit);
|
||||
|
||||
/**
|
||||
* Begins a transaction (if supported).
|
||||
*
|
||||
*/
|
||||
public function begin();
|
||||
|
||||
/**
|
||||
* Commits statements in a transaction.
|
||||
*
|
||||
*/
|
||||
public function commit();
|
||||
|
||||
/**
|
||||
* Rollback changes in a transaction.
|
||||
*
|
||||
*/
|
||||
public function rollback();
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the data manipulation
|
||||
* query.
|
||||
*
|
||||
* @return int Number of rows affected by the last query.
|
||||
*/
|
||||
public function getUpdateCount();
|
||||
|
||||
}
|
||||
377
lib/symfony/vendor/creole/Creole.php
vendored
Executable file
377
lib/symfony/vendor/creole/Creole.php
vendored
Executable file
@ -0,0 +1,377 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: Creole.php,v 1.14 2006/01/17 20:06:31 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
include_once 'creole/SQLException.php';
|
||||
include_once 'creole/Connection.php';
|
||||
|
||||
// static:
|
||||
// track errors is used by drivers to get better error messages
|
||||
// make sure it's set.
|
||||
|
||||
@ini_set('track_errors', true);
|
||||
|
||||
/**
|
||||
* This is the class that manages the database drivers.
|
||||
*
|
||||
* There are a number of default drivers (at the time of writing this comment: MySQL, MSSQL, SQLite, PgSQL, Oracle)
|
||||
* that are "shipped" with Creole. You may wish to either add a new driver or swap out one of the existing drivers
|
||||
* for your own custom driver. To do this you simply need to register your driver using the registerDriver() method.
|
||||
*
|
||||
* Note that you register your Connection class because the Connection class is responsible for calling the other
|
||||
* driver classes (e.g. ResultSet, PreparedStatement, etc.).
|
||||
*
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.14 $
|
||||
* @package creole
|
||||
*/
|
||||
class Creole {
|
||||
|
||||
/**
|
||||
* Constant that indicates a connection object should be used.
|
||||
*/
|
||||
const PERSISTENT = 1;
|
||||
|
||||
/**
|
||||
* Flag to pass to the connection to indicate that no case conversions
|
||||
* should be performed by ResultSet on keys of fetched rows.
|
||||
* @deprecated use COMPAT_ASSOC_LOWER
|
||||
*/
|
||||
const NO_ASSOC_LOWER = 16;
|
||||
|
||||
/**
|
||||
* Flag to pass to the connection to indicate that a to-lower case conversion
|
||||
* should be performed by ResultSet on keys of fetched rows.
|
||||
*/
|
||||
const COMPAT_ASSOC_LOWER = 32;
|
||||
|
||||
/**
|
||||
* Flag to pass to the connection to indicate that an rtrim() should be performed
|
||||
* on strings (using ResultSet->getString(), etc.).
|
||||
*/
|
||||
const COMPAT_RTRIM_STRING = 64;
|
||||
|
||||
/**
|
||||
* Flag to indicate that all compatibility flags should be set.
|
||||
*/
|
||||
const COMPAT_ALL = 96;
|
||||
|
||||
/**
|
||||
* Map of built-in drivers.
|
||||
* Change or add your own using registerDriver()
|
||||
* @see registerDriver()
|
||||
* @var array Hash mapping phptype => driver class (in dot-path notation, e.g. 'mysql' => 'creole.drivers.mysql.MySQLConnection').
|
||||
*/
|
||||
private static $driverMap = array( 'mysql' => 'creole.drivers.mysql.MySQLConnection',
|
||||
'mysqli' => 'creole.drivers.mysqli.MySQLiConnection',
|
||||
'pgsql' => 'creole.drivers.pgsql.PgSQLConnection',
|
||||
'sqlite' => 'creole.drivers.sqlite.SQLiteConnection',
|
||||
'oracle' => 'creole.drivers.oracle.OCI8Connection',
|
||||
'mssql' => 'creole.drivers.mssql.MSSQLConnection',
|
||||
'odbc' => 'creole.drivers.odbc.ODBCConnection'
|
||||
);
|
||||
|
||||
/**
|
||||
* Map of already established connections
|
||||
* @see getConnection()
|
||||
* @var array Hash mapping connection DSN => Connection instance
|
||||
*/
|
||||
private static $connectionMap = array();
|
||||
|
||||
/**
|
||||
* Register your own RDBMS driver class.
|
||||
*
|
||||
* You can use this to specify your own class that replaces a default driver or
|
||||
* adds support for a new driver. Register your own class by specifying the
|
||||
* 'phptype' (e.g. mysql) and a dot-path notation to where your Connection class is
|
||||
* relative to any location on the include path. You can also specify '*' as the phptype
|
||||
* if you want to register a driver that will handle any native type (e.g. if creating
|
||||
* a set of decorator classes that log SQL before calling native driver methods). YOU CAN
|
||||
* ONLY REGISTER ONE CATCHALL ('*') DRIVER.
|
||||
* <p>
|
||||
* Note: the class you need to register is your Connection class because this is the
|
||||
* class that's responsible for instantiating the other classes that are part of your
|
||||
* driver. It is possible to mix & match drivers -- i.e. to write a custom driver where
|
||||
* the Connection object just instantiates stock classes for ResultSet and PreparedStatement.
|
||||
* Note that if you wanted to "override" only the ResultSet class you would also have to override
|
||||
* the Connection and PreparedStatement classes so that they would return the correct ResultSet
|
||||
* class. In the future we may implement a more "packaged" approach to drivers; for now we
|
||||
* want to keep it simple.
|
||||
*
|
||||
* @param string $phptype The phptype (mysql, mssql, etc.). This is first part of DSN URL (e.g. mysql://localhost/...).
|
||||
* You may also specify '*' to register a driver that will "wrap" the any native drivers.
|
||||
* @param string $dotpath A dot-path locating your class. For example 'creole.drivers.mssql.MSSQLConnection'
|
||||
* will be included like: include 'creole/drivers/mssql/MSSQLConnection.php' and the
|
||||
* classname will be assumed to be 'MSSQLConnection'.
|
||||
* @return void
|
||||
*/
|
||||
public static function registerDriver($phptype, $dotpath)
|
||||
{
|
||||
self::$driverMap[$phptype] = $dotpath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the driver for a PHP type. Note that this will remove user-registered
|
||||
* drivers _and_ the default drivers.
|
||||
* @param string $phptype The PHP type for driver to de-register.
|
||||
* @see registerDriver()
|
||||
*/
|
||||
public static function deregisterDriver($phptype)
|
||||
{
|
||||
unset(self::$driverMap[$phptype]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class path to the driver registered for specified type.
|
||||
* @param string $phptype The phptype handled by driver (e.g. 'mysql', 'mssql', '*').
|
||||
* @return string The driver class in dot-path notation (e.g. creole.drivers.mssql.MSSQLConnection)
|
||||
* or NULL if no registered driver found.
|
||||
*/
|
||||
public static function getDriver($phptype)
|
||||
{
|
||||
if (isset(self::$driverMap[$phptype])) {
|
||||
return self::$driverMap[$phptype];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new DB connection object and connect to the specified
|
||||
* database
|
||||
*
|
||||
* @param mixed $dsn "data source name", see the self::parseDSN
|
||||
* method for a description of the dsn format. Can also be
|
||||
* specified as an array of the format returned by DB::parseDSN().
|
||||
|
||||
* @param int $flags Connection flags (e.g. PERSISTENT).
|
||||
*
|
||||
* @return Connection Newly created DB connection object
|
||||
* @throws SQLException
|
||||
* @see self::parseDSN()
|
||||
*/
|
||||
public static function getConnection($dsn, $flags = 0)
|
||||
{
|
||||
if (is_array($dsn)) {
|
||||
$dsninfo = $dsn;
|
||||
} else {
|
||||
$dsninfo = self::parseDSN($dsn);
|
||||
}
|
||||
|
||||
// gather any flags from the DSN
|
||||
if ( isset ( $dsninfo['persistent'] ) && ! empty ( $dsninfo['persistent'] ) )
|
||||
$flags |= Creole::PERSISTENT;
|
||||
if ( isset ( $dsninfo['compat_assoc_lower'] ) && ! empty ( $dsninfo['compat_assoc_lower'] ) )
|
||||
$flags |= Creole::COMPAT_ASSOC_LOWER;
|
||||
if ( isset ( $dsninfo['compat_rtrim_string'] ) && ! empty ( $dsninfo['compat_rtrim_string'] ) )
|
||||
$flags |= Creole::COMPAT_RTRIM_STRING;
|
||||
if ( isset ( $dsninfo['compat_all'] ) && ! empty ( $dsninfo['compat_all'] ) )
|
||||
$flags |= Creole::COMPAT_ALL;
|
||||
|
||||
if ($flags & Creole::NO_ASSOC_LOWER) {
|
||||
trigger_error("The Creole::NO_ASSOC_LOWER flag has been deprecated, and is now the default behavior. Use Creole::COMPAT_ASSOC_LOWER to lowercase resulset keys.", E_USER_WARNING);
|
||||
}
|
||||
|
||||
// sort $dsninfo by keys so the serialized result is always the same
|
||||
// for identical connection parameters, no matter what their order is
|
||||
ksort($dsninfo);
|
||||
$connectionMapKey = crc32(serialize($dsninfo + array('compat_flags' => ($flags & Creole::COMPAT_ALL))));
|
||||
|
||||
// see if we already have a connection with these parameters cached
|
||||
if(isset(self::$connectionMap[$connectionMapKey]))
|
||||
{
|
||||
// persistent connections will be used if a non-persistent one was requested and is available
|
||||
// but a persistent connection will be created if a non-persistent one is present
|
||||
|
||||
// TODO: impliment auto close of non persistent and replacing the
|
||||
// non persistent with the persistent object so as we dont have
|
||||
// both links open for no reason
|
||||
|
||||
if( isset(self::$connectionMap[$connectionMapKey][1]) ) { // is persistent
|
||||
// a persistent connection with these parameters is already there,
|
||||
// so we return it, no matter what was specified as persistent flag
|
||||
$con = self::$connectionMap[$connectionMapKey][1];
|
||||
} else {
|
||||
// we don't have a persistent connection, and since the persistent
|
||||
// flag wasn't set either, we just return the non-persistent connection
|
||||
$con = self::$connectionMap[$connectionMapKey][0];
|
||||
}
|
||||
|
||||
// if we're here, a non-persistent connection was already there, but
|
||||
// the user wants a persistent one, so it will be created
|
||||
|
||||
if ($con->isConnected())
|
||||
return $con;
|
||||
}
|
||||
|
||||
// support "catchall" drivers which will themselves handle the details of connecting
|
||||
// using the proper RDBMS driver.
|
||||
if (isset(self::$driverMap['*'])) {
|
||||
$type = '*';
|
||||
} else {
|
||||
$type = $dsninfo['phptype'];
|
||||
if (!isset(self::$driverMap[$type])) {
|
||||
throw new SQLException("No driver has been registered to handle connection type: $type");
|
||||
}
|
||||
}
|
||||
|
||||
// may need to make this more complex if we add support
|
||||
// for 'dbsyntax'
|
||||
$clazz = self::import(self::$driverMap[$type]);
|
||||
$obj = new $clazz();
|
||||
|
||||
if (!($obj instanceof Connection)) {
|
||||
throw new SQLException("Class does not implement creole.Connection interface: $clazz");
|
||||
}
|
||||
|
||||
try {
|
||||
$obj->connect($dsninfo, $flags);
|
||||
} catch(SQLException $sqle) {
|
||||
$sqle->setUserInfo($dsninfo);
|
||||
throw $sqle;
|
||||
}
|
||||
$persistent = ($flags & Creole::PERSISTENT) === Creole::PERSISTENT;
|
||||
return self::$connectionMap[$connectionMapKey][(int)$persistent] = $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a data source name.
|
||||
*
|
||||
* This isn't quite as powerful as DB::parseDSN(); it's also a lot simpler, a lot faster,
|
||||
* and many fewer lines of code.
|
||||
*
|
||||
* A array with the following keys will be returned:
|
||||
* phptype: Database backend used in PHP (mysql, odbc etc.)
|
||||
* protocol: Communication protocol to use (tcp, unix etc.)
|
||||
* hostspec: Host specification (hostname[:port])
|
||||
* database: Database to use on the DBMS server
|
||||
* username: User name for login
|
||||
* password: Password for login
|
||||
*
|
||||
* The format of the supplied DSN is in its fullest form:
|
||||
*
|
||||
* phptype://username:password@protocol+hostspec/database
|
||||
*
|
||||
* Most variations are allowed:
|
||||
*
|
||||
* phptype://username:password@protocol+hostspec:110//usr/db_file.db
|
||||
* phptype://username:password@hostspec/database_name
|
||||
* phptype://username:password@hostspec
|
||||
* phptype://username@hostspec
|
||||
* phptype://hostspec/database
|
||||
* phptype://hostspec
|
||||
* phptype
|
||||
*
|
||||
* @param string $dsn Data Source Name to be parsed
|
||||
* @return array An associative array
|
||||
*/
|
||||
public static function parseDSN($dsn)
|
||||
{
|
||||
if (is_array($dsn)) {
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
$parsed = array(
|
||||
'phptype' => null,
|
||||
'username' => null,
|
||||
'password' => null,
|
||||
'protocol' => null,
|
||||
'hostspec' => null,
|
||||
'port' => null,
|
||||
'socket' => null,
|
||||
'database' => null
|
||||
);
|
||||
|
||||
$info = parse_url($dsn);
|
||||
|
||||
if (count($info) === 1) { // if there's only one element in result, then it must be the phptype
|
||||
$parsed['phptype'] = array_pop($info);
|
||||
return $parsed;
|
||||
}
|
||||
|
||||
// some values can be copied directly
|
||||
$parsed['phptype'] = @$info['scheme'];
|
||||
$parsed['username'] = @$info['user'];
|
||||
$parsed['password'] = @$info['pass'];
|
||||
$parsed['port'] = @$info['port'];
|
||||
|
||||
$host = @$info['host'];
|
||||
if (false !== ($pluspos = strpos($host, '+'))) {
|
||||
$parsed['protocol'] = substr($host,0,$pluspos);
|
||||
if ($parsed['protocol'] === 'unix') {
|
||||
$parsed['socket'] = substr($host,$pluspos+1);
|
||||
} else {
|
||||
$parsed['hostspec'] = substr($host,$pluspos+1);
|
||||
}
|
||||
} else {
|
||||
$parsed['hostspec'] = $host;
|
||||
}
|
||||
|
||||
if (isset($info['path'])) {
|
||||
$parsed['database'] = substr($info['path'], 1); // remove first char, which is '/'
|
||||
}
|
||||
|
||||
if (isset($info['query'])) {
|
||||
$opts = explode('&', $info['query']);
|
||||
foreach ($opts as $opt) {
|
||||
list($key, $value) = explode('=', $opt);
|
||||
if (!isset($parsed[$key])) { // don't allow params overwrite
|
||||
$parsed[$key] = urldecode($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include once a file specified in DOT notation.
|
||||
* Package notation is expected to be relative to a location
|
||||
* on the PHP include_path.
|
||||
* @param string $class
|
||||
* @return string unqualified classname
|
||||
* @throws SQLException - if class does not exist and cannot load file
|
||||
* - if after loading file class still does not exist
|
||||
*/
|
||||
public static function import($class) {
|
||||
$pos = strrpos($class, '.');
|
||||
// get just classname ('path.to.ClassName' -> 'ClassName')
|
||||
if ($pos !== false) {
|
||||
$classname = substr($class, $pos + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$classname = $class;
|
||||
}
|
||||
if (!class_exists($classname, false)) {
|
||||
$path = strtr($class, '.', DIRECTORY_SEPARATOR) . '.php';
|
||||
$ret = include_once($path);
|
||||
if ($ret === false) {
|
||||
throw new SQLException("Unable to load driver class: " . $class);
|
||||
}
|
||||
if (!class_exists($classname)) {
|
||||
throw new SQLException("Unable to find loaded class: $classname (Hint: make sure classname matches filename)");
|
||||
}
|
||||
}
|
||||
return $classname;
|
||||
}
|
||||
|
||||
}
|
||||
187
lib/symfony/vendor/creole/CreoleTypes.php
vendored
Executable file
187
lib/symfony/vendor/creole/CreoleTypes.php
vendored
Executable file
@ -0,0 +1,187 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: CreoleTypes.php,v 1.18 2005/11/07 22:38:52 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generic Creole types modeled on JDBC types.
|
||||
*
|
||||
* @author David Giffin <david@giffin.org>
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.18 $
|
||||
* @package creole
|
||||
*/
|
||||
abstract class CreoleTypes {
|
||||
|
||||
const BOOLEAN = 1;
|
||||
const BIGINT = 2;
|
||||
const SMALLINT = 3;
|
||||
const TINYINT = 4;
|
||||
const INTEGER = 5;
|
||||
const CHAR = 6;
|
||||
const VARCHAR = 7;
|
||||
const TEXT = 17;
|
||||
const FLOAT = 8;
|
||||
const DOUBLE = 9;
|
||||
const DATE = 10;
|
||||
const TIME = 11;
|
||||
const TIMESTAMP = 12;
|
||||
const VARBINARY = 13;
|
||||
const NUMERIC = 14;
|
||||
const BLOB = 15;
|
||||
const CLOB = 16;
|
||||
const LONGVARCHAR = 17;
|
||||
const DECIMAL = 18;
|
||||
const REAL = 19;
|
||||
const BINARY = 20;
|
||||
const LONGVARBINARY = 21;
|
||||
const YEAR = 22;
|
||||
|
||||
/** this is "ARRAY" from JDBC types */
|
||||
const ARR = 23;
|
||||
|
||||
const OTHER = -1;
|
||||
|
||||
/** Map of Creole type integers to the setter/getter affix. */
|
||||
protected static $affixMap = array(
|
||||
self::BOOLEAN => 'Boolean',
|
||||
self::BIGINT => 'String',
|
||||
self::CHAR => 'String',
|
||||
self::DATE => 'Date',
|
||||
self::DOUBLE => 'Float',
|
||||
self::FLOAT => 'Float',
|
||||
self::INTEGER => 'Int',
|
||||
self::SMALLINT => 'Int',
|
||||
self::TINYINT => 'Int',
|
||||
self::TIME => 'Time',
|
||||
self::TIMESTAMP => 'Timestamp',
|
||||
self::VARCHAR => 'String',
|
||||
self::VARBINARY => 'Blob',
|
||||
self::NUMERIC => 'Float',
|
||||
self::BLOB => 'Blob',
|
||||
self::CLOB => 'Clob',
|
||||
self::LONGVARCHAR => 'String',
|
||||
self::DECIMAL => 'Float',
|
||||
self::REAL => 'Float',
|
||||
self::BINARY => 'Blob',
|
||||
self::LONGVARBINARY => 'Blob',
|
||||
self::YEAR => 'Int',
|
||||
self::ARR => 'Array',
|
||||
self::OTHER => '', // get() and set() for unknown
|
||||
);
|
||||
|
||||
/** Map of Creole type integers to their textual name. */
|
||||
protected static $creoleTypeMap = array(
|
||||
self::BOOLEAN => 'BOOLEAN',
|
||||
self::BIGINT => 'BIGINT',
|
||||
self::SMALLINT => 'SMALLINT',
|
||||
self::TINYINT => 'TINYINT',
|
||||
self::INTEGER => 'INTEGER',
|
||||
self::NUMERIC => 'NUMERIC',
|
||||
self::DECIMAL => 'DECIMAL',
|
||||
self::REAL => 'REAL',
|
||||
self::FLOAT => 'FLOAT',
|
||||
self::DOUBLE => 'DOUBLE',
|
||||
self::CHAR => 'CHAR',
|
||||
self::VARCHAR => 'VARCHAR',
|
||||
self::TEXT => 'TEXT',
|
||||
self::TIME => 'TIME',
|
||||
self::TIMESTAMP => 'TIMESTAMP',
|
||||
self::DATE => 'DATE',
|
||||
self::YEAR => 'YEAR',
|
||||
self::VARBINARY => 'VARBINARY',
|
||||
self::BLOB => 'BLOB',
|
||||
self::CLOB => 'CLOB',
|
||||
self::LONGVARCHAR => 'LONGVARCHAR',
|
||||
self::BINARY => 'BINARY',
|
||||
self::LONGVARBINARY => 'LONGVARBINARY',
|
||||
self::ARR => 'ARR',
|
||||
self::OTHER => 'OTHER', // string is "raw" return
|
||||
);
|
||||
|
||||
/**
|
||||
* This method returns the generic Creole (JDBC-like) type
|
||||
* when given the native db type.
|
||||
* @param string $nativeType DB native type (e.g. 'TEXT', 'byetea', etc.).
|
||||
* @return int Creole native type (e.g. Types::LONGVARCHAR, Types::BINARY, etc.).
|
||||
*/
|
||||
public static function getType($nativeType) {
|
||||
throw new Exception('This method must be overridden in subclasses!'); // abstract static not allowed since PHP 5.2
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return a native type that corresponds to the specified
|
||||
* Creole (JDBC-like) type.
|
||||
* If there is more than one matching native type, then the LAST defined
|
||||
* native type will be returned.
|
||||
* @return string Native type string.
|
||||
*/
|
||||
public static function getNativeType($creoleType) {
|
||||
throw new Exception('This method must be overridden in subclasses!'); // abstract static not allowed since PHP 5.2
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the "affix" to use for ResultSet::get*() and PreparedStatement::set*() methods.
|
||||
* <code>
|
||||
* $setter = 'set' . CreoleTypes::getAffix(CreoleTypes::INTEGER);
|
||||
* $stmt->$setter(1, $intval);
|
||||
* // or
|
||||
* $getter = 'get' . CreoleTypes::getAffix(CreoleTypes::TIMESTAMP);
|
||||
* $timestamp = $rs->$getter();
|
||||
* </code>
|
||||
* @param int $creoleType The Creole types.
|
||||
* @return string The default affix for getting/setting cols of this type.
|
||||
* @throws SQLException if $creoleType does not correspond to an affix
|
||||
*/
|
||||
public static function getAffix($creoleType)
|
||||
{
|
||||
if (!isset(self::$affixMap[$creoleType])) {
|
||||
$e = new SQLException("Unable to return 'affix' for unknown CreoleType: " . $creoleType);
|
||||
throw $e;
|
||||
}
|
||||
return self::$affixMap[$creoleType];
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the integer type, this method will return the corresponding type name.
|
||||
* @param int $creoleType the integer Creole type.
|
||||
* @return string The name of the Creole type (e.g. 'VARCHAR').
|
||||
*/
|
||||
public static function getCreoleName($creoleType)
|
||||
{
|
||||
if (!isset(self::$creoleTypeMap[$creoleType])) {
|
||||
return null;
|
||||
}
|
||||
return self::$creoleTypeMap[$creoleType];
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the name of a type (e.g. 'VARCHAR') this method will return the corresponding integer.
|
||||
* @param string $creoleTypeName The case-sensisive (must be uppercase) name of the Creole type (e.g. 'VARCHAR').
|
||||
* @return int the Creole type.
|
||||
*/
|
||||
public static function getCreoleCode($creoleTypeName)
|
||||
{
|
||||
$type = array_search($creoleTypeName, self::$creoleTypeMap);
|
||||
if ($type === false) {
|
||||
return null;
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
57
lib/symfony/vendor/creole/IdGenerator.php
vendored
Executable file
57
lib/symfony/vendor/creole/IdGenerator.php
vendored
Executable file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Interface for classes that provide functionality to get SEQUENCE or AUTO-INCREMENT ids from the database.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.3 $
|
||||
* @package creole
|
||||
*/
|
||||
interface IdGenerator {
|
||||
|
||||
/** SEQUENCE id generator type */
|
||||
const SEQUENCE = 1;
|
||||
|
||||
/** AUTO INCREMENT id generator type */
|
||||
const AUTOINCREMENT = 2;
|
||||
|
||||
/**
|
||||
* Convenience method that returns TRUE if id is generated
|
||||
* before an INSERT statement. This is the same as checking
|
||||
* whether the generator type is SEQUENCE.
|
||||
* @return boolean TRUE if gen id method is SEQUENCE
|
||||
* @see getIdMethod()
|
||||
*/
|
||||
public function isBeforeInsert();
|
||||
|
||||
/**
|
||||
* Convenience method that returns TRUE if id is generated
|
||||
* after an INSERT statement. This is the same as checking
|
||||
* whether the generator type is AUTOINCREMENT.
|
||||
* @return boolean TRUE if gen id method is AUTOINCREMENT
|
||||
* @see getIdMethod()
|
||||
*/
|
||||
public function isAfterInsert();
|
||||
|
||||
/**
|
||||
* Get the preferred type / style for generating ids for RDBMS.
|
||||
* @return int SEQUENCE or AUTOINCREMENT
|
||||
*/
|
||||
public function getIdMethod();
|
||||
|
||||
/**
|
||||
* Get the autoincrement or sequence id given the current connection
|
||||
* and any additional needed info (e.g. sequence name for sequences).
|
||||
* <p>
|
||||
* Note: if you take advantage of the fact that $keyInfo may not be specified
|
||||
* you should make sure that your code is setup in such a way that it will
|
||||
* be portable if you change from an RDBMS that uses AUTOINCREMENT to one that
|
||||
* uses SEQUENCE (i.e. in which case you would need to specify sequence name).
|
||||
*
|
||||
* @param mixed $keyInfo Any additional information (e.g. sequence name) needed to fetch the id.
|
||||
* @return int The last id / next id.
|
||||
*/
|
||||
public function getId($keyInfo = null);
|
||||
|
||||
}
|
||||
|
||||
253
lib/symfony/vendor/creole/PreparedStatement.php
vendored
Executable file
253
lib/symfony/vendor/creole/PreparedStatement.php
vendored
Executable file
@ -0,0 +1,253 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PreparedStatement.php,v 1.21 2005/03/29 16:56:09 gamr Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface for a pre-compiled SQL statement.
|
||||
*
|
||||
* Many drivers do not take advantage of pre-compiling SQL statements; for these
|
||||
* cases the precompilation is emulated. This emulation comes with slight penalty involved
|
||||
* in parsing the queries, but provides other benefits such as a cleaner object model and ability
|
||||
* to work with BLOB and CLOB values w/o needing special LOB-specific routines.
|
||||
*
|
||||
* This class is abstract because there are driver-specific implementations in [clearly] how queries
|
||||
* are executed, and how parameters are bound.
|
||||
*
|
||||
* This class is not as abstract as the JDBC version. For exmple, if you are using a driver
|
||||
* that uses name-based query param substitution, then you'd better bind your variables to
|
||||
* names rather than index numbers. e.g. in Oracle
|
||||
* <code>
|
||||
* $stmt = $conn->prepareStatement("INSERT INTO users (name, passwd) VALUES (:name, :pass)");
|
||||
* $stmt->setString(":name", $name);
|
||||
* $stmt->executeUpdate();
|
||||
* </code>
|
||||
*
|
||||
* Developer note: In many ways this interface is an extension of the Statement interface. However, due
|
||||
* to limitations in PHP5's interface extension model (specifically that you cannot change signatures on
|
||||
* methods defined in parent interface), we cannot extend the Statement interface.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.21 $
|
||||
* @package creole
|
||||
*/
|
||||
interface PreparedStatement {
|
||||
|
||||
/**
|
||||
* Gets the db Connection that created this statement.
|
||||
* @return Connection
|
||||
*/
|
||||
public function getConnection();
|
||||
|
||||
/**
|
||||
* Get the PHP native resource for the statement (if supported).
|
||||
* @return resource
|
||||
*/
|
||||
public function getResource();
|
||||
|
||||
/**
|
||||
* Free resources associated with this statement.
|
||||
* Some drivers will need to implement this method to free
|
||||
* database result resources.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function close();
|
||||
|
||||
/**
|
||||
* Get result set.
|
||||
* This assumes that the last thing done was an executeQuery() or an execute()
|
||||
* with SELECT-type query.
|
||||
*
|
||||
* @return RestultSet Last ResultSet or <code>null</code> if not applicable.
|
||||
*/
|
||||
public function getResultSet();
|
||||
|
||||
/**
|
||||
* Gets next result set (if this behavior is supported by driver).
|
||||
* Some drivers (e.g. MSSQL) support returning multiple result sets -- e.g.
|
||||
* from stored procedures.
|
||||
*
|
||||
* This function also closes any current restult set.
|
||||
*
|
||||
* Default behavior is for this function to return false. Driver-specific
|
||||
* implementations of this class can override this method if they actually
|
||||
* support multiple result sets.
|
||||
*
|
||||
* @return boolean True if there is another result set, otherwise false.
|
||||
*/
|
||||
public function getMoreResults();
|
||||
|
||||
/**
|
||||
* Get update count.
|
||||
*
|
||||
* @return int Number of records affected, or <code>null</code> if not applicable.
|
||||
*/
|
||||
public function getUpdateCount();
|
||||
|
||||
/**
|
||||
* Sets the maximum number of rows to return from db.
|
||||
* This will affect the SQL if the RDBMS supports native LIMIT; if not,
|
||||
* it will be emulated. Limit only applies to queries (not update sql).
|
||||
* @param int $v Maximum number of rows or 0 for all rows.
|
||||
* @return void
|
||||
*/
|
||||
public function setLimit($v);
|
||||
|
||||
/**
|
||||
* Returns the maximum number of rows to return or 0 for all.
|
||||
* @return int
|
||||
*/
|
||||
public function getLimit();
|
||||
|
||||
/**
|
||||
* Sets the start row.
|
||||
* This will affect the SQL if the RDBMS supports native OFFSET; if not,
|
||||
* it will be emulated. Offset only applies to queries (not update) and
|
||||
* only is evaluated when LIMIT is set!
|
||||
* @param int $v
|
||||
* @return void
|
||||
*/
|
||||
public function setOffset($v);
|
||||
|
||||
/**
|
||||
* Returns the start row.
|
||||
* Offset only applies when Limit is set!
|
||||
* @return int
|
||||
*/
|
||||
public function getOffset();
|
||||
|
||||
/**
|
||||
* Executes the SQL query in this PreparedStatement object and returns the resultset generated by the query.
|
||||
* We support two signatures for this method:
|
||||
* - $stmt->executeQuery(ResultSet::FETCHMODE_NUM);
|
||||
* - $stmt->executeQuery(array($param1, $param2), ResultSet::FETCHMODE_NUM);
|
||||
* @param mixed $p1 Either (array) Parameters that will be set using PreparedStatement::set() before query is executed or (int) fetchmode.
|
||||
* @param int $fetchmode The mode to use when fetching the results (e.g. ResultSet::FETCHMODE_NUM, ResultSet::FETCHMODE_ASSOC).
|
||||
* @return ResultSet
|
||||
* @throws SQLException if a database access error occurs.
|
||||
*/
|
||||
public function executeQuery();
|
||||
|
||||
/**
|
||||
* Executes the SQL INSERT, UPDATE, or DELETE statement in this PreparedStatement object.
|
||||
*
|
||||
* @param array $params Parameters that will be set using PreparedStatement::set() before query is executed.
|
||||
* @return int Number of affected rows (or 0 for drivers that return nothing).
|
||||
* @throws SQLException if a database access error occurs.
|
||||
*/
|
||||
public function executeUpdate($params = null);
|
||||
|
||||
/**
|
||||
* A generic set method.
|
||||
*
|
||||
* You can use this if you don't want to concern yourself with the details. It involves
|
||||
* slightly more overhead than the specific settesr, since it grabs the PHP type to determine
|
||||
* which method makes most sense.
|
||||
*
|
||||
* @param int $paramIndex
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function set($paramIndex, $value);
|
||||
|
||||
/**
|
||||
* Sets an array.
|
||||
* Unless a driver-specific method is used, this means simply serializing
|
||||
* the passed parameter and storing it as a string.
|
||||
* @param int $paramIndex
|
||||
* @param array $value
|
||||
* @return void
|
||||
*/
|
||||
public function setArray($paramIndex, $value);
|
||||
|
||||
/**
|
||||
* Sets a boolean value.
|
||||
* Default behavior is true = 1, false = 0.
|
||||
* @param int $paramIndex
|
||||
* @param boolean $value
|
||||
* @return void
|
||||
*/
|
||||
public function setBoolean($paramIndex, $value);
|
||||
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param mixed $blob Blob object or string containing data.
|
||||
* @return void
|
||||
*/
|
||||
public function setBlob($paramIndex, $blob);
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param mixed $clob Clob object or string containing data.
|
||||
* @return void
|
||||
*/
|
||||
public function setClob($paramIndex, $clob);
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
public function setDate($paramIndex, $value);
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param float $value
|
||||
* @return void
|
||||
*/
|
||||
public function setFloat($paramIndex, $value);
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param int $value
|
||||
* @return void
|
||||
*/
|
||||
public function setInt($paramIndex, $value);
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @return void
|
||||
*/
|
||||
public function setNull($paramIndex);
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
public function setString($paramIndex, $value);
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
public function setTime($paramIndex, $value);
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
public function setTimestamp($paramIndex, $value);
|
||||
|
||||
}
|
||||
380
lib/symfony/vendor/creole/ResultSet.php
vendored
Executable file
380
lib/symfony/vendor/creole/ResultSet.php
vendored
Executable file
@ -0,0 +1,380 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ResultSet.php,v 1.28 2006/01/17 19:44:38 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the interface for classes the wrap db results.
|
||||
*
|
||||
* The get*() methods in this interface will format values before returning them. Note
|
||||
* that if they will return null if the database returned NULL. If the requested column does
|
||||
* not exist than an exception (SQLException) will be thrown.
|
||||
*
|
||||
* <code>
|
||||
* $rs = $conn->executeQuery("SELECT MAX(stamp) FROM event", ResultSet::FETCHMODE_NUM);
|
||||
* $rs->next();
|
||||
*
|
||||
* $max_stamp = $rs->getTimestamp(1, "d/m/Y H:i:s");
|
||||
* // $max_stamp will be date string or null if no MAX(stamp) was found
|
||||
*
|
||||
* $max_stamp = $rs->getTimestamp("max(stamp)", "d/m/Y H:i:s");
|
||||
* // will THROW EXCEPTION, because the resultset was fetched using numeric indexing
|
||||
* // SQLException: Invalid resultset column: max(stamp)
|
||||
* </code>
|
||||
*
|
||||
* This class implements SPL IteratorAggregate, so you may iterate over the database results
|
||||
* using foreach():
|
||||
* <code>
|
||||
* foreach($rs as $row) {
|
||||
* print_r($row); // row is assoc array returned by getRow()
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.28 $
|
||||
* @package creole
|
||||
*/
|
||||
interface ResultSet extends IteratorAggregate {
|
||||
|
||||
/**
|
||||
* Index result set by field name.
|
||||
*/
|
||||
const FETCHMODE_ASSOC = 1;
|
||||
|
||||
/**
|
||||
* Index result set numerically.
|
||||
*/
|
||||
const FETCHMODE_NUM = 2;
|
||||
|
||||
/**
|
||||
* Get the PHP native resource for the result.
|
||||
* Arguably this should not be part of the interface: i.e. every driver should implement
|
||||
* it if they have a result resource, but conceivably drivers could be created that do
|
||||
* not. For now every single driver does have a "dblink" resource property, and other
|
||||
* classes (e.g. ResultSet) need this info in order to get correct native errors. We'll
|
||||
* leave it in for now, as it helps with driver development, with the caveat that it
|
||||
* could be removed from the interface at a later point.
|
||||
* @return resource Query result or NULL if not not applicable.
|
||||
*/
|
||||
public function getResource();
|
||||
|
||||
/**
|
||||
* Sets the fetchmode used to retrieve results.
|
||||
* Changing fetchmodes mid-result retrieval is supported (haven't encountered any drivers
|
||||
* that don't support that yet).
|
||||
* @param int $mode ResultSet::FETCHMODE_NUM or ResultSet::FETCHMODE_ASSOC (default).
|
||||
* @return void
|
||||
*/
|
||||
public function setFetchmode($mode);
|
||||
|
||||
/**
|
||||
* Gets the fetchmode used to retrieve results.
|
||||
* @return int ResultSet::FETCHMODE_NUM or ResultSet::FETCHMODE_ASSOC (default).
|
||||
*/
|
||||
public function getFetchmode();
|
||||
|
||||
/**
|
||||
* Whether assoc result keys get converted to lowercase for compatibility.
|
||||
*
|
||||
* This defaults to FALSE unless Creole::COMPAT_ASSOC_LOWER flag has been passed to connection.
|
||||
* This property is read-only since it must be set when connection is created. The
|
||||
* reason for this behavior is some drivers (e.g. SQLite) do the case conversions internally
|
||||
* based on a PHP ini value; it would not be possible to change the behavior from the ResultSet
|
||||
* (since query has already been executed).
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isLowerAssocCase();
|
||||
|
||||
/**
|
||||
* Moves the internal cursor to the next position and fetches the row at that position.
|
||||
*
|
||||
* @return boolean <tt>true</tt> if success, <tt>false</tt> if no next record.
|
||||
* @throws SQLException on any driver-level errors.
|
||||
*/
|
||||
public function next();
|
||||
|
||||
/**
|
||||
* Moves the internal cursor to the previous position and fetches the
|
||||
* row at that position.
|
||||
*
|
||||
* @return boolean <tt>true</tt> if success, <tt>false</tt> if no previous record.
|
||||
* @throws SQLException - if unable to move to previous position
|
||||
* - if ResultSet doesn't support reverse scrolling
|
||||
*/
|
||||
public function previous();
|
||||
|
||||
/**
|
||||
* Moves the cursor a relative number of rows, either positive or negative and fetches
|
||||
* the row at that position.
|
||||
*
|
||||
* Attempting to move beyond the first/last row in the result set positions the cursor before/after
|
||||
* the first/last row and issues a Warning. Calling relative(0) is valid, but does not change the cursor
|
||||
* position.
|
||||
*
|
||||
* @param integer $offset
|
||||
* @return boolean <tt>true</tt> if cursor is on a row, <tt>false</tt> otherwise.
|
||||
* @throws SQLException - if unable to move to relative position
|
||||
* - if rel pos is negative & ResultSet doesn't support reverse scrolling
|
||||
*/
|
||||
public function relative($offset);
|
||||
|
||||
|
||||
/**
|
||||
* Moves the cursor to an absolute cursor position and fetches the row at that position.
|
||||
*
|
||||
* Attempting to move beyond the first/last row in the result set positions the cursor before/after
|
||||
* the first/last row and issues a Warning.
|
||||
*
|
||||
* @param integer $pos cursor position, first position is 1.
|
||||
* @return boolean <tt>true</tt> if cursor is on a row, <tt>false</tt> otherwise.
|
||||
* @throws SQLException - if unable to move to absolute position
|
||||
* - if position is before current pos & ResultSet doesn't support reverse scrolling
|
||||
*/
|
||||
public function absolute($pos);
|
||||
|
||||
/**
|
||||
* Moves cursor position WITHOUT FETCHING ROW AT THAT POSITION.
|
||||
*
|
||||
* Generally this method is for internal driver stuff (e.g. other methods like
|
||||
* absolute() or relative() might call this and then call next() to get the row).
|
||||
* This method is public to facilitate more advanced ResultSet scrolling tools
|
||||
* -- e.g. cleaner implimentation of ResultSetIterator.
|
||||
*
|
||||
* Some drivers will emulate seek() and not allow reverse seek (Oracle).
|
||||
*
|
||||
* Seek is 0-based, but seek() is only for moving to the space _before_ the record
|
||||
* that you want to read. I.e. if you seek(0) and then call next() you will have the
|
||||
* first row (i.e. same as calling first() or absolute(1)).
|
||||
*
|
||||
* <strong>IMPORTANT: You cannot rely on the return value of this method to know whether a given
|
||||
* record exists for reading. In some cases seek() will correctly return <code>false</code> if
|
||||
* the position doesn't exist, but in other drivers the seek is not performed until the
|
||||
* record is fetched. You can check the return value of absolute() if you need to know
|
||||
* whether a specific rec position is valid.</strong>
|
||||
*
|
||||
* @param int $rownum The cursor pos to seek to.
|
||||
* @return boolean true on success, false if unable to seek to specified record.
|
||||
* @throws SQLException if trying to seek backwards with a driver that doesn't
|
||||
* support reverse-scrolling
|
||||
*/
|
||||
public function seek($rownum);
|
||||
|
||||
/**
|
||||
* Move cursor to beginning of recordset.
|
||||
* @return boolean <tt>true</tt> on success or <tt>false</tt> if not found.
|
||||
* @throws SQLException - if unable to move to first position
|
||||
* - if not at first pos & ResultSet doesn't support reverse scrolling
|
||||
*/
|
||||
public function first();
|
||||
|
||||
/**
|
||||
* Move cursor to end of recordset.
|
||||
* @return boolean <tt>true</tt> on success or <tt>false</tt> if not found.
|
||||
* @throws SQLException - if unable to move to last position
|
||||
* - if unable to get num rows
|
||||
*/
|
||||
public function last();
|
||||
|
||||
/**
|
||||
* Sets cursort to before first record. This does not actually seek(), but
|
||||
* simply sets cursor pos to 0.
|
||||
* This is useful for inserting a record before the first in the set, etc.
|
||||
* @return void
|
||||
*/
|
||||
public function beforeFirst();
|
||||
|
||||
|
||||
/**
|
||||
* Sets cursort to after the last record. This does not actually seek(), but
|
||||
* simply sets the cursor pos to last + 1.
|
||||
* This [will be] useful for inserting a record after the last in the set,
|
||||
* when/if Creole supports updateable ResultSets.
|
||||
* @return void
|
||||
*/
|
||||
public function afterLast();
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether cursor is after the last record.
|
||||
* @return boolean
|
||||
* @throws SQLException on any driver-level error.
|
||||
*/
|
||||
public function isAfterLast();
|
||||
|
||||
/**
|
||||
* Checks whether cursor is before the first record.
|
||||
* @return boolean
|
||||
* @throws SQLException on any driver-level error.
|
||||
*/
|
||||
public function isBeforeFirst();
|
||||
|
||||
/**
|
||||
* Returns the current cursor position.
|
||||
* Cursor positions start at 0, but as soon as first row is fetched
|
||||
* cursor position is 1. (so first row is 1)
|
||||
* @return int
|
||||
*/
|
||||
public function getCursorPos();
|
||||
|
||||
/**
|
||||
* Gets current fields (assoc array).
|
||||
* @return array
|
||||
*/
|
||||
public function getRow();
|
||||
|
||||
/**
|
||||
* Get the number of rows in a result set.
|
||||
* @return int the number of rows
|
||||
* @throws SQLException - if unable to get a rowcount.
|
||||
*/
|
||||
public function getRecordCount();
|
||||
|
||||
/**
|
||||
* Frees the resources allocated for this result set.
|
||||
* Also empties any internal field array so that any calls to
|
||||
* get() method on closed ResultSet will result in "Invalid column" SQLException.
|
||||
* @return void
|
||||
*/
|
||||
public function close();
|
||||
|
||||
/**
|
||||
* A generic get method returns unformatted (=string) value.
|
||||
* This returns the raw results from the database. Usually this will be a string, but some drivers
|
||||
* also can return objects (lob descriptors, etc) in certain cases.
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1 (if ResultSet::FETCHMODE_NUM was used) (if ResultSet::FETCHMODE_NUM was used).
|
||||
* @return mixed Usually expect a string.
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function get($column);
|
||||
|
||||
/**
|
||||
* Reads a column as an array.
|
||||
* The value of the column is unserialized & returned as an array. The generic case of this function is
|
||||
* very PHP-specific. Other drivers (e.g. Postgres) will format values into their native array format.
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1 (if ResultSet::FETCHMODE_NUM was used).
|
||||
* @return array value or null if database returned null.
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getArray($column);
|
||||
|
||||
/**
|
||||
* Returns value translated to boolean.
|
||||
* Default is to map 0 => false, 1 => true, but some database drivers may override this behavior.
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1 (if ResultSet::FETCHMODE_NUM was used).
|
||||
* @return boolean value or null if database returned null.
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getBoolean($column);
|
||||
|
||||
/**
|
||||
* Returns Blob with contents of column value.
|
||||
*
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1 (if ResultSet::FETCHMODE_NUM was used).
|
||||
* @return Blob New Blob with data from column or null if database returned null.
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getBlob($column);
|
||||
|
||||
/**
|
||||
* Returns Clob with contents of column value.
|
||||
*
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1 (if ResultSet::FETCHMODE_NUM was used).
|
||||
* @return Clob New Clob object with data from column or null if database returned null.
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getClob($column);
|
||||
|
||||
/**
|
||||
* Return a formatted date.
|
||||
*
|
||||
* The default format for dates returned is preferred (in your locale, as specified using setlocale())
|
||||
* format w/o time (i.e. strftime("%x", $val)). Override this by specifying a format second parameter. You
|
||||
* can also specify a date()-style formatter; if you do, make sure there are no "%" symbols in your format string.
|
||||
*
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1 (if ResultSet::FETCHMODE_NUM was used).
|
||||
* @param string $format Date formatter for use w/ strftime() or date() (it will choose based on examination of format string)
|
||||
* If format is NULL, then the integer unix timestamp will be returned (no formatting performed).
|
||||
* @return mixed Formatted date, or integer unix timestamp (using 00:00:00 for time) if $format was null.
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getDate($column, $format = '%x');
|
||||
|
||||
/**
|
||||
* Returns value cast as a float (in PHP this is same as double).
|
||||
*
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1 (if ResultSet::FETCHMODE_NUM was used).
|
||||
* @return float value or null if database returned null
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getFloat($column);
|
||||
|
||||
/**
|
||||
* Returns value cast as integer.
|
||||
*
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1 (if ResultSet::FETCHMODE_NUM was used).
|
||||
* @return int value or null if database returned null
|
||||
* @see getInteger()
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getInt($column);
|
||||
|
||||
/**
|
||||
* Returns value cast as string.
|
||||
*
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1 (if ResultSet::FETCHMODE_NUM was used).
|
||||
* @return string value or null if database returned null
|
||||
* @see get()
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getString($column);
|
||||
|
||||
/**
|
||||
* Return a formatted time.
|
||||
*
|
||||
* The default format for times returned is preferred (in your locale, as specified using setlocale())
|
||||
* format w/o date (i.e. strftime("%X", $val)). Override this by specifying a format second parameter. You
|
||||
* can also specify a date()-style formatter; if you do, make sure there are no "%" symbols in your format string.
|
||||
*
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1 (if ResultSet::FETCHMODE_NUM was used).
|
||||
* @param string $format Date formatter for use w/ strftime() or date() (it will choose based on examination of format string)
|
||||
* If format is NULL, then the integer unix timestamp will be returned (no formatting performed).
|
||||
* @return mixed Formatted time, or integer unix timestamp (using today's date) if $format was null.
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getTime($column, $format = '%X');
|
||||
|
||||
/**
|
||||
* Return a formatted timestamp.
|
||||
*
|
||||
* The default format for timestamp is ISO standard YYYY-MM-DD HH:MM:SS (i.e. date('Y-m-d H:i:s', $val).
|
||||
* Override this by specifying a format second parameter. You can also specify a strftime()-style formatter.
|
||||
*
|
||||
* Hint: if you want to get the unix timestamp use the "U" formatter string.
|
||||
*
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1 (if ResultSet::FETCHMODE_NUM was used).
|
||||
* @param string $format Date formatter for use w/ strftime() or date() (it will choose based on examination of format string)
|
||||
* If format is NULL, then the integer unix timestamp will be returned (no formatting performed).
|
||||
* @return mixed Formatted timestamp, or integer unix timestamp (if $format was null)
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getTimestamp($column, $format = 'Y-m-d H:i:s');
|
||||
|
||||
}
|
||||
|
||||
113
lib/symfony/vendor/creole/ResultSetIterator.php
vendored
Executable file
113
lib/symfony/vendor/creole/ResultSetIterator.php
vendored
Executable file
@ -0,0 +1,113 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ResultSetIterator.php,v 1.3 2004/03/15 17:47:45 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Basic ResultSet Iterator.
|
||||
*
|
||||
* This can be returned by your class's getIterator() method, but of course
|
||||
* you can also implement your own (e.g. to get better performance, by using direct
|
||||
* driver calls and avoiding other side-effects inherent in ResultSet scrolling
|
||||
* functions -- e.g. beforeFirst() / afterLast(), etc.).
|
||||
*
|
||||
* Important: ResultSet iteration does rewind the resultset if it is not at the
|
||||
* start. Not all drivers support reverse scrolling, so this may result in an
|
||||
* exception in some cases (Oracle).
|
||||
*
|
||||
* Developer note:
|
||||
* The implementation of this class is a little weird because it fetches the
|
||||
* array _early_ in order to answer valid() w/o needing to know total num
|
||||
* of fields. Remember the way iterators work:
|
||||
* <code>
|
||||
* $it = $obj->getIterator();
|
||||
* for($it->rewind(); $it->valid(); $it->next()) {
|
||||
* $key = $it->current();
|
||||
* $val = $it->key();
|
||||
* echo "$key = $val\n";
|
||||
* }
|
||||
* unset($it);
|
||||
* </code>
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.3 $
|
||||
* @package creole
|
||||
*/
|
||||
class ResultSetIterator implements Iterator {
|
||||
|
||||
private $rs;
|
||||
|
||||
/**
|
||||
* Construct the iterator.
|
||||
* @param ResultSet $rs
|
||||
*/
|
||||
public function __construct(ResultSet $rs)
|
||||
{
|
||||
$this->rs = $rs;
|
||||
}
|
||||
|
||||
/**
|
||||
* If not at start of resultset, this method will call seek(0).
|
||||
* @see ResultSet::seek()
|
||||
*/
|
||||
function rewind()
|
||||
{
|
||||
if (!$this->rs->isBeforeFirst()) {
|
||||
$this->rs->seek(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks to see whether there are more results
|
||||
* by advancing the cursor position.
|
||||
* @see ResultSet::next()
|
||||
*/
|
||||
function valid()
|
||||
{
|
||||
return $this->rs->next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cursor position.
|
||||
* @return int
|
||||
*/
|
||||
function key()
|
||||
{
|
||||
return $this->rs->getCursorPos();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the row (assoc array) at current cursor pos.
|
||||
* @return array
|
||||
*/
|
||||
function current()
|
||||
{
|
||||
return $this->rs->getRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method does not actually do anything since we have already advanced
|
||||
* the cursor pos in valid().
|
||||
* @see valid()
|
||||
*/
|
||||
function next()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
105
lib/symfony/vendor/creole/SQLException.php
vendored
Executable file
105
lib/symfony/vendor/creole/SQLException.php
vendored
Executable file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: SQLException.php,v 1.10 2004/03/20 04:16:49 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A class for handling database-related errors.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.10 $
|
||||
* @package creole
|
||||
*/
|
||||
class SQLException extends Exception {
|
||||
|
||||
/** Information that provides additional information for context of Exception (e.g. SQL statement or DSN). */
|
||||
protected $userInfo;
|
||||
|
||||
/** Native RDBMS error string */
|
||||
protected $nativeError;
|
||||
|
||||
/**
|
||||
* Constructs a SQLException.
|
||||
* @param string $msg Error message
|
||||
* @param string $native Native DB error message.
|
||||
* @param string $userinfo More info, e.g. the SQL statement or the connection string that caused the error.
|
||||
*/
|
||||
public function __construct($msg, $native = null, $userinfo = null)
|
||||
{
|
||||
parent::__construct($msg);
|
||||
if ($native !== null) {
|
||||
$this->setNativeError($native);
|
||||
}
|
||||
if ($userinfo !== null) {
|
||||
$this->setUserInfo($userinfo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets additional user / debug information for this error.
|
||||
*
|
||||
* @param array $info
|
||||
* @return void
|
||||
*/
|
||||
public function setUserInfo($info)
|
||||
{
|
||||
$this->userInfo = $info;
|
||||
$this->message .= " [User Info: " .$this->userInfo . "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the additional / debug information for this error.
|
||||
*
|
||||
* @return array hash of user info properties.
|
||||
*/
|
||||
public function getUserInfo()
|
||||
{
|
||||
return $this->userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets driver native error message.
|
||||
*
|
||||
* @param string $info
|
||||
* @return void
|
||||
*/
|
||||
public function setNativeError($msg)
|
||||
{
|
||||
$this->nativeError = $msg;
|
||||
$this->message .= " [Native Error: " .$this->nativeError . "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets driver native error message.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNativeError()
|
||||
{
|
||||
return $this->nativeError;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This method only exists right now for easier compatibility w/ PHPUnit!
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
return $this->getMessage();
|
||||
}
|
||||
}
|
||||
147
lib/symfony/vendor/creole/Statement.php
vendored
Executable file
147
lib/symfony/vendor/creole/Statement.php
vendored
Executable file
@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: Statement.php,v 1.17 2004/03/20 04:16:49 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class that represents a SQL statement.
|
||||
*
|
||||
* This class is very generic and has no driver-specific implementations. In fact,
|
||||
* it wouldn't be possible to have driver-specific classes, since PHP doesn't support
|
||||
* multiple inheritance. I.e. you couldn't have MySQLPreparedStatement that extended
|
||||
* both the abstract PreparedStatement class and the MySQLStatement class. In Java
|
||||
* this isn't a concern since PreparedStatement is an interface, not a class.
|
||||
*
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.17 $
|
||||
* @package creole
|
||||
*/
|
||||
interface Statement {
|
||||
|
||||
/**
|
||||
* Sets the maximum number of rows to return from db.
|
||||
* This will affect the SQL if the RDBMS supports native LIMIT; if not,
|
||||
* it will be emulated. Limit only applies to queries (not update sql).
|
||||
* @param int $v Maximum number of rows or 0 for all rows.
|
||||
* @return void
|
||||
*/
|
||||
public function setLimit($v);
|
||||
|
||||
/**
|
||||
* Returns the maximum number of rows to return or 0 for all.
|
||||
* @return int
|
||||
*/
|
||||
public function getLimit();
|
||||
|
||||
/**
|
||||
* Sets the start row.
|
||||
* This will affect the SQL if the RDBMS supports native OFFSET; if not,
|
||||
* it will be emulated. Offset only applies to queries (not update) and
|
||||
* only is evaluated when LIMIT is set!
|
||||
* @param int $v
|
||||
* @return void
|
||||
*/
|
||||
public function setOffset($v);
|
||||
|
||||
/**
|
||||
* Returns the start row.
|
||||
* Offset only applies when Limit is set!
|
||||
* @return int
|
||||
*/
|
||||
public function getOffset();
|
||||
|
||||
/**
|
||||
* Free resources associated with this statement.
|
||||
* Some drivers will need to implement this method to free
|
||||
* database result resources.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function close();
|
||||
|
||||
/**
|
||||
* Generic execute() function has to check to see whether SQL is an update or select query.
|
||||
*
|
||||
* If you already know whether it's a SELECT or an update (manipulating) SQL, then use
|
||||
* the appropriate method, as this one will incurr overhead to check the SQL.
|
||||
*
|
||||
* @param int $fetchmode Fetchmode (only applies to queries).
|
||||
* @return boolean True if it is a result set, false if not or if no more results (this is identical to JDBC return val).
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function execute($sql, $fetchmode = null);
|
||||
|
||||
/**
|
||||
* Get result set.
|
||||
* This assumes that the last thing done was an executeQuery() or an execute()
|
||||
* with SELECT-type query.
|
||||
*
|
||||
* @return RestultSet (or null if none)
|
||||
*/
|
||||
public function getResultSet();
|
||||
|
||||
/**
|
||||
* Get update count.
|
||||
*
|
||||
* @return int Number of records affected, or <code>null</code> if not applicable.
|
||||
*/
|
||||
public function getUpdateCount();
|
||||
|
||||
/**
|
||||
* Executes the SQL query in this PreparedStatement object and returns the resultset generated by the query.
|
||||
*
|
||||
* @param string $sql This method may optionally be called with the SQL statement.
|
||||
* @param int $fetchmode The mode to use when fetching the results (e.g. ResultSet::FETCHMODE_NUM, ResultSet::FETCHMODE_ASSOC).
|
||||
* @return object Creole::ResultSet
|
||||
* @throws SQLException if a database access error occurs.
|
||||
*/
|
||||
public function executeQuery($sql, $fetchmode = null);
|
||||
|
||||
/**
|
||||
* Executes the SQL INSERT, UPDATE, or DELETE statement in this PreparedStatement object.
|
||||
*
|
||||
* @param string $sql This method may optionally be called with the SQL statement.
|
||||
* @return int Number of affected rows (or 0 for drivers that return nothing).
|
||||
* @throws SQLException if a database access error occurs.
|
||||
*/
|
||||
public function executeUpdate($sql);
|
||||
|
||||
/**
|
||||
* Gets next result set (if this behavior is supported by driver).
|
||||
* Some drivers (e.g. MSSQL) support returning multiple result sets -- e.g.
|
||||
* from stored procedures.
|
||||
*
|
||||
* This function also closes any current restult set.
|
||||
*
|
||||
* Default behavior is for this function to return false. Driver-specific
|
||||
* implementations of this class can override this method if they actually
|
||||
* support multiple result sets.
|
||||
*
|
||||
* @return boolean True if there is another result set, otherwise false.
|
||||
*/
|
||||
public function getMoreResults();
|
||||
|
||||
/**
|
||||
* Gets the db Connection that created this statement.
|
||||
* @return Connection
|
||||
*/
|
||||
public function getConnection();
|
||||
|
||||
}
|
||||
258
lib/symfony/vendor/creole/common/ConnectionCommon.php
vendored
Executable file
258
lib/symfony/vendor/creole/common/ConnectionCommon.php
vendored
Executable file
@ -0,0 +1,258 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ConnectionCommon.php,v 1.5 2005/10/17 19:03:51 dlawson_mi Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class that contains some shared/default information for connections. Classes may wish to extend this so
|
||||
* as not to worry about the sleep/wakeup methods, etc.
|
||||
*
|
||||
* In reality this class is not very useful yet, so there's not much incentive for drivers to extend this.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.5 $
|
||||
* @package creole.common
|
||||
*/
|
||||
abstract class ConnectionCommon {
|
||||
|
||||
// Constants that define transaction isolation levels.
|
||||
// [We don't have any code using these yet, so there's no need
|
||||
// to initialize these values at this point.]
|
||||
// const TRANSACTION_NONE = 0;
|
||||
// const TRANSACTION_READ_UNCOMMITTED = 1;
|
||||
// const TRANSACTION_READ_COMMITTED = 2;
|
||||
// const TRANSACTION_REPEATABLE_READ = 3;
|
||||
// const TRANSACTION_SERIALIZABLE = 4;
|
||||
|
||||
/**
|
||||
* The depth level of current transaction.
|
||||
* @var int
|
||||
*/
|
||||
protected $transactionOpcount = 0;
|
||||
|
||||
/**
|
||||
* DB connection resource id.
|
||||
* @var resource
|
||||
*/
|
||||
protected $dblink;
|
||||
|
||||
/**
|
||||
* Array hash of connection properties.
|
||||
* @var array
|
||||
*/
|
||||
protected $dsn;
|
||||
|
||||
/**
|
||||
* Flags (e.g. Connection::PERSISTENT) for current connection.
|
||||
* @var int
|
||||
*/
|
||||
protected $flags = 0;
|
||||
|
||||
/**
|
||||
* This "magic" method is invoked upon serialize() and works in tandem with the __wakeup()
|
||||
* method to ensure that your database connection is serializable.
|
||||
*
|
||||
* This method returns an array containing the names of any members of your class
|
||||
* which need to be serialized in order to allow the class to re-connect to the database
|
||||
* when it is unserialized.
|
||||
*
|
||||
* <p>
|
||||
* Developers:
|
||||
*
|
||||
* Note that you cannot serialize resources (connection links) and expect them to
|
||||
* be valid when you unserialize. For this reason, you must re-connect to the database in the
|
||||
* __wakeup() method.
|
||||
*
|
||||
* It's up to your class implimentation to ensure that the necessary data is serialized.
|
||||
* You probably at least need to serialize:
|
||||
*
|
||||
* (1) the DSN array used by connect() method
|
||||
* (2) Any flags that were passed to the connection
|
||||
* (3) Possibly the autocommit state
|
||||
*
|
||||
* @return array The class variable names that should be serialized.
|
||||
* @see __wakeup()
|
||||
* @see DriverManager::getConnection()
|
||||
* @see DatabaseInfo::__sleep()
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
return array('dsn', 'flags');
|
||||
}
|
||||
|
||||
/**
|
||||
* This "magic" method is invoked upon unserialize().
|
||||
* This method will re-connects to the database using the information that was
|
||||
* stored using the __sleep() method.
|
||||
* @see __sleep()
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
$this->connect($this->dsn, $this->flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getResource()
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->dblink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getDSN()
|
||||
*/
|
||||
public function getDSN() {
|
||||
return $this->dsn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getFlags()
|
||||
*/
|
||||
public function getFlags()
|
||||
{
|
||||
return $this->flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a CallableStatement object for calling database stored procedures.
|
||||
*
|
||||
* @param string $sql
|
||||
* @return CallableStatement
|
||||
*/
|
||||
public function prepareCall($sql)
|
||||
{
|
||||
throw new SQLException("Current driver does not support stored procedures using CallableStatement.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Driver classes should override this if they support transactions.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function supportsNestedTrans()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins a transaction (if supported).
|
||||
*/
|
||||
public function begin()
|
||||
{
|
||||
if ($this->transactionOpcount === 0 || $this->supportsNestedTrans()) {
|
||||
$this->beginTrans();
|
||||
}
|
||||
$this->transactionOpcount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits statements in a transaction.
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
if ($this->transactionOpcount > 0) {
|
||||
if ($this->transactionOpcount == 1 || $this->supportsNestedTrans()) {
|
||||
$this->commitTrans();
|
||||
}
|
||||
$this->transactionOpcount--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback changes in a transaction.
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
if ($this->transactionOpcount > 0) {
|
||||
if ($this->transactionOpcount == 1 || $this->supportsNestedTrans()) {
|
||||
$this->rollbackTrans();
|
||||
}
|
||||
$this->transactionOpcount--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable automatic commits.
|
||||
*
|
||||
* Pushes SQLWarning onto $warnings stack if the autocommit value is being changed mid-transaction. This function
|
||||
* is overridden by driver classes so that they can perform the necessary begin/end transaction SQL.
|
||||
*
|
||||
* If auto-commit is being set to TRUE, then the current transaction will be committed immediately.
|
||||
*
|
||||
* @param boolean $bit New value for auto commit.
|
||||
* @return void
|
||||
*/
|
||||
public function setAutoCommit($bit)
|
||||
{
|
||||
if ($this->transactionOpcount > 0) {
|
||||
trigger_error("Changing autocommit in mid-transaction; committing " . $this->transactionOpcount . " uncommitted statements.", E_USER_WARNING);
|
||||
}
|
||||
|
||||
if (!$bit) {
|
||||
$this->begin();
|
||||
}
|
||||
else {
|
||||
$this->commit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get auto-commit status.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getAutoCommit()
|
||||
{
|
||||
return ($this->transactionOpcount == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin new transaction.
|
||||
* Driver classes should override this method if they support transactions.
|
||||
*/
|
||||
protected function beginTrans()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
* Driver classes should override this method if they support transactions.
|
||||
*/
|
||||
protected function commitTrans()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll back (undo) the current transaction.
|
||||
* Driver classes should override this method if they support transactions.
|
||||
*/
|
||||
protected function rollbackTrans()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns false if connection is closed.
|
||||
* @return boolean
|
||||
*/
|
||||
public function isConnected()
|
||||
{
|
||||
return !empty($this->dblink);
|
||||
}
|
||||
}
|
||||
640
lib/symfony/vendor/creole/common/PreparedStatementCommon.php
vendored
Executable file
640
lib/symfony/vendor/creole/common/PreparedStatementCommon.php
vendored
Executable file
@ -0,0 +1,640 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PreparedStatementCommon.php,v 1.16 2005/11/13 01:30:00 gamr Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class that represents a shared code for handling emulated pre-compiled statements.
|
||||
*
|
||||
* Many drivers do not take advantage of pre-compiling SQL statements; for these
|
||||
* cases the precompilation is emulated. This emulation comes with slight penalty involved
|
||||
* in parsing the queries, but provides other benefits such as a cleaner object model and ability
|
||||
* to work with BLOB and CLOB values w/o needing special LOB-specific routines.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.16 $
|
||||
* @package creole.common
|
||||
*/
|
||||
abstract class PreparedStatementCommon {
|
||||
|
||||
/**
|
||||
* The database connection.
|
||||
* @var Connection
|
||||
*/
|
||||
protected $conn;
|
||||
|
||||
/**
|
||||
* Max rows to retrieve from DB.
|
||||
* @var int
|
||||
*/
|
||||
protected $limit = 0;
|
||||
|
||||
/**
|
||||
* Offset at which to start processing DB rows.
|
||||
* "Skip X rows"
|
||||
* @var int
|
||||
*/
|
||||
protected $offset = 0;
|
||||
|
||||
/**
|
||||
* The SQL this class operates on.
|
||||
* @var string
|
||||
*/
|
||||
protected $sql;
|
||||
|
||||
/**
|
||||
* Possibly contains a cached prepared SQL Statement.
|
||||
* Gives an early out to replaceParams if the same
|
||||
* query is run multiple times without changing the
|
||||
* params.
|
||||
* @var string
|
||||
*/
|
||||
protected $sql_cache;
|
||||
|
||||
/**
|
||||
* Flag to set if the cache is upto date or not
|
||||
* @var boolean
|
||||
*/
|
||||
protected $sql_cache_valid = false;
|
||||
|
||||
/**
|
||||
* The string positions of the parameters in the SQL.
|
||||
* @var array
|
||||
*/
|
||||
protected $positions;
|
||||
|
||||
|
||||
/**
|
||||
* Number of positions (simply to save processing).
|
||||
* @var int
|
||||
*/
|
||||
protected $positionsCount;
|
||||
|
||||
/**
|
||||
* Map of index => value for bound params.
|
||||
* @var array string[]
|
||||
*/
|
||||
protected $boundInVars = array();
|
||||
|
||||
/**
|
||||
* Temporarily hold a ResultSet object after an execute() query.
|
||||
* @var ResultSet
|
||||
*/
|
||||
protected $resultSet;
|
||||
|
||||
/**
|
||||
* Temporary hold the affected row cound after an execute() query.
|
||||
* @var int
|
||||
*/
|
||||
protected $updateCount;
|
||||
|
||||
/**
|
||||
* Create new prepared statement instance.
|
||||
*
|
||||
* @param object $conn Connection object
|
||||
* @param string $sql The SQL to work with.
|
||||
* @param array $positions The positions in SQL of ?'s.
|
||||
* @param restult $stmt If the driver supports prepared queries, then $stmt will contain the statement to use.
|
||||
*/
|
||||
public function __construct(Connection $conn, $sql)
|
||||
{
|
||||
$this->conn = $conn;
|
||||
$this->sql = $sql;
|
||||
|
||||
$this->positions = $this->parseQuery ( $sql );
|
||||
// save processing later in cases where we may repeatedly exec statement
|
||||
$this->positionsCount = count ( $this->positions );
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the SQL query for ? positions
|
||||
*
|
||||
* @param string $sql The query to process
|
||||
* @return array Positions from the start of the string that ?'s appear at
|
||||
*/
|
||||
protected function parseQuery ( $sql )
|
||||
{
|
||||
|
||||
$positions = array();
|
||||
// match anything ? ' " or \ in $sql with an early out if we find nothing
|
||||
if ( preg_match_all ( '([\?]|[\']|[\"]|[\\\])', $sql, $matches, PREG_OFFSET_CAPTURE ) !== 0 ) {
|
||||
$matches = $matches['0'];
|
||||
$open = NULL;
|
||||
// go thru all our matches and see what we can find
|
||||
for ( $i = 0, $j = count ( $matches ); $i < $j; $i++ ) {
|
||||
switch ( $matches[$i]['0'] ) {
|
||||
// if we already have an open " or ' then check if this is the end
|
||||
// to close it or not
|
||||
case $open:
|
||||
$open = NULL;
|
||||
break;
|
||||
// we have a quote, set ourselves open
|
||||
case '"':
|
||||
case "'":
|
||||
$open = $matches[$i]['0'];
|
||||
break;
|
||||
// check if it is an escaped quote and skip if it is
|
||||
case '\\':
|
||||
$next_match = $matches[$i+1]['0'];
|
||||
if ( $next_match === '"' || $next_match === "'" ) {
|
||||
$i++;
|
||||
}
|
||||
unset ( $next_match );
|
||||
break;
|
||||
// we found a ?, check we arent in an open "/' first and
|
||||
// add it to the position list if we arent
|
||||
default:
|
||||
if ( $open === NULL ) {
|
||||
$positions[] = $matches[$i]['1'];
|
||||
}
|
||||
}
|
||||
unset ( $matches[$i] );
|
||||
}
|
||||
unset ( $open, $matches, $i, $j );
|
||||
}
|
||||
|
||||
return $positions;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::setLimit()
|
||||
*/
|
||||
public function setLimit($v)
|
||||
{
|
||||
$this->limit = (int) $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::getLimit()
|
||||
*/
|
||||
public function getLimit()
|
||||
{
|
||||
return $this->limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::setOffset()
|
||||
*/
|
||||
public function setOffset($v)
|
||||
{
|
||||
$this->offset = (int) $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::getOffset()
|
||||
*/
|
||||
public function getOffset()
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::getResultSet()
|
||||
*/
|
||||
public function getResultSet()
|
||||
{
|
||||
return $this->resultSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::getUpdateCount()
|
||||
*/
|
||||
public function getUpdateCount()
|
||||
{
|
||||
return $this->updateCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::getMoreResults()
|
||||
*/
|
||||
public function getMoreResults()
|
||||
{
|
||||
if ($this->resultSet) $this->resultSet->close();
|
||||
$this->resultSet = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::getConnection()
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Statement resources do not exist for emulated prepared statements,
|
||||
* so this just returns <code>null</code>.
|
||||
* @return null
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nothing to close for emulated prepared statements.
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces placeholders with the specified parameter values in the SQL.
|
||||
*
|
||||
* This is for emulated prepared statements.
|
||||
*
|
||||
* @return string New SQL statement with parameters replaced.
|
||||
* @throws SQLException - if param not bound.
|
||||
*/
|
||||
protected function replaceParams()
|
||||
{
|
||||
// early out if we still have the same query ready
|
||||
if ( $this->sql_cache_valid === true ) {
|
||||
return $this->sql_cache;
|
||||
}
|
||||
|
||||
// Default behavior for this function is to behave in 'emulated' mode.
|
||||
$sql = '';
|
||||
$last_position = 0;
|
||||
|
||||
for ($position = 0; $position < $this->positionsCount; $position++) {
|
||||
if (!isset($this->boundInVars[$position + 1])) {
|
||||
throw new SQLException('Replace params: undefined query param: ' . ($position + 1));
|
||||
}
|
||||
$current_position = $this->positions[$position];
|
||||
$sql .= substr($this->sql, $last_position, $current_position - $last_position);
|
||||
$sql .= $this->boundInVars[$position + 1];
|
||||
$last_position = $current_position + 1;
|
||||
}
|
||||
// append the rest of the query
|
||||
$sql .= substr($this->sql, $last_position);
|
||||
|
||||
// just so we dont touch anything with a blob/clob
|
||||
if ( strlen ( $sql ) > 2048 ) {
|
||||
$this->sql_cache = $sql;
|
||||
$this->sql_cache_valid = true;
|
||||
return $this->sql_cache;
|
||||
} else {
|
||||
return $sql;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the SQL query in this PreparedStatement object and returns the resultset generated by the query.
|
||||
* We support two signatures for this method:
|
||||
* - $stmt->executeQuery(ResultSet::FETCHMODE_NUM);
|
||||
* - $stmt->executeQuery(array($param1, $param2), ResultSet::FETCHMODE_NUM);
|
||||
* @param mixed $p1 Either (array) Parameters that will be set using PreparedStatement::set() before query is executed or (int) fetchmode.
|
||||
* @param int $fetchmode The mode to use when fetching the results (e.g. ResultSet::FETCHMODE_NUM, ResultSet::FETCHMODE_ASSOC).
|
||||
* @return ResultSet
|
||||
* @throws SQLException if a database access error occurs.
|
||||
*/
|
||||
public function executeQuery($p1 = null, $fetchmode = null)
|
||||
{
|
||||
$params = null;
|
||||
if ($fetchmode !== null) {
|
||||
$params = $p1;
|
||||
} elseif ($p1 !== null) {
|
||||
if (is_array($p1)) $params = $p1;
|
||||
else $fetchmode = $p1;
|
||||
}
|
||||
|
||||
foreach ( (array) $params as $i=>$param ) {
|
||||
$this->set ( $i + 1, $param );
|
||||
unset ( $i, $param );
|
||||
}
|
||||
unset ( $params );
|
||||
|
||||
$this->updateCount = null; // reset
|
||||
$sql = $this->replaceParams();
|
||||
|
||||
if ($this->limit > 0 || $this->offset > 0) {
|
||||
$this->conn->applyLimit($sql, $this->offset, $this->limit);
|
||||
}
|
||||
|
||||
$this->resultSet = $this->conn->executeQuery($sql, $fetchmode);
|
||||
return $this->resultSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the SQL INSERT, UPDATE, or DELETE statement in this PreparedStatement object.
|
||||
*
|
||||
* @param array $params Parameters that will be set using PreparedStatement::set() before query is executed.
|
||||
* @return int Number of affected rows (or 0 for drivers that return nothing).
|
||||
* @throws SQLException if a database access error occurs.
|
||||
*/
|
||||
public function executeUpdate($params = null)
|
||||
{
|
||||
foreach ( (array) $params as $i=>$param ) {
|
||||
$this->set ( $i + 1, $param );
|
||||
unset ( $i, $param );
|
||||
}
|
||||
unset ( $params );
|
||||
|
||||
if($this->resultSet) $this->resultSet->close();
|
||||
$this->resultSet = null; // reset
|
||||
$sql = $this->replaceParams();
|
||||
$this->updateCount = $this->conn->executeUpdate($sql);
|
||||
return $this->updateCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes special characters (usu. quotes) using native driver function.
|
||||
* @param string $str The input string.
|
||||
* @return string The escaped string.
|
||||
*/
|
||||
abstract protected function escape($str);
|
||||
|
||||
/**
|
||||
* A generic set method.
|
||||
*
|
||||
* You can use this if you don't want to concern yourself with the details. It involves
|
||||
* slightly more overhead than the specific settesr, since it grabs the PHP type to determine
|
||||
* which method makes most sense.
|
||||
*
|
||||
* @param int $paramIndex
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @throws SQLException
|
||||
*/
|
||||
function set($paramIndex, $value)
|
||||
{
|
||||
$type = gettype($value);
|
||||
if ($type == "object") {
|
||||
if (is_a($value, 'Blob')) {
|
||||
$this->setBlob($paramIndex, $value);
|
||||
} elseif (is_a($value, 'Clob')) {
|
||||
$this->setClob($paramIndex, $value);
|
||||
} elseif (is_a($value, 'Date')) {
|
||||
// can't be sure if the column type is a DATE, TIME, or TIMESTAMP column
|
||||
// we'll just use TIMESTAMP by default; hopefully DB won't complain (if
|
||||
// it does, then this method just shouldn't be used).
|
||||
$this->setTimestamp($paramIndex, $value);
|
||||
} else {
|
||||
throw new SQLException("Unsupported object type passed to set(): " . get_class($value));
|
||||
}
|
||||
} else {
|
||||
switch ( $type ) {
|
||||
case 'integer':
|
||||
$type = 'int';
|
||||
break;
|
||||
case 'double':
|
||||
$type = 'float';
|
||||
break;
|
||||
}
|
||||
$setter = 'set' . ucfirst($type); // PHP types are case-insensitive, but we'll do this in case that change
|
||||
if ( method_exists ( $this, $setter ) ) {
|
||||
$this->$setter($paramIndex, $value);
|
||||
} else {
|
||||
throw new SQLException ( "Unsupported datatype passed to set(): " . $type );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an array.
|
||||
* Unless a driver-specific method is used, this means simply serializing
|
||||
* the passed parameter and storing it as a string.
|
||||
* @param int $paramIndex
|
||||
* @param array $value
|
||||
* @return void
|
||||
*/
|
||||
function setArray($paramIndex, $value)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
$this->boundInVars[$paramIndex] = "'" . $this->escape(serialize($value)) . "'";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a boolean value.
|
||||
* Default behavior is true = 1, false = 0.
|
||||
* @param int $paramIndex
|
||||
* @param boolean $value
|
||||
* @return void
|
||||
*/
|
||||
function setBoolean($paramIndex, $value)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
$this->boundInVars[$paramIndex] = (int) $value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::setBlob()
|
||||
*/
|
||||
function setBlob($paramIndex, $blob)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
if ($blob === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
// they took magic __toString() out of PHP5.0.0; this sucks
|
||||
if (is_object($blob)) {
|
||||
$this->boundInVars[$paramIndex] = "'" . $this->escape($blob->__toString()) . "'";
|
||||
} else {
|
||||
$this->boundInVars[$paramIndex] = "'" . $this->escape($blob) . "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::setClob()
|
||||
*/
|
||||
function setClob($paramIndex, $clob)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
if ($clob === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
// they took magic __toString() out of PHP5.0.0; this sucks
|
||||
if (is_object($clob)) {
|
||||
$this->boundInVars[$paramIndex] = "'" . $this->escape($clob->__toString()) . "'";
|
||||
} else {
|
||||
$this->boundInVars[$paramIndex] = "'" . $this->escape($clob) . "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
function setDate($paramIndex, $value)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
if (is_numeric($value)) $value = date("Y-m-d", $value);
|
||||
elseif (is_object($value)) $value = date("Y-m-d", $value->getTime());
|
||||
$this->boundInVars[$paramIndex] = "'" . $this->escape($value) . "'";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param double $value
|
||||
* @return void
|
||||
*/
|
||||
function setDecimal($paramIndex, $value)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
$this->boundInVars[$paramIndex] = (float) $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param double $value
|
||||
* @return void
|
||||
*/
|
||||
function setDouble($paramIndex, $value)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
$this->boundInVars[$paramIndex] = (double) $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param float $value
|
||||
* @return void
|
||||
*/
|
||||
function setFloat($paramIndex, $value)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
$this->boundInVars[$paramIndex] = (float) $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param int $value
|
||||
* @return void
|
||||
*/
|
||||
function setInt($paramIndex, $value)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
$this->boundInVars[$paramIndex] = (int) $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for setInt()
|
||||
* @param int $paramIndex
|
||||
* @param int $value
|
||||
*/
|
||||
function setInteger($paramIndex, $value)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
$this->setInt($paramIndex, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @return void
|
||||
*/
|
||||
function setNull($paramIndex)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
$this->boundInVars[$paramIndex] = 'NULL';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
function setString($paramIndex, $value)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
// it's ok to have a fatal error here, IMO, if object doesn't have
|
||||
// __toString() and is being passed to this method.
|
||||
if ( is_object ( $value ) ) {
|
||||
$this->boundInVars[$paramIndex] = "'" . $this->escape($value->__toString()) . "'";
|
||||
} else {
|
||||
$this->boundInVars[$paramIndex] = "'" . $this->escape((string)$value) . "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
function setTime($paramIndex, $value)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
if ( is_numeric ( $value ) ) {
|
||||
$value = date ('H:i:s', $value );
|
||||
} elseif ( is_object ( $value ) ) {
|
||||
$value = date ('H:i:s', $value->getTime ( ) );
|
||||
}
|
||||
$this->boundInVars [ $paramIndex ] = "'" . $this->escape ( $value ) . "'";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
function setTimestamp($paramIndex, $value)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
if (is_numeric($value)) $value = date('Y-m-d H:i:s', $value);
|
||||
elseif (is_object($value)) $value = date('Y-m-d H:i:s', $value->getTime());
|
||||
$this->boundInVars[$paramIndex] = "'".$this->escape($value)."'";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
447
lib/symfony/vendor/creole/common/ResultSetCommon.php
vendored
Executable file
447
lib/symfony/vendor/creole/common/ResultSetCommon.php
vendored
Executable file
@ -0,0 +1,447 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ResultSetCommon.php,v 1.9 2006/01/17 19:44:38 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class implements many shared or common methods needed by resultset drivers.
|
||||
*
|
||||
* This class may (optionally) be extended by driver classes simply to make it easier
|
||||
* to create driver classes. This is also useful in the early stages of Creole development
|
||||
* as it means that API changes affect fewer files. As Creole matures/stabalizes having
|
||||
* a common class may become less useful, as drivers may have their own ways of doing things
|
||||
* (and we'll have a solid unit test framework to make sure drivers conform to the API
|
||||
* described by the interfaces).
|
||||
*
|
||||
* The get*() methods in this class will format values before returning them. Note
|
||||
* that if they will return <code>null</code> if the database returned <code>NULL</code>
|
||||
* which makes these functions easier to use than simply typecasting the values from the
|
||||
* db. If the requested column does not exist than an exception (SQLException) will be thrown.
|
||||
*
|
||||
* <code>
|
||||
* $rs = $conn->executeQuery("SELECT MAX(stamp) FROM event", ResultSet::FETCHMODE_NUM);
|
||||
* $rs->next();
|
||||
*
|
||||
* $max_stamp = $rs->getTimestamp(1, "d/m/Y H:i:s");
|
||||
* // $max_stamp will be date string or null if no MAX(stamp) was found
|
||||
*
|
||||
* $max_stamp = $rs->getTimestamp("max(stamp)", "d/m/Y H:i:s");
|
||||
* // will THROW EXCEPTION, because the resultset was fetched using numeric indexing
|
||||
* // SQLException: Invalid resultset column: max(stamp)
|
||||
* </code>
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.9 $
|
||||
* @package creole.common
|
||||
*/
|
||||
abstract class ResultSetCommon {
|
||||
|
||||
/**
|
||||
* The fetchmode for this recordset.
|
||||
* @var int
|
||||
*/
|
||||
protected $fetchmode;
|
||||
|
||||
/**
|
||||
* DB connection.
|
||||
* @var Connection
|
||||
*/
|
||||
protected $conn;
|
||||
|
||||
/**
|
||||
* Resource identifier used for native result set handling.
|
||||
* @var resource
|
||||
*/
|
||||
protected $result;
|
||||
|
||||
/**
|
||||
* The current cursor position (row number). First row is 1. Before first row is 0.
|
||||
* @var int
|
||||
*/
|
||||
protected $cursorPos = 0;
|
||||
|
||||
/**
|
||||
* The current unprocessed record/row from the db.
|
||||
* @var array
|
||||
*/
|
||||
protected $fields;
|
||||
|
||||
/**
|
||||
* Whether to convert assoc col case.
|
||||
* @var boolean
|
||||
*/
|
||||
protected $lowerAssocCase = false;
|
||||
|
||||
/**
|
||||
* Whether to apply rtrim() to strings.
|
||||
* @var boolean
|
||||
*/
|
||||
protected $rtrimString = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct(Connection $conn, $result, $fetchmode = null)
|
||||
{
|
||||
$this->conn = $conn;
|
||||
$this->result = $result;
|
||||
if ($fetchmode !== null) {
|
||||
$this->fetchmode = $fetchmode;
|
||||
} else {
|
||||
$this->fetchmode = ResultSet::FETCHMODE_ASSOC; // default
|
||||
}
|
||||
$this->lowerAssocCase = (($conn->getFlags() & Creole::COMPAT_ASSOC_LOWER) === Creole::COMPAT_ASSOC_LOWER);
|
||||
$this->rtrimString = (($conn->getFlags() & Creole::COMPAT_RTRIM_STRING) === Creole::COMPAT_RTRIM_STRING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*
|
||||
* Free db result resource.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getIterator()
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
require_once 'creole/ResultSetIterator.php';
|
||||
return new ResultSetIterator($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getResource()
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::isLowereAssocCase()
|
||||
*/
|
||||
public function isLowerAssocCase()
|
||||
{
|
||||
return $this->lowerAssocCase;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::setFetchmode()
|
||||
*/
|
||||
public function setFetchmode($mode)
|
||||
{
|
||||
$this->fetchmode = $mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getFetchmode()
|
||||
*/
|
||||
public function getFetchmode()
|
||||
{
|
||||
return $this->fetchmode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::previous()
|
||||
*/
|
||||
public function previous()
|
||||
{
|
||||
// Go back 2 spaces so that we can then advance 1 space.
|
||||
$ok = $this->seek($this->cursorPos - 2);
|
||||
if ($ok === false) {
|
||||
$this->beforeFirst();
|
||||
return false;
|
||||
}
|
||||
return $this->next();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::isBeforeFirst()
|
||||
*/
|
||||
public function relative($offset)
|
||||
{
|
||||
// which absolute row number are we seeking
|
||||
$pos = $this->cursorPos + ($offset - 1);
|
||||
$ok = $this->seek($pos);
|
||||
|
||||
if ($ok === false) {
|
||||
if ($pos < 0) {
|
||||
$this->beforeFirst();
|
||||
} else {
|
||||
$this->afterLast();
|
||||
}
|
||||
} else {
|
||||
$ok = $this->next();
|
||||
}
|
||||
|
||||
return $ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::absolute()
|
||||
*/
|
||||
public function absolute($pos)
|
||||
{
|
||||
$ok = $this->seek( $pos - 1 ); // compensate for next() factor
|
||||
if ($ok === false) {
|
||||
if ($pos - 1 < 0) {
|
||||
$this->beforeFirst();
|
||||
} else {
|
||||
$this->afterLast();
|
||||
}
|
||||
} else {
|
||||
$ok = $this->next();
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::first()
|
||||
*/
|
||||
public function first()
|
||||
{
|
||||
if($this->cursorPos !== 0) { $this->seek(0); }
|
||||
return $this->next();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::last()
|
||||
*/
|
||||
public function last()
|
||||
{
|
||||
if($this->cursorPos !== ($last = $this->getRecordCount() - 1)) {
|
||||
$this->seek( $last );
|
||||
}
|
||||
return $this->next();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::beforeFirst()
|
||||
*/
|
||||
public function beforeFirst()
|
||||
{
|
||||
$this->cursorPos = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::afterLast()
|
||||
*/
|
||||
public function afterLast()
|
||||
{
|
||||
$this->cursorPos = $this->getRecordCount() + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::isAfterLast()
|
||||
*/
|
||||
public function isAfterLast()
|
||||
{
|
||||
return ($this->cursorPos === $this->getRecordCount() + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::isBeforeFirst()
|
||||
*/
|
||||
public function isBeforeFirst()
|
||||
{
|
||||
return ($this->cursorPos === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getCursorPos()
|
||||
*/
|
||||
public function getCursorPos()
|
||||
{
|
||||
return $this->cursorPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getRow()
|
||||
*/
|
||||
public function getRow()
|
||||
{
|
||||
return $this->fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::get()
|
||||
*/
|
||||
public function get($column)
|
||||
{
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
return $this->fields[$idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getArray()
|
||||
*/
|
||||
public function getArray($column)
|
||||
{
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
if ($this->fields[$idx] === null) { return null; }
|
||||
return (array) unserialize($this->fields[$idx]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getBoolean()
|
||||
*/
|
||||
public function getBoolean($column)
|
||||
{
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
if ($this->fields[$idx] === null) { return null; }
|
||||
return (boolean) $this->fields[$idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getBlob()
|
||||
*/
|
||||
public function getBlob($column)
|
||||
{
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
if ($this->fields[$idx] === null) { return null; }
|
||||
require_once 'creole/util/Blob.php';
|
||||
$b = new Blob();
|
||||
$b->setContents($this->fields[$idx]);
|
||||
return $b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getClob()
|
||||
*/
|
||||
public function getClob($column)
|
||||
{
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
if ($this->fields[$idx] === null) { return null; }
|
||||
require_once 'creole/util/Clob.php';
|
||||
$c = new Clob();
|
||||
$c->setContents($this->fields[$idx]);
|
||||
return $c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getDate()
|
||||
*/
|
||||
public function getDate($column, $format = '%x')
|
||||
{
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
if ($this->fields[$idx] === null) { return null; }
|
||||
$ts = strtotime($this->fields[$idx]);
|
||||
if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE
|
||||
throw new SQLException("Unable to convert value at column " . $column . " to timestamp: " . $this->fields[$idx]);
|
||||
}
|
||||
if ($format === null) {
|
||||
return $ts;
|
||||
}
|
||||
if (strpos($format, '%') !== false) {
|
||||
return strftime($format, $ts);
|
||||
} else {
|
||||
return date($format, $ts);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getFloat()
|
||||
*/
|
||||
public function getFloat($column)
|
||||
{
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
if ($this->fields[$idx] === null) { return null; }
|
||||
return (float) $this->fields[$idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getInt()
|
||||
*/
|
||||
public function getInt($column)
|
||||
{
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
if ($this->fields[$idx] === null) { return null; }
|
||||
return (int) $this->fields[$idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getString()
|
||||
*/
|
||||
public function getString($column)
|
||||
{
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
if ($this->fields[$idx] === null) { return null; }
|
||||
return ($this->rtrimString ? rtrim($this->fields[$idx]) : (string) $this->fields[$idx]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getTime()
|
||||
*/
|
||||
public function getTime($column, $format = '%X')
|
||||
{
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
if ($this->fields[$idx] === null) { return null; }
|
||||
|
||||
$ts = strtotime($this->fields[$idx]);
|
||||
|
||||
if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE
|
||||
throw new SQLException("Unable to convert value at column " . (is_int($column) ? $column + 1 : $column) . " to timestamp: " . $this->fields[$idx]);
|
||||
}
|
||||
if ($format === null) {
|
||||
return $ts;
|
||||
}
|
||||
if (strpos($format, '%') !== false) {
|
||||
return strftime($format, $ts);
|
||||
} else {
|
||||
return date($format, $ts);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getTimestamp()
|
||||
*/
|
||||
public function getTimestamp($column, $format = 'Y-m-d H:i:s')
|
||||
{
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
if ($this->fields[$idx] === null) { return null; }
|
||||
|
||||
$ts = strtotime($this->fields[$idx]);
|
||||
if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE
|
||||
throw new SQLException("Unable to convert value at column " . $column . " to timestamp: " . $this->fields[$idx]);
|
||||
}
|
||||
if ($format === null) {
|
||||
return $ts;
|
||||
}
|
||||
if (strpos($format, '%') !== false) {
|
||||
return strftime($format, $ts);
|
||||
} else {
|
||||
return date($format, $ts);
|
||||
}
|
||||
}
|
||||
}
|
||||
289
lib/symfony/vendor/creole/common/StatementCommon.php
vendored
Executable file
289
lib/symfony/vendor/creole/common/StatementCommon.php
vendored
Executable file
@ -0,0 +1,289 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: StatementCommon.php,v 1.4 2004/06/13 02:31:07 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class that contains common/shared functionality for Statements.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.4 $
|
||||
* @package creole.common
|
||||
*/
|
||||
abstract class StatementCommon {
|
||||
|
||||
/**
|
||||
* The database connection.
|
||||
* @var Connection
|
||||
*/
|
||||
protected $conn;
|
||||
|
||||
/**
|
||||
* Temporarily hold a ResultSet object after an execute() query.
|
||||
* @var ResultSet
|
||||
*/
|
||||
protected $resultSet;
|
||||
|
||||
/**
|
||||
* Temporary hold the affected row cound after an execute() query.
|
||||
* @var int
|
||||
*/
|
||||
protected $updateCount;
|
||||
|
||||
/**
|
||||
* Array of warning objects generated by methods performed on result set.
|
||||
* @var array SQLWarning[]
|
||||
*/
|
||||
protected $warnings = array();
|
||||
|
||||
/**
|
||||
* The ResultSet class name.
|
||||
* @var string
|
||||
*/
|
||||
protected $resultClass;
|
||||
|
||||
/**
|
||||
* The prepared statement resource id.
|
||||
* @var resource
|
||||
*/
|
||||
protected $stmt;
|
||||
|
||||
/**
|
||||
* Max rows to retrieve from DB.
|
||||
* @var int
|
||||
*/
|
||||
protected $limit = 0;
|
||||
|
||||
/**
|
||||
* Offset at which to start processing DB rows.
|
||||
* "Skip X rows"
|
||||
* @var int
|
||||
*/
|
||||
protected $offset = 0;
|
||||
|
||||
/**
|
||||
* Create new statement instance.
|
||||
*
|
||||
* @param Connection $conn Connection object
|
||||
*/
|
||||
function __construct(Connection $conn)
|
||||
{
|
||||
$this->conn = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum number of rows to return from db.
|
||||
* This will affect the SQL if the RDBMS supports native LIMIT; if not,
|
||||
* it will be emulated. Limit only applies to queries (not update sql).
|
||||
* @param int $v Maximum number of rows or 0 for all rows.
|
||||
* @return void
|
||||
*/
|
||||
public function setLimit($v)
|
||||
{
|
||||
$this->limit = (int) $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum number of rows to return or 0 for all.
|
||||
* @return int
|
||||
*/
|
||||
public function getLimit()
|
||||
{
|
||||
return $this->limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the start row.
|
||||
* This will affect the SQL if the RDBMS supports native OFFSET; if not,
|
||||
* it will be emulated. Offset only applies to queries (not update) and
|
||||
* only is evaluated when LIMIT is set!
|
||||
* @param int $v
|
||||
* @return void
|
||||
*/
|
||||
public function setOffset($v)
|
||||
{
|
||||
$this->offset = (int) $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start row.
|
||||
* Offset only applies when Limit is set!
|
||||
* @return int
|
||||
*/
|
||||
public function getOffset()
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free resources associated with this statement.
|
||||
* Some drivers will need to implement this method to free
|
||||
* database result resources.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
// do nothing here (subclasses will implement)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic execute() function has to check to see whether SQL is an update or select query.
|
||||
*
|
||||
* If you already know whether it's a SELECT or an update (manipulating) SQL, then use
|
||||
* the appropriate method, as this one will incurr overhead to check the SQL.
|
||||
*
|
||||
* @param int $fetchmode Fetchmode (only applies to queries).
|
||||
* @return boolean True if it is a result set, false if not or if no more results (this is identical to JDBC return val).
|
||||
* @throws SQLException
|
||||
* @todo -cStatementCommon Update execute() to not use isSelect() method, but rather to determine type based on returned results.
|
||||
*/
|
||||
public function execute($sql, $fetchmode = null)
|
||||
{
|
||||
|
||||
if (!$this->isSelect($sql)) {
|
||||
$this->updateCount = $this->executeUpdate($sql);
|
||||
return false;
|
||||
} else {
|
||||
$this->resultSet = $this->executeQuery($sql, $fetchmode);
|
||||
if ($this->resultSet->getRecordCount() === 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get result set.
|
||||
* This assumes that the last thing done was an executeQuery() or an execute()
|
||||
* with SELECT-type query.
|
||||
*
|
||||
* @return RestultSet (or null if none)
|
||||
*/
|
||||
public function getResultSet()
|
||||
{
|
||||
return $this->resultSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get update count.
|
||||
*
|
||||
* @return int Number of records affected, or <code>null</code> if not applicable.
|
||||
*/
|
||||
public function getUpdateCount()
|
||||
{
|
||||
return $this->updateCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the passed SQL is a SELECT statement.
|
||||
*
|
||||
* Returns true if SQL starts with 'SELECT' but not 'SELECT INTO'. This exists
|
||||
* to support the execute() function -- which could either execute an update or
|
||||
* a query.
|
||||
*
|
||||
* Currently this function does not take into consideration comments, primarily
|
||||
* because there are a number of different comment options for different drivers:
|
||||
* <pre>
|
||||
* -- SQL-defined comment, but not truly comment in Oracle
|
||||
* # comment in mysql
|
||||
* /* comment in mssql, others * /
|
||||
* // comment sometimes?
|
||||
* REM also comment ...
|
||||
* </pre>
|
||||
*
|
||||
* If you're wondering why we can't just execute the query and look at the return results
|
||||
* to see whether it was an update or a select, the reason is that for update queries we
|
||||
* need to do stuff before we execute them -- like start transactions if auto-commit is off.
|
||||
*
|
||||
* @param string $sql
|
||||
* @return boolean Whether statement is a SELECT SQL statement.
|
||||
* @see execute()
|
||||
*/
|
||||
protected function isSelect($sql)
|
||||
{
|
||||
// is first word is SELECT, then return true, unless it's SELECT INTO ...
|
||||
// this doesn't, however, take comments into account ...
|
||||
$sql = trim($sql);
|
||||
return (stripos($sql, 'select') === 0 && stripos($sql, 'select into ') !== 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the SQL query in this PreparedStatement object and returns the resultset generated by the query.
|
||||
*
|
||||
* @param string $sql This method may optionally be called with the SQL statement.
|
||||
* @param int $fetchmode The mode to use when fetching the results (e.g. ResultSet::FETCHMODE_NUM, ResultSet::FETCHMODE_ASSOC).
|
||||
* @return object Creole::ResultSet
|
||||
* @throws SQLException If there is an error executing the specified query.
|
||||
* @todo -cStatementCommon Put native query execution logic in statement subclasses.
|
||||
*/
|
||||
public function executeQuery($sql, $fetchmode = null)
|
||||
{
|
||||
$this->updateCount = null;
|
||||
if ($this->limit > 0 || $this->offset > 0) {
|
||||
$this->conn->applyLimit($sql, $this->offset, $this->limit);
|
||||
}
|
||||
$this->resultSet = $this->conn->executeQuery($sql, $fetchmode);
|
||||
return $this->resultSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the SQL INSERT, UPDATE, or DELETE statement in this PreparedStatement object.
|
||||
*
|
||||
* @param string $sql This method may optionally be called with the SQL statement.
|
||||
* @return int Number of affected rows (or 0 for drivers that return nothing).
|
||||
* @throws SQLException if a database access error occurs.
|
||||
*/
|
||||
public function executeUpdate($sql)
|
||||
{
|
||||
if ($this->resultSet) $this->resultSet->close();
|
||||
$this->resultSet = null;
|
||||
$this->updateCount = $this->conn->executeUpdate($sql);
|
||||
return $this->updateCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets next result set (if this behavior is supported by driver).
|
||||
* Some drivers (e.g. MSSQL) support returning multiple result sets -- e.g.
|
||||
* from stored procedures.
|
||||
*
|
||||
* This function also closes any current restult set.
|
||||
*
|
||||
* Default behavior is for this function to return false. Driver-specific
|
||||
* implementations of this class can override this method if they actually
|
||||
* support multiple result sets.
|
||||
*
|
||||
* @return boolean True if there is another result set, otherwise false.
|
||||
*/
|
||||
public function getMoreResults()
|
||||
{
|
||||
if ($this->resultSet) $this->resultSet->close();
|
||||
$this->resultSet = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the db Connection that created this statement.
|
||||
* @return Connection
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->conn;
|
||||
}
|
||||
}
|
||||
478
lib/symfony/vendor/creole/drivers/mssql/MSSQLCallableStatement.php
vendored
Executable file
478
lib/symfony/vendor/creole/drivers/mssql/MSSQLCallableStatement.php
vendored
Executable file
@ -0,0 +1,478 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MSSQLCallableStatement.php,v 1.20 2005/09/16 13:09:50 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/drivers/mssql/MSSQLPreparedStatement.php';
|
||||
require_once 'creole/CallableStatement.php';
|
||||
include_once 'creole/CreoleTypes.php';
|
||||
|
||||
/**
|
||||
* MS SQL Server class to handle stored procedure execution.
|
||||
*
|
||||
* Developer note:
|
||||
*
|
||||
* There is no CallableStatement superclass. Unlike JDBC, Creole
|
||||
* uses abstract parent classes rather than interfaces -- in order
|
||||
* to minimize code duplication. Since PHP doesn't support multiple
|
||||
* inheritance, the DRIVERCallableStatement class cannot extend both
|
||||
* the DRIVERPreparedStatement class and the would-be abstract
|
||||
* CallableStatement class.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.20 $
|
||||
* @package creole.drivers.mssql
|
||||
*/
|
||||
class MSSQLCallableStatement extends MSSQLPreparedStatement implements CallableStatement {
|
||||
|
||||
/** Output variables */
|
||||
private $boundOutVars = array();
|
||||
|
||||
/**
|
||||
* Match Creole types to SQL Server types
|
||||
* @var array
|
||||
*/
|
||||
private static $typeMap = array(
|
||||
CreoleTypes::BOOLEAN => SQLBIT,
|
||||
CreoleTypes::BIGINT => SQLINT4,
|
||||
CreoleTypes::SMALLINT => SQLINT2,
|
||||
CreoleTypes::TINYINT => SQLINT2,
|
||||
CreoleTypes::INTEGER => SQLINT4,
|
||||
CreoleTypes::CHAR => SQLCHAR,
|
||||
CreoleTypes::VARCHAR => SQLVARCHAR,
|
||||
CreoleTypes::TEXT => SQLTEXT,
|
||||
CreoleTypes::FLOAT => SQLFLT8,
|
||||
CreoleTypes::DOUBLE => SQLFLT8,
|
||||
CreoleTypes::DATE => SQLVARCHAR,
|
||||
CreoleTypes::TIME => SQLVARCHAR,
|
||||
CreoleTypes::TIMESTAMP => SQLVARCHAR,
|
||||
CreoleTypes::VARBINARY => SQLVARCHAR,
|
||||
CreoleTypes::NUMERIC => SQLINT4,
|
||||
CreoleTypes::DECIMAL => SQLFLT8
|
||||
);
|
||||
|
||||
/**
|
||||
* Statement created by mssql_init()
|
||||
* @var resource
|
||||
*/
|
||||
private $stmt;
|
||||
|
||||
|
||||
/**
|
||||
* The result resource.
|
||||
* @var resource
|
||||
*/
|
||||
private $result;
|
||||
|
||||
/**
|
||||
* Construct new MSSQLCallableStatement.
|
||||
*
|
||||
* @param Connection $conn
|
||||
* @param resource $stmt
|
||||
*/
|
||||
public function __construct(Connection $conn, $stmt)
|
||||
{
|
||||
print " - > IN CONSTRUCTOR \n";
|
||||
$this->conn = $conn;
|
||||
$this->stmt = $stmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::getResource()
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->stmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::close()
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
@mssql_free_statement($this->stmt);
|
||||
$this->rsFetchCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::executeQuery()
|
||||
*/
|
||||
function executeQuery($p1 = null, $fetchmode = null)
|
||||
{
|
||||
$params = null;
|
||||
if ($fetchmode !== null) {
|
||||
$params = $p1;
|
||||
} elseif ($p1 !== null) {
|
||||
if (is_array($p1)) $params = $p1;
|
||||
else $fetchmode = $p1;
|
||||
}
|
||||
|
||||
if ($params) {
|
||||
for($i=0,$cnt=count($params); $i < $cnt; $i++) {
|
||||
$this->set($i+1, $params[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->result = mssql_execute($this->stmt);
|
||||
if (!$this->result) {
|
||||
throw new SQLException('unable to execute callable statement', mssql_get_last_message());
|
||||
}
|
||||
|
||||
return new MSSQLResultSet($this->conn, $this->result, $fetchmode, $this->offset, $this->limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::getMoreResults()
|
||||
*/
|
||||
function getMoreResults()
|
||||
{
|
||||
$this->rsFetchCount++; // we track this because
|
||||
$hasMore = mssql_next_result($this->result);
|
||||
if ($this->resultSet) $this->resultSet->close();
|
||||
if ($hasMore) {
|
||||
$clazz = $this->resultClass;
|
||||
$this->resultSet = new $clazz($this, $this->result);
|
||||
} else {
|
||||
$this->resultSet = null;
|
||||
}
|
||||
return $hasMore;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::registerOutParameter()
|
||||
*/
|
||||
function registerOutParameter($paramIndex, $sqlType, $maxLength = null)
|
||||
{
|
||||
mssql_bind($this->stmt, $paramIndex, $this->boundOutVars[$paramIndex], self::$typeMap[$sqlType], true, false, $maxLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::setArray()
|
||||
*/
|
||||
function setArray($paramIndex, $value, $out = false)
|
||||
{
|
||||
if ($out) $this->boundOutVars[$paramIndex] = &$value; // reference means that changes to value, will be reflected
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
$value = serialize($value);
|
||||
mssql_bind($this->stmt, $paramIndex, $value, SQLTEXT, $out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::setBoolean()
|
||||
*/
|
||||
function setBoolean($paramIndex, $value, $out = false)
|
||||
{
|
||||
if ($out) $this->boundOutVars[$paramIndex] = &$value; // reference means that changes to value, will be reflected
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
$value = ($value) ? 1 : 0;
|
||||
mssql_bind($this->stmt, $paramIndex, $value, SQLBIT, $out);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see CallableStatement::setBlob()
|
||||
*/
|
||||
function setBlob($paramIndex, $blob, $out = false)
|
||||
{
|
||||
if ($blob === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
if (is_object($blob)) {
|
||||
$blob = $blob->__toString();
|
||||
}
|
||||
if ($out) $this->boundOutVars[$paramIndex] = &$blob; // reference means that changes to value, will be reflected
|
||||
$data = unpack("H*hex", $blob);
|
||||
mssql_bind($this->stmt, $paramIndex, $data, SQLTEXT, $out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::setClob()
|
||||
*/
|
||||
function setClob($paramIndex, $clob, $out = false)
|
||||
{
|
||||
if ($clob === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
if (is_object($clob)) {
|
||||
$clob = $clob->__toString();
|
||||
}
|
||||
if ($out) $this->boundOutVars[$paramIndex] = &$clob; // reference means that changes to value, will be reflected
|
||||
mssql_bind($this->stmt, $paramIndex, $clob, SQLTEXT, $out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::setDate()
|
||||
*/
|
||||
function setDate($paramIndex, $value, $out = false)
|
||||
{
|
||||
if ($out) $this->boundOutVars[$paramIndex] = &$value; // reference means that changes to value, will be reflected
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
if (is_numeric($value)) $value = date("Y-m-d", $value);
|
||||
mssql_bind($this->stmt, $paramIndex, $value, SQLVARCHAR, $out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::setFloat()
|
||||
*/
|
||||
function setFloat($paramIndex, $value, $out = false)
|
||||
{
|
||||
if ($out) $this->boundOutVars[$paramIndex] = &$value; // reference means that changes to value, will be reflected
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
$value = (float) $value;
|
||||
mssql_bind($this->stmt, $paramIndex, $value, SQLFLT8, $out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::setInt()
|
||||
*/
|
||||
function setInt($paramIndex, $value, $out = false)
|
||||
{
|
||||
if ($out) $this->boundOutVars[$paramIndex] = &$value; // reference means that changes to value, will be reflected
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
$value = (int) $value;
|
||||
mssql_bind($this->stmt, $paramIndex, $value, SQLINT4, $out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::setNull()
|
||||
*/
|
||||
function setNull($paramIndex)
|
||||
{
|
||||
// hopefully type isn't essential here :)
|
||||
$value = null; // wants a var to pass by reference
|
||||
mssql_bind($this->stmt, $paramIndex, $value, $type=null, $out=false, $is_null=true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::setString()
|
||||
*/
|
||||
function setString($paramIndex, $value, $out = false)
|
||||
{
|
||||
if ($out) $this->boundOutVars[$paramIndex] = &$value; // reference means that changes to value, will be reflected
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
$value = (string) $value;
|
||||
mssql_bind($this->stmt, $paramIndex, $value, SQLVARCHAR, $out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::setTime()
|
||||
*/
|
||||
function setTime($paramIndex, $value, $out = false)
|
||||
{
|
||||
if ($out) $this->boundOutVars[$paramIndex] = &$value; // reference means that changes to value, will be reflected
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
if (is_numeric($value)) $value = date("H:i:s", $value);
|
||||
mssql_bind($this->stmt, $paramIndex, $value, SQLVARCHAR, $out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::setTimestamp()
|
||||
*/
|
||||
function setTimestamp($paramIndex, $value, $out = false)
|
||||
{
|
||||
if ($out) $this->boundOutVars[$paramIndex] = &$value; // reference means that changes to value, will be reflected
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
if (is_numeric($value)) $value = date('Y-m-d H:i:s', $value);
|
||||
mssql_bind($this->stmt, $paramIndex, $value, SQLVARCHAR, $out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::getArray()
|
||||
*/
|
||||
function getArray($paramIndex)
|
||||
{
|
||||
if (!array_key_exists($paramIndex, $this->boundOutVars)) {
|
||||
throw new SQLException('Requesting variable not bound to output var: '.$paramIndex);
|
||||
}
|
||||
if ($this->boundOutVars[$paramIndex] === null) { return null; }
|
||||
return (array) unserialize($this->boundOutVars[$paramIndex]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::getBoolean()
|
||||
*/
|
||||
function getBoolean($paramIndex)
|
||||
{
|
||||
if (!array_key_exists($paramIndex, $this->boundOutVars)) {
|
||||
throw new SQLException('Requesting variable not bound to output var: '.$paramIndex);
|
||||
}
|
||||
if ($this->boundOutVars[$paramIndex] === null) { return null; }
|
||||
return (boolean) $this->boundOutVars[$paramIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::getBlob()
|
||||
*/
|
||||
function getBlob($paramIndex)
|
||||
{
|
||||
if (!array_key_exists($paramIndex, $this->boundOutVars)) {
|
||||
throw new SQLException('Requesting variable not bound to output var: '.$paramIndex);
|
||||
}
|
||||
if ($this->boundOutVars[$paramIndex] === null) { return null; }
|
||||
require_once 'creole/util/Blob.php';
|
||||
$b = new Blob();
|
||||
$b->setContents($this->boundOutVars[$paramIndex]);
|
||||
return $b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::getClob()
|
||||
*/
|
||||
function getClob($paramIndex)
|
||||
{
|
||||
if (!array_key_exists($paramIndex, $this->boundOutVars)) {
|
||||
throw new SQLException('Requesting variable not bound to output var: '.$paramIndex);
|
||||
}
|
||||
if ($this->boundOutVars[$paramIndex] === null) { return null; }
|
||||
require_once 'creole/util/Clob.php';
|
||||
$c = new Clob();
|
||||
$c->setContents($this->boundOutVars[$paramIndex]);
|
||||
return $c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::getDate()
|
||||
*/
|
||||
function getDate($paramIndex, $fmt = '%Y-%m-%d')
|
||||
{
|
||||
if (!array_key_exists($paramIndex, $this->boundOutVars)) {
|
||||
throw new SQLException('Requesting variable not bound to output var: '.$paramIndex);
|
||||
}
|
||||
if ($this->boundOutVars[$paramIndex] === null) { return null; }
|
||||
|
||||
$ts = strtotime($this->boundOutVars[$paramIndex]);
|
||||
if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE
|
||||
throw new SQLException("Unable to convert value at column " . $paramIndex . " to timestamp: " . $this->boundOutVars[$paramIndex]);
|
||||
}
|
||||
if (strpos($format, '%') !== false) {
|
||||
return strftime($format, $ts);
|
||||
} else {
|
||||
return date($format, $ts);
|
||||
}
|
||||
|
||||
return $this->boundOutVars[$paramIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $paramIndex Column name (string) or index (int).
|
||||
* @return float
|
||||
*/
|
||||
function getFloat($paramIndex)
|
||||
{
|
||||
if (!array_key_exists($paramIndex, $this->boundOutVars)) {
|
||||
throw new SQLException('Requesting variable not bound to output var: '.$paramIndex);
|
||||
}
|
||||
if ($this->boundOutVars[$paramIndex] === null) { return null; }
|
||||
return (float) $this->boundOutVars[$paramIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::getInt()
|
||||
*/
|
||||
function getInt($paramIndex)
|
||||
{
|
||||
if (!array_key_exists($paramIndex, $this->boundOutVars)) {
|
||||
throw new SQLException('Requesting variable not bound to output var: '.$paramIndex);
|
||||
}
|
||||
if ($this->boundOutVars[$paramIndex] === null) { return null; }
|
||||
return (int) $this->boundOutVars[$paramIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::getString()
|
||||
*/
|
||||
function getString($paramIndex)
|
||||
{
|
||||
if (!array_key_exists($paramIndex, $this->boundOutVars)) {
|
||||
throw new SQLException('Requesting variable not bound to output var: '.$paramIndex);
|
||||
}
|
||||
if ($this->boundOutVars[$paramIndex] === null) { return null; }
|
||||
return (string) $this->boundOutVars[$paramIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::getTime()
|
||||
*/
|
||||
function getTime($paramIndex, $format='%X')
|
||||
{
|
||||
if (!array_key_exists($paramIndex, $this->boundOutVars)) {
|
||||
throw new SQLException('Requesting variable not bound to output var: '.$paramIndex);
|
||||
}
|
||||
if ($this->boundOutVars[$paramIndex] === null) { return null; }
|
||||
|
||||
$ts = strtotime($this->boundOutVars[$paramIndex]);
|
||||
if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE
|
||||
throw new SQLException("Unable to convert value at column " . $paramIndex . " to timestamp: " . $this->boundOutVars[$paramIndex]);
|
||||
}
|
||||
if (strpos($format, '%') !== false) {
|
||||
return strftime($format, $ts);
|
||||
} else {
|
||||
return date($format, $ts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CallableStatement::getTimestamp()
|
||||
*/
|
||||
function getTimestamp($paramIndex, $format = 'Y-m-d H:i:s')
|
||||
{
|
||||
if (!array_key_exists($paramIndex, $this->boundOutVars)) {
|
||||
throw new SQLException('Requesting variable not bound to output var: '.$paramIndex);
|
||||
}
|
||||
if ($this->boundOutVars[$paramIndex] === null) { return null; }
|
||||
|
||||
$ts = strtotime($this->boundOutVars[$paramIndex]);
|
||||
if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE
|
||||
throw new SQLException("Unable to convert value at column " . $paramIndex . " to timestamp: " . $this->boundOutVars[$paramIndex]);
|
||||
}
|
||||
if (strpos($format, '%') !== false) {
|
||||
return strftime($format, $ts);
|
||||
} else {
|
||||
return date($format, $ts);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
283
lib/symfony/vendor/creole/drivers/mssql/MSSQLConnection.php
vendored
Executable file
283
lib/symfony/vendor/creole/drivers/mssql/MSSQLConnection.php
vendored
Executable file
@ -0,0 +1,283 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* $Id: MSSQLConnection.php,v 1.25 2005/10/17 19:03:51 dlawson_mi Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
|
||||
require_once 'creole/Connection.php';
|
||||
require_once 'creole/common/ConnectionCommon.php';
|
||||
include_once 'creole/drivers/mssql/MSSQLResultSet.php';
|
||||
|
||||
/**
|
||||
* MS SQL Server implementation of Connection.
|
||||
*
|
||||
* If you have trouble with BLOB / CLOB support
|
||||
* --------------------------------------------
|
||||
*
|
||||
* You may need to change some PHP ini settings. In particular, the following settings
|
||||
* set the text size to maximum which should get around issues with truncated data:
|
||||
* <code>
|
||||
* ini_set('mssql.textsize', 2147483647);
|
||||
* ini_set('mssql.textlimit', 2147483647);
|
||||
* </code>
|
||||
* We do not set these by default (anymore) because they do not apply to cases where MSSQL
|
||||
* is being used w/ FreeTDS.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
* @author Lukas Smith
|
||||
* @version $Revision: 1.25 $
|
||||
* @package creole.drivers.mssql
|
||||
*/
|
||||
class MSSQLConnection extends ConnectionCommon implements Connection {
|
||||
|
||||
/** Current database (used in mssql_select_db()). */
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* @see Connection::connect()
|
||||
*/
|
||||
function connect($dsninfo, $flags = 0)
|
||||
{
|
||||
if (!extension_loaded('mssql') && !extension_loaded('sybase') && !extension_loaded('sybase_ct')) {
|
||||
throw new SQLException('mssql extension not loaded');
|
||||
}
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$this->flags = $flags;
|
||||
|
||||
$persistent = ($flags & Creole::PERSISTENT === Creole::PERSISTENT);
|
||||
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
$dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
|
||||
|
||||
if (PHP_OS == "WINNT" || PHP_OS == "WIN32") {
|
||||
$portDelimiter = ",";
|
||||
} else {
|
||||
$portDelimiter = ":";
|
||||
}
|
||||
|
||||
if(!empty($dsninfo['port'])) {
|
||||
$dbhost .= $portDelimiter.$dsninfo['port'];
|
||||
} else {
|
||||
$dbhost .= $portDelimiter.'1433';
|
||||
}
|
||||
|
||||
$connect_function = $persistent ? 'mssql_pconnect' : 'mssql_connect';
|
||||
|
||||
if ($dbhost && $user && $pw) {
|
||||
$conn = @$connect_function($dbhost, $user, $pw);
|
||||
} elseif ($dbhost && $user) {
|
||||
$conn = @$connect_function($dbhost, $user);
|
||||
} else {
|
||||
$conn = @$connect_function($dbhost);
|
||||
}
|
||||
if (!$conn) {
|
||||
throw new SQLException('connect failed', mssql_get_last_message());
|
||||
}
|
||||
|
||||
if ($dsninfo['database']) {
|
||||
if (!@mssql_select_db($dsninfo['database'], $conn)) {
|
||||
throw new SQLException('No database selected');
|
||||
}
|
||||
|
||||
$this->database = $dsninfo['database'];
|
||||
}
|
||||
|
||||
$this->dblink = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getDatabaseInfo()
|
||||
*/
|
||||
public function getDatabaseInfo()
|
||||
{
|
||||
require_once 'creole/drivers/mssql/metadata/MSSQLDatabaseInfo.php';
|
||||
return new MSSQLDatabaseInfo($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getIdGenerator()
|
||||
*/
|
||||
public function getIdGenerator()
|
||||
{
|
||||
require_once 'creole/drivers/mssql/MSSQLIdGenerator.php';
|
||||
return new MSSQLIdGenerator($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareStatement()
|
||||
*/
|
||||
public function prepareStatement($sql)
|
||||
{
|
||||
require_once 'creole/drivers/mssql/MSSQLPreparedStatement.php';
|
||||
return new MSSQLPreparedStatement($this, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::createStatement()
|
||||
*/
|
||||
public function createStatement()
|
||||
{
|
||||
require_once 'creole/drivers/mssql/MSSQLStatement.php';
|
||||
return new MSSQLStatement($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns false since MSSQL doesn't support this method.
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::close()
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
$ret = @mssql_close($this->dblink);
|
||||
$this->dblink = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::executeQuery()
|
||||
*/
|
||||
function executeQuery($sql, $fetchmode = null)
|
||||
{
|
||||
$this->lastQuery = $sql;
|
||||
if (!@mssql_select_db($this->database, $this->dblink)) {
|
||||
throw new SQLException('No database selected');
|
||||
}
|
||||
$result = @mssql_query($sql, $this->dblink);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not execute query', mssql_get_last_message());
|
||||
}
|
||||
return new MSSQLResultSet($this, $result, $fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::executeUpdate()
|
||||
*/
|
||||
function executeUpdate($sql)
|
||||
{
|
||||
|
||||
$this->lastQuery = $sql;
|
||||
if (!mssql_select_db($this->database, $this->dblink)) {
|
||||
throw new SQLException('No database selected');
|
||||
}
|
||||
|
||||
$result = @mssql_query($sql, $this->dblink);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not execute update', mssql_get_last_message(), $sql);
|
||||
}
|
||||
|
||||
return $this->getUpdateCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a database transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function beginTrans()
|
||||
{
|
||||
$result = @mssql_query('BEGIN TRAN', $this->dblink);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not begin transaction', mssql_get_last_message());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function commitTrans()
|
||||
{
|
||||
if (!@mssql_select_db($this->database, $this->dblink)) {
|
||||
throw new SQLException('No database selected');
|
||||
}
|
||||
$result = @mssql_query('COMMIT TRAN', $this->dblink);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not commit transaction', mssql_get_last_message());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll back (undo) the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function rollbackTrans()
|
||||
{
|
||||
if (!@mssql_select_db($this->database, $this->dblink)) {
|
||||
throw new SQLException('no database selected');
|
||||
}
|
||||
$result = @mssql_query('ROLLBACK TRAN', $this->dblink);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not rollback transaction', mssql_get_last_message());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the last query.
|
||||
* if the last query was a select, returns 0.
|
||||
*
|
||||
* @return int Number of rows affected by the last query
|
||||
* @throws SQLException
|
||||
*/
|
||||
function getUpdateCount()
|
||||
{
|
||||
$res = @mssql_query('select @@rowcount', $this->dblink);
|
||||
if (!$res) {
|
||||
throw new SQLException('Unable to get affected row count', mssql_get_last_message());
|
||||
}
|
||||
$ar = @mssql_fetch_row($res);
|
||||
if (!$ar) {
|
||||
$result = 0;
|
||||
} else {
|
||||
@mssql_free_result($res);
|
||||
$result = $ar[0];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a CallableStatement object for calling database stored procedures.
|
||||
*
|
||||
* @param string $sql
|
||||
* @return CallableStatement
|
||||
* @throws SQLException
|
||||
*/
|
||||
function prepareCall($sql)
|
||||
{
|
||||
require_once 'creole/drivers/mssql/MSSQLCallableStatement.php';
|
||||
$stmt = mssql_init($sql);
|
||||
if (!$stmt) {
|
||||
throw new SQLException('Unable to prepare statement', mssql_get_last_message(), $sql);
|
||||
}
|
||||
return new MSSQLCallableStatement($this, $stmt);
|
||||
}
|
||||
}
|
||||
62
lib/symfony/vendor/creole/drivers/mssql/MSSQLIdGenerator.php
vendored
Executable file
62
lib/symfony/vendor/creole/drivers/mssql/MSSQLIdGenerator.php
vendored
Executable file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
require_once 'creole/IdGenerator.php';
|
||||
|
||||
/**
|
||||
* MSSQL IdGenerator implimenation.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.6 $
|
||||
* @package creole.drivers.mssql
|
||||
*/
|
||||
class MSSQLIdGenerator implements IdGenerator {
|
||||
|
||||
/** Connection object that instantiated this class */
|
||||
private $conn;
|
||||
|
||||
/**
|
||||
* Creates a new IdGenerator class, saves passed connection for use
|
||||
* later by getId() method.
|
||||
* @param Connection $conn
|
||||
*/
|
||||
public function __construct(Connection $conn)
|
||||
{
|
||||
$this->conn = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::isBeforeInsert()
|
||||
*/
|
||||
public function isBeforeInsert()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::isAfterInsert()
|
||||
*/
|
||||
public function isAfterInsert()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::getIdMethod()
|
||||
*/
|
||||
public function getIdMethod()
|
||||
{
|
||||
return self::AUTOINCREMENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::getId()
|
||||
*/
|
||||
public function getId($unused = null)
|
||||
{
|
||||
$rs = $this->conn->executeQuery("SELECT SCOPE_IDENTITY()", ResultSet::FETCHMODE_NUM);
|
||||
$rs->next();
|
||||
return $rs->getInt(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
99
lib/symfony/vendor/creole/drivers/mssql/MSSQLPreparedStatement.php
vendored
Executable file
99
lib/symfony/vendor/creole/drivers/mssql/MSSQLPreparedStatement.php
vendored
Executable file
@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MSSQLPreparedStatement.php,v 1.13 2005/11/13 01:29:01 gamr Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/PreparedStatement.php';
|
||||
require_once 'creole/common/PreparedStatementCommon.php';
|
||||
|
||||
/**
|
||||
* MSSQL specific PreparedStatement functions.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.13 $
|
||||
* @package creole.drivers.mssql
|
||||
*/
|
||||
class MSSQLPreparedStatement extends PreparedStatementCommon implements PreparedStatement {
|
||||
|
||||
/**
|
||||
* MSSQL-specific implementation of setBlob().
|
||||
*
|
||||
* If you are having trouble getting BLOB data into the database, see the phpdoc comment
|
||||
* in the MSSQLConnection for some PHP ini values that may need to be set. (This also
|
||||
* applies to CLOB support.)
|
||||
*
|
||||
* @param int $paramIndex
|
||||
* @param mixed $value Blob object or string.
|
||||
* @return void
|
||||
*/
|
||||
function setBlob($paramIndex, $blob)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
if ($blob === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
// they took magic __toString() out of PHP5.0.0; this sucks
|
||||
if (is_object($blob)) {
|
||||
$blob = $blob->__toString();
|
||||
}
|
||||
$data = unpack("H*hex", $blob);
|
||||
$this->boundInVars[$paramIndex] = '0x'.$data['hex']; // no surrounding quotes!
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add quotes using str_replace.
|
||||
* This is not as thorough as MySQL.
|
||||
*/
|
||||
protected function escape($subject)
|
||||
{
|
||||
// use this instead of magic_quotes_sybase + addslashes(),
|
||||
// just in case multiple RDBMS being used at the same time
|
||||
return str_replace("'", "''", $subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* MSSQL must emulate OFFSET/LIMIT support.
|
||||
*/
|
||||
public function executeQuery($p1 = null, $fetchmode = null)
|
||||
{
|
||||
$params = null;
|
||||
if ($fetchmode !== null) {
|
||||
$params = $p1;
|
||||
} elseif ($p1 !== null) {
|
||||
if (is_array($p1)) $params = $p1;
|
||||
else $fetchmode = $p1;
|
||||
}
|
||||
|
||||
if ($params) {
|
||||
for($i=0,$cnt=count($params); $i < $cnt; $i++) {
|
||||
$this->set($i+1, $params[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->updateCount = null; // reset
|
||||
$sql = $this->replaceParams();
|
||||
|
||||
$this->resultSet = $this->conn->executeQuery($sql, $fetchmode);
|
||||
$this->resultSet->_setOffset($this->offset);
|
||||
$this->resultSet->_setLimit($this->limit);
|
||||
return $this->resultSet;
|
||||
}
|
||||
}
|
||||
159
lib/symfony/vendor/creole/drivers/mssql/MSSQLResultSet.php
vendored
Executable file
159
lib/symfony/vendor/creole/drivers/mssql/MSSQLResultSet.php
vendored
Executable file
@ -0,0 +1,159 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MSSQLResultSet.php,v 1.21 2006/01/17 19:44:38 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/ResultSet.php';
|
||||
require_once 'creole/common/ResultSetCommon.php';
|
||||
|
||||
/**
|
||||
* MSSQL implementation of ResultSet.
|
||||
*
|
||||
* MS SQL does not support LIMIT or OFFSET natively so the methods
|
||||
* in here need to perform some adjustments and extra checking to make sure
|
||||
* that this behaves the same as RDBMS drivers using native OFFSET/LIMIT.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.21 $
|
||||
* @package creole.drivers.mssql
|
||||
*/
|
||||
class MSSQLResultSet extends ResultSetCommon implements ResultSet {
|
||||
|
||||
/**
|
||||
* Offset at which to start reading rows.
|
||||
* @var int
|
||||
*/
|
||||
private $offset = 0;
|
||||
|
||||
/**
|
||||
* Maximum rows to retrieve, or 0 if all.
|
||||
* @var int
|
||||
*/
|
||||
private $limit = 0;
|
||||
|
||||
/**
|
||||
* This MSSQL-only function exists to set offset after ResultSet is instantiated.
|
||||
* This function should be "protected" in Java sense: only available to classes in package.
|
||||
* THIS METHOD SHOULD NOT BE CALLED BY ANYTHING EXCEPTION DRIVER CLASSES.
|
||||
* @param int $offset New offset. If great than 0, then seek(0) will be called to move cursor.
|
||||
* @access protected
|
||||
*/
|
||||
public function _setOffset($offset)
|
||||
{
|
||||
$this->offset = $offset;
|
||||
if ($offset > 0) {
|
||||
$this->seek(0); // 0 becomes $offset by seek() method
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This MSSQL-only function exists to set limit after ResultSet is instantiated.
|
||||
* This function should be "protected" in Java sense: only available to classes in package.
|
||||
* THIS METHOD SHOULD NOT BE CALLED BY ANYTHING EXCEPTION DRIVER CLASSES.
|
||||
* @param int $limit New limit.
|
||||
* @access protected
|
||||
*/
|
||||
public function _setLimit($limit)
|
||||
{
|
||||
$this->limit = $limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::seek()
|
||||
*/
|
||||
function seek($rownum)
|
||||
{
|
||||
// support emulated OFFSET
|
||||
$actual = $rownum + $this->offset;
|
||||
|
||||
if (($this->limit > 0 && $rownum >= $this->limit) || $rownum < 0) {
|
||||
// have to check for rownum < 0, because mssql_seek() won't
|
||||
// complain if the $actual is valid.
|
||||
return false;
|
||||
}
|
||||
|
||||
// MSSQL rows start w/ 0, but this works, because we are
|
||||
// looking to move the position _before_ the next desired position
|
||||
if (!@mssql_data_seek($this->result, $actual)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->cursorPos = $rownum;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::next()
|
||||
*/
|
||||
function next()
|
||||
{
|
||||
// support emulated LIMIT
|
||||
if ( $this->limit > 0 && ($this->cursorPos >= $this->limit) ) {
|
||||
$this->afterLast();
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->fields = mssql_fetch_array($this->result, $this->fetchmode);
|
||||
|
||||
if (!$this->fields) {
|
||||
if ($errmsg = mssql_get_last_message()) {
|
||||
throw new SQLException("Error fetching result", $errmsg);
|
||||
} else {
|
||||
// We've advanced beyond end of recordset.
|
||||
$this->afterLast();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->fetchmode === ResultSet::FETCHMODE_ASSOC && $this->lowerAssocCase) {
|
||||
$this->fields = array_change_key_case($this->fields, CASE_LOWER);
|
||||
}
|
||||
|
||||
// Advance cursor position
|
||||
$this->cursorPos++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getRecordCount()
|
||||
*/
|
||||
function getRecordCount()
|
||||
{
|
||||
$rows = @mssql_num_rows($this->result);
|
||||
if ($rows === null) {
|
||||
throw new SQLException('Error getting record count', mssql_get_last_message());
|
||||
}
|
||||
// adjust count based on emulated LIMIT/OFFSET
|
||||
$rows -= $this->offset;
|
||||
return ($this->limit > 0 && $rows > $this->limit ? $this->limit : $rows);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::close()
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
$ret = @mssql_free_result($this->result);
|
||||
$this->result = false;
|
||||
$this->fields = array();
|
||||
$this->limit = 0;
|
||||
$this->offset = 0;
|
||||
}
|
||||
|
||||
}
|
||||
72
lib/symfony/vendor/creole/drivers/mssql/MSSQLStatement.php
vendored
Executable file
72
lib/symfony/vendor/creole/drivers/mssql/MSSQLStatement.php
vendored
Executable file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MSSQLStatement.php,v 1.4 2004/06/13 02:31:07 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/common/StatementCommon.php';
|
||||
require_once 'creole/Statement.php';
|
||||
|
||||
/**
|
||||
* Class that contains MSSQL functionality for Statements.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.4 $
|
||||
* @package creole.drivers.mssql
|
||||
*/
|
||||
class MSSQLStatement extends StatementCommon implements Statement {
|
||||
|
||||
/**
|
||||
* Executes the SQL query in this PreparedStatement object and returns the resultset generated by the query.
|
||||
*
|
||||
* @param string $sql This method may optionally be called with the SQL statement.
|
||||
* @param int $fetchmode The mode to use when fetching the results (e.g. ResultSet::FETCHMODE_NUM, ResultSet::FETCHMODE_ASSOC).
|
||||
* @return object Creole::ResultSet
|
||||
* @throws SQLException If there is an error executing the specified query.
|
||||
*/
|
||||
public function executeQuery($sql, $fetchmode = null)
|
||||
{
|
||||
$this->updateCount = null;
|
||||
$this->resultSet = $this->conn->executeQuery($sql, $fetchmode);
|
||||
$this->resultSet->_setOffset($this->offset);
|
||||
$this->resultSet->_setLimit($this->limit);
|
||||
return $this->resultSet;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets next result set (if this behavior is supported by driver).
|
||||
* Some drivers (e.g. MSSQL) support returning multiple result sets -- e.g.
|
||||
* from stored procedures.
|
||||
*
|
||||
* This function also closes any current restult set.
|
||||
*
|
||||
* Default behavior is for this function to return false. Driver-specific
|
||||
* implementations of this class can override this method if they actually
|
||||
* support multiple result sets.
|
||||
*
|
||||
* @return boolean True if there is another result set, otherwise false.
|
||||
*/
|
||||
public function getMoreResults()
|
||||
{
|
||||
if ($this->resultSet) $this->resultSet->close();
|
||||
$this->resultSet = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
94
lib/symfony/vendor/creole/drivers/mssql/MSSQLTypes.php
vendored
Executable file
94
lib/symfony/vendor/creole/drivers/mssql/MSSQLTypes.php
vendored
Executable file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* $Id: MSSQLTypes.php,v 1.8 2004/07/27 23:16:50 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/CreoleTypes.php';
|
||||
|
||||
/**
|
||||
* MSSQL types / type map.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.8 $
|
||||
* @package creole.drivers.mssql
|
||||
*/
|
||||
class MSSQLTypes extends CreoleTypes {
|
||||
|
||||
/** Map PostgreSQL native types to Creole (JDBC) types. */
|
||||
private static $typeMap = array (
|
||||
"binary" => CreoleTypes::BINARY,
|
||||
"bit" => CreoleTypes::BOOLEAN,
|
||||
"char" => CreoleTypes::CHAR,
|
||||
"datetime" => CreoleTypes::TIMESTAMP,
|
||||
"decimal() identity" => CreoleTypes::DECIMAL,
|
||||
"decimal" => CreoleTypes::DECIMAL,
|
||||
"image" => CreoleTypes::LONGVARBINARY,
|
||||
"int" => CreoleTypes::INTEGER,
|
||||
"int identity" => CreoleTypes::INTEGER,
|
||||
"integer" => CreoleTypes::INTEGER,
|
||||
"money" => CreoleTypes::DECIMAL,
|
||||
"nchar" => CreoleTypes::CHAR,
|
||||
"ntext" => CreoleTypes::LONGVARCHAR,
|
||||
"numeric() identity" => CreoleTypes::NUMERIC,
|
||||
"numeric" => CreoleTypes::NUMERIC,
|
||||
"nvarchar" => CreoleTypes::VARCHAR,
|
||||
"real" => CreoleTypes::REAL,
|
||||
"float" => CreoleTypes::FLOAT,
|
||||
"smalldatetime" => CreoleTypes::TIMESTAMP,
|
||||
"smallint" => CreoleTypes::SMALLINT,
|
||||
"smallint identity" => CreoleTypes::SMALLINT,
|
||||
"smallmoney" => CreoleTypes::DECIMAL,
|
||||
"sysname" => CreoleTypes::VARCHAR,
|
||||
"text" => CreoleTypes::LONGVARCHAR,
|
||||
"timestamp" => CreoleTypes::BINARY,
|
||||
"tinyint identity" => CreoleTypes::TINYINT,
|
||||
"tinyint" => CreoleTypes::TINYINT,
|
||||
"uniqueidentifier" => CreoleTypes::CHAR,
|
||||
"varbinary" => CreoleTypes::VARBINARY,
|
||||
"varchar" => CreoleTypes::VARCHAR,
|
||||
"uniqueidentifier" => CreoleTypes::CHAR,
|
||||
// SQL Server 2000 only
|
||||
"bigint identity" => CreoleTypes::BIGINT,
|
||||
"bigint" => CreoleTypes::BIGINT,
|
||||
"sql_variant" => CreoleTypes::VARCHAR,
|
||||
);
|
||||
|
||||
/** Reverse lookup map, created on demand. */
|
||||
private static $reverseMap = null;
|
||||
|
||||
public static function getType($mssqlType)
|
||||
{
|
||||
$t = strtolower($mssqlType);
|
||||
if (isset(self::$typeMap[$t])) {
|
||||
return self::$typeMap[$t];
|
||||
} else {
|
||||
return CreoleTypes::OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getNativeType($creoleType)
|
||||
{
|
||||
if (self::$reverseMap === null) {
|
||||
self::$reverseMap = array_flip(self::$typeMap);
|
||||
}
|
||||
return @self::$reverseMap[$creoleType];
|
||||
}
|
||||
|
||||
}
|
||||
69
lib/symfony/vendor/creole/drivers/mssql/metadata/MSSQLDatabaseInfo.php
vendored
Executable file
69
lib/symfony/vendor/creole/drivers/mssql/metadata/MSSQLDatabaseInfo.php
vendored
Executable file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MSSQLDatabaseInfo.php,v 1.11 2006/01/17 19:44:39 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/metadata/DatabaseInfo.php';
|
||||
|
||||
/**
|
||||
* MSSQL impementation of DatabaseInfo.
|
||||
*
|
||||
* @author Hans Lellelid
|
||||
* @version $Revision: 1.11 $
|
||||
* @package creole.drivers.mssql.metadata
|
||||
*/
|
||||
class MSSQLDatabaseInfo extends DatabaseInfo {
|
||||
|
||||
/**
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function initTables()
|
||||
{
|
||||
include_once 'creole/drivers/mssql/metadata/MSSQLTableInfo.php';
|
||||
|
||||
$dsn = $this->conn->getDSN();
|
||||
|
||||
|
||||
if (!@mssql_select_db($this->dbname, $this->conn->getResource())) {
|
||||
throw new SQLException('No database selected');
|
||||
}
|
||||
|
||||
$result = mssql_query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME <> 'dtproperties'", $this->conn->getResource());
|
||||
|
||||
if (!$result) {
|
||||
throw new SQLException("Could not list tables", mssql_get_last_message());
|
||||
}
|
||||
|
||||
while ($row = mssql_fetch_row($result)) {
|
||||
$this->tables[strtoupper($row[0])] = new MSSQLTableInfo($this, $row[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return void
|
||||
* @throws SQLException
|
||||
*/
|
||||
protected function initSequences()
|
||||
{
|
||||
// there are no sequences -- afaik -- in MSSQL.
|
||||
}
|
||||
|
||||
}
|
||||
183
lib/symfony/vendor/creole/drivers/mssql/metadata/MSSQLTableInfo.php
vendored
Executable file
183
lib/symfony/vendor/creole/drivers/mssql/metadata/MSSQLTableInfo.php
vendored
Executable file
@ -0,0 +1,183 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MSSQLTableInfo.php,v 1.14 2006/01/17 19:44:39 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/CreoleTypes.php';
|
||||
require_once 'creole/metadata/TableInfo.php';
|
||||
|
||||
/**
|
||||
* MSSQL implementation of TableInfo.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.14 $
|
||||
* @package creole.drivers.mssql.metadata
|
||||
*/
|
||||
class MSSQLTableInfo extends TableInfo {
|
||||
|
||||
/**
|
||||
* Loads the columns for this table.
|
||||
* @return void
|
||||
*/
|
||||
protected function initColumns()
|
||||
{
|
||||
include_once 'creole/metadata/ColumnInfo.php';
|
||||
include_once 'creole/drivers/mssql/MSSQLTypes.php';
|
||||
|
||||
if (!@mssql_select_db($this->dbname, $this->conn->getResource())) {
|
||||
throw new SQLException('No database selected');
|
||||
}
|
||||
|
||||
$res = mssql_query("sp_columns ".$this->name, $this->conn->getResource());
|
||||
if (!$res) {
|
||||
throw new SQLException('Could not get column names', mssql_get_last_message());
|
||||
}
|
||||
|
||||
while ($row = mssql_fetch_array($res)) {
|
||||
$name = $row['COLUMN_NAME'];
|
||||
$type = $row['TYPE_NAME'];
|
||||
$length = $row['LENGTH'];
|
||||
$is_nullable = $row['NULLABLE'];
|
||||
$default = $row['COLUMN_DEF'];
|
||||
$precision = $row['PRECISION'];
|
||||
$scale = $row['SCALE'];
|
||||
$identity = false;
|
||||
if (strtolower($type) == "int identity") {
|
||||
$identity = true;
|
||||
}
|
||||
$this->columns[$name] = new ColumnInfo($this, $name, MSSQLTypes::getType($type), $type, $length, $precision, $scale, $is_nullable, $default, $identity);
|
||||
}
|
||||
|
||||
$this->colsLoaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the indexes for this table.
|
||||
* @return void
|
||||
*/
|
||||
protected function initIndexes()
|
||||
{
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
include_once 'creole/metadata/IndexInfo.php';
|
||||
|
||||
if (!@mssql_select_db($this->dbname, $this->conn->getResource())) {
|
||||
throw new SQLException('No database selected');
|
||||
}
|
||||
|
||||
$res = mssql_query("sp_indexes_rowset ".$this->name, $this->conn->getResource());
|
||||
|
||||
while ($row = mssql_fetch_array($res)) {
|
||||
$name = $row['INDEX_NAME'];
|
||||
// All primary keys are indexes (right...?)
|
||||
if (!isset($this->indexes[$name])) {
|
||||
$this->indexes[$name] = new IndexInfo($name);
|
||||
}
|
||||
$this->indexes[$name]->addColumn($this->columns[ $row['COLUMN_NAME'] ]);
|
||||
}
|
||||
|
||||
$this->indexesLoaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the foreign keys for this table.
|
||||
* @return void
|
||||
*/
|
||||
protected function initForeignKeys()
|
||||
{
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
include_once 'creole/metadata/ForeignKeyInfo.php';
|
||||
|
||||
if (!@mssql_select_db($this->dbname, $this->conn->getResource())) {
|
||||
throw new SQLException('No database selected');
|
||||
}
|
||||
|
||||
$res = mssql_query("SELECT ccu1.TABLE_NAME, ccu1.COLUMN_NAME, ccu2.TABLE_NAME AS FK_TABLE_NAME, ccu2.COLUMN_NAME AS FK_COLUMN_NAME
|
||||
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu1 INNER JOIN
|
||||
INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc1 ON tc1.CONSTRAINT_NAME = ccu1.CONSTRAINT_NAME AND
|
||||
CONSTRAINT_TYPE = 'Foreign Key' INNER JOIN
|
||||
INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc1 ON rc1.CONSTRAINT_NAME = tc1.CONSTRAINT_NAME INNER JOIN
|
||||
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu2 ON ccu2.CONSTRAINT_NAME = rc1.UNIQUE_CONSTRAINT_NAME
|
||||
WHERE (ccu1.table_name = '".$this->name."')", $this->conn->getResource());
|
||||
|
||||
while($row = mssql_fetch_array($res)) {
|
||||
$name = $row['COLUMN_NAME'];
|
||||
$ftbl = $row['FK_TABLE_NAME'];
|
||||
$fcol = $row['FK_COLUMN_NAME'];
|
||||
|
||||
if (!isset($this->foreignKeys[$name])) {
|
||||
$this->foreignKeys[$name] = new ForeignKeyInfo($name);
|
||||
|
||||
if ($this->database->hasTable($ftbl)) {
|
||||
$foreignTable = $this->database->getTable($ftbl);
|
||||
} else {
|
||||
$foreignTable = new TableInfo($ltbl);
|
||||
$this->database->addTable($foreignTable);
|
||||
}
|
||||
|
||||
if ($foreignTable->hasColumn($fcol)) {
|
||||
$foreignCol = $foreignTable->getColumn($fcol);
|
||||
} else {
|
||||
$foreignCol = new ColumnInfo($foreignTable, $fcol);
|
||||
$foreignTable->addColumn($foreignCol);
|
||||
}
|
||||
|
||||
$this->foreignKeys[$name]->addReference($this->columns[$name], $foreignCol);
|
||||
}
|
||||
}
|
||||
|
||||
$this->fksLoaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the primary key info for this table.
|
||||
* @return void
|
||||
*/
|
||||
protected function initPrimaryKey()
|
||||
{
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
include_once 'creole/metadata/PrimaryKeyInfo.php';
|
||||
|
||||
if (!@mssql_select_db($this->dbname, $this->conn->getResource())) {
|
||||
throw new SQLException('No database selected');
|
||||
}
|
||||
|
||||
$res = mssql_query("SELECT COLUMN_NAME
|
||||
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
|
||||
INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ON
|
||||
INFORMATION_SCHEMA.TABLE_CONSTRAINTS.CONSTRAINT_NAME = INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE.constraint_name
|
||||
WHERE (INFORMATION_SCHEMA.TABLE_CONSTRAINTS.CONSTRAINT_TYPE = 'PRIMARY KEY') AND
|
||||
(INFORMATION_SCHEMA.TABLE_CONSTRAINTS.TABLE_NAME = '".$this->name."')", $this->conn->getResource());
|
||||
|
||||
// Loop through the returned results, grouping the same key_name together.
|
||||
// name of the primary key will be the first column name in the key.
|
||||
while($row = mssql_fetch_row($res)) {
|
||||
$name = $row[0];
|
||||
if (!isset($this->primaryKey)) {
|
||||
$this->primaryKey = new PrimaryKeyInfo($name);
|
||||
}
|
||||
$this->primaryKey->addColumn($this->columns[ $name ]);
|
||||
}
|
||||
|
||||
$this->pkLoaded = true;
|
||||
}
|
||||
|
||||
}
|
||||
290
lib/symfony/vendor/creole/drivers/mysql/MySQLConnection.php
vendored
Executable file
290
lib/symfony/vendor/creole/drivers/mysql/MySQLConnection.php
vendored
Executable file
@ -0,0 +1,290 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MySQLConnection.php,v 1.18 2004/09/01 14:00:28 dlawson_mi Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/Connection.php';
|
||||
require_once 'creole/common/ConnectionCommon.php';
|
||||
include_once 'creole/drivers/mysql/MySQLResultSet.php';
|
||||
|
||||
/**
|
||||
* MySQL implementation of Connection.
|
||||
*
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
* @author Lukas Smith
|
||||
* @version $Revision: 1.18 $
|
||||
* @package creole.drivers.mysql
|
||||
*/
|
||||
class MySQLConnection extends ConnectionCommon implements Connection {
|
||||
|
||||
/** Current database (used in mysql_select_db()). */
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param $dsn the data source name (see DB::parseDSN for syntax)
|
||||
* @param $flags Any conneciton flags.
|
||||
* @access public
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
function connect($dsninfo, $flags = 0)
|
||||
{
|
||||
if (!extension_loaded('mysql')) {
|
||||
throw new SQLException('mysql extension not loaded');
|
||||
}
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$this->flags = $flags;
|
||||
|
||||
$persistent = ($flags & Creole::PERSISTENT) === Creole::PERSISTENT;
|
||||
|
||||
if (isset($dsninfo['protocol']) && $dsninfo['protocol'] == 'unix') {
|
||||
$dbhost = ':' . $dsninfo['socket'];
|
||||
} else {
|
||||
$dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
|
||||
if (!empty($dsninfo['port'])) {
|
||||
$dbhost .= ':' . $dsninfo['port'];
|
||||
}
|
||||
}
|
||||
$user = $dsninfo['username'];
|
||||
$pw = $dsninfo['password'];
|
||||
|
||||
$encoding = !empty($dsninfo['encoding']) ? $dsninfo['encoding'] : null;
|
||||
|
||||
$connect_function = $persistent ? 'mysql_pconnect' : 'mysql_connect';
|
||||
|
||||
@ini_set('track_errors', true);
|
||||
if ($dbhost && $user && $pw) {
|
||||
$conn = @$connect_function($dbhost, $user, $pw);
|
||||
} elseif ($dbhost && $user) {
|
||||
$conn = @$connect_function($dbhost, $user);
|
||||
} elseif ($dbhost) {
|
||||
$conn = @$connect_function($dbhost);
|
||||
} else {
|
||||
$conn = false;
|
||||
}
|
||||
@ini_restore('track_errors');
|
||||
if (empty($conn)) {
|
||||
if (($err = @mysql_error()) != '') {
|
||||
throw new SQLException("connect failed", $err);
|
||||
} elseif (empty($php_errormsg)) {
|
||||
throw new SQLException("connect failed");
|
||||
} else {
|
||||
throw new SQLException("connect failed", $php_errormsg);
|
||||
}
|
||||
}
|
||||
|
||||
if ($dsninfo['database']) {
|
||||
if (!@mysql_select_db($dsninfo['database'], $conn)) {
|
||||
switch(mysql_errno($conn)) {
|
||||
case 1049:
|
||||
$exc = new SQLException("no such database", mysql_error($conn));
|
||||
break;
|
||||
case 1044:
|
||||
$exc = new SQLException("access violation", mysql_error($conn));
|
||||
break;
|
||||
default:
|
||||
$exc = new SQLException("cannot select database", mysql_error($conn));
|
||||
}
|
||||
|
||||
throw $exc;
|
||||
|
||||
}
|
||||
// fix to allow calls to different databases in the same script
|
||||
$this->database = $dsninfo['database'];
|
||||
}
|
||||
|
||||
$this->dblink = $conn;
|
||||
|
||||
if ($encoding) {
|
||||
$this->executeUpdate("SET NAMES " . $encoding);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getDatabaseInfo()
|
||||
*/
|
||||
public function getDatabaseInfo()
|
||||
{
|
||||
require_once 'creole/drivers/mysql/metadata/MySQLDatabaseInfo.php';
|
||||
return new MySQLDatabaseInfo($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getIdGenerator()
|
||||
*/
|
||||
public function getIdGenerator()
|
||||
{
|
||||
require_once 'creole/drivers/mysql/MySQLIdGenerator.php';
|
||||
return new MySQLIdGenerator($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareStatement()
|
||||
*/
|
||||
public function prepareStatement($sql)
|
||||
{
|
||||
require_once 'creole/drivers/mysql/MySQLPreparedStatement.php';
|
||||
return new MySQLPreparedStatement($this, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareCall()
|
||||
*/
|
||||
public function prepareCall($sql) {
|
||||
throw new SQLException('MySQL does not support stored procedures.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::createStatement()
|
||||
*/
|
||||
public function createStatement()
|
||||
{
|
||||
require_once 'creole/drivers/mysql/MySQLStatement.php';
|
||||
return new MySQLStatement($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::disconnect()
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
$ret = mysql_close($this->dblink);
|
||||
$this->dblink = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::applyLimit()
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
if ( $limit > 0 ) {
|
||||
$sql .= " LIMIT " . ($offset > 0 ? $offset . ", " : "") . $limit;
|
||||
} else if ( $offset > 0 ) {
|
||||
$sql .= " LIMIT " . $offset . ", 18446744073709551615";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::executeQuery()
|
||||
*/
|
||||
function executeQuery($sql, $fetchmode = null)
|
||||
{
|
||||
$this->lastQuery = $sql;
|
||||
if ($this->database) {
|
||||
if (!@mysql_select_db($this->database, $this->dblink)) {
|
||||
throw new SQLException('No database selected', mysql_error($this->dblink));
|
||||
}
|
||||
}
|
||||
$result = @mysql_query($sql, $this->dblink);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not execute query', mysql_error($this->dblink), $sql);
|
||||
}
|
||||
return new MySQLResultSet($this, $result, $fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::executeUpdate()
|
||||
*/
|
||||
function executeUpdate($sql)
|
||||
{
|
||||
$this->lastQuery = $sql;
|
||||
|
||||
if ($this->database) {
|
||||
if (!@mysql_select_db($this->database, $this->dblink)) {
|
||||
throw new SQLException('No database selected', mysql_error($this->dblink));
|
||||
}
|
||||
}
|
||||
|
||||
$result = @mysql_query($sql, $this->dblink);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not execute update', mysql_error($this->dblink), $sql);
|
||||
}
|
||||
return (int) mysql_affected_rows($this->dblink);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a database transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function beginTrans()
|
||||
{
|
||||
$result = @mysql_query('SET AUTOCOMMIT=0', $this->dblink);
|
||||
$result = @mysql_query('BEGIN', $this->dblink);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not begin transaction', mysql_error($this->dblink));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function commitTrans()
|
||||
{
|
||||
if ($this->database) {
|
||||
if (!@mysql_select_db($this->database, $this->dblink)) {
|
||||
throw new SQLException('No database selected', mysql_error($this->dblink));
|
||||
}
|
||||
}
|
||||
$result = @mysql_query('COMMIT', $this->dblink);
|
||||
$result = @mysql_query('SET AUTOCOMMIT=1', $this->dblink);
|
||||
if (!$result) {
|
||||
throw new SQLException('Can not commit transaction', mysql_error($this->dblink));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll back (undo) the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function rollbackTrans()
|
||||
{
|
||||
if ($this->database) {
|
||||
if (!@mysql_select_db($this->database, $this->dblink)) {
|
||||
throw new SQLException('No database selected', mysql_error($this->dblink));
|
||||
}
|
||||
}
|
||||
$result = @mysql_query('ROLLBACK', $this->dblink);
|
||||
$result = @mysql_query('SET AUTOCOMMIT=1', $this->dblink);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not rollback transaction', mysql_error($this->dblink));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the data manipulation
|
||||
* query.
|
||||
*
|
||||
* @return int Number of rows affected by the last query.
|
||||
*/
|
||||
function getUpdateCount()
|
||||
{
|
||||
return (int) @mysql_affected_rows($this->dblink);
|
||||
}
|
||||
|
||||
}
|
||||
75
lib/symfony/vendor/creole/drivers/mysql/MySQLIdGenerator.php
vendored
Executable file
75
lib/symfony/vendor/creole/drivers/mysql/MySQLIdGenerator.php
vendored
Executable file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
require_once 'creole/IdGenerator.php';
|
||||
|
||||
/**
|
||||
* MySQL IdGenerator implimenation.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.6 $
|
||||
* @package creole.drivers.mysql
|
||||
*/
|
||||
class MySQLIdGenerator implements IdGenerator {
|
||||
|
||||
/** Connection object that instantiated this class */
|
||||
private $conn;
|
||||
|
||||
/**
|
||||
* Creates a new IdGenerator class, saves passed connection for use
|
||||
* later by getId() method.
|
||||
* @param Connection $conn
|
||||
*/
|
||||
public function __construct(Connection $conn)
|
||||
{
|
||||
$this->conn = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::isBeforeInsert()
|
||||
*/
|
||||
public function isBeforeInsert()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::isAfterInsert()
|
||||
*/
|
||||
public function isAfterInsert()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::getIdMethod()
|
||||
*/
|
||||
public function getIdMethod()
|
||||
{
|
||||
return self::AUTOINCREMENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last-generated auto-increment ID.
|
||||
*
|
||||
* Note that for very large values (2,147,483,648 to 9,223,372,036,854,775,807) a string
|
||||
* will be returned, because these numbers are larger than supported by PHP's native
|
||||
* numeric datatypes.
|
||||
*
|
||||
* @see IdGenerator::getId()
|
||||
*/
|
||||
public function getId($unused = null)
|
||||
{
|
||||
$insert_id = mysql_insert_id($this->conn->getResource());
|
||||
if ( $insert_id < 0 ) {
|
||||
$insert_id = null;
|
||||
$result = mysql_query('SELECT LAST_INSERT_ID()', $this->conn->getResource());
|
||||
if ( $result ) {
|
||||
$row = mysql_fetch_row($result);
|
||||
$insert_id = $row ? $row[0] : null;
|
||||
}
|
||||
}
|
||||
return $insert_id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
44
lib/symfony/vendor/creole/drivers/mysql/MySQLPreparedStatement.php
vendored
Executable file
44
lib/symfony/vendor/creole/drivers/mysql/MySQLPreparedStatement.php
vendored
Executable file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MySQLPreparedStatement.php,v 1.7 2005/12/10 13:46:55 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/PreparedStatement.php';
|
||||
require_once 'creole/common/PreparedStatementCommon.php';
|
||||
|
||||
/**
|
||||
* MySQL subclass for prepared statements.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.7 $
|
||||
* @package creole.drivers.mysql
|
||||
*/
|
||||
class MySQLPreparedStatement extends PreparedStatementCommon implements PreparedStatement {
|
||||
|
||||
/**
|
||||
* Quotes string using native mysql function (mysql_real_escape_string()).
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
protected function escape($str)
|
||||
{
|
||||
return mysql_real_escape_string($str, $this->conn->getResource());
|
||||
}
|
||||
|
||||
}
|
||||
149
lib/symfony/vendor/creole/drivers/mysql/MySQLResultSet.php
vendored
Executable file
149
lib/symfony/vendor/creole/drivers/mysql/MySQLResultSet.php
vendored
Executable file
@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MySQLResultSet.php,v 1.24 2006/01/17 19:44:39 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/ResultSet.php';
|
||||
require_once 'creole/common/ResultSetCommon.php';
|
||||
|
||||
/**
|
||||
* MySQL implementation of ResultSet class.
|
||||
*
|
||||
* MySQL supports OFFSET / LIMIT natively; this means that no adjustments or checking
|
||||
* are performed. We will assume that if the lmitSQL() operation failed that an
|
||||
* exception was thrown, and that OFFSET/LIMIT will never be emulated for MySQL.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.24 $
|
||||
* @package creole.drivers.mysql
|
||||
*/
|
||||
class MySQLResultSet extends ResultSetCommon implements ResultSet {
|
||||
|
||||
/**
|
||||
* @see ResultSet::seek()
|
||||
*/
|
||||
public function seek($rownum)
|
||||
{
|
||||
// MySQL rows start w/ 0, but this works, because we are
|
||||
// looking to move the position _before_ the next desired position
|
||||
if (!@mysql_data_seek($this->result, $rownum)) {
|
||||
return false;
|
||||
}
|
||||
$this->cursorPos = $rownum;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::next()
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->fields = mysql_fetch_array($this->result, $this->fetchmode);
|
||||
|
||||
if (!$this->fields) {
|
||||
$errno = mysql_errno($this->conn->getResource());
|
||||
if (!$errno) {
|
||||
// We've advanced beyond end of recordset.
|
||||
$this->afterLast();
|
||||
return false;
|
||||
} else {
|
||||
throw new SQLException("Error fetching result", mysql_error($this->conn->getResource()));
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->fetchmode === ResultSet::FETCHMODE_ASSOC && $this->lowerAssocCase) {
|
||||
$this->fields = array_change_key_case($this->fields, CASE_LOWER);
|
||||
}
|
||||
|
||||
// Advance cursor position
|
||||
$this->cursorPos++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getRecordCount()
|
||||
*/
|
||||
function getRecordCount()
|
||||
{
|
||||
$rows = @mysql_num_rows($this->result);
|
||||
if ($rows === null) {
|
||||
throw new SQLException("Error fetching num rows", mysql_error($this->conn->getResource()));
|
||||
}
|
||||
return (int) $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::close()
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
if(is_resource($this->result))
|
||||
@mysql_free_result($this->result);
|
||||
$this->fields = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string version of column.
|
||||
* No rtrim() necessary for MySQL, as this happens natively.
|
||||
* @see ResultSet::getString()
|
||||
*/
|
||||
public function getString($column)
|
||||
{
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
if ($this->fields[$idx] === null) { return null; }
|
||||
return (string) $this->fields[$idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unix epoch timestamp based on either a TIMESTAMP or DATETIME field.
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1.
|
||||
* @return string
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
function getTimestamp($column, $format='Y-m-d H:i:s')
|
||||
{
|
||||
if (is_int($column)) { $column--; } // because Java convention is to start at 1
|
||||
if (!array_key_exists($column, $this->fields)) { throw new SQLException("Invalid resultset column: " . (is_int($column) ? $column + 1 : $column)); }
|
||||
if ($this->fields[$column] === null) { return null; }
|
||||
|
||||
$ts = strtotime($this->fields[$column]);
|
||||
if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE
|
||||
// otherwise it's an ugly MySQL timestamp!
|
||||
// YYYYMMDDHHMMSS
|
||||
if (preg_match('/([\d]{4})([\d]{2})([\d]{2})([\d]{2})([\d]{2})([\d]{2})/', $this->fields[$column], $matches)) {
|
||||
// YYYY MM DD HH MM SS
|
||||
// $1 $2 $3 $4 $5 $6
|
||||
$ts = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
|
||||
}
|
||||
}
|
||||
if ($ts === -1 || $ts === false) { // if it's still -1, then there's nothing to be done; use a different method.
|
||||
throw new SQLException("Unable to convert value at column " . (is_int($column) ? $column + 1 : $column) . " to timestamp: " . $this->fields[$column]);
|
||||
}
|
||||
if ($format === null) {
|
||||
return $ts;
|
||||
}
|
||||
if (strpos($format, '%') !== false) {
|
||||
return strftime($format, $ts);
|
||||
} else {
|
||||
return date($format, $ts);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
36
lib/symfony/vendor/creole/drivers/mysql/MySQLStatement.php
vendored
Executable file
36
lib/symfony/vendor/creole/drivers/mysql/MySQLStatement.php
vendored
Executable file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MySQLStatement.php,v 1.1 2004/02/19 02:49:42 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/Statement.php';
|
||||
require_once 'creole/common/StatementCommon.php';
|
||||
|
||||
/**
|
||||
* MySQL Statement
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
* @author Lukas Smith
|
||||
* @version $Revision: 1.1 $
|
||||
* @package creole.drivers.mysql
|
||||
*/
|
||||
class MySQLStatement extends StatementCommon implements Statement {
|
||||
|
||||
}
|
||||
102
lib/symfony/vendor/creole/drivers/mysql/MySQLTypes.php
vendored
Executable file
102
lib/symfony/vendor/creole/drivers/mysql/MySQLTypes.php
vendored
Executable file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* $Id: MySQLTypes.php,v 1.8 2005/02/10 09:22:40 pachanga Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/CreoleTypes.php';
|
||||
|
||||
/**
|
||||
* MySQL types / type map.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.8 $
|
||||
* @package creole.drivers.mysql
|
||||
*/
|
||||
class MySQLTypes extends CreoleTypes {
|
||||
|
||||
/** Map MySQL native types to Creole (JDBC) types. */
|
||||
private static $typeMap = array(
|
||||
'tinyint' => CreoleTypes::TINYINT,
|
||||
'smallint' => CreoleTypes::SMALLINT,
|
||||
'mediumint' => CreoleTypes::SMALLINT,
|
||||
'int' => CreoleTypes::INTEGER,
|
||||
'integer' => CreoleTypes::INTEGER,
|
||||
'bigint' => CreoleTypes::BIGINT,
|
||||
'int24' => CreoleTypes::BIGINT,
|
||||
'real' => CreoleTypes::REAL,
|
||||
'float' => CreoleTypes::FLOAT,
|
||||
'decimal' => CreoleTypes::DECIMAL,
|
||||
'numeric' => CreoleTypes::NUMERIC,
|
||||
'double' => CreoleTypes::DOUBLE,
|
||||
'char' => CreoleTypes::CHAR,
|
||||
'varchar' => CreoleTypes::VARCHAR,
|
||||
'date' => CreoleTypes::DATE,
|
||||
'time' => CreoleTypes::TIME,
|
||||
'year' => CreoleTypes::YEAR,
|
||||
'datetime' => CreoleTypes::TIMESTAMP,
|
||||
'timestamp' => CreoleTypes::TIMESTAMP,
|
||||
'tinyblob' => CreoleTypes::BINARY,
|
||||
'blob' => CreoleTypes::VARBINARY,
|
||||
'mediumblob' => CreoleTypes::VARBINARY,
|
||||
'longblob' => CreoleTypes::VARBINARY,
|
||||
'longtext' => CreoleTypes::LONGVARCHAR,
|
||||
'tinytext' => CreoleTypes::VARCHAR,
|
||||
'mediumtext' => CreoleTypes::LONGVARCHAR,
|
||||
'text' => CreoleTypes::LONGVARCHAR,
|
||||
'enum' => CreoleTypes::CHAR,
|
||||
'set' => CreoleTypes::CHAR,
|
||||
);
|
||||
|
||||
/** Reverse mapping, created on demand. */
|
||||
private static $reverseMap = null;
|
||||
|
||||
/**
|
||||
* This method returns the generic Creole (JDBC-like) type
|
||||
* when given the native db type.
|
||||
* @param string $nativeType DB native type (e.g. 'TEXT', 'byetea', etc.).
|
||||
* @return int Creole native type (e.g. CreoleTypes::LONGVARCHAR, CreoleTypes::BINARY, etc.).
|
||||
*/
|
||||
public static function getType($nativeType)
|
||||
{
|
||||
$t = strtolower($nativeType);
|
||||
if (isset(self::$typeMap[$t])) {
|
||||
return self::$typeMap[$t];
|
||||
} else {
|
||||
return CreoleTypes::OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return a native type that corresponds to the specified
|
||||
* Creole (JDBC-like) type.
|
||||
* If there is more than one matching native type, then the LAST defined
|
||||
* native type will be returned.
|
||||
* @param int $creoleType
|
||||
* @return string Native type string.
|
||||
*/
|
||||
public static function getNativeType($creoleType)
|
||||
{
|
||||
if (self::$reverseMap === null) {
|
||||
self::$reverseMap = array_flip(self::$typeMap);
|
||||
}
|
||||
return @self::$reverseMap[$creoleType];
|
||||
}
|
||||
|
||||
}
|
||||
66
lib/symfony/vendor/creole/drivers/mysql/metadata/MySQLDatabaseInfo.php
vendored
Executable file
66
lib/symfony/vendor/creole/drivers/mysql/metadata/MySQLDatabaseInfo.php
vendored
Executable file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MySQLDatabaseInfo.php,v 1.13 2006/01/17 19:44:39 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/metadata/DatabaseInfo.php';
|
||||
|
||||
/**
|
||||
* MySQL implementation of DatabaseInfo.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.13 $
|
||||
* @package creole.drivers.mysql.metadata
|
||||
*/
|
||||
class MySQLDatabaseInfo extends DatabaseInfo {
|
||||
|
||||
/**
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function initTables()
|
||||
{
|
||||
include_once 'creole/drivers/mysql/metadata/MySQLTableInfo.php';
|
||||
// using $this->dblink was causing tests to break
|
||||
// perhaps dblink is changed by another test ... ?
|
||||
$result = @mysql_query("SHOW TABLES FROM `" . $this->dbname . "`", $this->conn->getResource());
|
||||
|
||||
if (!$result) {
|
||||
throw new SQLException("Could not list tables", mysql_error($this->conn->getResource()));
|
||||
}
|
||||
|
||||
while ($row = mysql_fetch_row($result)) {
|
||||
$this->tables[strtoupper($row[0])] = new MySQLTableInfo($this, $row[0]);
|
||||
}
|
||||
|
||||
$this->tablesLoaded = true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* MySQL does not support sequences.
|
||||
*
|
||||
* @return void
|
||||
* @throws SQLException
|
||||
*/
|
||||
protected function initSequences()
|
||||
{
|
||||
// throw new SQLException("MySQL does not support sequences natively.");
|
||||
}
|
||||
}
|
||||
252
lib/symfony/vendor/creole/drivers/mysql/metadata/MySQLTableInfo.php
vendored
Executable file
252
lib/symfony/vendor/creole/drivers/mysql/metadata/MySQLTableInfo.php
vendored
Executable file
@ -0,0 +1,252 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MySQLTableInfo.php,v 1.20 2006/01/17 19:44:39 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/metadata/TableInfo.php';
|
||||
|
||||
/**
|
||||
* MySQL implementation of TableInfo.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.20 $
|
||||
* @package creole.drivers.mysql.metadata
|
||||
*/
|
||||
class MySQLTableInfo extends TableInfo {
|
||||
|
||||
/** Loads the columns for this table. */
|
||||
protected function initColumns()
|
||||
{
|
||||
include_once 'creole/metadata/ColumnInfo.php';
|
||||
include_once 'creole/drivers/mysql/MySQLTypes.php';
|
||||
|
||||
if (!@mysql_select_db($this->dbname, $this->conn->getResource())) {
|
||||
throw new SQLException('No database selected');
|
||||
}
|
||||
|
||||
// To get all of the attributes we need, we use
|
||||
// the MySQL "SHOW COLUMNS FROM $tablename" SQL. We cannot
|
||||
// use the API functions (e.g. mysql_list_fields() because they
|
||||
// do not return complete information -- e.g. precision / scale, default
|
||||
// values).
|
||||
|
||||
$res = mysql_query("SHOW COLUMNS FROM `" . $this->name . "`", $this->conn->getResource());
|
||||
|
||||
$defaults = array();
|
||||
$nativeTypes = array();
|
||||
$precisions = array();
|
||||
|
||||
while($row = mysql_fetch_assoc($res)) {
|
||||
$name = $row['Field'];
|
||||
$is_nullable = ($row['Null'] == 'YES');
|
||||
$is_auto_increment = (strpos($row['Extra'], 'auto_increment') !== false);
|
||||
$size = null;
|
||||
$precision = null;
|
||||
$scale = null;
|
||||
|
||||
if (preg_match('/^(\w+)[\(]?([\d,]*)[\)]?( |$)/', $row['Type'], $matches)) {
|
||||
// colname[1] size/precision[2]
|
||||
$nativeType = $matches[1];
|
||||
if ($matches[2]) {
|
||||
if ( ($cpos = strpos($matches[2], ',')) !== false) {
|
||||
$size = (int) substr($matches[2], 0, $cpos);
|
||||
$precision = $size;
|
||||
$scale = (int) substr($matches[2], $cpos + 1);
|
||||
} else {
|
||||
$size = (int) $matches[2];
|
||||
}
|
||||
}
|
||||
} elseif (preg_match('/^(\w+)\(/', $row['Type'], $matches)) {
|
||||
$nativeType = $matches[1];
|
||||
} else {
|
||||
$nativeType = $row['Type'];
|
||||
}
|
||||
//BLOBs can't have any default values in MySQL
|
||||
$default = preg_match('~blob|text~', $nativeType) ? null : $row['Default'];
|
||||
$this->columns[$name] = new ColumnInfo($this,
|
||||
$name,
|
||||
MySQLTypes::getType($nativeType),
|
||||
$nativeType,
|
||||
$size,
|
||||
$precision,
|
||||
$scale,
|
||||
$is_nullable,
|
||||
$default,
|
||||
$is_auto_increment,
|
||||
$row);
|
||||
}
|
||||
|
||||
$this->colsLoaded = true;
|
||||
}
|
||||
|
||||
/** Loads the primary key information for this table. */
|
||||
protected function initPrimaryKey()
|
||||
{
|
||||
include_once 'creole/metadata/PrimaryKeyInfo.php';
|
||||
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
|
||||
if (!@mysql_select_db($this->dbname, $this->conn->getResource())) {
|
||||
throw new SQLException('No database selected');
|
||||
}
|
||||
|
||||
// Primary Keys
|
||||
$res = mysql_query("SHOW KEYS FROM `" . $this->name . "`", $this->conn->getResource());
|
||||
|
||||
// Loop through the returned results, grouping the same key_name together
|
||||
// adding each column for that key.
|
||||
|
||||
while($row = mysql_fetch_assoc($res)) {
|
||||
// Skip any non-primary keys.
|
||||
if ($row['Key_name'] !== 'PRIMARY') {
|
||||
continue;
|
||||
}
|
||||
$name = $row["Column_name"];
|
||||
if (!isset($this->primaryKey)) {
|
||||
$this->primaryKey = new PrimaryKeyInfo($name, $row);
|
||||
}
|
||||
$this->primaryKey->addColumn($this->columns[$name]);
|
||||
}
|
||||
|
||||
$this->pkLoaded = true;
|
||||
}
|
||||
|
||||
/** Loads the indexes for this table. */
|
||||
protected function initIndexes() {
|
||||
|
||||
include_once 'creole/metadata/IndexInfo.php';
|
||||
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
|
||||
if (!@mysql_select_db($this->dbname, $this->conn->getResource())) {
|
||||
throw new SQLException('No database selected');
|
||||
}
|
||||
|
||||
// Indexes
|
||||
$res = mysql_query("SHOW INDEX FROM `" . $this->name . "`", $this->conn->getResource());
|
||||
|
||||
// Loop through the returned results, grouping the same key_name together
|
||||
// adding each column for that key.
|
||||
|
||||
while($row = mysql_fetch_assoc($res)) {
|
||||
$colName = $row["Column_name"];
|
||||
$name = $row["Key_name"];
|
||||
|
||||
if($name == "PRIMARY") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($this->indexes[$name])) {
|
||||
$isUnique = ($row["Non_unique"] == 0);
|
||||
$this->indexes[$name] = new IndexInfo($name, $isUnique, $row);
|
||||
}
|
||||
$this->indexes[$name]->addColumn($this->columns[$colName]);
|
||||
}
|
||||
|
||||
$this->indexesLoaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load foreign keys for supporting versions of MySQL.
|
||||
* @author Tony Bibbs
|
||||
*/
|
||||
protected function initForeignKeys() {
|
||||
|
||||
// First make sure we have supported version of MySQL:
|
||||
$res = mysql_query("SELECT VERSION()");
|
||||
$row = mysql_fetch_row($res);
|
||||
|
||||
// Yes, it is OK to hardcode this...this was the first version of MySQL
|
||||
// that supported foreign keys
|
||||
if ($row[0] < '3.23.44') {
|
||||
$this->fksLoaded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
include_once 'creole/metadata/ForeignKeyInfo.php';
|
||||
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
if (!@mysql_select_db($this->dbname, $this->conn->getResource())) {
|
||||
throw new SQLException('No database selected');
|
||||
}
|
||||
// Get the CREATE TABLE syntax
|
||||
$res = mysql_query("SHOW CREATE TABLE `" . $this->name . "`", $this->conn->getResource());
|
||||
$row = mysql_fetch_row($res);
|
||||
|
||||
// Get the information on all the foreign keys
|
||||
$regEx = '/FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)(.*)/';
|
||||
if (preg_match_all($regEx,$row[1],$matches)) {
|
||||
$tmpArray = array_keys($matches[0]);
|
||||
foreach ($tmpArray as $curKey) {
|
||||
$name = $matches[1][$curKey];
|
||||
$ftbl = $matches[2][$curKey];
|
||||
$fcol = $matches[3][$curKey];
|
||||
$fkey = $matches[4][$curKey];
|
||||
if (!isset($this->foreignKeys[$name])) {
|
||||
$this->foreignKeys[$name] = new ForeignKeyInfo($name);
|
||||
if ($this->database->hasTable($ftbl)) {
|
||||
$foreignTable = $this->database->getTable($ftbl);
|
||||
} else {
|
||||
$foreignTable = new MySQLTableInfo($this->database, $ftbl);
|
||||
$this->database->addTable($foreignTable);
|
||||
}
|
||||
if ($foreignTable->hasColumn($fcol)) {
|
||||
$foreignCol = $foreignTable->getColumn($fcol);
|
||||
} else {
|
||||
$foreignCol = new ColumnInfo($foreignTable, $fcol);
|
||||
$foreignTable->addColumn($foreignCol);
|
||||
}
|
||||
|
||||
//typical for mysql is RESTRICT
|
||||
$fkactions = array(
|
||||
'ON DELETE' => ForeignKeyInfo::RESTRICT,
|
||||
'ON UPDATE' => ForeignKeyInfo::RESTRICT,
|
||||
);
|
||||
|
||||
if ($fkey) {
|
||||
//split foreign key information -> search for ON DELETE and afterwords for ON UPDATE action
|
||||
foreach (array_keys($fkactions) as $fkaction) {
|
||||
$result = NULL;
|
||||
preg_match('/' . $fkaction . ' (' . ForeignKeyInfo::CASCADE . '|' . ForeignKeyInfo::SETNULL . ')/', $fkey, $result);
|
||||
if ($result && is_array($result) && isset($result[1])) {
|
||||
$fkactions[$fkaction] = $result[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->foreignKeys[$name]->addReference($this->columns[$name], $foreignCol, $fkactions['ON DELETE'], $fkactions['ON UPDATE']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->fksLoaded = true;
|
||||
|
||||
}
|
||||
|
||||
protected function initVendorSpecificInfo()
|
||||
{
|
||||
$res = mysql_query("SHOW TABLE STATUS LIKE '" . $this->name . "'", $this->conn->getResource());
|
||||
$this->vendorSpecificInfo = mysql_fetch_assoc($res);
|
||||
|
||||
$this->vendorLoaded = true;
|
||||
}
|
||||
|
||||
}
|
||||
293
lib/symfony/vendor/creole/drivers/mysqli/MySQLiConnection.php
vendored
Executable file
293
lib/symfony/vendor/creole/drivers/mysqli/MySQLiConnection.php
vendored
Executable file
@ -0,0 +1,293 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MySQLiConnection.php,v 1.7 2004/09/18 09:29:22 sb Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/Connection.php';
|
||||
require_once 'creole/common/ConnectionCommon.php';
|
||||
include_once 'creole/drivers/mysqli/MySQLiResultSet.php';
|
||||
|
||||
/**
|
||||
* MySQLi implementation of Connection.
|
||||
*
|
||||
*
|
||||
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
|
||||
* @version $Revision: 1.7 $
|
||||
* @package creole.drivers.mysqli
|
||||
*/
|
||||
class MySQLiConnection extends ConnectionCommon implements Connection {
|
||||
/** Current database (used in mysqli_select_db()). */
|
||||
private $database;
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param $dsn the data source name (see DB::parseDSN for syntax)
|
||||
* @param $flags Any conneciton flags.
|
||||
* @access public
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
public function connect($dsninfo, $flags = 0)
|
||||
{
|
||||
if (!extension_loaded('mysqli')) {
|
||||
throw new SQLException('mysqli extension not loaded');
|
||||
}
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$this->flags = $flags;
|
||||
|
||||
$dbhost = null;
|
||||
|
||||
|
||||
if (isset($dsninfo['protocol']) && $dsninfo['protocol'] == 'unix') {
|
||||
$dbhost = ':' . $dsninfo['socket'];
|
||||
} else {
|
||||
$dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
|
||||
|
||||
if (!empty($dsninfo['port'])) {
|
||||
$dbhost .= ':' . $dsninfo['port'];
|
||||
}
|
||||
}
|
||||
|
||||
$host = !empty($dsninfo['hostspec']) ? $dsninfo['hostspec'] : null;
|
||||
$user = !empty($dsninfo['username']) ? $dsninfo['username'] : null;
|
||||
$pw = !empty($dsninfo['password']) ? $dsninfo['password'] : null;
|
||||
$port = !empty($dsninfo['port']) ? $dsninfo['port'] : null;
|
||||
$socket = !empty($dsninfo['socket']) ? $dsninfo['socket'] : null;
|
||||
$database = !empty($dsninfo['database']) ? $dsninfo['database'] : null;
|
||||
|
||||
$encoding = !empty($dsninfo['encoding']) ? $dsninfo['encoding'] : null;
|
||||
|
||||
@ini_set('track_errors', true);
|
||||
|
||||
$conn = mysqli_connect($host, $user, $pw, $database, $port, $socket);
|
||||
|
||||
@ini_restore('track_errors');
|
||||
|
||||
if (empty($conn)) {
|
||||
if (($err = @mysqli_error()) != '') {
|
||||
throw new SQLException("connect failed", $err);
|
||||
} elseif (empty($php_errormsg)) {
|
||||
throw new SQLException("connect failed");
|
||||
} else {
|
||||
throw new SQLException("connect failed", $php_errormsg);
|
||||
}
|
||||
}
|
||||
|
||||
if ($dsninfo['database']) {
|
||||
if (!@mysqli_select_db($conn, $dsninfo['database'])) {
|
||||
switch(mysqli_errno($conn)) {
|
||||
case 1049:
|
||||
$exc = new SQLException("no such database", mysqli_error($conn));
|
||||
break;
|
||||
case 1044:
|
||||
$exc = new SQLException("access violation", mysqli_error($conn));
|
||||
break;
|
||||
default:
|
||||
$exc = new SQLException("cannot select database", mysqli_error($conn));
|
||||
}
|
||||
|
||||
throw $exc;
|
||||
|
||||
}
|
||||
|
||||
// fix to allow calls to different databases in the same script
|
||||
$this->database = $dsninfo['database'];
|
||||
}
|
||||
|
||||
$this->dblink = $conn;
|
||||
|
||||
if ($encoding) {
|
||||
$this->executeUpdate("SET NAMES " . $encoding);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getDatabaseInfo()
|
||||
*/
|
||||
public function getDatabaseInfo()
|
||||
{
|
||||
require_once 'creole/drivers/mysqli/metadata/MySQLiDatabaseInfo.php';
|
||||
return new MySQLiDatabaseInfo($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getIdGenerator()
|
||||
*/
|
||||
public function getIdGenerator()
|
||||
{
|
||||
require_once 'creole/drivers/mysqli/MySQLiIdGenerator.php';
|
||||
return new MySQLiIdGenerator($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareStatement()
|
||||
*/
|
||||
public function prepareStatement($sql)
|
||||
{
|
||||
require_once 'creole/drivers/mysqli/MySQLiPreparedStatement.php';
|
||||
return new MySQLiPreparedStatement($this, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareCall()
|
||||
*/
|
||||
public function prepareCall($sql) {
|
||||
throw new SQLException('MySQL does not support stored procedures.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::createStatement()
|
||||
*/
|
||||
public function createStatement()
|
||||
{
|
||||
require_once 'creole/drivers/mysqli/MySQLiStatement.php';
|
||||
return new MySQLiStatement($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::disconnect()
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$ret = mysqli_close($this->dblink);
|
||||
$this->dblink = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::applyLimit()
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
if ( $limit > 0 ) {
|
||||
$sql .= " LIMIT " . ($offset > 0 ? $offset . ", " : "") . $limit;
|
||||
} else if ( $offset > 0 ) {
|
||||
$sql .= " LIMIT " . $offset . ", 18446744073709551615";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::executeQuery()
|
||||
*/
|
||||
public function executeQuery($sql, $fetchmode = null)
|
||||
{
|
||||
$this->lastQuery = $sql;
|
||||
|
||||
if ($this->database) {
|
||||
if (!@mysqli_select_db($this->dblink, $this->database)) {
|
||||
throw new SQLException('No database selected', mysqli_error($this->dblink));
|
||||
}
|
||||
}
|
||||
|
||||
$result = @mysqli_query($this->dblink, $sql);
|
||||
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not execute query', mysqli_error($this->dblink), $sql);
|
||||
}
|
||||
|
||||
return new MySQLiResultSet($this, $result, $fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::executeUpdate()
|
||||
*/
|
||||
public function executeUpdate($sql)
|
||||
{
|
||||
$this->lastQuery = $sql;
|
||||
|
||||
if ($this->database) {
|
||||
if (!@mysqli_select_db($this->dblink, $this->database)) {
|
||||
throw new SQLException('No database selected', mysqli_error($this->dblink));
|
||||
}
|
||||
}
|
||||
|
||||
$result = @mysqli_query($this->dblink, $sql);
|
||||
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not execute update', mysqli_error($this->dblink), $sql);
|
||||
}
|
||||
|
||||
return (int) mysqli_affected_rows($this->dblink);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a database transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function beginTrans()
|
||||
{
|
||||
if (!mysqli_autocommit($this->dblink, FALSE)) {
|
||||
throw new SQLException('Could not begin transaction', mysqli_error($this->dblink));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function commitTrans()
|
||||
{
|
||||
if ($this->database) {
|
||||
if (!@mysqli_select_db($this->dblink, $this->database)) {
|
||||
throw new SQLException('No database selected', mysqli_error($this->dblink));
|
||||
}
|
||||
}
|
||||
|
||||
if (!mysqli_commit($this->dblink)) {
|
||||
throw new SQLException('Can not commit transaction', mysqli_error($this->dblink));
|
||||
}
|
||||
|
||||
mysqli_autocommit($this->dblink, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll back (undo) the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function rollbackTrans()
|
||||
{
|
||||
if ($this->database) {
|
||||
if (!@mysqli_select_db($this->dblink, $this->database)) {
|
||||
throw new SQLException('No database selected', mysqli_error($this->dblink));
|
||||
}
|
||||
}
|
||||
|
||||
if (!mysqli_rollback($this->dblink)) {
|
||||
throw new SQLException('Could not rollback transaction', mysqli_error($this->dblink));
|
||||
}
|
||||
|
||||
mysqli_autocommit($this->dblink, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the data manipulation
|
||||
* query.
|
||||
*
|
||||
* @return int Number of rows affected by the last query.
|
||||
*/
|
||||
public function getUpdateCount()
|
||||
{
|
||||
return (int) @mysqli_affected_rows($this->dblink);
|
||||
}
|
||||
}
|
||||
96
lib/symfony/vendor/creole/drivers/mysqli/MySQLiIdGenerator.php
vendored
Executable file
96
lib/symfony/vendor/creole/drivers/mysqli/MySQLiIdGenerator.php
vendored
Executable file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MySQLiIdGenerator.php,v 1.4 2004/09/18 09:15:49 sb Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/IdGenerator.php';
|
||||
|
||||
/**
|
||||
* MySQLi implementation of IdGenerator.
|
||||
*
|
||||
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
|
||||
* @version $Revision: 1.4 $
|
||||
* @package creole.drivers.mysqli
|
||||
*/
|
||||
class MySQLiIdGenerator implements IdGenerator {
|
||||
/** Connection object that instantiated this class */
|
||||
private $conn;
|
||||
|
||||
/**
|
||||
* Creates a new IdGenerator class, saves passed connection for use
|
||||
* later by getId() method.
|
||||
* @param Connection $conn
|
||||
*/
|
||||
public function __construct(Connection $conn)
|
||||
{
|
||||
$this->conn = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::isBeforeInsert()
|
||||
*/
|
||||
public function isBeforeInsert()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::isAfterInsert()
|
||||
*/
|
||||
public function isAfterInsert()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::getIdMethod()
|
||||
*/
|
||||
public function getIdMethod()
|
||||
{
|
||||
return self::AUTOINCREMENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last-generated auto-increment ID.
|
||||
*
|
||||
* Note that for very large values (2,147,483,648 to 9,223,372,036,854,775,807) a string
|
||||
* will be returned, because these numbers are larger than supported by PHP's native
|
||||
* numeric datatypes.
|
||||
*
|
||||
* @see IdGenerator::getId()
|
||||
*/
|
||||
public function getId($unused = null)
|
||||
{
|
||||
$resource = $this->conn->getResource();
|
||||
$insert_id = mysqli_insert_id($resource);
|
||||
|
||||
if ( $insert_id < 0 ) {
|
||||
$insert_id = null;
|
||||
|
||||
$result = mysqli_query($resource, 'SELECT LAST_INSERT_ID()');
|
||||
|
||||
if ( $result ) {
|
||||
$row = mysqli_fetch_row($result);
|
||||
$insert_id = $row ? $row[0] : null;
|
||||
}
|
||||
}
|
||||
|
||||
return $insert_id;
|
||||
}
|
||||
}
|
||||
42
lib/symfony/vendor/creole/drivers/mysqli/MySQLiPreparedStatement.php
vendored
Executable file
42
lib/symfony/vendor/creole/drivers/mysqli/MySQLiPreparedStatement.php
vendored
Executable file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MySQLiPreparedStatement.php,v 1.3 2004/09/18 09:15:49 sb Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/PreparedStatement.php';
|
||||
require_once 'creole/common/PreparedStatementCommon.php';
|
||||
|
||||
/**
|
||||
* MySQLi implementation of PreparedStatement.
|
||||
*
|
||||
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
|
||||
* @version $Revision: 1.3 $
|
||||
* @package creole.drivers.mysqli
|
||||
*/
|
||||
class MySQLiPreparedStatement extends PreparedStatementCommon implements PreparedStatement {
|
||||
/**
|
||||
* Quotes string using native MySQL function.
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
protected function escape($str)
|
||||
{
|
||||
return mysqli_real_escape_string($this->getConnection()->getResource(), $str);
|
||||
}
|
||||
}
|
||||
173
lib/symfony/vendor/creole/drivers/mysqli/MySQLiResultSet.php
vendored
Executable file
173
lib/symfony/vendor/creole/drivers/mysqli/MySQLiResultSet.php
vendored
Executable file
@ -0,0 +1,173 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MySQLiResultSet.php,v 1.5 2006/01/17 19:44:39 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/ResultSet.php';
|
||||
require_once 'creole/common/ResultSetCommon.php';
|
||||
|
||||
/**
|
||||
* MySQLi implementation of ResultSet.
|
||||
*
|
||||
* MySQL supports OFFSET / LIMIT natively; this means that no adjustments or checking
|
||||
* are performed. We will assume that if the lmitSQL() operation failed that an
|
||||
* exception was thrown, and that OFFSET/LIMIT will never be emulated for MySQL.
|
||||
*
|
||||
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
|
||||
* @version $Revision: 1.5 $
|
||||
* @package creole.drivers.mysqli
|
||||
*/
|
||||
class MySQLiResultSet extends ResultSetCommon implements ResultSet {
|
||||
/**
|
||||
* @see ResultSet::seek()
|
||||
*/
|
||||
public function seek($rownum)
|
||||
{
|
||||
// MySQL rows start w/ 0, but this works, because we are
|
||||
// looking to move the position _before_ the next desired position
|
||||
if (!@mysqli_data_seek($this->result, $rownum)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->cursorPos = $rownum;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::next()
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->fields = mysqli_fetch_array($this->result, $this->fetchmode);
|
||||
$resource = $this->conn->getResource();
|
||||
|
||||
if (!$this->fields) {
|
||||
$errno = mysqli_errno($resource);
|
||||
|
||||
if (!$errno) {
|
||||
// We've advanced beyond end of recordset.
|
||||
$this->afterLast();
|
||||
return false;
|
||||
} else {
|
||||
throw new SQLException("Error fetching result", mysqli_error($resource));
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->fetchmode === ResultSet::FETCHMODE_ASSOC && $this->lowerAssocCase) {
|
||||
$this->fields = array_change_key_case($this->fields, CASE_LOWER);
|
||||
}
|
||||
|
||||
// Advance cursor position
|
||||
$this->cursorPos++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getRecordCount()
|
||||
*/
|
||||
public function getRecordCount()
|
||||
{
|
||||
$rows = @mysqli_num_rows($this->result);
|
||||
|
||||
if ($rows === null) {
|
||||
throw new SQLException("Error fetching num rows", mysqli_error($this->conn->getResource()));
|
||||
}
|
||||
|
||||
return (int) $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::close()
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
@mysqli_free_result($this->result);
|
||||
$this->fields = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string version of column.
|
||||
* No rtrim() necessary for MySQL, as this happens natively.
|
||||
* @see ResultSet::getString()
|
||||
*/
|
||||
public function getString($column)
|
||||
{
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
|
||||
if (!array_key_exists($idx, $this->fields)) {
|
||||
throw new SQLException("Invalid resultset column: " . $column);
|
||||
}
|
||||
|
||||
if ($this->fields[$idx] === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (string) $this->fields[$idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unix epoch timestamp based on either a TIMESTAMP or DATETIME field.
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1.
|
||||
* @return string
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getTimestamp($column, $format='Y-m-d H:i:s')
|
||||
{
|
||||
if (is_int($column)) {
|
||||
// because Java convention is to start at 1
|
||||
$column--;
|
||||
}
|
||||
|
||||
if (!array_key_exists($column, $this->fields)) {
|
||||
throw new SQLException("Invalid resultset column: " . (is_int($column) ? $column + 1 : $column));
|
||||
}
|
||||
|
||||
if ($this->fields[$column] === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$ts = strtotime($this->fields[$column]);
|
||||
|
||||
if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE
|
||||
// otherwise it's an ugly MySQL timestamp!
|
||||
// YYYYMMDDHHMMSS
|
||||
if (preg_match('/([\d]{4})([\d]{2})([\d]{2})([\d]{2})([\d]{2})([\d]{2})/', $this->fields[$column], $matches)) {
|
||||
// YYYY MM DD HH MM SS
|
||||
// $1 $2 $3 $4 $5 $6
|
||||
$ts = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE
|
||||
// if it's still -1, then there's nothing to be done; use a different method.
|
||||
throw new SQLException("Unable to convert value at column " . (is_int($column) ? $column + 1 : $column) . " to timestamp: " . $this->fields[$column]);
|
||||
}
|
||||
|
||||
if ($format === null) {
|
||||
return $ts;
|
||||
}
|
||||
|
||||
if (strpos($format, '%') !== false) {
|
||||
return strftime($format, $ts);
|
||||
} else {
|
||||
return date($format, $ts);
|
||||
}
|
||||
}
|
||||
}
|
||||
33
lib/symfony/vendor/creole/drivers/mysqli/MySQLiStatement.php
vendored
Executable file
33
lib/symfony/vendor/creole/drivers/mysqli/MySQLiStatement.php
vendored
Executable file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MySQLiStatement.php,v 1.2 2004/09/18 09:15:49 sb Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/Statement.php';
|
||||
require_once 'creole/common/StatementCommon.php';
|
||||
|
||||
/**
|
||||
* MySQLi implementation of Statement.
|
||||
*
|
||||
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
|
||||
* @version $Revision: 1.2 $
|
||||
* @package creole.drivers.mysqli
|
||||
*/
|
||||
class MySQLiStatement extends StatementCommon implements Statement {
|
||||
}
|
||||
61
lib/symfony/vendor/creole/drivers/mysqli/metadata/MySQLiDatabaseInfo.php
vendored
Executable file
61
lib/symfony/vendor/creole/drivers/mysqli/metadata/MySQLiDatabaseInfo.php
vendored
Executable file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MySQLiDatabaseInfo.php,v 1.3 2006/01/17 19:44:39 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/metadata/DatabaseInfo.php';
|
||||
|
||||
/**
|
||||
* MySQLi implementation of DatabaseInfo.
|
||||
*
|
||||
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
|
||||
* @version $Revision: 1.3 $
|
||||
* @package creole.drivers.mysqli.metadata
|
||||
*/
|
||||
class MySQLiDatabaseInfo extends DatabaseInfo {
|
||||
/**
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function initTables()
|
||||
{
|
||||
include_once 'creole/drivers/mysqli/metadata/MySQLiTableInfo.php';
|
||||
|
||||
$result = @mysqli_query($this->conn->getResource(), 'SHOW TABLES FROM ' . $this->dbname);
|
||||
|
||||
if (!$result) {
|
||||
throw new SQLException("Could not list tables", mysqli_error($this->conn->getResource()));
|
||||
}
|
||||
|
||||
while ($row = mysqli_fetch_row($result)) {
|
||||
$this->tables[strtoupper($row[0])] = new MySQLiTableInfo($this, $row[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MySQL does not support sequences.
|
||||
*
|
||||
* @return void
|
||||
* @throws SQLException
|
||||
*/
|
||||
protected function initSequences()
|
||||
{
|
||||
// throw new SQLException("MySQL does not support sequences natively.");
|
||||
}
|
||||
}
|
||||
155
lib/symfony/vendor/creole/drivers/mysqli/metadata/MySQLiTableInfo.php
vendored
Executable file
155
lib/symfony/vendor/creole/drivers/mysqli/metadata/MySQLiTableInfo.php
vendored
Executable file
@ -0,0 +1,155 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MySQLiTableInfo.php,v 1.3 2006/01/17 19:44:39 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/metadata/TableInfo.php';
|
||||
|
||||
/**
|
||||
* MySQLi implementation of TableInfo.
|
||||
*
|
||||
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
|
||||
* @version $Revision: 1.3 $
|
||||
* @package creole.drivers.mysqli.metadata
|
||||
*/
|
||||
class MySQLiTableInfo extends TableInfo {
|
||||
/** Loads the columns for this table. */
|
||||
protected function initColumns()
|
||||
{
|
||||
require_once 'creole/metadata/ColumnInfo.php';
|
||||
require_once 'creole/drivers/mysql/MySQLTypes.php';
|
||||
|
||||
if (!@mysqli_select_db($this->conn->getResource(), $this->dbname)) {
|
||||
throw new SQLException('No database selected');
|
||||
}
|
||||
|
||||
// To get all of the attributes we need, we use
|
||||
// the MySQL "SHOW COLUMNS FROM $tablename" SQL.
|
||||
$res = mysqli_query($this->conn->getResource(), "SHOW COLUMNS FROM " . $this->name);
|
||||
|
||||
$defaults = array();
|
||||
$nativeTypes = array();
|
||||
$precisions = array();
|
||||
|
||||
while($row = mysqli_fetch_assoc($res)) {
|
||||
$name = $row['Field'];
|
||||
$default = $row['Default'];
|
||||
$is_nullable = ($row['Null'] == 'YES');
|
||||
|
||||
$size = null;
|
||||
$precision = null;
|
||||
$scale = null;
|
||||
|
||||
if (preg_match('/^(\w+)[\(]?([\d,]*)[\)]?( |$)/', $row['Type'], $matches)) {
|
||||
// colname[1] size/precision[2]
|
||||
$nativeType = $matches[1];
|
||||
if ($matches[2]) {
|
||||
if ( ($cpos = strpos($matches[2], ',')) !== false) {
|
||||
$size = (int) substr($matches[2], 0, $cpos);
|
||||
$precision = $size;
|
||||
$scale = (int) substr($matches[2], $cpos + 1);
|
||||
} else {
|
||||
$size = (int) $matches[2];
|
||||
}
|
||||
}
|
||||
} elseif (preg_match('/^(\w+)\(/', $row['Type'], $matches)) {
|
||||
$nativeType = $matches[1];
|
||||
} else {
|
||||
$nativeType = $row['Type'];
|
||||
}
|
||||
|
||||
$this->columns[$name] = new ColumnInfo($this, $name, MySQLTypes::getType($nativeType), $nativeType, $size, $precision, $scale, $is_nullable, $default);
|
||||
}
|
||||
|
||||
$this->colsLoaded = true;
|
||||
}
|
||||
|
||||
/** Loads the primary key information for this table. */
|
||||
protected function initPrimaryKey()
|
||||
{
|
||||
require_once 'creole/metadata/PrimaryKeyInfo.php';
|
||||
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) {
|
||||
$this->initColumns();
|
||||
}
|
||||
|
||||
if (!@mysqli_select_db($this->conn->getResource(), $this->dbname)) {
|
||||
throw new SQLException('No database selected');
|
||||
}
|
||||
|
||||
// Primary Keys
|
||||
$res = mysqli_query($this->conn->getResource(), "SHOW KEYS FROM " . $this->name);
|
||||
|
||||
// Loop through the returned results, grouping the same key_name together
|
||||
// adding each column for that key.
|
||||
while($row = mysqli_fetch_assoc($res)) {
|
||||
$name = $row["Column_name"];
|
||||
if (!isset($this->primaryKey)) {
|
||||
$this->primaryKey = new PrimaryKeyInfo($name);
|
||||
}
|
||||
|
||||
$this->primaryKey->addColumn($this->columns[ $name ]);
|
||||
}
|
||||
|
||||
$this->pkLoaded = true;
|
||||
}
|
||||
|
||||
/** Loads the indexes for this table. */
|
||||
protected function initIndexes() {
|
||||
require_once 'creole/metadata/IndexInfo.php';
|
||||
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) {
|
||||
$this->initColumns();
|
||||
}
|
||||
|
||||
if (!@mysqli_select_db($this->conn->getResource(), $this->dbname)) {
|
||||
throw new SQLException('No database selected');
|
||||
}
|
||||
|
||||
// Indexes
|
||||
$res = mysqli_query($this->conn->getResource(), "SHOW INDEX FROM " . $this->name);
|
||||
|
||||
// Loop through the returned results, grouping the same key_name together
|
||||
// adding each column for that key.
|
||||
while($row = mysqli_fetch_assoc($res)) {
|
||||
$name = $row["Column_name"];
|
||||
|
||||
if (!isset($this->indexes[$name])) {
|
||||
$this->indexes[$name] = new IndexInfo($name);
|
||||
}
|
||||
|
||||
$this->indexes[$name]->addColumn($this->columns[ $name ]);
|
||||
}
|
||||
|
||||
$this->indexesLoaded = true;
|
||||
}
|
||||
|
||||
/** Load foreign keys (unsupported in MySQL). */
|
||||
protected function initForeignKeys() {
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) {
|
||||
$this->initColumns();
|
||||
}
|
||||
|
||||
// Foreign keys are not supported in mysql.
|
||||
$this->fksLoaded = true;
|
||||
}
|
||||
}
|
||||
218
lib/symfony/vendor/creole/drivers/odbc/ODBCCachedResultSet.php
vendored
Executable file
218
lib/symfony/vendor/creole/drivers/odbc/ODBCCachedResultSet.php
vendored
Executable file
@ -0,0 +1,218 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCCachedResultSet.php,v 1.2 2005/04/01 17:04:00 dlawson_mi Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/drivers/odbc/ODBCResultSetCommon.php';
|
||||
require_once 'creole/drivers/odbc/ODBCTypes.php';
|
||||
|
||||
/**
|
||||
* ODBC implementation of a cached ResultSet.
|
||||
*
|
||||
* In addition to limit/offset emulation, this class implements a resultset
|
||||
* cache. This can be useful as a workaround for some ODBC drivers which lack
|
||||
* support for reverse/absolute cursor scrolling, etc.
|
||||
*
|
||||
* This class will cache rows _on-demand_. So if you only read the first couple
|
||||
* rows of a result, then only those rows will be cached. However, note that if
|
||||
* you call getRecordCount() or last(), the class must read and cache all
|
||||
* available records.
|
||||
*
|
||||
* The offset / limit variables are also taken into account when caching. Any
|
||||
* rows preceding the offset value will be skipped. Caching will stop once the
|
||||
* limit value is reached.
|
||||
*
|
||||
* To use this class, create a derived {@link ODBCAdapter} class which returns
|
||||
* an instance of ODBCCachedResultSet from the {@link ODBCAdapter::createResultSet()} method.
|
||||
* Specify the adapter via the query portion of the Connection URL:
|
||||
*
|
||||
* odbc://localhost/Driver=MySQL ODBC 3.51 Driver;Database=test?adapter=MySQL
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.2 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCCachedResultSet extends ODBCResultSetCommon implements ResultSet
|
||||
{
|
||||
/**
|
||||
* Record cache
|
||||
* @var array
|
||||
*/
|
||||
protected $recs = array();
|
||||
|
||||
/**
|
||||
* Tracks the last cursor position of the recordset.
|
||||
* @var integer
|
||||
*/
|
||||
protected $lastPos = -1;
|
||||
|
||||
/**
|
||||
* True if blobs/clobs should also be cached.
|
||||
* @var boolean
|
||||
*/
|
||||
protected $cacheLobs = false;
|
||||
|
||||
/**
|
||||
* @see ResultSet::__construct()
|
||||
*/
|
||||
public function __construct(Connection $conn, $result, $fetchmode = null, $cacheLobs = false)
|
||||
{
|
||||
parent::__construct($conn, $result, $fetchmode);
|
||||
|
||||
$this->cacheLobs = $cacheLobs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ODBCResultSetCommon::close()
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
parent::close();
|
||||
$this->recs = null;
|
||||
$this->lastPos = -1;
|
||||
$this->cacheLobs = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches specified records up to and including the specified 1-based
|
||||
* record position. If -1 is specified, all records will be cached.
|
||||
* @param integer Maximum record position to cache.
|
||||
* @return void
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function loadCache($recPos = -1)
|
||||
{
|
||||
$rid = $this->result->getHandle();
|
||||
|
||||
$curRecs = count($this->recs);
|
||||
$totRecs = ($curRecs ? $this->offset + $curRecs : 0);
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Is record already cached?
|
||||
if ($this->lastPos != -1 || ($recPos > -1 && $recPos <= $curRecs))
|
||||
return;
|
||||
|
||||
// Fetch row (no buffers copied yet).
|
||||
$rowNum = ++$totRecs;
|
||||
$result = @odbc_fetch_row($rid, $rowNum);
|
||||
|
||||
// All records cached?
|
||||
if ($result === false || ($this->limit > 0 && $curRecs+1 > $this->limit))
|
||||
{
|
||||
$this->lastPos = $curRecs;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore offset records.
|
||||
if ($totRecs <= $this->offset)
|
||||
continue;
|
||||
|
||||
// Load row array.
|
||||
$row = array();
|
||||
for ($i = 0, $n = @odbc_num_fields($rid); $i < $n; $i++)
|
||||
{
|
||||
$fldNum = $i+1;
|
||||
$row[$i] = odbc_result($rid, $fldNum);
|
||||
|
||||
// Cache lobs if necessary
|
||||
if ($this->cacheLobs)
|
||||
{
|
||||
ODBCTypes::loadTypeMap($this->conn);
|
||||
|
||||
$nativeType = @odbc_field_type($rid, $fldNum);
|
||||
$creoleType = ODBCTypes::getType($nativeType);
|
||||
|
||||
$isBlob = ($creoleType == CreoleTypes::BLOB ||
|
||||
$creoleType == CreoleTypes::LONGVARBINARY);
|
||||
|
||||
$isClob = ($creoleType == CreoleTypes::CLOB ||
|
||||
$creoleType == CreoleTypes::LONGVARCHAR);
|
||||
|
||||
if (($isBlob || $isClob) && $row[$i] !== null)
|
||||
{
|
||||
$binmode = ($isBlob ? ODBC_BINMODE_RETURN : ODBC_BINMODE_CONVERT);
|
||||
$curdata = $row[$i];
|
||||
$row[$i] = $this->readLobData($fldNum, $binmode, $curdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add record to cache.
|
||||
$this->recs[++$curRecs] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::seek()
|
||||
*/
|
||||
public function seek($rownum)
|
||||
{
|
||||
$this->loadCache($rownum);
|
||||
|
||||
if ($rownum < 0 || $rownum > count($this->recs)+1)
|
||||
return false;
|
||||
|
||||
$this->cursorPos = $rownum;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::next()
|
||||
*/
|
||||
function next()
|
||||
{
|
||||
$this->loadCache(++$this->cursorPos);
|
||||
|
||||
if ($this->isAfterLast())
|
||||
{
|
||||
$this->afterLast();
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->fields =& $this->checkFetchMode($this->recs[$this->cursorPos]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getRecordCount()
|
||||
*/
|
||||
function getRecordCount()
|
||||
{
|
||||
if ($this->lastPos == -1)
|
||||
$this->loadCache(-1);
|
||||
|
||||
return $this->lastPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::isAfterLast()
|
||||
*/
|
||||
public function isAfterLast()
|
||||
{
|
||||
// All records cached yet?
|
||||
if ($this->lastPos == -1)
|
||||
return false;
|
||||
|
||||
return ($this->cursorPos > $this->lastPos);
|
||||
}
|
||||
|
||||
}
|
||||
362
lib/symfony/vendor/creole/drivers/odbc/ODBCConnection.php
vendored
Executable file
362
lib/symfony/vendor/creole/drivers/odbc/ODBCConnection.php
vendored
Executable file
@ -0,0 +1,362 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCConnection.php,v 1.6 2006/01/17 19:44:39 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/Connection.php';
|
||||
require_once 'creole/common/ConnectionCommon.php';
|
||||
require_once 'creole/drivers/odbc/adapters/ODBCAdapter.php';
|
||||
|
||||
/**
|
||||
* ODBC implementation of Connection.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.6 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCConnection extends ConnectionCommon implements Connection {
|
||||
|
||||
/**
|
||||
* Implements driver-specific behavior
|
||||
* @var ODBCAdapter
|
||||
*/
|
||||
protected $adapter = null;
|
||||
|
||||
/**
|
||||
* Last ODBC result resource from executeQuery/executeUpdate. Used in getUpdateCount()
|
||||
* @var ODBCResultResource
|
||||
*/
|
||||
protected $odbcresult = null;
|
||||
|
||||
/**
|
||||
* @see Connection::connect()
|
||||
*/
|
||||
public function connect($dsninfo, $flags = 0)
|
||||
{
|
||||
if (!function_exists('odbc_connect'))
|
||||
throw new SQLException('odbc extension not loaded');
|
||||
|
||||
$adapterclass = isset($dsninfo['adapter']) ? $dsninfo['adapter'] : null;
|
||||
|
||||
if (!$adapterclass)
|
||||
$adapterclass = 'ODBCAdapter';
|
||||
else
|
||||
$adapterclass .= 'Adapter';
|
||||
|
||||
Creole::import('creole.drivers.odbc.adapters.' . $adapterclass);
|
||||
$this->adapter = new $adapterclass();
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$this->flags = $flags;
|
||||
|
||||
if ( !($this->flags & Creole::COMPAT_ASSOC_LOWER) && !$this->adapter->preservesColumnCase())
|
||||
{
|
||||
trigger_error('Connection created without Creole::COMPAT_ASSOC_LOWER, ' .
|
||||
'but driver does not support case preservation.',
|
||||
E_USER_WARNING);
|
||||
$this->flags != Creole::COMPAT_ASSOC_LOWER;
|
||||
}
|
||||
|
||||
$persistent = ($flags & Creole::PERSISTENT) === Creole::PERSISTENT;
|
||||
|
||||
if ($dsninfo['database'])
|
||||
$odbcdsn = $dsninfo['database'];
|
||||
elseif ($dsninfo['hostspec'])
|
||||
$odbcdsn = $dsninfo['hostspec'];
|
||||
else
|
||||
$odbcdsn = 'localhost';
|
||||
|
||||
$user = @$dsninfo['username'];
|
||||
$pw = @$dsninfo['password'];
|
||||
|
||||
$connect_function = $persistent ? 'odbc_pconnect' : 'odbc_connect';
|
||||
|
||||
$conn = @$connect_function($odbcdsn, $user, $pw, SQL_CUR_USE_IF_NEEDED);
|
||||
|
||||
if (!is_resource($conn))
|
||||
throw new SQLException('connect failed', $this->nativeError(), $odbcdsn);
|
||||
|
||||
$this->dblink = $conn;
|
||||
|
||||
/**
|
||||
* This prevents blob fields from being fetched when a row is loaded
|
||||
* from a recordset. Clob fields however are loaded with up to
|
||||
* 'odbc.defaultlrl' data. This should be the default anyway, but we'll
|
||||
* set it here just to keep things consistent.
|
||||
*/
|
||||
@odbc_binmode(0, ODBC_BINMODE_PASSTHRU);
|
||||
@odbc_longreadlen(0, ini_get('odbc.defaultlrl'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::close()
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$ret = true;
|
||||
|
||||
$this->adapter = null;
|
||||
$this->odbcresult = null;
|
||||
|
||||
if ($this->dblink !== null)
|
||||
{
|
||||
$ret = @odbc_close($this->dblink);
|
||||
$this->dblink = null;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shouldn't this be in ConnectionCommon.php?
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted ODBC error string.
|
||||
* @return string
|
||||
*/
|
||||
public function nativeError()
|
||||
{
|
||||
if ($this->dblink && is_resource($this->dblink))
|
||||
$errstr = '[' . @odbc_error($this->dblink) . '] ' . @odbc_errormsg($this->dblink);
|
||||
else
|
||||
$errstr = '[' . @odbc_error() . '] ' . @odbc_errormsg();
|
||||
|
||||
return $errstr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns driver-specific ODBCAdapter.
|
||||
* @return ODBCAdapter
|
||||
*/
|
||||
public function getAdapter()
|
||||
{
|
||||
return $this->adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getDatabaseInfo()
|
||||
*/
|
||||
public function getDatabaseInfo()
|
||||
{
|
||||
require_once 'creole/drivers/odbc/metadata/ODBCDatabaseInfo.php';
|
||||
return new ODBCDatabaseInfo($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getIdGenerator()
|
||||
*/
|
||||
public function getIdGenerator()
|
||||
{
|
||||
return $this->adapter->getIdGenerator($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the appropriate ResultSet
|
||||
* @return ResultSet
|
||||
*/
|
||||
public function createResultSet($odbcresult, $fetchmode)
|
||||
{
|
||||
return $this->adapter->createResultSet($this, $odbcresult, $fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareStatement()
|
||||
*/
|
||||
public function prepareStatement($sql)
|
||||
{
|
||||
require_once 'creole/drivers/odbc/ODBCPreparedStatement.php';
|
||||
return new ODBCPreparedStatement($this, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::createStatement()
|
||||
*/
|
||||
public function createStatement()
|
||||
{
|
||||
require_once 'creole/drivers/odbc/ODBCStatement.php';
|
||||
return new ODBCStatement($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo To be implemented
|
||||
* @see Connection::prepareCall()
|
||||
*/
|
||||
public function prepareCall($sql)
|
||||
{
|
||||
throw new SQLException('Stored procedures not currently implemented.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::applyLimit()
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
if ($this->adapter->hasLimitOffset())
|
||||
$this->adapter->applyLimit($sql, $offset, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::executeQuery()
|
||||
*/
|
||||
public function executeQuery($sql, $fetchmode = null)
|
||||
{
|
||||
if ($this->odbcresult)
|
||||
$this->odbcresult = null;
|
||||
|
||||
$r = @odbc_exec($this->dblink, $sql);
|
||||
|
||||
if ($r === false)
|
||||
throw new SQLException('Could not execute query', $this->nativeError(), $sql);
|
||||
|
||||
$this->odbcresult = new ODBCResultResource($r);
|
||||
|
||||
return $this->createResultSet($this->odbcresult, $fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::executeUpdate()
|
||||
*/
|
||||
public function executeUpdate($sql)
|
||||
{
|
||||
if ($this->odbcresult)
|
||||
$this->odbcresult = null;
|
||||
|
||||
$r = @odbc_exec($this->dblink, $sql);
|
||||
|
||||
if ($r === false)
|
||||
throw new SQLException('Could not execute update', $this->nativeError(), $sql);
|
||||
|
||||
$this->odbcresult = new ODBCResultResource($r);
|
||||
|
||||
return $this->getUpdateCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a database transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function beginTrans()
|
||||
{
|
||||
if ($this->adapter->supportsTransactions()) {
|
||||
@odbc_autocommit($this->dblink, false);
|
||||
if (odbc_error($this->dblink) == 'S1C00') {
|
||||
throw new SQLException('Could not begin transaction', $this->nativeError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function commitTrans()
|
||||
{
|
||||
if ($this->adapter->supportsTransactions()) {
|
||||
$result = @odbc_commit($this->dblink);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not commit transaction', $this->nativeError());
|
||||
}
|
||||
@odbc_autocommit($this->dblink, true);
|
||||
if (odbc_error($this->dblink) == 'S1C00') {
|
||||
throw new SQLException('Could not commit transaction (autocommit failed)', $this->nativeError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll back (undo) the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function rollbackTrans()
|
||||
{
|
||||
if ($this->adapter->supportsTransactions()) {
|
||||
$result = @odbc_rollback($this->dblink);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not rollback transaction', $this->nativeError());
|
||||
}
|
||||
@odbc_autocommit($this->dblink, true);
|
||||
if (odbc_error($this->dblink) == 'S1C00') {
|
||||
throw new SQLException('Could not rollback transaction (autocommit failed)', $this->nativeError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getUpdateCount()
|
||||
*/
|
||||
public function getUpdateCount()
|
||||
{
|
||||
if ($this->odbcresult === null)
|
||||
return 0;
|
||||
|
||||
$n = @odbc_num_rows($this->odbcresult->getHandle());
|
||||
|
||||
if ($n == -1)
|
||||
throw new SQLException('Could not retrieve update count', $this->nativeError());
|
||||
|
||||
return (int) $n;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a simple wrapper class to manage the lifetime of an ODBC result resource
|
||||
* (returned by odbc_exec(), odbc_execute(), etc.) We use a separate class because
|
||||
* the resource can be shared by both ODBCConnection and an ODBCResultSet at the
|
||||
* same time. ODBCConnection hangs on to the last result resource to be used in
|
||||
* its getUpdateCount() method. It also passes this resource to new instances of
|
||||
* ODBCResultSet. At some point the resource has to be cleaned up via
|
||||
* odbc_free_result(). Using this class as a wrapper, we can pass around multiple
|
||||
* references to the same resource. PHP's reference counting mechanism will clean
|
||||
* up the resource when its no longer used via ODBCResultResource::__destruct().
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCResultResource
|
||||
{
|
||||
/**
|
||||
* @var resource ODBC result resource returned by {@link odbc_exec()}/{@link odbc_execute()}.
|
||||
*/
|
||||
protected $handle = null;
|
||||
|
||||
public function __construct($handle)
|
||||
{
|
||||
if (is_resource($handle))
|
||||
$this->handle = $handle;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->handle !== null)
|
||||
@odbc_free_result($this->handle);
|
||||
}
|
||||
|
||||
public function getHandle()
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
}
|
||||
118
lib/symfony/vendor/creole/drivers/odbc/ODBCIdGenerator.php
vendored
Executable file
118
lib/symfony/vendor/creole/drivers/odbc/ODBCIdGenerator.php
vendored
Executable file
@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
require_once 'creole/IdGenerator.php';
|
||||
|
||||
/**
|
||||
* ODBC IdGenerator implimenation.
|
||||
*
|
||||
* NOTE: I tried keeping the SQL as basic as possible in this class.
|
||||
* If you need something more optimized, derive your own IdGenerator
|
||||
* and use {@link ODBCAdapter::getIdGenerator()} to use it.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.2 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCIdGenerator implements IdGenerator {
|
||||
|
||||
/** Connection object that instantiated this class */
|
||||
private $conn;
|
||||
|
||||
/**
|
||||
* Creates a new IdGenerator class, saves passed connection for use
|
||||
* later by getId() method.
|
||||
* @param Connection $conn
|
||||
*/
|
||||
public function __construct(Connection $conn)
|
||||
{
|
||||
$this->conn = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::isBeforeInsert()
|
||||
*/
|
||||
public function isBeforeInsert()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::isAfterInsert()
|
||||
*/
|
||||
public function isAfterInsert()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::getIdMethod()
|
||||
*/
|
||||
public function getIdMethod()
|
||||
{
|
||||
return self::SEQUENCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::getId()
|
||||
*/
|
||||
public function getId($seqname = null)
|
||||
{
|
||||
if ($seqname === null)
|
||||
throw new SQLException('You must specify the sequence name when calling getId() method.');
|
||||
|
||||
$triedcreate = false;
|
||||
|
||||
while (1)
|
||||
{
|
||||
try
|
||||
{
|
||||
$n = $this->conn->executeUpdate("UPDATE $seqname SET id = id + 1", ResultSet::FETCHMODE_NUM);
|
||||
|
||||
if ($n == 0)
|
||||
throw new SQLException('Failed to update IdGenerator id', $this->conn->nativeError());
|
||||
|
||||
$rs = $this->conn->executeQuery("SELECT id FROM $seqname", ResultSet::FETCHMODE_NUM);
|
||||
}
|
||||
catch (SQLException $e)
|
||||
{
|
||||
//$odbcerr = odbc_error($this->conn->getResource());
|
||||
|
||||
if ($triedcreate)// || ($odbcerr != 'S0000' && $odbcerr != 'S0002'))
|
||||
throw $e;
|
||||
|
||||
$this->drop($seqname, true);
|
||||
$this->create($seqname);
|
||||
$triedcreate = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$rs->first();
|
||||
|
||||
return $rs->getInt(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the sequence emulation table.
|
||||
*/
|
||||
public function create($seqname)
|
||||
{
|
||||
$this->conn->executeUpdate("CREATE TABLE $seqname ( id numeric(19,0) NOT NULL )");
|
||||
$this->conn->executeUpdate("INSERT INTO $seqname ( id ) VALUES ( 0 )");
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the sequence emulation table.
|
||||
*/
|
||||
public function drop($seqname, $ignoreerrs = false)
|
||||
{
|
||||
try {
|
||||
$this->conn->executeUpdate("DROP TABLE $seqname");
|
||||
} catch (Exception $e) {
|
||||
if (!$ignoreerrs) throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
246
lib/symfony/vendor/creole/drivers/odbc/ODBCPreparedStatement.php
vendored
Executable file
246
lib/symfony/vendor/creole/drivers/odbc/ODBCPreparedStatement.php
vendored
Executable file
@ -0,0 +1,246 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCPreparedStatement.php,v 1.4 2005/11/13 01:29:01 gamr Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/PreparedStatement.php';
|
||||
require_once 'creole/common/PreparedStatementCommon.php';
|
||||
require_once 'creole/util/Lob.php';
|
||||
|
||||
/**
|
||||
* ODBC specific PreparedStatement functions.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.4 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCPreparedStatement extends PreparedStatementCommon implements PreparedStatement
|
||||
{
|
||||
/**
|
||||
* This does nothing since ODBC natively supports prepared statements.
|
||||
* @see PreparedStatementCommon::replaceParams()
|
||||
*/
|
||||
protected function replaceParams()
|
||||
{
|
||||
if ($this->conn->getAdapter()->emulatePrepareStmt())
|
||||
return parent::replaceParams();
|
||||
else
|
||||
return $this->sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function to call native ODBC prepare/execute functions.
|
||||
*/
|
||||
protected function _execute($sql, $params, $fetchmode, $isupdate)
|
||||
{
|
||||
if ($this->resultSet)
|
||||
{
|
||||
$this->resultSet->close();
|
||||
$this->resultSet = null;
|
||||
}
|
||||
|
||||
$this->updateCount = null;
|
||||
|
||||
if ($this->conn->getAdapter()->emulatePrepareStmt())
|
||||
{
|
||||
$stmt = @odbc_exec($this->conn->getResource(), $sql);
|
||||
$ret = ($stmt !== false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Trim surrounding quotes added from default set methods.
|
||||
// Exception: for LOB-based parameters, odbc_execute() will
|
||||
// accept a filename surrounded by single-quotes.
|
||||
foreach ($this->boundInVars as $idx => $var)
|
||||
{
|
||||
if ($var instanceof Lob)
|
||||
{
|
||||
$file = ($isupdate ? $var->getInputFile() : $var->getOutputFile());
|
||||
$this->boundInVars[$idx] = "'$file'";
|
||||
}
|
||||
else if (is_string($var))
|
||||
{
|
||||
$this->boundInVars[$idx] = trim($var, "\"\'");
|
||||
}
|
||||
}
|
||||
|
||||
$stmt = @odbc_prepare($this->conn->getResource(), $sql);
|
||||
|
||||
if ($stmt === FALSE)
|
||||
throw new SQLException('Could not prepare query', $this->conn->nativeError(), $sql);
|
||||
|
||||
$ret = @odbc_execute($stmt, $this->boundInVars);
|
||||
}
|
||||
|
||||
if ($ret === FALSE)
|
||||
{
|
||||
@odbc_free_result($stmt);
|
||||
throw new SQLException('Could not execute query', $this->conn->nativeError(), $sql);
|
||||
}
|
||||
|
||||
return $this->conn->createResultSet(new ODBCResultResource($stmt), $fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::executeQuery()
|
||||
*/
|
||||
public function executeQuery()
|
||||
{
|
||||
switch (func_num_args()) {
|
||||
case 2:
|
||||
list($params, $fetchmode) = func_get_args();
|
||||
if (!is_array($params)) {
|
||||
unset($params);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
$params = null;
|
||||
list($fetchmode) = func_get_args();
|
||||
break;
|
||||
case 0:
|
||||
$params = null;
|
||||
$fetchmode = null;
|
||||
break;
|
||||
}
|
||||
|
||||
// Set any params passed directly
|
||||
if (isset($params)) {
|
||||
for($i=0,$cnt=count($params); $i < $cnt; $i++) {
|
||||
$this->set($i+1, $params[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
$sql = $this->replaceParams();
|
||||
|
||||
if ($this->conn->getAdapter()->hasLimitOffset())
|
||||
{
|
||||
if ($this->limit > 0 || $this->offset > 0)
|
||||
$this->conn->applyLimit($sql, $this->offset, $this->limit);
|
||||
}
|
||||
|
||||
$this->resultSet = $this->_execute($sql, $params, $fetchmode, false);
|
||||
|
||||
if (!$this->conn->getAdapter()->hasLimitOffset())
|
||||
{
|
||||
$this->resultSet->_setOffset($this->offset);
|
||||
$this->resultSet->_setLimit($this->limit);
|
||||
}
|
||||
|
||||
return $this->resultSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::executeUpdate()
|
||||
*/
|
||||
public function executeUpdate($params = null)
|
||||
{
|
||||
// Set any params passed directly
|
||||
if ($params) {
|
||||
for($i=0,$cnt=count($params); $i < $cnt; $i++) {
|
||||
$this->set($i+1, $params[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
$sql = $this->replaceParams();
|
||||
$this->_execute($sql, $params, 0, true);
|
||||
$this->updateCount = $this->conn->getUpdateCount();
|
||||
|
||||
return $this->updateCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatementCommon::escape()
|
||||
*/
|
||||
protected function escape($str)
|
||||
{
|
||||
if ($this->conn->getAdapter()->emulatePrepareStmt())
|
||||
return $this->conn->getAdapter()->escape($str);
|
||||
|
||||
// Nothing to do here. odbc_execute() takes care of escaping strings.
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::setNull()
|
||||
*/
|
||||
function setNull($paramIndex)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
$this->boundInVars[$paramIndex] = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::setBlob()
|
||||
*/
|
||||
function setBlob($paramIndex, $blob)
|
||||
{
|
||||
if ($this->conn->getAdapter()->emulatePrepareStmt())
|
||||
return parent::setBlob($paramIndex, $blob);
|
||||
|
||||
$this->sql_cache_valid = false;
|
||||
if ($blob === null)
|
||||
{
|
||||
$this->setNull($paramIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($blob instanceof Blob)
|
||||
{
|
||||
if ($blob->isFromFile() && !$blob->isModified())
|
||||
{
|
||||
$this->boundInVars[$paramIndex] = $blob;
|
||||
return;
|
||||
}
|
||||
|
||||
$blob = $blob->__toString();
|
||||
}
|
||||
|
||||
$this->boundInVars[$paramIndex] = "'" . $this->escape($blob) . "'";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::setClob()
|
||||
*/
|
||||
function setClob($paramIndex, $clob)
|
||||
{
|
||||
if ($this->conn->getAdapter()->emulatePrepareStmt())
|
||||
return parent::setClob($paramIndex, $clob);
|
||||
|
||||
$this->sql_cache_valid = false;
|
||||
if ($clob === null)
|
||||
{
|
||||
$this->setNull($paramIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($clob instanceof Clob)
|
||||
{
|
||||
if ($clob->isFromFile() && !$clob->isModified())
|
||||
{
|
||||
$this->boundInVars[$paramIndex] = $clob;
|
||||
return;
|
||||
}
|
||||
|
||||
$clob = $clob->__toString();
|
||||
}
|
||||
|
||||
$this->boundInVars[$paramIndex] = "'" . $this->escape($clob) . "'";
|
||||
}
|
||||
|
||||
}
|
||||
209
lib/symfony/vendor/creole/drivers/odbc/ODBCResultSet.php
vendored
Executable file
209
lib/symfony/vendor/creole/drivers/odbc/ODBCResultSet.php
vendored
Executable file
@ -0,0 +1,209 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCResultSet.php,v 1.2 2005/04/01 17:10:42 dlawson_mi Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/drivers/odbc/ODBCResultSetCommon.php';
|
||||
|
||||
/**
|
||||
* ODBC implementation of ResultSet.
|
||||
*
|
||||
* If the current ODBC driver does not support LIMIT or OFFSET natively,
|
||||
* the methods in here perform some adjustments and extra checking to make
|
||||
* sure that this behaves the same as RDBMS drivers using native OFFSET/LIMIT.
|
||||
*
|
||||
* This class also emulates a row count if the driver is not capable of
|
||||
* providing one natively.
|
||||
*
|
||||
* NOTE: This class only works with drivers that support absolute cursor
|
||||
* positioning (SQL_FETCH_DIRECTION = SQL_FD_FETCH_ABSOLUTE). If the
|
||||
* driver you are using does not support reverse/absolute cursor
|
||||
* scrolling, you should use the {@link ODBCCachedResultSet} class instead.
|
||||
* See the documentation for ODBCCachedResultSet for instructions on how
|
||||
* to use it.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.2 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCResultSet extends ODBCResultSetCommon implements ResultSet
|
||||
{
|
||||
/**
|
||||
* Number of rows in resultset.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $numRows = -1;
|
||||
|
||||
/**
|
||||
* True if ODBC driver supports odbc_num_rows().
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $hasRowCount = false;
|
||||
|
||||
/**
|
||||
* @see ResultSet::__construct()
|
||||
*/
|
||||
public function __construct(Connection $conn, $result, $fetchmode = null)
|
||||
{
|
||||
parent::__construct($conn, $result, $fetchmode);
|
||||
|
||||
/**
|
||||
* Some ODBC drivers appear not to handle odbc_num_rows() very well when
|
||||
* more than one result handle is active at once. For example, the MySQL
|
||||
* ODBC driver always returns the number of rows for the last executed
|
||||
* result. For this reason, we'll store the row count here.
|
||||
*
|
||||
* Note also that many ODBC drivers do not support this method. In this
|
||||
* case, getRecordCount() will perform a manual count.
|
||||
*/
|
||||
$this->numRows = @odbc_num_rows($result->getHandle());
|
||||
$this->hasRowCount = $this->numRows != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ODBCResultSetCommon::close()
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
parent::close();
|
||||
$numRows = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::seek()
|
||||
*/
|
||||
public function seek($rownum)
|
||||
{
|
||||
if ($rownum < 0 || $this->limit > 0 && $rownum > $this->limit)
|
||||
return false;
|
||||
|
||||
$this->cursorPos = $rownum;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::next()
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->cursorPos++;
|
||||
|
||||
if ($this->limit > 0 && $this->cursorPos > $this->limit) {
|
||||
$this->cursorPos = $this->limit+1;
|
||||
return false;
|
||||
}
|
||||
|
||||
$rowNum = $this->offset + $this->cursorPos;
|
||||
$fields = null;
|
||||
|
||||
$cols = @odbc_fetch_into($this->result->getHandle(), $fields, $rowNum);
|
||||
|
||||
if ($cols === false) {
|
||||
$this->cursorPos = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->fields =& $this->checkFetchMode($fields);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::isAfterLast()
|
||||
*/
|
||||
public function isAfterLast()
|
||||
{
|
||||
// Force calculation of last record pos.
|
||||
if ($this->cursorPos == -1)
|
||||
$this->getRecordCount();
|
||||
|
||||
return parent::isAfterLast();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getRecordCount()
|
||||
*/
|
||||
function getRecordCount()
|
||||
{
|
||||
if ($this->hasRowCount)
|
||||
{
|
||||
// Use driver row count if provided.
|
||||
$numRows = $this->numRows - $this->offset;
|
||||
|
||||
if ($this->limit > 0 && $numRows > $this->limit)
|
||||
$numRows = $this->limit;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do manual row count if driver doesn't provide one.
|
||||
if ($this->numRows == -1)
|
||||
{
|
||||
$this->numRows = 0;
|
||||
$this->beforeFirst();
|
||||
|
||||
while($this->next())
|
||||
$this->numRows++;
|
||||
}
|
||||
|
||||
$numRows = $this->numRows;
|
||||
}
|
||||
|
||||
// Cursor pos is -1 when an attempt to fetch past the last row was made
|
||||
// (or a fetch error occured).
|
||||
|
||||
if ($this->cursorPos == -1)
|
||||
$this->cursorPos = $numRows+1;
|
||||
|
||||
return $numRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getBlob()
|
||||
*/
|
||||
public function getBlob($column)
|
||||
{
|
||||
require_once 'creole/util/Blob.php';
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
$data = $this->readLobData($column, ODBC_BINMODE_RETURN, $this->fields[$idx]);
|
||||
if (!$data) { return null; }
|
||||
$b = new Blob();
|
||||
$b->setContents($data);
|
||||
return $b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getClob()
|
||||
*/
|
||||
public function getClob($column)
|
||||
{
|
||||
require_once 'creole/util/Clob.php';
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
$data = $this->readLobData($column, ODBC_BINMODE_CONVERT, $this->fields[$idx]);
|
||||
if (!$data) { return null; }
|
||||
$c = new Clob();
|
||||
$c->setContents($data);
|
||||
return $c;
|
||||
}
|
||||
|
||||
}
|
||||
188
lib/symfony/vendor/creole/drivers/odbc/ODBCResultSetCommon.php
vendored
Executable file
188
lib/symfony/vendor/creole/drivers/odbc/ODBCResultSetCommon.php
vendored
Executable file
@ -0,0 +1,188 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCResultSetCommon.php,v 1.3 2006/01/17 19:44:39 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/ResultSet.php';
|
||||
require_once 'creole/common/ResultSetCommon.php';
|
||||
|
||||
/**
|
||||
* Base class for ODBC implementation of ResultSet.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.3 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
abstract class ODBCResultSetCommon extends ResultSetCommon
|
||||
{
|
||||
/**
|
||||
* Offset at which to start reading rows (for emulated offset).
|
||||
* @var int
|
||||
*/
|
||||
protected $offset = 0;
|
||||
|
||||
/**
|
||||
* Maximum rows to retrieve, or 0 if all (for emulated limit).
|
||||
* @var int
|
||||
*/
|
||||
protected $limit = 0;
|
||||
|
||||
/**
|
||||
* @see ResultSet::__construct()
|
||||
*/
|
||||
public function __construct(Connection $conn, $result, $fetchmode = null)
|
||||
{
|
||||
parent::__construct($conn, $result, $fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::close()
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->result = null;
|
||||
$this->conn = null;
|
||||
$this->fetchmode = null;
|
||||
$this->cursorPos = 0;
|
||||
$this->fields = null;
|
||||
$this->lowerAssocCase = false;
|
||||
$this->limit = 0;
|
||||
$this->offset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function exists to set offset after ResultSet is instantiated.
|
||||
* This function should be "protected" in Java sense: only available to classes in package.
|
||||
* THIS METHOD SHOULD NOT BE CALLED BY ANYTHING EXCEPTION DRIVER CLASSES.
|
||||
* @param int $offset New offset.
|
||||
* @access protected
|
||||
*/
|
||||
public function _setOffset($offset)
|
||||
{
|
||||
$this->offset = $offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function exists to set limit after ResultSet is instantiated.
|
||||
* This function should be "protected" in Java sense: only available to classes in package.
|
||||
* THIS METHOD SHOULD NOT BE CALLED BY ANYTHING EXCEPTION DRIVER CLASSES.
|
||||
* @param int $limit New limit.
|
||||
* @access protected
|
||||
*/
|
||||
public function _setLimit($limit)
|
||||
{
|
||||
$this->limit = $limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* If fetchmode is FETCHMODE_ASSOC, returns the 1-based field index number
|
||||
* for the specified column name. Otherwise returns 0 (false).
|
||||
* @return int
|
||||
*/
|
||||
function getFieldNum($colname)
|
||||
{
|
||||
$fieldnum = 0;
|
||||
|
||||
if ($this->fetchmode == ResultSet::FETCHMODE_ASSOC)
|
||||
{
|
||||
$keys = array_keys($this->fields);
|
||||
$fieldnum = array_search($colname, $keys);
|
||||
}
|
||||
|
||||
return $fieldnum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in any unread LOB data. For long char fields, we may already
|
||||
* have up to odbc_longreadlen() bytes in the buffer. These are passed
|
||||
* in via the $curdata parm. For long binary fields, no data is read
|
||||
* initially since odbc_binmode() is set to ODBC_BINMODE_PASSTHRU.
|
||||
* This method adjusts the binmode and longreadlen to finish reading
|
||||
* these datatypes into the buffer. Returns a string with the complete
|
||||
* contents.
|
||||
*
|
||||
* @param int|string $column Column index or name to read data from.
|
||||
* @param int $binmode ODBC_BINMODE_RETURN for binary data, ODBC_BINMODE_CONVERT for char data.
|
||||
* @param string $curdata Existing LOB data already in buffer.
|
||||
* @return string
|
||||
*/
|
||||
protected function readLobData($column, $binmode, $curdata = null)
|
||||
{
|
||||
// Retrieve field num
|
||||
$fldNum = (is_int($column) ? $column : getFieldNum($column));
|
||||
|
||||
$data = $curdata;
|
||||
$newdata = null;
|
||||
|
||||
// Adjust binmode and longreadlen
|
||||
odbc_binmode($this->result->getHandle(), $binmode);
|
||||
odbc_longreadlen($this->result->getHandle(), 4096);
|
||||
|
||||
while (1)
|
||||
{
|
||||
$newdata = odbc_result($this->result->getHandle(), $fldNum);
|
||||
|
||||
if ($newdata === false)
|
||||
break;
|
||||
else
|
||||
$data .= $newdata;
|
||||
}
|
||||
|
||||
// Restore the default binmode and longreadlen
|
||||
odbc_binmode($this->result->getHandle(), ODBC_BINMODE_PASSTHRU);
|
||||
odbc_longreadlen($this->result->getHandle(), ini_get('odbc.defaultlrl'));
|
||||
|
||||
// The ODBC driver I use seems to return a string with an escaped
|
||||
// null char at the end for clob data.
|
||||
$data = rtrim($data, "\x0");
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts row fields to names if FETCHMODE_ASSOC is set.
|
||||
*
|
||||
* @param array& Row to convert.
|
||||
*
|
||||
* @return array& Converted row.
|
||||
*/
|
||||
protected function checkFetchMode(&$row)
|
||||
{
|
||||
if ($this->fetchmode == ResultSet::FETCHMODE_ASSOC)
|
||||
{
|
||||
$newrow = array();
|
||||
|
||||
for ($i = 0, $n = count($row); $i < $n; $i++)
|
||||
{
|
||||
$colname = @odbc_field_name($this->result->getHandle(), $i+1);
|
||||
|
||||
if ($this->lowerAssocCase) {
|
||||
$colname = strtolower($colname);
|
||||
}
|
||||
|
||||
$newrow[$colname] = $row[$i];
|
||||
}
|
||||
|
||||
$row =& $newrow;
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
}
|
||||
64
lib/symfony/vendor/creole/drivers/odbc/ODBCStatement.php
vendored
Executable file
64
lib/symfony/vendor/creole/drivers/odbc/ODBCStatement.php
vendored
Executable file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCStatement.php,v 1.1 2004/07/27 23:08:30 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/Statement.php';
|
||||
require_once 'creole/common/StatementCommon.php';
|
||||
|
||||
/**
|
||||
* ODBC Statement
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.1 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCStatement extends StatementCommon implements Statement
|
||||
{
|
||||
/**
|
||||
* @see Statement::executeQuery()
|
||||
*/
|
||||
public function executeQuery($sql, $fetchmode = null)
|
||||
{
|
||||
if ($this->resultSet)
|
||||
{
|
||||
$this->resultSet->close();
|
||||
$this->resultSet = null;
|
||||
}
|
||||
|
||||
$this->updateCount = null;
|
||||
|
||||
if ($this->conn->getAdapter()->hasLimitOffset())
|
||||
{
|
||||
if ($this->limit > 0 || $this->offset > 0)
|
||||
$this->conn->applyLimit($sql, $this->offset, $this->limit);
|
||||
}
|
||||
|
||||
$this->resultSet = $this->conn->executeQuery($sql, $fetchmode);
|
||||
|
||||
if (!$this->conn->getAdapter()->hasLimitOffset())
|
||||
{
|
||||
$this->resultSet->_setOffset($this->offset);
|
||||
$this->resultSet->_setLimit($this->limit);
|
||||
}
|
||||
|
||||
return $this->resultSet;
|
||||
}
|
||||
|
||||
}
|
||||
189
lib/symfony/vendor/creole/drivers/odbc/ODBCTypes.php
vendored
Executable file
189
lib/symfony/vendor/creole/drivers/odbc/ODBCTypes.php
vendored
Executable file
@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* $Id: ODBCTypes.php,v 1.1 2004/07/27 23:08:30 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/CreoleTypes.php';
|
||||
|
||||
/**
|
||||
* ODBC types / type map.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.1 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCTypes extends CreoleTypes {
|
||||
|
||||
/**
|
||||
* Map ODBC native types to Creole (JDBC) types.
|
||||
*/
|
||||
protected static $typeMap = null;
|
||||
|
||||
/**
|
||||
* Reverse mapping, created on demand.
|
||||
*/
|
||||
protected static $reverseMap = null;
|
||||
|
||||
/**
|
||||
* Loads the map of ODBC data types to Creole (JDBC) types.
|
||||
*
|
||||
* NOTE: This function cannot map DBMS-specific datatypes. If you use a
|
||||
* driver which implements DBMS-specific datatypes, you will need
|
||||
* to modify/extend this class to add the correct mapping.
|
||||
*/
|
||||
public static function loadTypeMap($conn = null)
|
||||
{
|
||||
if (self::$typeMap !== null && count(self::$typeMap) > 0)
|
||||
return;
|
||||
|
||||
if ($conn == null)
|
||||
throw new SQLException('No connection specified when loading ODBC type map.');
|
||||
|
||||
self::$typeMap = array();
|
||||
|
||||
$result = @odbc_gettypeinfo($conn->getResource());
|
||||
|
||||
if ($result === false)
|
||||
throw new SQLException('Failed to retrieve type info.', $conn->nativeError());
|
||||
|
||||
$rowNum = 1;
|
||||
|
||||
while (odbc_fetch_row($result, $rowNum++))
|
||||
{
|
||||
$odbctypeid = odbc_result($result, 'DATA_TYPE');
|
||||
$odbctypename = odbc_result($result, 'TYPE_NAME');
|
||||
|
||||
switch ($odbctypeid)
|
||||
{
|
||||
case SQL_CHAR:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::CHAR;
|
||||
break;
|
||||
case SQL_VARCHAR:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::VARCHAR;
|
||||
break;
|
||||
case SQL_LONGVARCHAR:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::LONGVARCHAR;
|
||||
break;
|
||||
case SQL_DECIMAL:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::DECIMAL;
|
||||
break;
|
||||
case SQL_NUMERIC:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::NUMERIC;
|
||||
break;
|
||||
case SQL_BIT:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::BOOLEAN;
|
||||
break;
|
||||
case SQL_TINYINT:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::TINYINT;
|
||||
break;
|
||||
case SQL_SMALLINT:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::SMALLINT;
|
||||
break;
|
||||
case SQL_INTEGER:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::INTEGER;
|
||||
break;
|
||||
case SQL_BIGINT:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::BIGINT;
|
||||
break;
|
||||
case SQL_REAL:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::REAL;
|
||||
break;
|
||||
case SQL_FLOAT:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::FLOAT;
|
||||
break;
|
||||
case SQL_DOUBLE:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::DOUBLE;
|
||||
break;
|
||||
case SQL_BINARY:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::BINARY;
|
||||
break;
|
||||
case SQL_VARBINARY:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::VARBINARY;
|
||||
break;
|
||||
case SQL_LONGVARBINARY:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::LONGVARBINARY;
|
||||
break;
|
||||
case SQL_DATE:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::DATE;
|
||||
break;
|
||||
case SQL_TIME:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::TIME;
|
||||
break;
|
||||
case SQL_TIMESTAMP:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::TIMESTAMP;
|
||||
break;
|
||||
case SQL_TYPE_DATE:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::DATE;
|
||||
break;
|
||||
case SQL_TYPE_TIME:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::TIME;
|
||||
break;
|
||||
case SQL_TYPE_TIMESTAMP:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::TIMESTAMP;
|
||||
break;
|
||||
default:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::OTHER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@odbc_free_result($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the generic Creole (JDBC-like) type
|
||||
* when given the native db type.
|
||||
* @param string $nativeType DB native type (e.g. 'TEXT', 'byetea', etc.).
|
||||
* @return int Creole native type (e.g. CreoleTypes::LONGVARCHAR, CreoleTypes::BINARY, etc.).
|
||||
*/
|
||||
public static function getType($nativeType)
|
||||
{
|
||||
if (!self::$typeMap)
|
||||
self::loadTypeMap();
|
||||
|
||||
$t = strtoupper($nativeType);
|
||||
|
||||
if (isset(self::$typeMap[$t])) {
|
||||
return self::$typeMap[$t];
|
||||
} else {
|
||||
return CreoleTypes::OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return a native type that corresponds to the specified
|
||||
* Creole (JDBC-like) type.
|
||||
* If there is more than one matching native type, then the LAST defined
|
||||
* native type will be returned.
|
||||
* @param int $creoleType
|
||||
* @return string Native type string.
|
||||
*/
|
||||
public static function getNativeType($creoleType)
|
||||
{
|
||||
if (!self::$typeMap)
|
||||
self::loadTypeMap();
|
||||
|
||||
if (self::$reverseMap === null) {
|
||||
self::$reverseMap = array_flip(self::$typeMap);
|
||||
}
|
||||
return @self::$reverseMap[$creoleType];
|
||||
}
|
||||
|
||||
}
|
||||
90
lib/symfony/vendor/creole/drivers/odbc/README
vendored
Executable file
90
lib/symfony/vendor/creole/drivers/odbc/README
vendored
Executable file
@ -0,0 +1,90 @@
|
||||
|
||||
|
||||
Creole ODBC Bridge Driver
|
||||
=========================
|
||||
|
||||
|
||||
I. Overview
|
||||
-----------
|
||||
|
||||
In the text below, the word "driver" can get somewhat muddled since there are
|
||||
two libraries concerned here (Creole & ODBC). So, we'll use the term "bridge
|
||||
driver" to refer to Creole's ODBC bridge driver, and "ODBC driver" to refer to
|
||||
an ODBC database driver.
|
||||
|
||||
The Creole ODBC Bridge driver provides a solution for databases which
|
||||
currently have no PHP-native interface. It is currently in an experimental
|
||||
stage of development. It has been tested with two ODBC drivers (Sequiter's
|
||||
CodeBase ODBC driver and the MySQL ODBC driver (as a baseline test)). To
|
||||
use any other ODBC drivers you may need to write your own ODBCAdapter-derived
|
||||
class (see below).
|
||||
|
||||
|
||||
II. ODBCAdapter
|
||||
---------------
|
||||
|
||||
Because ODBC itself is a database abstraction library, the bridge driver needed
|
||||
a way of hiding ODBC driver-specific behavior. The solution to this was to
|
||||
create an adapter layer (akin to how the Propel runtime engine works). Think of
|
||||
it as a sub-driver for the bridge driver. Any ODBC driver-specific behavior is
|
||||
handled by an ODBCAdapter-derived class. To use a specific adapter class, you
|
||||
specify its name via a parameter in the connection string:
|
||||
|
||||
odbc://localhost/DSN=CodeBase;?adapter=CodeBase
|
||||
|
||||
The string above will load the following file as the adapter to use with the
|
||||
bridge driver: creole/drivers/odbc/adapters/CodeBaseAdapter.php
|
||||
|
||||
Some ODBC drivers are limited in support for various Creole features. The
|
||||
ODBCAdapter also provides a method for emulation of some of these missing
|
||||
features:
|
||||
|
||||
-The emulatePrepareStmt() method provides a switch for enabling prepared
|
||||
statement emulation for drivers that do not support (or have trouble with)
|
||||
prepared statements. This emulation is disabled by default.
|
||||
|
||||
-The hasLimitOffset() method provides a switch for enabling LIMIT/OFFSET
|
||||
emulation for drivers that do not support this. This emulation is enabled
|
||||
by default. The LIMIT/OFFSET emulation was borrowed from the MSSQL Creole
|
||||
driver.
|
||||
|
||||
-The createResultSet() method provides a switch for enabling cached
|
||||
result sets. To enable this feature, return an instance of
|
||||
ODBCCachedResultSet in the createResultSet() method of your ODBCAdapter-
|
||||
derived class. This can be useful as a workaround for ODBC drivers which
|
||||
lack support for record count retrieval, reverse/absolute cursor
|
||||
scrolling, etc. In most cases, result rows are cached on-demand. So if
|
||||
you only read the first couple rows of a result, then only those rows will
|
||||
be cached.
|
||||
|
||||
-The getIdGenerator() method provides a switch for enabling sequence
|
||||
emulation. This feature is enabled by default in ODBCAdapter and is
|
||||
implemented in the ODBCIdGenerator class. The emulation code was inspired
|
||||
by the PEAR::DB nextID() method. If your database supports sequences or
|
||||
autoincrement natively, you can return your own IdGenerator-derived class
|
||||
instead. Check out some of the other Creole drivers for IdGenerator
|
||||
examples.
|
||||
|
||||
|
||||
III. Incomplete Features
|
||||
------------------------
|
||||
|
||||
-The database metadata classes are not fully tested/complete. Specifically,
|
||||
the ODBCDatabaseInfo class does not currently set the database name. There
|
||||
may be other problems as well.
|
||||
|
||||
-The Creole CallableStatement class (stored procedures) is not currently
|
||||
implemented. No immediate plans to do this in the future, but it looks
|
||||
feasible.
|
||||
|
||||
|
||||
IV. Known Issues
|
||||
----------------
|
||||
|
||||
This driver was developed using the PHP v5.0 final build. During the course
|
||||
of testing I uncovered several bugs in the php_odbc module. I submitted
|
||||
patches for these bugs, but have not yet received word that they were
|
||||
committed (they were just submitted this morning). If you want more details
|
||||
on the problems I encountered or would like a copy of the patches, please
|
||||
e-mail me (dlawson@masterytech.com).
|
||||
|
||||
73
lib/symfony/vendor/creole/drivers/odbc/adapters/CodeBaseAdapter.php
vendored
Executable file
73
lib/symfony/vendor/creole/drivers/odbc/adapters/CodeBaseAdapter.php
vendored
Executable file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: CodeBaseAdapter.php,v 1.3 2005/10/17 19:03:51 dlawson_mi Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/drivers/odbc/adapters/ODBCAdapter.php';
|
||||
|
||||
/**
|
||||
* CodeBase driver-specific behavior.
|
||||
*
|
||||
* This adapter is for Sequiter's CodeBaseSQL product. It is a dBase ODBC
|
||||
* driver. The driver only supports forward-only cursor scrolling so this
|
||||
* adapter causes the ODBCCachedResultSet to be used.
|
||||
*
|
||||
* A couple other quirks exist:
|
||||
*
|
||||
* 1) Cannot get blobs to work correctly. If I try writing one to a
|
||||
* LONGVARBINARY typed field, only the first few bytes are written.
|
||||
* This will cause the ResultSetTest::testGetBlob() test case to fail
|
||||
* when running tests for the driver.
|
||||
*
|
||||
* 2) For some reason the character count is off for the
|
||||
* ResultSetTest::testSetClob() test case _only_ when running from the
|
||||
* command line. If I run the same test through a web server it works fine.
|
||||
* Looks like it has something to do with line endings in Windows. The
|
||||
* difference in file sizes is 9803 vs 10090.
|
||||
*
|
||||
* 3) Setting a clob field to null writes a space to the field in the table.
|
||||
* This causes the PreparedStatementTest::testSetNull() test case to fail
|
||||
* when running tests for the driver.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.3 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class CodeBaseAdapter extends ODBCAdapter
|
||||
{
|
||||
/**
|
||||
* @see ODBCAdapter::createResultSet()
|
||||
*/
|
||||
public function preservesColumnCase()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ODBCAdapter::createResultSet()
|
||||
*/
|
||||
public function createResultSet($conn, $odbcresult, $fetchmode)
|
||||
{
|
||||
require_once 'creole/drivers/odbc/ODBCResultSet.php';
|
||||
return new ODBCResultSet($conn, $odbcresult, $fetchmode, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
78
lib/symfony/vendor/creole/drivers/odbc/adapters/MySQLAdapter.php
vendored
Executable file
78
lib/symfony/vendor/creole/drivers/odbc/adapters/MySQLAdapter.php
vendored
Executable file
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MySQLAdapter.php,v 1.1 2004/07/27 23:08:30 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/drivers/odbc/ODBCCachedResultSet.php';
|
||||
require_once 'creole/drivers/odbc/ODBCResultSet.php';
|
||||
require_once 'creole/drivers/odbc/adapters/ODBCAdapter.php';
|
||||
|
||||
/**
|
||||
* Implements MySQL driver-specific behavior.
|
||||
*
|
||||
* Obviously it would be much more efficient to simply use the Creole
|
||||
* MySQL driver. This adapter was created for the sole purpose of testing
|
||||
* the ODBC driver.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.1 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class MySQLAdapter extends ODBCAdapter
|
||||
{
|
||||
/**
|
||||
* @see ODBCAdapter::hasLimitOffset()
|
||||
*/
|
||||
public function hasLimitOffset()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ODBCAdapter::applyLimit()
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
if ( $limit > 0 ) {
|
||||
$sql .= " LIMIT " . ($offset > 0 ? $offset . ", " : "") . $limit;
|
||||
} else if ( $offset > 0 ) {
|
||||
$sql .= " LIMIT " . $offset . ", 18446744073709551615";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ODBCAdapter::escape()
|
||||
*/
|
||||
public function escape($str)
|
||||
{
|
||||
return addslashes($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ODBCAdapter::createResultSet()
|
||||
*/
|
||||
public function createResultSet($conn, $odbcresult, $fetchmode)
|
||||
{
|
||||
// return new ODBCCachedResultSet($conn, $odbcresult, $fetchmode, true);
|
||||
return new ODBCResultSet($conn, $odbcresult, $fetchmode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
115
lib/symfony/vendor/creole/drivers/odbc/adapters/ODBCAdapter.php
vendored
Executable file
115
lib/symfony/vendor/creole/drivers/odbc/adapters/ODBCAdapter.php
vendored
Executable file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCAdapter.php,v 1.3 2005/10/17 19:03:51 dlawson_mi Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default class for ODBC driver-specific behavior.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.3 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCAdapter
|
||||
{
|
||||
/**
|
||||
* Returns true if column case is preserved in the database when a table
|
||||
* is first created. Returns false if table does not preserve case (i.e.
|
||||
* ProductID => PRODUCTID).
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function preservesColumnCase()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if prepared statements should be emulated. This
|
||||
* might be useful if your driver does not support (or has trouble with)
|
||||
* prepared statements.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function emulatePrepareStmt()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if ODBC driver supports LIMIT/OFFSET via SQL.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasLimitOffset()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::applyLimit()
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatementCommon::escape()
|
||||
*/
|
||||
public function escape($str)
|
||||
{
|
||||
// use this instead of magic_quotes_sybase + addslashes(),
|
||||
// just in case multiple RDBMS being used at the same time
|
||||
return str_replace("'", "''", $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the default resultset.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function createResultSet($conn, $odbcresult, $fetchmode)
|
||||
{
|
||||
require_once 'creole/drivers/odbc/ODBCResultSet.php';
|
||||
return new ODBCResultSet($conn, $odbcresult, $fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default ODBCIdGenerator for emulating sequences.
|
||||
*
|
||||
* @return ODBCIdGenerator
|
||||
*/
|
||||
public function getIdGenerator($conn)
|
||||
{
|
||||
require_once 'creole/drivers/odbc/ODBCIdGenerator.php';
|
||||
return new ODBCIdGenerator($conn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if driver support transactions.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function supportsTransactions()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
66
lib/symfony/vendor/creole/drivers/odbc/metadata/ODBCDatabaseInfo.php
vendored
Executable file
66
lib/symfony/vendor/creole/drivers/odbc/metadata/ODBCDatabaseInfo.php
vendored
Executable file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCDatabaseInfo.php,v 1.2 2006/01/17 19:44:39 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/metadata/DatabaseInfo.php';
|
||||
|
||||
/**
|
||||
* ODBC implementation of DatabaseInfo.
|
||||
*
|
||||
* @todo Still need a way to obtain the database name. Not sure how to do this yet.
|
||||
* @todo This might need to be an {@link ODBCAdapter} method.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.2 $
|
||||
* @package creole.drivers.odbc.metadata
|
||||
*/
|
||||
class ODBCDatabaseInfo extends DatabaseInfo {
|
||||
|
||||
/**
|
||||
* @see DatabaseInfo::initTables()
|
||||
*/
|
||||
protected function initTables()
|
||||
{
|
||||
include_once 'creole/drivers/odbc/metadata/ODBCTableInfo.php';
|
||||
|
||||
$result = @odbc_tables($this->conn->getResource());
|
||||
|
||||
if (!$result)
|
||||
throw new SQLException('Could not list tables', $this->conn->nativeError());
|
||||
|
||||
while (odbc_fetch_row($result))
|
||||
{
|
||||
$tablename = strtoupper(odbc_result($result, 'TABLE_NAME'));
|
||||
$this->tables[$tablename] = new ODBCTableInfo($this, $tablename);
|
||||
}
|
||||
|
||||
@odbc_free_result($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @throws SQLException
|
||||
*/
|
||||
protected function initSequences()
|
||||
{
|
||||
// Not sure how this is used yet.
|
||||
}
|
||||
|
||||
}
|
||||
141
lib/symfony/vendor/creole/drivers/odbc/metadata/ODBCTableInfo.php
vendored
Executable file
141
lib/symfony/vendor/creole/drivers/odbc/metadata/ODBCTableInfo.php
vendored
Executable file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCTableInfo.php,v 1.2 2006/01/17 19:44:39 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/metadata/TableInfo.php';
|
||||
|
||||
/**
|
||||
* ODBC implementation of TableInfo.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.2 $
|
||||
* @package creole.drivers.odbc.metadata
|
||||
*/
|
||||
class ODBCTableInfo extends TableInfo {
|
||||
|
||||
/**
|
||||
* @see TableInfo::initColumns()
|
||||
*/
|
||||
protected function initColumns()
|
||||
{
|
||||
include_once 'creole/metadata/ColumnInfo.php';
|
||||
include_once 'creole/drivers/odbc/ODBCTypes.php';
|
||||
|
||||
ODBCTypes::loadTypeMap($this->conn);
|
||||
|
||||
$result = @odbc_columns($this->conn->getResource(), $this->dbname, '', $this->name);
|
||||
|
||||
if (!$result)
|
||||
throw new SQLException('Could not get column names', $this->conn->nativeError());
|
||||
|
||||
while (odbc_fetch_row($result))
|
||||
{
|
||||
$name = odbc_result($result, 'COLUMN_NAME');
|
||||
$type = odbc_result($result, 'TYPE_NAME');
|
||||
$length = odbc_result($result, 'LENGTH');
|
||||
$is_nullable = odbc_result($result, 'NULLABLE');
|
||||
$default = '';
|
||||
$precision = odbc_result($result, 'PRECISION');
|
||||
$scale = odbc_result($result, 'SCALE');
|
||||
$this->columns[$name] = new ColumnInfo($this, $name, ODBCTypes::getType($type), $type, $length, $precision, $scale, $is_nullable, $default);
|
||||
}
|
||||
|
||||
@odbc_free_result($result);
|
||||
|
||||
$this->colsLoaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TableInfo::initPrimaryKey()
|
||||
*/
|
||||
protected function initPrimaryKey()
|
||||
{
|
||||
include_once 'creole/metadata/PrimaryKeyInfo.php';
|
||||
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
|
||||
$result = @odbc_primarykeys($this->conn->getResource(), $this->dbname, '', $this->name);
|
||||
|
||||
while (odbc_fetch_row($result))
|
||||
{
|
||||
$name = odbc_result($result, 'COLUMN_NAME');
|
||||
|
||||
if (!isset($this->primaryKey))
|
||||
$this->primaryKey = new PrimaryKeyInfo($name);
|
||||
|
||||
$this->primaryKey->addColumn($this->columns[$name]);
|
||||
}
|
||||
|
||||
@odbc_free_result($result);
|
||||
|
||||
$this->pkLoaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TableInfo::initIndexes()
|
||||
*/
|
||||
protected function initIndexes()
|
||||
{
|
||||
// Not sure if this can be implemented in a driver-independent way.
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TableInfo::initForeignKeys()
|
||||
*/
|
||||
protected function initForeignKeys()
|
||||
{
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
|
||||
$result = @odbc_foreignkeys($this->conn->getResource(), '', '', '', $this->dbname, '', $this->name);
|
||||
|
||||
while (odbc_fetch_row($result))
|
||||
{
|
||||
$name = odbc_result($result, 'COLUMN_NAME');
|
||||
$ftbl = odbc_result($result, 'FKTABLE_NAME');
|
||||
$fcol = odbc_result($result, 'FKCOLUMN_NAME');
|
||||
|
||||
if (!isset($this->foreignKeys[$name]))
|
||||
{
|
||||
$this->foreignKeys[$name] = new ForeignKeyInfo($name);
|
||||
|
||||
if (($foreignTable = $this->database->getTable($ftbl)) === null)
|
||||
{
|
||||
$foreignTable = new TableInfo($ltbl);
|
||||
$this->database->addTable($foreignTable);
|
||||
}
|
||||
|
||||
if (($foreignCol = $foreignTable->getColumn($name)) === null)
|
||||
{
|
||||
$foreignCol = new ColumnInfo($foreignTable, $name);
|
||||
$foreignTable->addColumn($foreignCol);
|
||||
}
|
||||
|
||||
$this->foreignKeys[$name]->addReference($this->columns[$name], $foreignCol);
|
||||
}
|
||||
}
|
||||
|
||||
@odbc_free_result($result);
|
||||
|
||||
$this->fksLoaded = true;
|
||||
}
|
||||
|
||||
}
|
||||
398
lib/symfony/vendor/creole/drivers/oracle/OCI8Connection.php
vendored
Executable file
398
lib/symfony/vendor/creole/drivers/oracle/OCI8Connection.php
vendored
Executable file
@ -0,0 +1,398 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* $Id: OCI8Connection.php,v 1.18 2005/10/17 19:03:51 dlawson_mi Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/Connection.php';
|
||||
require_once 'creole/common/ConnectionCommon.php';
|
||||
include_once 'creole/drivers/oracle/OCI8ResultSet.php';
|
||||
|
||||
/**
|
||||
* Oracle implementation of Connection.
|
||||
*
|
||||
* @author David Giffin <david@giffin.org>
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
* @author Lukas Smith
|
||||
* @version $Revision: 1.18 $
|
||||
* @package creole.drivers.oracle
|
||||
*/
|
||||
class OCI8Connection extends ConnectionCommon implements Connection
|
||||
{
|
||||
protected $lastStmt = null;
|
||||
|
||||
/**
|
||||
* Auto commit mode for oci_execute
|
||||
* @var int
|
||||
*/
|
||||
protected $execMode = OCI_COMMIT_ON_SUCCESS;
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param array $dsn The data source hash.
|
||||
* @param int $flags Any connection flags.
|
||||
* @access public
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
function connect( $dsninfo, $flags = 0 )
|
||||
{
|
||||
if ( !extension_loaded( 'oci8' ) )
|
||||
{
|
||||
throw new SQLException( 'oci8 extension not loaded' );
|
||||
}
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$this->flags = $flags;
|
||||
|
||||
$persistent =
|
||||
( $flags & Creole::PERSISTENT === Creole::PERSISTENT );
|
||||
|
||||
$user = $dsninfo[ 'username' ];
|
||||
$pw = $dsninfo[ 'password' ];
|
||||
$hostspec = $dsninfo[ 'hostspec' ];
|
||||
$port = $dsninfo[ 'port' ];
|
||||
$db = $dsninfo[ 'database' ];
|
||||
|
||||
$connect_function = ( $persistent )
|
||||
? 'oci_pconnect'
|
||||
: 'oci_connect';
|
||||
$encoding = !empty($dsninfo['encoding']) ? $dsninfo['encoding'] : null;
|
||||
|
||||
@ini_set( 'track_errors', true );
|
||||
|
||||
if ( $hostspec && $port )
|
||||
{
|
||||
$hostspec .= ':' . $port;
|
||||
}
|
||||
|
||||
if ( $db && $hostspec && $user && $pw )
|
||||
{
|
||||
$conn = @$connect_function( $user, $pw, "//$hostspec/$db", $encoding);
|
||||
}
|
||||
elseif ( $hostspec && $user && $pw )
|
||||
{
|
||||
$conn = @$connect_function( $user, $pw, $hostspec, $encoding );
|
||||
}
|
||||
|
||||
elseif ( $user || $pw )
|
||||
{
|
||||
$conn = @$connect_function( $user, $pw, null, $encoding );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
$conn = false;
|
||||
}
|
||||
|
||||
@ini_restore( 'track_errors' );
|
||||
|
||||
if ( $conn == false )
|
||||
{
|
||||
$error = oci_error();
|
||||
$error = ( is_array( $error ) )
|
||||
? $error[ 'message' ]
|
||||
: null;
|
||||
|
||||
throw new SQLException( 'connect failed', $error );
|
||||
}
|
||||
|
||||
$this->dblink = $conn;
|
||||
|
||||
//connected ok, need to set a few environment settings
|
||||
//please note, if this is changed, the function setTimestamp and setDate in OCI8PreparedStatement.php
|
||||
//must be changed to match
|
||||
$sql = "ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'";
|
||||
$this->executeQuery($sql);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see Connection::disconnect()
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
$ret = @oci_close( $this->dblink );
|
||||
$this->dblink = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::executeQuery()
|
||||
*/
|
||||
function executeQuery( $sql, $fetchmode = null )
|
||||
{
|
||||
$this->lastQuery = $sql;
|
||||
|
||||
// $result = @oci_parse( $this->dblink, $sql );
|
||||
$result = oci_parse( $this->dblink, $sql );
|
||||
|
||||
if ( ! $result )
|
||||
{
|
||||
throw new SQLException( 'Unable to prepare query'
|
||||
, $this->nativeError()
|
||||
, $sql
|
||||
);
|
||||
}
|
||||
|
||||
$success = oci_execute( $result, $this->execMode );
|
||||
|
||||
if ( ! $success )
|
||||
{
|
||||
throw new SQLException( 'Unable to execute query'
|
||||
, $this->nativeError( $result )
|
||||
, $sql
|
||||
);
|
||||
}
|
||||
|
||||
return new OCI8ResultSet( $this, $result, $fetchmode );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see Connection::simpleUpdate()
|
||||
*/
|
||||
|
||||
function executeUpdate( $sql )
|
||||
{
|
||||
$this->lastQuery = $sql;
|
||||
|
||||
$statement = oci_parse( $this->dblink, $sql );
|
||||
|
||||
if ( ! $statement )
|
||||
{
|
||||
throw new SQLException( 'Unable to prepare update'
|
||||
, $this->nativeError()
|
||||
, $sql
|
||||
);
|
||||
}
|
||||
|
||||
$success = oci_execute( $statement, $this->execMode );
|
||||
|
||||
if ( ! $success )
|
||||
{
|
||||
throw new SQLException( 'Unable to execute update'
|
||||
, $this->nativeError( $statement )
|
||||
, $sql
|
||||
);
|
||||
}
|
||||
|
||||
$this->lastStmt = $statement;
|
||||
|
||||
return oci_num_rows( $statement );
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a database transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function beginTrans()
|
||||
{
|
||||
$this->execMode = OCI_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function commitTrans()
|
||||
{
|
||||
$result = oci_commit( $this->dblink );
|
||||
|
||||
if ( ! $result )
|
||||
{
|
||||
throw new SQLException( 'Unable to commit transaction'
|
||||
, $this->nativeError()
|
||||
);
|
||||
}
|
||||
|
||||
$this->execMode = OCI_COMMIT_ON_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Roll back ( undo ) the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function rollbackTrans()
|
||||
{
|
||||
$result = oci_rollback( $this->dblink );
|
||||
|
||||
if ( ! $result )
|
||||
{
|
||||
throw new SQLException( 'Unable to rollback transaction'
|
||||
, $this->nativeError()
|
||||
);
|
||||
}
|
||||
|
||||
$this->execMode = OCI_COMMIT_ON_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the data manipulation
|
||||
* query.
|
||||
*
|
||||
* @return int Number of rows affected by the last query.
|
||||
* @todo -cOCI8Connection Figure out whether getUpdateCount() should throw exception on error or just return 0.
|
||||
*/
|
||||
function getUpdateCount()
|
||||
{
|
||||
if ( ! $this->lastStmt )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
$result = oci_num_rows( $this->lastStmt );
|
||||
|
||||
if ( $result === false )
|
||||
{
|
||||
throw new SQLException( 'Update count failed'
|
||||
, $this->nativeError( $this->lastStmt )
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build Oracle-style query with limit or offset.
|
||||
* If the original SQL is in variable: query then the requlting
|
||||
* SQL looks like this:
|
||||
* <pre>
|
||||
* SELECT B.* FROM (
|
||||
* SELECT A.*, rownum as TORQUE$ROWNUM FROM (
|
||||
* query
|
||||
* ) A
|
||||
* ) B WHERE B.TORQUE$ROWNUM > offset AND B.TORQUE$ROWNUM
|
||||
* <= offset + limit
|
||||
* </pre>
|
||||
*
|
||||
* @param string &$sql the query
|
||||
* @param int $offset
|
||||
* @param int $limit
|
||||
* @return void ( $sql parameter is currently manipulated directly )
|
||||
*/
|
||||
public function applyLimit( &$sql, $offset, $limit )
|
||||
{
|
||||
$sql =
|
||||
'SELECT B.* FROM ( '
|
||||
. 'SELECT A.*, rownum AS CREOLE$ROWNUM FROM ( '
|
||||
. $sql
|
||||
. ' ) A '
|
||||
. ' ) B WHERE ';
|
||||
|
||||
if ( $offset > 0 )
|
||||
{
|
||||
$sql .= ' B.CREOLE$ROWNUM > ' . $offset;
|
||||
|
||||
if ( $limit > 0 )
|
||||
{
|
||||
$sql .= ' AND B.CREOLE$ROWNUM <= '
|
||||
. ( $offset + $limit );
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
$sql .= ' B.CREOLE$ROWNUM <= ' . $limit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the native Oracle Error Message as a string.
|
||||
*
|
||||
* @param string $msg The Internal Error Message
|
||||
* @param mixed $errno The Oracle Error resource
|
||||
*/
|
||||
public function nativeError( $result = null )
|
||||
{
|
||||
if ( $result !== null )
|
||||
{
|
||||
$error = oci_error( $result );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
$error = oci_error( $this->dblink );
|
||||
}
|
||||
|
||||
return $error[ 'code' ] . ': ' . $error[ 'message' ];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see Connection::getDatabaseInfo()
|
||||
*/
|
||||
public function getDatabaseInfo()
|
||||
{
|
||||
require_once 'creole/drivers/oracle/metadata/OCI8DatabaseInfo.php';
|
||||
|
||||
return new OCI8DatabaseInfo( $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getIdGenerator()
|
||||
*/
|
||||
public function getIdGenerator()
|
||||
{
|
||||
require_once 'creole/drivers/oracle/OCI8IdGenerator.php';
|
||||
|
||||
return new OCI8IdGenerator( $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Oracle supports native prepared statements, but the oci_parse call
|
||||
* is actually called by the OCI8PreparedStatement class because
|
||||
* some additional SQL processing may be necessary ( e.g. to apply limit ).
|
||||
* @see OCI8PreparedStatement::executeQuery()
|
||||
* @see OCI8PreparedStatement::executeUpdate()
|
||||
* @see Connection::prepareStatement()
|
||||
*/
|
||||
public function prepareStatement( $sql )
|
||||
{
|
||||
require_once 'creole/drivers/oracle/OCI8PreparedStatement.php';
|
||||
|
||||
return new OCI8PreparedStatement( $this, $sql );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareCall()
|
||||
*/
|
||||
public function prepareCall( $sql )
|
||||
{
|
||||
throw new SQLException( 'Oracle driver does not yet support stored procedures using CallableStatement.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::createStatement()
|
||||
*/
|
||||
public function createStatement()
|
||||
{
|
||||
require_once 'creole/drivers/oracle/OCI8Statement.php';
|
||||
|
||||
return new OCI8Statement( $this );
|
||||
}
|
||||
}
|
||||
65
lib/symfony/vendor/creole/drivers/oracle/OCI8IdGenerator.php
vendored
Executable file
65
lib/symfony/vendor/creole/drivers/oracle/OCI8IdGenerator.php
vendored
Executable file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
require_once 'creole/IdGenerator.php';
|
||||
|
||||
/**
|
||||
* Oracle (OCI8) IdGenerator implimenation.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.5 $
|
||||
* @package creole.drivers.oracle
|
||||
*/
|
||||
class OCI8IdGenerator implements IdGenerator {
|
||||
|
||||
/** Connection object that instantiated this class */
|
||||
private $conn;
|
||||
|
||||
/**
|
||||
* Creates a new IdGenerator class, saves passed connection for use
|
||||
* later by getId() method.
|
||||
* @param Connection $conn
|
||||
*/
|
||||
public function __construct(Connection $conn)
|
||||
{
|
||||
$this->conn = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::isBeforeInsert()
|
||||
*/
|
||||
public function isBeforeInsert()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::isAfterInsert()
|
||||
*/
|
||||
public function isAfterInsert()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::getIdMethod()
|
||||
*/
|
||||
public function getIdMethod()
|
||||
{
|
||||
return self::SEQUENCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::getId()
|
||||
*/
|
||||
public function getId($name = null)
|
||||
{
|
||||
if ($name === null) {
|
||||
throw new SQLException("You must specify the sequence name when calling getId() method.");
|
||||
}
|
||||
$rs = $this->conn->executeQuery("select " . $name . ".nextval from dual", ResultSet::FETCHMODE_NUM);
|
||||
$rs->next();
|
||||
return $rs->getInt(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
424
lib/symfony/vendor/creole/drivers/oracle/OCI8PreparedStatement.php
vendored
Executable file
424
lib/symfony/vendor/creole/drivers/oracle/OCI8PreparedStatement.php
vendored
Executable file
@ -0,0 +1,424 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: OCI8PreparedStatement.php,v 1.26 2006/01/30 21:32:05 sethr Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/PreparedStatement.php';
|
||||
require_once 'creole/common/PreparedStatementCommon.php';
|
||||
|
||||
/**
|
||||
* Oracle (OCI8) implementation of PreparedStatement.
|
||||
*
|
||||
* @author David Giffin <david@giffin.org>
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.26 $
|
||||
* @package creole.drivers.oracle
|
||||
*/
|
||||
class OCI8PreparedStatement extends PreparedStatementCommon implements PreparedStatement {
|
||||
|
||||
/**
|
||||
* Descriptor holders for LOB values.
|
||||
* There are other types of descriptors, but we need to keep
|
||||
* them separate, because we need to execute the save()/savefile() method
|
||||
* on lob descriptors.
|
||||
* @var array object from oci_new_descriptor
|
||||
*/
|
||||
private $lobDescriptors = array();
|
||||
|
||||
/**
|
||||
* Hold any Blob/Clob data.
|
||||
* These can be matched (by key) to descriptors in $lobDescriptors.
|
||||
* @var array Lob[]
|
||||
*/
|
||||
private $lobs = array();
|
||||
|
||||
/**
|
||||
* Array to store the columns in an insert or update statement.
|
||||
* This is necessary for the proper handling of lob variables
|
||||
* @var arrary columns[]
|
||||
*/
|
||||
private $columns = array();
|
||||
|
||||
/**
|
||||
* If the statement is set, free it.
|
||||
* @see PreparedStatement::close()
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
if (isset($this->stmt))
|
||||
@oci_free_statement($this->stmt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Nothing to do - since oci_bind is used to insert data, no escaping is needed
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
protected function escape($str)
|
||||
{
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the SQL query in this PreparedStatement object and returns the resultset generated by the query.
|
||||
* @param mixed $p1 Either (array) Parameters that will be set using PreparedStatement::set() before query is executed or (int) fetchmode.
|
||||
* @param int $fetchmode The mode to use when fetching the results (e.g. ResultSet::FETCHMODE_NUM, ResultSet::FETCHMODE_ASSOC).
|
||||
* @return ResultSet
|
||||
* @throws SQLException if a database access error occurs.
|
||||
*/
|
||||
public function executeQuery($p1 = null, $fetchmode = null)
|
||||
{
|
||||
$params = null;
|
||||
if ($fetchmode !== null) {
|
||||
$params = $p1;
|
||||
} elseif ($p1 !== null) {
|
||||
if (is_array($p1)) $params = $p1;
|
||||
else $fetchmode = $p1;
|
||||
}
|
||||
|
||||
if ($params) {
|
||||
for($i=0,$cnt=count($params); $i < $cnt; $i++) {
|
||||
$this->set($i+1, $params[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->updateCount = null; // reset
|
||||
|
||||
$sql = $this->sqlToOracleBindVars($this->sql);
|
||||
|
||||
if ($this->limit > 0 || $this->offset > 0) {
|
||||
$this->conn->applyLimit($sql, $this->offset, $this->limit);
|
||||
}
|
||||
|
||||
$result = oci_parse($this->conn->getResource(), $sql);
|
||||
if (!$result) {
|
||||
throw new SQLException("Unable to prepare query", $this->conn->nativeError(), $this->sqlToOracleBindVars($this->sql));
|
||||
}
|
||||
|
||||
// bind all variables
|
||||
$this->bindVars($result);
|
||||
|
||||
$success = oci_execute($result, OCI_DEFAULT);
|
||||
if (!$success) {
|
||||
throw new SQLException("Unable to execute query", $this->conn->nativeError($result), $this->sqlToOracleBindVars($this->sql));
|
||||
}
|
||||
|
||||
$this->resultSet = new OCI8ResultSet($this->conn, $result, $fetchmode);
|
||||
|
||||
return $this->resultSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the SQL INSERT, UPDATE, or DELETE statement in this PreparedStatement object.
|
||||
*
|
||||
* @param array $params Parameters that will be set using PreparedStatement::set() before query is executed.
|
||||
* @return int Number of affected rows (or 0 for drivers that return nothing).
|
||||
* @throws SQLException if a database access error occurs.
|
||||
*/
|
||||
public function executeUpdate($params = null)
|
||||
{
|
||||
if ($params) {
|
||||
for($i=0,$cnt=count($params); $i < $cnt; $i++) {
|
||||
$this->set($i+1, $params[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
if($this->resultSet) $this->resultSet->close();
|
||||
$this->resultSet = null; // reset
|
||||
|
||||
$stmt = oci_parse($this->conn->getResource(), $this->sqlToOracleBindVars($this->sql));
|
||||
|
||||
if (!$stmt) {
|
||||
throw new SQLException("Unable to prepare update", $this->conn->nativeError(), $this->sqlToOracleBindVars($this->sql));
|
||||
}
|
||||
|
||||
// bind all variables
|
||||
$this->bindVars($stmt);
|
||||
|
||||
// Even if autocommit is on, delay commit until after LOBS have been saved
|
||||
$success = oci_execute($stmt, OCI_DEFAULT);
|
||||
if (!$success) {
|
||||
throw new SQLException("Unable to execute update", $this->conn->nativeError($stmt), $this->sqlToOracleBindVars($this->sql));
|
||||
}
|
||||
|
||||
// save data in any LOB descriptors, then free them
|
||||
foreach($this->lobDescriptors as $paramIndex => $lobster) {
|
||||
$lob = $this->lobs[$paramIndex]; // corresponding Blob/Clob
|
||||
if ($lob->isFromFile()) {
|
||||
$success = $lobster->savefile($lob->getInputFile());
|
||||
} else {
|
||||
$success = $lobster->save($lob->getContents());
|
||||
}
|
||||
if (!$success) {
|
||||
$lobster->free();
|
||||
throw new SQLException("Error saving lob bound to " . $paramIndex);
|
||||
}
|
||||
$lobster->free();
|
||||
}
|
||||
|
||||
if ($this->conn->getAutoCommit()) {
|
||||
oci_commit($this->conn->getResource()); // perform deferred commit
|
||||
}
|
||||
|
||||
$this->updateCount = @oci_num_rows($stmt);
|
||||
|
||||
return $this->updateCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the actual binding of variables using oci_bind_by_name().
|
||||
*
|
||||
* This may seem like useless overhead, but the reason why calls to oci_bind_by_name()
|
||||
* are not performed in the set*() methods is that it is possible that the SQL will
|
||||
* need to be modified -- e.g. by a setLimit() call -- and re-prepared. We cannot assume
|
||||
* that the statement has been prepared when the set*() calls are invoked. This also means,
|
||||
* therefore, that the set*() calls will not throw exceptions; all exceptions will be thrown
|
||||
* when the statement is prepared.
|
||||
*
|
||||
* @param resource $stmt The statement result of oci_parse to use for binding.
|
||||
* @return void
|
||||
*/
|
||||
private function bindVars($stmt)
|
||||
{
|
||||
foreach ($this->boundInVars as $idx => $val) {
|
||||
$idxName = ":var" . $idx;
|
||||
if (!oci_bind_by_name($stmt, $idxName, $this->boundInVars[$idx], -1)) {
|
||||
throw new SQLException("Erorr binding value to placeholder " . $idx);
|
||||
}
|
||||
} // foreach
|
||||
|
||||
foreach ($this->lobs as $idx => $val) {
|
||||
$idxName = ":var" . $idx;
|
||||
if (class_exists('Blob') && $val instanceof Blob){
|
||||
if (!oci_bind_by_name($stmt, $idxName, $this->lobDescriptors[$idx], -1, OCI_B_BLOB))
|
||||
throw new SQLException("Erorr binding blob to placeholder " . $idx);
|
||||
} elseif (class_exists('Clob') && $val instanceof Clob){
|
||||
if (!oci_bind_by_name($stmt, $idxName, $this->lobDescriptors[$idx], -1, OCI_B_CLOB))
|
||||
throw new SQLException("Erorr binding clob to placeholder " . $idx);
|
||||
}
|
||||
} // foreach
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a Propel SQL into Oracle SQL
|
||||
*
|
||||
* Look for all of the '?' and replace with ":varX"
|
||||
*
|
||||
* @param string $sql SQL in Propel native format
|
||||
* @return string SQL in Oracle Bind Var format
|
||||
* @todo -cOCI8PreparedStatement Consider changing this implementation to use the fact that we
|
||||
* already know where all the '?' chars are (in $positions array).
|
||||
*/
|
||||
private function sqlToOracleBindVars($sql)
|
||||
{
|
||||
$out = "";
|
||||
$in_literal = 0;
|
||||
$idxNum = 1;
|
||||
for ($i = 0; $i < strlen($sql); $i++) {
|
||||
$char = $sql[$i];
|
||||
if (strcmp($char,"'")==0) {
|
||||
$in_literal = ~$in_literal;
|
||||
}
|
||||
if (strcmp($char,"?")==0 && !$in_literal) {
|
||||
if (array_key_exists($idxNum, $this->lobs)){
|
||||
if (class_exists('Blob') && ($this->lobs[$idxNum] instanceof Blob))
|
||||
$out .= "empty_blob()";
|
||||
if (class_exists('Clob') && ($this->lobs[$idxNum] instanceof Clob))
|
||||
$out .= "empty_clob()";
|
||||
} else
|
||||
$out .= ":var" . $idxNum;
|
||||
$idxNum++;
|
||||
} else {
|
||||
$out .= $char;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->lobs) && !empty($this->lobs)) {
|
||||
$this->setColumnArray();
|
||||
|
||||
$retstmt = " Returning ";
|
||||
$collist = "";
|
||||
$bindlist = "";
|
||||
foreach ($this->lobs as $idx=>$val) {
|
||||
$idxName = ":var" . $idx;
|
||||
if ((class_exists('Blob') && $val instanceof Blob) || (class_exists('Clob') && $val instanceof Clob)) {
|
||||
//the columns array starts at zero instead of 1 like the lobs array
|
||||
$collist .= $this->columns[$idx-1] . ",";
|
||||
$bindlist .= $idxName . ",";
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($collist))
|
||||
$out .= $retstmt . rtrim($collist, ",") . " into " . rtrim($bindlist, ",");
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $paramIndex
|
||||
* @param mixed $blob Blob object or string containing data.
|
||||
* @return void
|
||||
*/
|
||||
function setBlob($paramIndex, $blob)
|
||||
{
|
||||
require_once 'creole/util/Blob.php';
|
||||
if (!($blob instanceof Blob)) {
|
||||
$b = new Blob();
|
||||
$b->setContents($blob);
|
||||
$blob = $b;
|
||||
}
|
||||
$this->lobDescriptors[$paramIndex] = oci_new_descriptor($this->conn->getResource(), OCI_D_LOB);
|
||||
$this->lobs[$paramIndex] = $blob;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $paramIndex
|
||||
* @param mixed $clob Clob object or string containing data.
|
||||
* @return void
|
||||
*/
|
||||
function setClob($paramIndex, $clob)
|
||||
{
|
||||
require_once 'creole/util/Clob.php';
|
||||
if (!($clob instanceof Clob)) {
|
||||
$c = new Clob();
|
||||
$c->setContents($clob);
|
||||
$clob = $c;
|
||||
}
|
||||
$this->lobDescriptors[$paramIndex] = oci_new_descriptor($this->conn->getResource(), OCI_D_LOB);
|
||||
$this->lobs[$paramIndex] = $clob;
|
||||
}
|
||||
|
||||
/**
|
||||
* Since bind variables in oracle have no special characters, this setString method differs from the
|
||||
* common one in that it does not single quote strings.
|
||||
*
|
||||
* @param int $paramIndex
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
function setString($paramIndex, $value)
|
||||
{
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
// it's ok to have a fatal error here, IMO, if object doesn't have
|
||||
// __toString() and is being passed to this method.
|
||||
if ( is_object ( $value ) ) {
|
||||
$this->boundInVars[$paramIndex] = $value->__toString();
|
||||
} else {
|
||||
$this->boundInVars[$paramIndex] = (string)$value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copied this function from common/PreparedStatement.php and modified to work with Oracle
|
||||
* Please note the format used with date() matches that of NLS_DATE_FORMAT set in
|
||||
* OCI8Connection.php
|
||||
*
|
||||
* @param int $paramIndex
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
function setTimestamp($paramIndex, $value)
|
||||
{
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
if (is_numeric($value)) $value = date('Y-m-d H:i:s', $value);
|
||||
elseif (is_object($value)) $value = date('Y-m-d H:i:s', $value->getTime());
|
||||
$this->boundInVars[$paramIndex] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Please note the format used with date() matches that of NLS_DATE_FORMAT set in
|
||||
* OCI8Connection.php
|
||||
*
|
||||
* @param int $paramIndex
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
function setDate($paramIndex, $value)
|
||||
{
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
if (is_numeric($value)) $value = date("Y-m-d", $value);
|
||||
elseif (is_object($value)) $value = date("Y-m-d", $value->getTime());
|
||||
$this->boundInVars[$paramIndex] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* In order to send lob data (clob/blob) to the Oracle data base, the
|
||||
* sqlToOracleBindVars function needs to have an ordered list of the
|
||||
* columns being addressed in the sql statement.
|
||||
* Since only insert and update statements require special handling,
|
||||
* there are two ways to find the columns:
|
||||
* 1) find the first set of () and parse out the columns names based on
|
||||
* the token ','
|
||||
* 2) find all the text strings to the left of the equal signs.
|
||||
*
|
||||
* @param void
|
||||
* @return void
|
||||
*/
|
||||
private function setColumnArray()
|
||||
{
|
||||
$this->columns = array();
|
||||
|
||||
//handle the simple insert case first
|
||||
if(strtoupper(substr($this->sql, 0, 6)) == 'INSERT') {
|
||||
$firstPos = strpos($this->sql, '(');
|
||||
$secPos = strpos($this->sql, ')');
|
||||
$collist = substr($this->sql, $firstPos + 1, $secPos - $firstPos - 1);
|
||||
$this->columns = explode(',', $collist);
|
||||
}
|
||||
if (strtoupper(substr($this->sql, 0, 6)) == 'UPDATE') {
|
||||
//handle more complex update case
|
||||
//first get the string setup so we can explode based on '=?'
|
||||
//second split results from previous action based on ' '
|
||||
// the last token from this should be a column name
|
||||
$tmp = $this->sql;
|
||||
$tmp = str_replace(" =", "=", $this->sql);
|
||||
$tmp = str_replace("= ", "=", $tmp);
|
||||
$tmp = str_replace(",", " ", $tmp);
|
||||
$stage1 = explode("=?",$tmp);
|
||||
|
||||
foreach($stage1 as $chunk) {
|
||||
$stage2 = explode(' ', $chunk);
|
||||
$this->columns[count($this->columns)] = $stage2[count($stage2) - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @return void
|
||||
*/
|
||||
function setNull($paramIndex)
|
||||
{
|
||||
$this->boundInVars[$paramIndex] = '';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
131
lib/symfony/vendor/creole/drivers/oracle/OCI8ResultSet.php
vendored
Executable file
131
lib/symfony/vendor/creole/drivers/oracle/OCI8ResultSet.php
vendored
Executable file
@ -0,0 +1,131 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: OCI8ResultSet.php,v 1.13 2006/01/17 19:44:40 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/ResultSet.php';
|
||||
require_once 'creole/common/ResultSetCommon.php';
|
||||
|
||||
/**
|
||||
* Oracle (OCI8) implementation of ResultSet class.
|
||||
*
|
||||
* @author David Giffin <david@giffin.org>
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.13 $
|
||||
* @package creole.drivers.oracle
|
||||
*/
|
||||
class OCI8ResultSet extends ResultSetCommon implements ResultSet
|
||||
{
|
||||
/**
|
||||
* @see ResultSet::seek()
|
||||
*/
|
||||
function seek($rownum)
|
||||
{
|
||||
if ( $rownum < $this->cursorPos )
|
||||
{
|
||||
// this will effectively disable previous(), first() and some calls to relative() or absolute()
|
||||
throw new SQLException( 'Oracle ResultSet is FORWARD-ONLY' );
|
||||
}
|
||||
|
||||
// Oracle has no seek function imulate it here
|
||||
while ( $this->cursorPos < $rownum )
|
||||
{
|
||||
$this->next();
|
||||
}
|
||||
|
||||
$this->cursorPos = $rownum;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::next()
|
||||
*/
|
||||
function next()
|
||||
{
|
||||
// no specific result position available
|
||||
|
||||
// Returns an array, which corresponds to the next result row or FALSE
|
||||
// in case of error or there is no more rows in the result.
|
||||
$this->fields = oci_fetch_array( $this->result
|
||||
, $this->fetchmode
|
||||
+ OCI_RETURN_NULLS
|
||||
+ OCI_RETURN_LOBS
|
||||
);
|
||||
|
||||
if ( ! $this->fields )
|
||||
{
|
||||
// grab error via array
|
||||
$error = oci_error( $this->result );
|
||||
|
||||
if ( ! $error )
|
||||
{
|
||||
// end of recordset
|
||||
$this->afterLast();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
throw new SQLException( 'Error fetching result'
|
||||
, $error[ 'code' ] . ': ' . $error[ 'message' ]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Oracle returns all field names in uppercase and associative indices
|
||||
// in the result array will be uppercased too.
|
||||
if ($this->fetchmode === ResultSet::FETCHMODE_ASSOC && $this->lowerAssocCase)
|
||||
{
|
||||
$this->fields = array_change_key_case($this->fields, CASE_LOWER);
|
||||
}
|
||||
|
||||
// Advance cursor position
|
||||
$this->cursorPos++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getRecordCount()
|
||||
*/
|
||||
function getRecordCount()
|
||||
{
|
||||
$rows = oci_num_rows( $this->result );
|
||||
|
||||
if ( $rows === false )
|
||||
{
|
||||
throw new SQLException( 'Error fetching num rows'
|
||||
, $this->conn->nativeError( $this->result )
|
||||
);
|
||||
}
|
||||
|
||||
return ( int ) $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::close()
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
$this->fields = array();
|
||||
@oci_free_statement( $this->result );
|
||||
}
|
||||
}
|
||||
34
lib/symfony/vendor/creole/drivers/oracle/OCI8Statement.php
vendored
Executable file
34
lib/symfony/vendor/creole/drivers/oracle/OCI8Statement.php
vendored
Executable file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: OCI8Statement.php,v 1.2 2004/03/05 15:46:12 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/Statement.php';
|
||||
require_once 'creole/common/StatementCommon.php';
|
||||
|
||||
/**
|
||||
* Oracle (OCI8) Statement implementation.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.2 $
|
||||
* @package creole.drivers.oracle
|
||||
*/
|
||||
class OCI8Statement extends StatementCommon implements Statement {
|
||||
|
||||
}
|
||||
90
lib/symfony/vendor/creole/drivers/oracle/OCI8Types.php
vendored
Executable file
90
lib/symfony/vendor/creole/drivers/oracle/OCI8Types.php
vendored
Executable file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* $Id: OCI8Types.php,v 1.8 2004/03/20 04:16:50 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/CreoleTypes.php';
|
||||
|
||||
/**
|
||||
* Oracle types / type map.
|
||||
*
|
||||
* @author David Giffin <david@giffin.org>
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.8 $
|
||||
* @package creole.drivers.oracle
|
||||
*/
|
||||
class OCI8Types extends CreoleTypes {
|
||||
|
||||
/** Map Oracle native types to Creole (JDBC) types. */
|
||||
private static $typeMap = array(
|
||||
'char' => CreoleTypes::CHAR,
|
||||
'varchar2' => CreoleTypes::VARCHAR,
|
||||
'long' => CreoleTypes::LONGVARCHAR,
|
||||
'number' => CreoleTypes::NUMERIC,
|
||||
'float' => CreoleTypes::FLOAT,
|
||||
'integer' => CreoleTypes::INTEGER,
|
||||
'smallint' => CreoleTypes::SMALLINT,
|
||||
'double' => CreoleTypes::DOUBLE,
|
||||
'raw' => CreoleTypes::VARBINARY,
|
||||
'longraw' => CreoleTypes::LONGVARBINARY,
|
||||
'date' => CreoleTypes::DATE,
|
||||
'timestamp' => CreoleTypes::TIMESTAMP,
|
||||
'blob' => CreoleTypes::BLOB,
|
||||
'clob' => CreoleTypes::CLOB,
|
||||
'varray' => CreoleTypes::ARR,
|
||||
);
|
||||
|
||||
/** Reverse mapping, created on demand. */
|
||||
private static $reverseMap = null;
|
||||
|
||||
/**
|
||||
* This method returns the generic Creole (JDBC-like) type
|
||||
* when given the native db type.
|
||||
* @param string $nativeType DB native type (e.g. 'TEXT', 'byetea', etc.).
|
||||
* @return int Creole native type (e.g. CreoleTypes::LONGVARCHAR, CreoleTypes::BINARY, etc.).
|
||||
*/
|
||||
public static function getType($nativeType)
|
||||
{
|
||||
$t = str_replace(' ', '', strtolower($nativeType));
|
||||
if ( substr($t, 0, 9) == 'timestamp' ) return CreoleTypes::TIMESTAMP;
|
||||
if (isset(self::$typeMap[$t])) {
|
||||
return self::$typeMap[$t];
|
||||
} else {
|
||||
return CreoleTypes::OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return a native type that corresponds to the specified
|
||||
* Creole (JDBC-like) type.
|
||||
* If there is more than one matching native type, then the LAST defined
|
||||
* native type will be returned.
|
||||
* @param int $creoleType
|
||||
* @return string Native type string.
|
||||
*/
|
||||
public static function getNativeType($creoleType)
|
||||
{
|
||||
if (self::$reverseMap === null) {
|
||||
self::$reverseMap = array_flip(self::$typeMap);
|
||||
}
|
||||
return @self::$reverseMap[$creoleType];
|
||||
}
|
||||
|
||||
}
|
||||
90
lib/symfony/vendor/creole/drivers/oracle/metadata/OCI8DatabaseInfo.php
vendored
Executable file
90
lib/symfony/vendor/creole/drivers/oracle/metadata/OCI8DatabaseInfo.php
vendored
Executable file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: OCI8DatabaseInfo.php,v 1.11 2006/01/17 19:44:40 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/metadata/DatabaseInfo.php';
|
||||
|
||||
/**
|
||||
* Oracle (OCI8) implementation of DatabaseInfo.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.11 $
|
||||
* @package creole.drivers.oracle.metadata
|
||||
*/
|
||||
class OCI8DatabaseInfo extends DatabaseInfo {
|
||||
|
||||
private $schema;
|
||||
|
||||
public function __construct(Connection $conn) {
|
||||
parent::__construct($conn);
|
||||
|
||||
$dsn = $conn->getDSN();
|
||||
|
||||
if (isset($dsn['schema'])) {
|
||||
$this->schema = $dsn['schema'];
|
||||
} else {
|
||||
// For Changing DB/Schema in Meta Data Interface
|
||||
$this->schema = $dsn['username'];
|
||||
}
|
||||
|
||||
$this->schema = strtoupper( $this->schema );
|
||||
}
|
||||
|
||||
public function getSchema() {
|
||||
return $this->schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function initTables()
|
||||
{
|
||||
include_once 'creole/drivers/oracle/metadata/OCI8TableInfo.php';
|
||||
|
||||
$sql = "SELECT table_name
|
||||
FROM all_tables
|
||||
WHERE owner = '{$this->schema}'";
|
||||
|
||||
$statement = @oci_parse($this->conn->getResource(),$sql);
|
||||
|
||||
$success = @oci_execute($statement,OCI_DEFAULT);
|
||||
if (!$success) {
|
||||
throw new SQLException("Could not get tables", $this->conn->getResource()->nativeError($statement));
|
||||
}
|
||||
while ( $statement && $row = oci_fetch_assoc( $statement ) )
|
||||
{
|
||||
$row = array_change_key_case($row,CASE_LOWER);
|
||||
$this->tables[strtoupper($row['table_name'])] = new OCI8TableInfo($this,$row['table_name']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Oracle supports sequences.
|
||||
*
|
||||
* @return void
|
||||
* @throws SQLException
|
||||
*/
|
||||
protected function initSequences()
|
||||
{
|
||||
// throw new SQLException("MySQL does not support sequences natively.");
|
||||
}
|
||||
|
||||
}
|
||||
273
lib/symfony/vendor/creole/drivers/oracle/metadata/OCI8TableInfo.php
vendored
Executable file
273
lib/symfony/vendor/creole/drivers/oracle/metadata/OCI8TableInfo.php
vendored
Executable file
@ -0,0 +1,273 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: OCI8TableInfo.php,v 1.13 2006/01/06 00:02:38 sethr Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/metadata/TableInfo.php';
|
||||
|
||||
/**
|
||||
* Oracle (OCI8) implementation of TableInfo.
|
||||
*
|
||||
* @author David Giffin <david@giffin.org>
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision$
|
||||
* @package creole.drivers.oracle.metadata
|
||||
*/
|
||||
class OCI8TableInfo extends TableInfo {
|
||||
|
||||
private $schema;
|
||||
|
||||
public function __construct(OCI8DatabaseInfo $database, $name)
|
||||
{
|
||||
$this->schema = strtoupper( $database->getSchema() );
|
||||
parent::__construct($database, $name);
|
||||
$this->name = strtoupper( $this->name );
|
||||
}
|
||||
|
||||
/** Loads the columns for this table. */
|
||||
protected function initColumns()
|
||||
{
|
||||
|
||||
include_once 'creole/metadata/ColumnInfo.php';
|
||||
include_once 'creole/drivers/oracle/OCI8Types.php';
|
||||
|
||||
|
||||
// To get all of the attributes we need, we'll actually do
|
||||
// two separate queries. The first gets names and default values
|
||||
// the second will fill in some more details.
|
||||
|
||||
$sql = "
|
||||
SELECT column_name
|
||||
, data_type
|
||||
, data_precision
|
||||
, data_length
|
||||
, data_default
|
||||
, nullable
|
||||
, data_scale
|
||||
FROM all_tab_columns
|
||||
WHERE table_name = '{$this->name}'
|
||||
AND OWNER = '{$this->schema}'";
|
||||
|
||||
$statement = @oci_parse($this->conn->getResource(),$sql);
|
||||
$success = @oci_execute($statement,OCI_DEFAULT);
|
||||
if (!$success) {
|
||||
throw new SQLException("Could Not Get Columns");
|
||||
}
|
||||
|
||||
while ( $statement && $row = oci_fetch_array( $statement
|
||||
, OCI_ASSOC + OCI_RETURN_NULLS ) ) {
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
$this->columns[$row['column_name']] = new ColumnInfo( $this
|
||||
, $row['column_name']
|
||||
, OCI8Types::getType($row['data_type'])
|
||||
, $row['data_type']
|
||||
, $row['data_length']
|
||||
, $row['data_precision']
|
||||
, $row['data_scale']
|
||||
, $row['nullable']
|
||||
, $row['data_default']
|
||||
);
|
||||
}
|
||||
|
||||
$this->colsLoaded = true;
|
||||
}
|
||||
|
||||
/** Loads the primary key information for this table. */
|
||||
protected function initPrimaryKey()
|
||||
{
|
||||
include_once 'creole/metadata/PrimaryKeyInfo.php';
|
||||
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
|
||||
|
||||
// Primary Keys Query
|
||||
$sql = "SELECT a.owner, a.table_name,
|
||||
a.constraint_name, a.column_name
|
||||
FROM all_cons_columns a, all_constraints b
|
||||
WHERE b.constraint_type = 'P'
|
||||
AND a.constraint_name = b.constraint_name
|
||||
AND b.table_name = '{$this->name}'
|
||||
AND b.owner = '{$this->schema}'
|
||||
";
|
||||
|
||||
|
||||
$statement = @oci_parse($this->conn->getResource(),$sql);
|
||||
$success = @oci_execute($statement,OCI_DEFAULT);
|
||||
if (!$success) {
|
||||
throw new SQLException("Could Not Get Primary Keys");
|
||||
}
|
||||
|
||||
while ( $statement && $row = oci_fetch_assoc( $statement )) {
|
||||
$row = array_change_key_case($row,CASE_LOWER);
|
||||
|
||||
$name = $row['column_name'];
|
||||
|
||||
if (!isset($this->primaryKey)) {
|
||||
$this->primaryKey = new PrimaryKeyInfo($name);
|
||||
}
|
||||
|
||||
$this->primaryKey->addColumn($this->columns[$name]);
|
||||
}
|
||||
|
||||
$this->pkLoaded = true;
|
||||
}
|
||||
|
||||
/** Loads the indexes for this table. */
|
||||
protected function initIndexes() {
|
||||
|
||||
include_once 'creole/metadata/IndexInfo.php';
|
||||
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
|
||||
// Indexes
|
||||
$sql = "SELECT
|
||||
allind.index_name,
|
||||
allind.table_name,
|
||||
allind.index_type,
|
||||
allind.uniqueness,
|
||||
indcol.column_name
|
||||
FROM all_indexes allind INNER JOIN all_ind_columns indcol
|
||||
ON allind.owner = indcol.index_owner
|
||||
AND allind.index_name = indcol.index_name
|
||||
WHERE allind.table_owner = '{$this->schema}'
|
||||
AND allind.table_name = '{$this->name}'
|
||||
AND allind.index_name NOT IN (SELECT
|
||||
constraint_name
|
||||
FROM all_constraints
|
||||
WHERE constraint_type = 'P')
|
||||
ORDER BY allind.index_name,
|
||||
indcol.column_position";
|
||||
|
||||
$statement = @oci_parse($this->conn->getResource(),$sql);
|
||||
$success = @oci_execute($statement,OCI_DEFAULT);
|
||||
if (!$success) {
|
||||
throw new SQLException("Could Not Get Primary Keys");
|
||||
}
|
||||
|
||||
|
||||
// Loop through the returned results, grouping the same key_name together
|
||||
// adding each column for that key.
|
||||
|
||||
while ( $statement && $row = oci_fetch_assoc( $statement )) {
|
||||
$row = array_change_key_case($row,CASE_LOWER);
|
||||
|
||||
$name = $row['index_name'];
|
||||
$index_col_name = $row['column_name'];
|
||||
|
||||
if (!isset($this->indexes[$name])) {
|
||||
$this->indexes[$name] = new IndexInfo($name);
|
||||
}
|
||||
|
||||
$this->indexes[$name]->addColumn($this->columns[ $index_col_name ]);
|
||||
}
|
||||
|
||||
|
||||
$this->indexesLoaded = true;
|
||||
}
|
||||
|
||||
/** Load foreign keys */
|
||||
protected function initForeignKeys() {
|
||||
|
||||
include_once 'creole/metadata/ForeignKeyInfo.php';
|
||||
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
|
||||
// Foreign keys
|
||||
// TODO resolve cross schema references
|
||||
// use all_cons... to do so, however, very slow queries then
|
||||
// optimizations are very ugly
|
||||
$sql = "
|
||||
SELECT a.owner AS local_owner
|
||||
, a.table_name AS local_table
|
||||
, c.column_name AS local_column
|
||||
, a.constraint_name AS foreign_key_name
|
||||
, b.owner AS foreign_owner
|
||||
, b.table_name AS foreign_table
|
||||
, d.column_name AS foreign_column
|
||||
, b.constraint_name AS foreign_constraint_name
|
||||
, a.delete_rule AS on_delete
|
||||
FROM user_constraints a
|
||||
, user_constraints b
|
||||
, user_cons_columns c
|
||||
, user_cons_columns d
|
||||
WHERE a.r_constraint_name = b.constraint_name
|
||||
AND c.constraint_name = a.constraint_name
|
||||
AND d.constraint_name = b.constraint_name
|
||||
AND a.r_owner = b.owner
|
||||
AND a.constraint_type='R'
|
||||
AND a.table_name = '{$this->name}'
|
||||
AND a.owner = '{$this->schema}'
|
||||
";
|
||||
|
||||
$statement = @oci_parse($this->conn->getResource(),$sql);
|
||||
$success = @oci_execute($statement,OCI_DEFAULT);
|
||||
if (!$success) {
|
||||
throw new SQLException("Could Not Get Primary Keys");
|
||||
}
|
||||
|
||||
// Loop through the returned results, grouping the same key_name
|
||||
// together adding each column for that key.
|
||||
|
||||
while ( $statement && $row = oci_fetch_assoc( $statement )) {
|
||||
$row = array_change_key_case($row,CASE_LOWER);
|
||||
|
||||
$name = $row['foreign_key_name'];
|
||||
|
||||
$foreignTable = $this->database->getTable($row['foreign_table']);
|
||||
$foreignColumn = $foreignTable->getColumn($row['foreign_column']);
|
||||
|
||||
$localTable = $this->database->getTable($row['local_table']);
|
||||
$localColumn = $localTable->getColumn($row['local_column']);
|
||||
|
||||
if (!isset($this->foreignKeys[$name])) {
|
||||
$this->foreignKeys[$name] = new ForeignKeyInfo($name);
|
||||
}
|
||||
|
||||
switch ( $row[ 'on_delete' ] )
|
||||
{
|
||||
case 'CASCADE':
|
||||
$onDelete = ForeignKeyInfo::CASCADE;
|
||||
break;
|
||||
|
||||
case 'SET NULL':
|
||||
$onDelete = ForeignKeyInfo::SETNULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'NO ACTION':
|
||||
$onDelete = ForeignKeyInfo::NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
// addReference( local, foreign, onDelete, onUpdate )
|
||||
// Oracle doesn't support 'on update'
|
||||
$this->foreignKeys[ $name ]->addReference(
|
||||
$localColumn
|
||||
, $foreignColumn
|
||||
, $onDelete
|
||||
);
|
||||
}
|
||||
|
||||
$this->fksLoaded = true;
|
||||
}
|
||||
|
||||
}
|
||||
260
lib/symfony/vendor/creole/drivers/pgsql/PgSQLConnection.php
vendored
Executable file
260
lib/symfony/vendor/creole/drivers/pgsql/PgSQLConnection.php
vendored
Executable file
@ -0,0 +1,260 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PgSQLConnection.php,v 1.21 2005/08/03 17:56:22 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/Connection.php';
|
||||
require_once 'creole/common/ConnectionCommon.php';
|
||||
include_once 'creole/drivers/pgsql/PgSQLResultSet.php';
|
||||
|
||||
/**
|
||||
* PgSQL implementation of Connection.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org> (Creole)
|
||||
* @author Stig Bakken <ssb@fast.no> (PEAR::DB)
|
||||
* @author Lukas Smith (PEAR::MDB)
|
||||
* @version $Revision: 1.21 $
|
||||
* @package creole.drivers.pgsql
|
||||
*/
|
||||
class PgSQLConnection extends ConnectionCommon implements Connection {
|
||||
|
||||
/**
|
||||
* Affected Rows of last executed query.
|
||||
* Postgres needs this for getUpdateCount()
|
||||
* We used to store the entire result set
|
||||
* instead but that can be a large dataset.
|
||||
* @var int
|
||||
*/
|
||||
private $result_affected_rows;
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param array $dsn The datasource hash.
|
||||
* @param $flags Any connection flags.
|
||||
* @access public
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
function connect($dsninfo, $flags = 0)
|
||||
{
|
||||
global $php_errormsg;
|
||||
|
||||
if (!extension_loaded('pgsql')) {
|
||||
throw new SQLException('pgsql extension not loaded');
|
||||
}
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$this->flags = $flags;
|
||||
|
||||
$persistent = ($flags & Creole::PERSISTENT === Creole::PERSISTENT);
|
||||
|
||||
$protocol = (isset($dsninfo['protocol'])) ? $dsninfo['protocol'] : 'tcp';
|
||||
$connstr = '';
|
||||
|
||||
if ($protocol == 'tcp') {
|
||||
if (!empty($dsninfo['hostspec'])) {
|
||||
$connstr = 'host=' . $dsninfo['hostspec'];
|
||||
}
|
||||
if (!empty($dsninfo['port'])) {
|
||||
$connstr .= ' port=' . $dsninfo['port'];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($dsninfo['database'])) {
|
||||
$connstr .= ' dbname=\'' . addslashes($dsninfo['database']) . '\'';
|
||||
}
|
||||
if (!empty($dsninfo['username'])) {
|
||||
$connstr .= ' user=\'' . addslashes($dsninfo['username']) . '\'';
|
||||
}
|
||||
if (!empty($dsninfo['password'])) {
|
||||
$connstr .= ' password=\'' . addslashes($dsninfo['password']) . '\'';
|
||||
}
|
||||
if (!empty($dsninfo['options'])) {
|
||||
$connstr .= ' options=' . $dsninfo['options'];
|
||||
}
|
||||
if (!empty($dsninfo['tty'])) {
|
||||
$connstr .= ' tty=' . $dsninfo['tty'];
|
||||
}
|
||||
|
||||
if ($persistent) {
|
||||
$conn = @pg_pconnect($connstr);
|
||||
} else {
|
||||
$conn = @pg_connect($connstr);
|
||||
}
|
||||
|
||||
if (!$conn) {
|
||||
// hide the password from connstr
|
||||
$cleanconnstr = preg_replace('/password=\'.*?\'($|\s)/', 'password=\'*********\'', $connstr);
|
||||
throw new SQLException('Could not connect', $php_errormsg, $cleanconnstr);
|
||||
}
|
||||
|
||||
$this->dblink = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::applyLimit()
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
if ( $limit > 0 ) {
|
||||
$sql .= " LIMIT ".$limit;
|
||||
}
|
||||
if ( $offset > 0 ) {
|
||||
$sql .= " OFFSET ".$offset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::disconnect()
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
$ret = @pg_close($this->dblink);
|
||||
$this->result_affected_rows = null;
|
||||
$this->dblink = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::simpleQuery()
|
||||
*/
|
||||
function executeQuery($sql, $fetchmode = null)
|
||||
{
|
||||
$result = @pg_query($this->dblink, $sql);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not execute query', pg_last_error($this->dblink), $sql);
|
||||
}
|
||||
$this->result_affected_rows = (int) @pg_affected_rows($result);
|
||||
|
||||
return new PgSQLResultSet($this, $result, $fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::simpleUpdate()
|
||||
*/
|
||||
function executeUpdate($sql)
|
||||
{
|
||||
$result = @pg_query($this->dblink, $sql);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not execute update', pg_last_error($this->dblink), $sql);
|
||||
}
|
||||
$this->result_affected_rows = (int) @pg_affected_rows($result);
|
||||
|
||||
return $this->result_affected_rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a database transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function beginTrans()
|
||||
{
|
||||
$result = @pg_query($this->dblink, "BEGIN");
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not begin transaction', pg_last_error($this->dblink));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function commitTrans()
|
||||
{
|
||||
$result = @pg_query($this->dblink, "COMMIT");
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not commit transaction', pg_last_error($this->dblink));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll back (undo) the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function rollbackTrans()
|
||||
{
|
||||
$result = @pg_query($this->dblink, "ROLLBACK");
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not rollback transaction', pg_last_error($this->dblink));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the data manipulation
|
||||
* query.
|
||||
* @see Statement::getUpdateCount()
|
||||
* @return int Number of rows affected by the last query.
|
||||
*/
|
||||
function getUpdateCount()
|
||||
{
|
||||
if ( $this->result_affected_rows === null ) {
|
||||
throw new SQLException('getUpdateCount called before any sql queries were executed');
|
||||
}
|
||||
return $this->result_affected_rows;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see Connection::getDatabaseInfo()
|
||||
*/
|
||||
public function getDatabaseInfo()
|
||||
{
|
||||
require_once 'creole/drivers/pgsql/metadata/PgSQLDatabaseInfo.php';
|
||||
return new PgSQLDatabaseInfo($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getIdGenerator()
|
||||
*/
|
||||
public function getIdGenerator()
|
||||
{
|
||||
require_once 'creole/drivers/pgsql/PgSQLIdGenerator.php';
|
||||
return new PgSQLIdGenerator($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareStatement()
|
||||
*/
|
||||
public function prepareStatement($sql)
|
||||
{
|
||||
require_once 'creole/drivers/pgsql/PgSQLPreparedStatement.php';
|
||||
return new PgSQLPreparedStatement($this, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareCall()
|
||||
*/
|
||||
public function prepareCall($sql) {
|
||||
throw new SQLException('PostgreSQL does not support stored procedures.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::createStatement()
|
||||
*/
|
||||
public function createStatement()
|
||||
{
|
||||
require_once 'creole/drivers/pgsql/PgSQLStatement.php';
|
||||
return new PgSQLStatement($this);
|
||||
}
|
||||
|
||||
}
|
||||
84
lib/symfony/vendor/creole/drivers/pgsql/PgSQLIdGenerator.php
vendored
Executable file
84
lib/symfony/vendor/creole/drivers/pgsql/PgSQLIdGenerator.php
vendored
Executable file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PgSQLIdGenerator.php,v 1.5 2004/03/19 14:19:50 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/IdGenerator.php';
|
||||
|
||||
/**
|
||||
* PostgreSQL IdGenerator implemenation.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.5 $
|
||||
* @package creole.drivers.pgsql
|
||||
*/
|
||||
class PgSQLIdGenerator implements IdGenerator {
|
||||
|
||||
/** Connection object that instantiated this class */
|
||||
private $conn;
|
||||
|
||||
/**
|
||||
* Creates a new IdGenerator class, saves passed connection for use
|
||||
* later by getId() method.
|
||||
* @param Connection $conn
|
||||
*/
|
||||
public function __construct(Connection $conn)
|
||||
{
|
||||
$this->conn = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::isBeforeInsert()
|
||||
*/
|
||||
public function isBeforeInsert()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::isAfterInsert()
|
||||
*/
|
||||
public function isAfterInsert()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::getIdMethod()
|
||||
*/
|
||||
public function getIdMethod()
|
||||
{
|
||||
return self::SEQUENCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::getId()
|
||||
*/
|
||||
public function getId($name = null)
|
||||
{
|
||||
if ($name === null) {
|
||||
throw new SQLException("You must specify the sequence name when calling getId() method.");
|
||||
}
|
||||
$rs = $this->conn->executeQuery("SELECT nextval('" . pg_escape_string ( $name ) . "')", ResultSet::FETCHMODE_NUM);
|
||||
$rs->next();
|
||||
return $rs->getInt(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
157
lib/symfony/vendor/creole/drivers/pgsql/PgSQLPreparedStatement.php
vendored
Executable file
157
lib/symfony/vendor/creole/drivers/pgsql/PgSQLPreparedStatement.php
vendored
Executable file
@ -0,0 +1,157 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PgSQLPreparedStatement.php,v 1.14 2005/04/16 18:55:28 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/PreparedStatement.php';
|
||||
require_once 'creole/common/PreparedStatementCommon.php';
|
||||
|
||||
/**
|
||||
* PgSQL subclass for prepared statements.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.14 $
|
||||
* @package creole.drivers.pgsql
|
||||
*/
|
||||
class PgSQLPreparedStatement extends PreparedStatementCommon implements PreparedStatement {
|
||||
|
||||
/**
|
||||
* Quotes string using native pgsql function (pg_escape_string).
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
protected function escape($str)
|
||||
{
|
||||
return pg_escape_string($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive function to turn multi-dim array into str representation.
|
||||
* @param array $arr
|
||||
* @return string Array in pgsql-friendly string notation: {val1, val2} or {{sub1,sub2}, {sub3, sub4}}
|
||||
*/
|
||||
private function arrayToStr($arr)
|
||||
{
|
||||
$parts = array();
|
||||
foreach((array)$arr as $el) {
|
||||
if (is_array($el)) {
|
||||
$parts[] = $this->arrayToStr($el);
|
||||
} else {
|
||||
if (is_string($el)) {
|
||||
$parts[] = '"' . $this->escape($el) . '"';
|
||||
} else {
|
||||
$parts[] = $el;
|
||||
}
|
||||
}
|
||||
}
|
||||
return '{' . implode(',', $parts) . '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an array.
|
||||
* Unless a driver-specific method is used, this means simply serializing
|
||||
* the passed parameter and storing it as a string.
|
||||
* @param int $paramIndex
|
||||
* @param array $value
|
||||
* @return void
|
||||
* @see PreparedStatement::setArray()
|
||||
*/
|
||||
function setArray($paramIndex, $value)
|
||||
{
|
||||
if( $paramIndex > $this->positionsCount || $paramIndex < 1) {
|
||||
throw new SQLException('Cannot bind to invalid param index: '.$paramIndex);
|
||||
}
|
||||
if ($value === null)
|
||||
$this->setNull($paramIndex);
|
||||
else
|
||||
$this->boundInVars[$paramIndex] = "'" . $this->arrayToStr($value) . "'";
|
||||
}
|
||||
|
||||
/**
|
||||
* For setting value of Postgres BOOLEAN column.
|
||||
* @param int $paramIndex
|
||||
* @param boolean $value
|
||||
* @return void
|
||||
*/
|
||||
function setBoolean($paramIndex, $value)
|
||||
{
|
||||
if( $paramIndex > $this->positionsCount || $paramIndex < 1) {
|
||||
throw new SQLException('Cannot bind to invalid param index: '.$paramIndex);
|
||||
}
|
||||
if ($value === null)
|
||||
$this->setNull($paramIndex);
|
||||
else
|
||||
$this->boundInVars[$paramIndex] = ($value ? "'t'" : "'f'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies sqlite_udf_encode_binary() to ensure that binary contents will be handled correctly by sqlite.
|
||||
* @param int $paramIndex
|
||||
* @param mixed $blob Blob object or string containing data.
|
||||
* @return void
|
||||
*/
|
||||
function setBlob($paramIndex, $blob)
|
||||
{
|
||||
if ($blob === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
// they took magic __toString() out of PHP5.0.0; this sucks
|
||||
if (is_object($blob)) {
|
||||
$blob = $blob->__toString();
|
||||
}
|
||||
$this->boundInVars[$paramIndex] = "'" . pg_escape_bytea( $blob ) . "'";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
function setTime($paramIndex, $value)
|
||||
{
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
if ( is_numeric ( $value ) ) {
|
||||
$value = date ( "H:i:s O", $value );
|
||||
} elseif ( is_object ( $value ) ) {
|
||||
$value = date ( "H:i:s O", $value->getTime ( ) );
|
||||
}
|
||||
$this->boundInVars [ $paramIndex ] = "'" . $this->escape ( $value ) . "'";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
function setTimestamp($paramIndex, $value)
|
||||
{
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
if (is_numeric($value)) $value = date('Y-m-d H:i:s O', $value);
|
||||
elseif (is_object($value)) $value = date("Y-m-d H:i:s O", $value->getTime());
|
||||
$this->boundInVars[$paramIndex] = "'".$this->escape($value)."'";
|
||||
}
|
||||
}
|
||||
}
|
||||
205
lib/symfony/vendor/creole/drivers/pgsql/PgSQLResultSet.php
vendored
Executable file
205
lib/symfony/vendor/creole/drivers/pgsql/PgSQLResultSet.php
vendored
Executable file
@ -0,0 +1,205 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PgSQLResultSet.php,v 1.31 2006/01/17 19:44:40 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/ResultSet.php';
|
||||
require_once 'creole/common/ResultSetCommon.php';
|
||||
|
||||
/**
|
||||
* PostgreSQL implementation of ResultSet.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.31 $
|
||||
* @package creole.drivers.pgsql
|
||||
*/
|
||||
class PgSQLResultSet extends ResultSetCommon implements ResultSet {
|
||||
|
||||
|
||||
/**
|
||||
* Gets optimized PgSQLResultSetIterator.
|
||||
* @return PgSQLResultSetIterator
|
||||
*/
|
||||
/*
|
||||
public function getIterator()
|
||||
{
|
||||
require_once 'creole/drivers/pgsql/PgSQLResultSetIterator.php';
|
||||
return new PgSQLResultSetIterator($this);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Postgres doesn't actually move the db pointer. The specific row
|
||||
* is fetched by call to pg_fetch_array() rather than by a seek and
|
||||
* then an unspecified pg_fetch_array() call.
|
||||
*
|
||||
* The only side-effect of this situation is that we don't really know
|
||||
* if the seek will fail or succeed until we have called next(). This
|
||||
* behavior is acceptible - and explicitly documented in
|
||||
* ResultSet::seek() phpdoc.
|
||||
*
|
||||
* @see ResultSet::seek()
|
||||
*/
|
||||
public function seek($rownum)
|
||||
{
|
||||
if ($rownum < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// PostgreSQL rows start w/ 0, but this works, because we are
|
||||
// looking to move the position _before_ the next desired position
|
||||
$this->cursorPos = $rownum;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::next()
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
|
||||
$this->fields = @pg_fetch_array($this->result, $this->cursorPos, $this->fetchmode);
|
||||
|
||||
if (!$this->fields) {
|
||||
$err = @pg_result_error($this->result);
|
||||
if (!$err) {
|
||||
// We've advanced beyond end of recordset.
|
||||
$this->afterLast();
|
||||
return false;
|
||||
} else {
|
||||
throw new SQLException("Error fetching result", $err);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->fetchmode === ResultSet::FETCHMODE_ASSOC && $this->lowerAssocCase) {
|
||||
$this->fields = array_change_key_case($this->fields, CASE_LOWER);
|
||||
}
|
||||
// Advance cursor position
|
||||
$this->cursorPos++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getRecordCount()
|
||||
*/
|
||||
public function getRecordCount()
|
||||
{
|
||||
$rows = @pg_num_rows($this->result);
|
||||
if ($rows === null) {
|
||||
throw new SQLException("Error fetching num rows", pg_result_error($this->result));
|
||||
}
|
||||
return (int) $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::close()
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->fields = array();
|
||||
@pg_free_result($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Postgres string representation of array into native PHP array.
|
||||
* @param string $str Postgres string array rep: {1223, 2343} or {{"welcome", "home"}, {"test2", ""}}
|
||||
* @return array
|
||||
*/
|
||||
private function strToArray($str)
|
||||
{
|
||||
$str = substr($str, 1, -1); // remove { }
|
||||
$res = array();
|
||||
|
||||
$subarr = array();
|
||||
$in_subarr = 0;
|
||||
|
||||
$toks = explode(',', $str);
|
||||
foreach($toks as $tok) {
|
||||
if ($in_subarr > 0) { // already in sub-array?
|
||||
$subarr[$in_subarr][] = $tok;
|
||||
if ('}' === substr($tok, -1, 1)) { // check to see if we just added last component
|
||||
$res[] = $this->strToArray(implode(',', $subarr[$in_subarr]));
|
||||
$in_subarr--;
|
||||
}
|
||||
} elseif ($tok{0} === '{') { // we're inside a new sub-array
|
||||
if ('}' !== substr($tok, -1, 1)) {
|
||||
$in_subarr++;
|
||||
// if sub-array has more than one element
|
||||
$subarr[$in_subarr] = array();
|
||||
$subarr[$in_subarr][] = $tok;
|
||||
} else {
|
||||
$res[] = $this->strToArray($tok);
|
||||
}
|
||||
} else { // not sub-array
|
||||
$val = trim($tok, '"'); // remove " (surrounding strings)
|
||||
// perform type castng here?
|
||||
$res[] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a column as an array.
|
||||
* The value of the column is unserialized & returned as an array.
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1.
|
||||
* @return array
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getArray($column)
|
||||
{
|
||||
if (is_int($column)) { $column--; } // because Java convention is to start at 1
|
||||
if (!array_key_exists($column, $this->fields)) { throw new SQLException("Invalid resultset column: " . (is_int($column) ? $column + 1 : $column)); }
|
||||
if ($this->fields[$column] === null) { return null; }
|
||||
return $this->strToArray($this->fields[$column]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Blob with contents of column value.
|
||||
*
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1 (if ResultSet::FETCHMODE_NUM was used).
|
||||
* @return Blob New Blob with data from column.
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getBlob($column)
|
||||
{
|
||||
if (is_int($column)) { $column--; } // because Java convention is to start at 1
|
||||
if (!array_key_exists($column, $this->fields)) { throw new SQLException("Invalid resultset column: " . (is_int($column) ? $column + 1 : $column)); }
|
||||
if ($this->fields[$column] === null) { return null; }
|
||||
require_once 'creole/util/Blob.php';
|
||||
$b = new Blob();
|
||||
$b->setContents(pg_unescape_bytea($this->fields[$column]));
|
||||
return $b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1.
|
||||
* @return boolean
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getBoolean($column)
|
||||
{
|
||||
if (is_int($column)) { $column--; } // because Java convention is to start at 1
|
||||
if (!array_key_exists($column, $this->fields)) { throw new SQLException("Invalid resultset column: " . (is_int($column) ? $column + 1 : $column)); }
|
||||
if ($this->fields[$column] === null) { return null; }
|
||||
return ($this->fields[$column] === 't');
|
||||
}
|
||||
|
||||
}
|
||||
109
lib/symfony/vendor/creole/drivers/pgsql/PgSQLResultSetIterator.php
vendored
Executable file
109
lib/symfony/vendor/creole/drivers/pgsql/PgSQLResultSetIterator.php
vendored
Executable file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PgSQLResultSetIterator.php,v 1.1 2004/12/04 05:58:53 gamr Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Optimized iterator for PostgreSQL, based off of SQLite iterator.
|
||||
* Testing with SeekableIterator, no idea if it will keep this
|
||||
* functionality or what uses it or even how to use it as yet.
|
||||
*
|
||||
* @author Cameron Brunner <webmaster@animetorrents.com>
|
||||
* @version $Revision: 1.1 $
|
||||
* @package creole.drivers.pgsql
|
||||
*/
|
||||
class PgSQLResultSetIterator implements SeekableIterator, Countable {
|
||||
|
||||
private $result;
|
||||
private $pos = 0;
|
||||
private $fetchmode;
|
||||
private $row_count;
|
||||
private $rs;
|
||||
|
||||
/**
|
||||
* Construct the iterator.
|
||||
* @param PgSQLResultSet $rs
|
||||
*/
|
||||
public function __construct(PgSQLResultSet $rs)
|
||||
{
|
||||
$this->result = $rs->getResource();
|
||||
$this->fetchmode = $rs->getFetchmode();
|
||||
$this->row_count = $rs->getRecordCount();
|
||||
$this->rs = $rs; // This is to address reference count bug: http://creole.phpdb.org/trac/ticket/6
|
||||
}
|
||||
|
||||
/**
|
||||
* This method actually has no effect, since we do not rewind ResultSet for iteration.
|
||||
*/
|
||||
function rewind()
|
||||
{
|
||||
$this->pos = 0;
|
||||
}
|
||||
|
||||
function valid()
|
||||
{
|
||||
return ( $this->pos < $this->row_count );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cursor position. Note that this will not necessarily
|
||||
* be 1 for the first row, since no rewind is performed at beginning
|
||||
* of iteration.
|
||||
* @return int
|
||||
*/
|
||||
function key()
|
||||
{
|
||||
return $this->pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the row (assoc array) at current cursor pos.
|
||||
* @return array
|
||||
*/
|
||||
function current()
|
||||
{
|
||||
return pg_fetch_array($this->result, $this->pos, $this->fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances internal cursor pos.
|
||||
*/
|
||||
function next()
|
||||
{
|
||||
$this->pos++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets cursor to specific value.
|
||||
*/
|
||||
function seek ( $index )
|
||||
{
|
||||
if ( ! is_int ( $index ) ) {
|
||||
throw new InvalidArgumentException ( 'Invalid arguement to seek' );
|
||||
}
|
||||
if ( $index < 0 || $index > $this->row_count ) {
|
||||
throw new OutOfBoundsException ( 'Invalid seek position' );
|
||||
}
|
||||
$this->pos = $index;
|
||||
}
|
||||
|
||||
function count ( ) {
|
||||
return $this->row_count;
|
||||
}
|
||||
}
|
||||
34
lib/symfony/vendor/creole/drivers/pgsql/PgSQLStatement.php
vendored
Executable file
34
lib/symfony/vendor/creole/drivers/pgsql/PgSQLStatement.php
vendored
Executable file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PgSQLStatement.php,v 1.1 2004/02/19 02:49:42 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/Statement.php';
|
||||
require_once 'creole/common/StatementCommon.php';
|
||||
|
||||
/**
|
||||
* PostgreSQL Statement implementation.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.1 $
|
||||
* @package creole.drivers.pgsql
|
||||
*/
|
||||
class PgSQLStatement extends StatementCommon implements Statement {
|
||||
|
||||
}
|
||||
101
lib/symfony/vendor/creole/drivers/pgsql/PgSQLTypes.php
vendored
Executable file
101
lib/symfony/vendor/creole/drivers/pgsql/PgSQLTypes.php
vendored
Executable file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* $Id: PgSQLTypes.php,v 1.8 2004/04/09 19:16:05 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/CreoleTypes.php';
|
||||
|
||||
/**
|
||||
* PostgreSQL types / type map.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.8 $
|
||||
* @package creole.drivers.pgsql
|
||||
*/
|
||||
class PgSQLTypes extends CreoleTypes {
|
||||
|
||||
/** Map PostgreSQL native types to Creole (JDBC) types. */
|
||||
private static $typeMap = array (
|
||||
"int2" => CreoleTypes::SMALLINT,
|
||||
"int4" => CreoleTypes::INTEGER,
|
||||
"oid" => CreoleTypes::INTEGER,
|
||||
"int8" => CreoleTypes::BIGINT,
|
||||
"cash" => CreoleTypes::DOUBLE,
|
||||
"money" => CreoleTypes::DOUBLE,
|
||||
"numeric" => CreoleTypes::NUMERIC,
|
||||
"float4" => CreoleTypes::REAL,
|
||||
"float8" => CreoleTypes::DOUBLE,
|
||||
"bpchar" => CreoleTypes::CHAR,
|
||||
"char" => CreoleTypes::CHAR,
|
||||
"char2" => CreoleTypes::CHAR,
|
||||
"char4" => CreoleTypes::CHAR,
|
||||
"char8" => CreoleTypes::CHAR,
|
||||
"char16" => CreoleTypes::CHAR,
|
||||
"varchar" => CreoleTypes::VARCHAR,
|
||||
"text" => CreoleTypes::VARCHAR,
|
||||
"name" => CreoleTypes::VARCHAR,
|
||||
"filename" => CreoleTypes::VARCHAR,
|
||||
"bytea" => CreoleTypes::BINARY,
|
||||
"bool" => CreoleTypes::BOOLEAN,
|
||||
"date" => CreoleTypes::DATE,
|
||||
"time" => CreoleTypes::TIME,
|
||||
"abstime" => CreoleTypes::TIMESTAMP,
|
||||
"timestamp" => CreoleTypes::TIMESTAMP,
|
||||
"timestamptz" => CreoleTypes::TIMESTAMP,
|
||||
"_bool" => CreoleTypes::ARR,
|
||||
"_char" => CreoleTypes::ARR,
|
||||
"_int2" => CreoleTypes::ARR,
|
||||
"_int4" => CreoleTypes::ARR,
|
||||
"_text" => CreoleTypes::ARR,
|
||||
"_oid" => CreoleTypes::ARR,
|
||||
"_varchar" => CreoleTypes::ARR,
|
||||
"_int8" => CreoleTypes::ARR,
|
||||
"_float4" => CreoleTypes::ARR,
|
||||
"_float8" => CreoleTypes::ARR,
|
||||
"_abstime" => CreoleTypes::ARR,
|
||||
"_date" => CreoleTypes::ARR,
|
||||
"_time" => CreoleTypes::ARR,
|
||||
"_timestamp" => CreoleTypes::ARR,
|
||||
"_numeric" => CreoleTypes::ARR,
|
||||
"_bytea" => CreoleTypes::ARR,
|
||||
);
|
||||
|
||||
/** Reverse lookup map, created on demand. */
|
||||
private static $reverseMap = null;
|
||||
|
||||
public static function getType($pgsqlType)
|
||||
{
|
||||
$t = strtolower($pgsqlType);
|
||||
if (isset(self::$typeMap[$t])) {
|
||||
return self::$typeMap[$t];
|
||||
} else {
|
||||
return CreoleTypes::OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getNativeType($creoleType)
|
||||
{
|
||||
if (self::$reverseMap === null) {
|
||||
self::$reverseMap = array_flip(self::$typeMap);
|
||||
}
|
||||
return @self::$reverseMap[$creoleType];
|
||||
}
|
||||
|
||||
}
|
||||
115
lib/symfony/vendor/creole/drivers/pgsql/metadata/PgSQLDatabaseInfo.php
vendored
Executable file
115
lib/symfony/vendor/creole/drivers/pgsql/metadata/PgSQLDatabaseInfo.php
vendored
Executable file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PgSQLDatabaseInfo.php,v 1.11 2006/01/17 19:44:40 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/metadata/DatabaseInfo.php';
|
||||
|
||||
/**
|
||||
* MySQL implementation of DatabaseInfo.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.11 $
|
||||
* @package creole.drivers.pgsql.metadata
|
||||
*/
|
||||
class PgSQLDatabaseInfo extends DatabaseInfo {
|
||||
|
||||
/**
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function initTables()
|
||||
{
|
||||
include_once 'creole/drivers/pgsql/metadata/PgSQLTableInfo.php';
|
||||
|
||||
// Get Database Version
|
||||
// TODO: www.php.net/pg_version
|
||||
$result = pg_query ($this->conn->getResource(), "SELECT version() as ver");
|
||||
|
||||
if (!$result)
|
||||
{
|
||||
throw new SQLException ("Failed to select database version");
|
||||
} // if (!$result)
|
||||
$row = pg_fetch_assoc ($result, 0);
|
||||
$arrVersion = sscanf ($row['ver'], '%*s %d.%d');
|
||||
$version = sprintf ("%d.%d", $arrVersion[0], $arrVersion[1]);
|
||||
// Clean up
|
||||
$arrVersion = null;
|
||||
$row = null;
|
||||
pg_free_result ($result);
|
||||
$result = null;
|
||||
|
||||
$result = pg_query($this->conn->getResource(), "SELECT oid, relname FROM pg_class
|
||||
WHERE relkind = 'r' AND relnamespace = (SELECT oid
|
||||
FROM pg_namespace
|
||||
WHERE
|
||||
nspname NOT IN ('information_schema','pg_catalog')
|
||||
AND nspname NOT LIKE 'pg_temp%'
|
||||
AND nspname NOT LIKE 'pg_toast%'
|
||||
LIMIT 1)
|
||||
ORDER BY relname");
|
||||
|
||||
if (!$result) {
|
||||
throw new SQLException("Could not list tables", pg_last_error($this->dblink));
|
||||
}
|
||||
|
||||
while ($row = pg_fetch_assoc($result)) {
|
||||
$this->tables[strtoupper($row['relname'])] = new PgSQLTableInfo($this, $row['relname'], $version, $row['oid']);
|
||||
}
|
||||
|
||||
$this->tablesLoaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* PgSQL sequences.
|
||||
*
|
||||
* @return void
|
||||
* @throws SQLException
|
||||
*/
|
||||
protected function initSequences()
|
||||
{
|
||||
|
||||
$this->sequences = array();
|
||||
|
||||
$result = pg_query($this->conn->getResource(), "SELECT oid, relname FROM pg_class
|
||||
WHERE relkind = 'S' AND relnamespace = (SELECT oid
|
||||
FROM pg_namespace
|
||||
WHERE
|
||||
nspname NOT IN ('information_schema','pg_catalog')
|
||||
AND nspname NOT LIKE 'pg_temp%'
|
||||
AND nspname NOT LIKE 'pg_toast%'
|
||||
LIMIT 1)
|
||||
ORDER BY relname");
|
||||
|
||||
if (!$result) {
|
||||
throw new SQLException("Could not list sequences", pg_last_error($this->dblink));
|
||||
}
|
||||
|
||||
while ($row = pg_fetch_assoc($result)) {
|
||||
// FIXME -- decide what info we need for sequences & then create a SequenceInfo object (if needed)
|
||||
$obj = new stdClass;
|
||||
$obj->name = $row['relname'];
|
||||
$obj->oid = $row['oid'];
|
||||
$this->sequences[strtoupper($row['relname'])] = $obj;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
423
lib/symfony/vendor/creole/drivers/pgsql/metadata/PgSQLTableInfo.php
vendored
Executable file
423
lib/symfony/vendor/creole/drivers/pgsql/metadata/PgSQLTableInfo.php
vendored
Executable file
@ -0,0 +1,423 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PgSQLTableInfo.php,v 1.31 2006/01/17 19:44:40 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/metadata/TableInfo.php';
|
||||
|
||||
/**
|
||||
* PgSQL implementation of TableInfo.
|
||||
*
|
||||
* See this Python code by David M. Cook for some good reference on Pgsql metadata
|
||||
* functions:
|
||||
* @link http://www.sandpyt.org/pipermail/sandpyt/2003-March/000008.html
|
||||
*
|
||||
* Here's some more information from postgresql:
|
||||
* @link http://developer.postgresql.org/docs/pgsql/src/backend/catalog/information_schema.sql
|
||||
*
|
||||
* @todo -c Eventually move to supporting only Postgres >= 7.4, which has the information_schema
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.31 $
|
||||
* @package creole.drivers.pgsql.metadata
|
||||
*/
|
||||
class PgSQLTableInfo extends TableInfo {
|
||||
|
||||
/**
|
||||
* Database Version.
|
||||
* @var String
|
||||
*/
|
||||
private $version;
|
||||
|
||||
/**
|
||||
* Table OID
|
||||
* @var Integer
|
||||
*/
|
||||
private $oid;
|
||||
|
||||
/**
|
||||
* @param string $table The table name.
|
||||
* @param string $database The database name.
|
||||
* @param resource $dblink The db connection resource.
|
||||
*/
|
||||
function __construct(DatabaseInfo $database, $name, $version, $intOID) {
|
||||
parent::__construct ($database, $name);
|
||||
$this->version = $version;
|
||||
$this->oid = $intOID;
|
||||
} // function __construct(DatabaseInfo $database, $name) {
|
||||
|
||||
/** Load the columns for this table */
|
||||
protected function initColumns () {
|
||||
// Include dependencies
|
||||
include_once ('creole/metadata/ColumnInfo.php');
|
||||
include_once ('creole/drivers/pgsql/PgSQLTypes.php');
|
||||
|
||||
// Get the columns, types, etc.
|
||||
// Based on code from pgAdmin3 (http://www.pgadmin.org/)
|
||||
$result = pg_query ($this->conn->getResource(), sprintf ("SELECT
|
||||
att.attname,
|
||||
att.atttypmod,
|
||||
att.atthasdef,
|
||||
att.attnotnull,
|
||||
def.adsrc,
|
||||
CASE WHEN att.attndims > 0 THEN 1 ELSE 0 END AS isarray,
|
||||
CASE
|
||||
WHEN ty.typname = 'bpchar'
|
||||
THEN 'char'
|
||||
WHEN ty.typname = '_bpchar'
|
||||
THEN '_char'
|
||||
ELSE
|
||||
ty.typname
|
||||
END AS typname,
|
||||
ty.typtype
|
||||
FROM pg_attribute att
|
||||
JOIN pg_type ty ON ty.oid=att.atttypid
|
||||
LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum
|
||||
WHERE att.attrelid = %d AND att.attnum > 0
|
||||
AND att.attisdropped IS FALSE
|
||||
ORDER BY att.attnum", $this->oid));
|
||||
|
||||
if (!$result) {
|
||||
throw new SQLException("Could not list fields for table: " . $this->name, pg_last_error($this->conn->getResource()));
|
||||
}
|
||||
while($row = pg_fetch_assoc($result)) {
|
||||
|
||||
$size = null;
|
||||
$precision = null;
|
||||
$scale = null;
|
||||
|
||||
// Check to ensure that this column isn't an array data type
|
||||
if (((int) $row['isarray']) === 1)
|
||||
{
|
||||
throw new SQLException (sprintf ("Array datatypes are not currently supported [%s.%s]", $this->name, $row['attname']));
|
||||
} // if (((int) $row['isarray']) === 1)
|
||||
$name = $row['attname'];
|
||||
// If they type is a domain, Process it
|
||||
if (strtolower ($row['typtype']) == 'd')
|
||||
{
|
||||
$arrDomain = $this->processDomain ($row['typname']);
|
||||
$type = $arrDomain['type'];
|
||||
$size = $arrDomain['length'];
|
||||
$precision = $size;
|
||||
$scale = $arrDomain['scale'];
|
||||
$boolHasDefault = (strlen (trim ($row['atthasdef'])) > 0) ? $row['atthasdef'] : $arrDomain['hasdefault'];
|
||||
$default = (strlen (trim ($row['adsrc'])) > 0) ? $row['adsrc'] : $arrDomain['default'];
|
||||
$is_nullable = (strlen (trim ($row['attnotnull'])) > 0) ? $row['attnotnull'] : $arrDomain['notnull'];
|
||||
$is_nullable = (($is_nullable == 't') ? false : true);
|
||||
} // if (strtolower ($row['typtype']) == 'd')
|
||||
else
|
||||
{
|
||||
$type = $row['typname'];
|
||||
$arrLengthPrecision = $this->processLengthScale ($row['atttypmod'], $type);
|
||||
$size = $arrLengthPrecision['length'];
|
||||
$precision = $size;
|
||||
$scale = $arrLengthPrecision['scale'];
|
||||
$boolHasDefault = $row['atthasdef'];
|
||||
$default = $row['adsrc'];
|
||||
$is_nullable = (($row['attnotnull'] == 't') ? false : true);
|
||||
} // else (strtolower ($row['typtype']) == 'd')
|
||||
|
||||
$autoincrement = null;
|
||||
|
||||
// if column has a default
|
||||
if (($boolHasDefault == 't') && (strlen (trim ($default)) > 0))
|
||||
{
|
||||
if (!preg_match('/^nextval\(/', $default))
|
||||
{
|
||||
$strDefault= preg_replace ('/::[\W\D]*/', '', $default);
|
||||
$default = str_replace ("'", '', $strDefault);
|
||||
} // if (!preg_match('/^nextval\(/', $row['atthasdef']))
|
||||
else
|
||||
{
|
||||
$autoincrement = true;
|
||||
$default = null;
|
||||
} // else
|
||||
} // if (($boolHasDefault == 't') && (strlen (trim ($default)) > 0))
|
||||
else
|
||||
{
|
||||
$default = null;
|
||||
} // else (($boolHasDefault == 't') && (strlen (trim ($default)) > 0))
|
||||
|
||||
$this->columns[$name] = new ColumnInfo($this, $name, PgSQLTypes::getType($type), $type, $size, $precision, $scale, $is_nullable, $default, $autoincrement);
|
||||
}
|
||||
|
||||
$this->colsLoaded = true;
|
||||
} // protected function initColumns ()
|
||||
|
||||
private function processLengthScale ($intTypmod, $strName)
|
||||
{
|
||||
// Define the return array
|
||||
$arrRetVal = array ('length'=>null, 'scale'=>null);
|
||||
|
||||
// Some datatypes don't have a Typmod
|
||||
if ($intTypmod == -1)
|
||||
{
|
||||
return $arrRetVal;
|
||||
} // if ($intTypmod == -1)
|
||||
|
||||
// Numeric Datatype?
|
||||
if ($strName == PgSQLTypes::getNativeType (CreoleTypes::NUMERIC))
|
||||
{
|
||||
$intLen = ($intTypmod - 4) >> 16;
|
||||
$intPrec = ($intTypmod - 4) & 0xffff;
|
||||
$intLen = sprintf ("%ld", $intLen);
|
||||
if ($intPrec)
|
||||
{
|
||||
$intPrec = sprintf ("%ld", $intPrec);
|
||||
} // if ($intPrec)
|
||||
$arrRetVal['length'] = $intLen;
|
||||
$arrRetVal['scale'] = $intPrec;
|
||||
} // if ($strName == PgSQLTypes::getNativeType (CreoleTypes::NUMERIC))
|
||||
elseif ($strName == PgSQLTypes::getNativeType (CreoleTypes::TIME) || $strName == 'timetz'
|
||||
|| $strName == PgSQLTypes::getNativeType (CreoleTypes::TIMESTAMP) || $strName == 'timestamptz'
|
||||
|| $strName == 'interval' || $strName == 'bit')
|
||||
{
|
||||
$arrRetVal['length'] = sprintf ("%ld", $intTypmod);
|
||||
} // elseif (TIME, TIMESTAMP, INTERVAL, BIT)
|
||||
else
|
||||
{
|
||||
$arrRetVal['length'] = sprintf ("%ld", ($intTypmod - 4));
|
||||
} // else
|
||||
return $arrRetVal;
|
||||
} // private function processLengthScale ($intTypmod, $strName)
|
||||
|
||||
private function processDomain ($strDomain)
|
||||
{
|
||||
if (strlen (trim ($strDomain)) < 1)
|
||||
{
|
||||
throw new SQLException ("Invalid domain name [" . $strDomain . "]");
|
||||
} // if (strlen (trim ($strDomain)) < 1)
|
||||
$result = pg_query ($this->conn->getResource(), sprintf ("SELECT
|
||||
d.typname as domname,
|
||||
b.typname as basetype,
|
||||
d.typlen,
|
||||
d.typtypmod,
|
||||
d.typnotnull,
|
||||
d.typdefault
|
||||
FROM pg_type d
|
||||
INNER JOIN pg_type b ON b.oid = CASE WHEN d.typndims > 0 then d.typelem ELSE d.typbasetype END
|
||||
WHERE
|
||||
d.typtype = 'd'
|
||||
AND d.typname = '%s'
|
||||
ORDER BY d.typname", $strDomain));
|
||||
|
||||
if (!$result) {
|
||||
throw new SQLException("Query for domain [" . $strDomain . "] failed.", pg_last_error($this->conn->getResource()));
|
||||
}
|
||||
|
||||
$row = pg_fetch_assoc ($result);
|
||||
if (!$row)
|
||||
{
|
||||
throw new SQLException ("Domain [" . $strDomain . "] not found.");
|
||||
} // if (!$row)
|
||||
$arrDomain = array ();
|
||||
$arrDomain['type'] = $row['basetype'];
|
||||
$arrLengthPrecision = $this->processLengthScale ($row['typtypmod'], $row['basetype']);
|
||||
$arrDomain['length'] = $arrLengthPrecision['length'];
|
||||
$arrDomain['scale'] = $arrLengthPrecision['scale'];
|
||||
$arrDomain['notnull'] = $row['typnotnull'];
|
||||
$arrDomain['default'] = $row['typdefault'];
|
||||
$arrDomain['hasdefault'] = (strlen (trim ($row['typdefault'])) > 0) ? 't' : 'f';
|
||||
|
||||
pg_free_result ($result);
|
||||
return $arrDomain;
|
||||
} // private function processDomain ($strDomain)
|
||||
|
||||
/** Load foreign keys for this table. */
|
||||
protected function initForeignKeys()
|
||||
{
|
||||
include_once 'creole/metadata/ForeignKeyInfo.php';
|
||||
|
||||
$result = pg_query ($this->conn->getResource(), sprintf ("SELECT
|
||||
conname,
|
||||
confupdtype,
|
||||
confdeltype,
|
||||
cl.relname as fktab,
|
||||
a2.attname as fkcol,
|
||||
cr.relname as reftab,
|
||||
a1.attname as refcol
|
||||
FROM pg_constraint ct
|
||||
JOIN pg_class cl ON cl.oid=conrelid
|
||||
JOIN pg_class cr ON cr.oid=confrelid
|
||||
LEFT JOIN pg_catalog.pg_attribute a1 ON a1.attrelid = ct.confrelid
|
||||
LEFT JOIN pg_catalog.pg_attribute a2 ON a2.attrelid = ct.conrelid
|
||||
WHERE
|
||||
contype='f'
|
||||
AND conrelid = %d
|
||||
AND a2.attnum = ct.conkey[1]
|
||||
AND a1.attnum = ct.confkey[1]
|
||||
ORDER BY conname", $this->oid));
|
||||
if (!$result) {
|
||||
throw new SQLException("Could not list foreign keys for table: " . $this->name, pg_last_error($this->conn->getResource()));
|
||||
}
|
||||
|
||||
while($row = pg_fetch_assoc($result)) {
|
||||
$name = $row['conname'];
|
||||
$local_table = $row['fktab'];
|
||||
$local_column = $row['fkcol'];
|
||||
$foreign_table = $row['reftab'];
|
||||
$foreign_column = $row['refcol'];
|
||||
|
||||
// On Update
|
||||
switch ($row['confupdtype']) {
|
||||
case 'c':
|
||||
$onupdate = ForeignKeyInfo::CASCADE; break;
|
||||
case 'd':
|
||||
$onupdate = ForeignKeyInfo::SETDEFAULT; break;
|
||||
case 'n':
|
||||
$onupdate = ForeignKeyInfo::SETNULL; break;
|
||||
case 'r':
|
||||
$onupdate = ForeignKeyInfo::RESTRICT; break;
|
||||
default:
|
||||
case 'a':
|
||||
//NOACTION is the postgresql default
|
||||
$onupdate = ForeignKeyInfo::NONE; break;
|
||||
}
|
||||
// On Delete
|
||||
switch ($row['confdeltype']) {
|
||||
case 'c':
|
||||
$ondelete = ForeignKeyInfo::CASCADE; break;
|
||||
case 'd':
|
||||
$ondelete = ForeignKeyInfo::SETDEFAULT; break;
|
||||
case 'n':
|
||||
$ondelete = ForeignKeyInfo::SETNULL; break;
|
||||
case 'r':
|
||||
$ondelete = ForeignKeyInfo::RESTRICT; break;
|
||||
default:
|
||||
case 'a':
|
||||
//NOACTION is the postgresql default
|
||||
$ondelete = ForeignKeyInfo::NONE; break;
|
||||
}
|
||||
|
||||
|
||||
$foreignTable = $this->database->getTable($foreign_table);
|
||||
$foreignColumn = $foreignTable->getColumn($foreign_column);
|
||||
|
||||
$localTable = $this->database->getTable($local_table);
|
||||
$localColumn = $localTable->getColumn($local_column);
|
||||
|
||||
if (!isset($this->foreignKeys[$name])) {
|
||||
$this->foreignKeys[$name] = new ForeignKeyInfo($name);
|
||||
}
|
||||
$this->foreignKeys[$name]->addReference($localColumn, $foreignColumn, $ondelete, $onupdate);
|
||||
}
|
||||
|
||||
$this->fksLoaded = true;
|
||||
}
|
||||
|
||||
/** Load indexes for this table */
|
||||
protected function initIndexes()
|
||||
{
|
||||
include_once 'creole/metadata/IndexInfo.php';
|
||||
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
|
||||
$result = pg_query ($this->conn->getResource(), sprintf ("SELECT
|
||||
DISTINCT ON(cls.relname)
|
||||
cls.relname as idxname,
|
||||
indkey,
|
||||
indisunique
|
||||
FROM pg_index idx
|
||||
JOIN pg_class cls ON cls.oid=indexrelid
|
||||
WHERE indrelid = %d AND NOT indisprimary
|
||||
ORDER BY cls.relname", $this->oid));
|
||||
|
||||
|
||||
if (!$result) {
|
||||
throw new SQLException("Could not list indexes keys for table: " . $this->name, pg_last_error($this->conn->getResource()));
|
||||
}
|
||||
|
||||
while($row = pg_fetch_assoc($result)) {
|
||||
$name = $row["idxname"];
|
||||
$unique = ($row["indisunique"] == 't') ? true : false;
|
||||
if (!isset($this->indexes[$name])) {
|
||||
$this->indexes[$name] = new IndexInfo($name, $unique);
|
||||
}
|
||||
$arrColumns = explode (' ', $row['indkey']);
|
||||
foreach ($arrColumns as $intColNum)
|
||||
{
|
||||
$result2 = pg_query ($this->conn->getResource(), sprintf ("SELECT a.attname
|
||||
FROM pg_catalog.pg_class c JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid
|
||||
WHERE c.oid = '%s' AND a.attnum = %d AND NOT a.attisdropped
|
||||
ORDER BY a.attnum", $this->oid, $intColNum));
|
||||
if (!$result2)
|
||||
{
|
||||
throw new SQLException("Could not list indexes keys for table: " . $this->name, pg_last_error($this->conn->getResource()));
|
||||
}
|
||||
$row2 = pg_fetch_assoc($result2);
|
||||
$this->indexes[$name]->addColumn($this->columns[ $row2['attname'] ]);
|
||||
} // foreach ($arrColumns as $intColNum)
|
||||
}
|
||||
|
||||
$this->indexesLoaded = true;
|
||||
}
|
||||
|
||||
/** Loads the primary keys for this table. */
|
||||
protected function initPrimaryKey() {
|
||||
|
||||
include_once 'creole/metadata/PrimaryKeyInfo.php';
|
||||
|
||||
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
|
||||
// Primary Keys
|
||||
|
||||
$result = pg_query($this->conn->getResource(), sprintf ("SELECT
|
||||
DISTINCT ON(cls.relname)
|
||||
cls.relname as idxname,
|
||||
indkey,
|
||||
indisunique
|
||||
FROM pg_index idx
|
||||
JOIN pg_class cls ON cls.oid=indexrelid
|
||||
WHERE indrelid = %s AND indisprimary
|
||||
ORDER BY cls.relname", $this->oid));
|
||||
if (!$result) {
|
||||
throw new SQLException("Could not list primary keys for table: " . $this->name, pg_last_error($this->conn->getResource()));
|
||||
}
|
||||
|
||||
// Loop through the returned results, grouping the same key_name together
|
||||
// adding each column for that key.
|
||||
|
||||
while($row = pg_fetch_assoc($result)) {
|
||||
$arrColumns = explode (' ', $row['indkey']);
|
||||
foreach ($arrColumns as $intColNum)
|
||||
{
|
||||
$result2 = pg_query ($this->conn->getResource(), sprintf ("SELECT a.attname
|
||||
FROM pg_catalog.pg_class c JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid
|
||||
WHERE c.oid = '%s' AND a.attnum = %d AND NOT a.attisdropped
|
||||
ORDER BY a.attnum", $this->oid, $intColNum));
|
||||
if (!$result2)
|
||||
{
|
||||
throw new SQLException("Could not list indexes keys for table: " . $this->name, pg_last_error($this->conn->getResource()));
|
||||
}
|
||||
$row2 = pg_fetch_assoc($result2);
|
||||
if (!isset($this->primaryKey)) {
|
||||
$this->primaryKey = new PrimaryKeyInfo($row2['attname']);
|
||||
}
|
||||
$this->primaryKey->addColumn($this->columns[ $row2['attname'] ]);
|
||||
} // foreach ($arrColumns as $intColNum)
|
||||
}
|
||||
$this->pkLoaded = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
245
lib/symfony/vendor/creole/drivers/sqlite/SQLiteConnection.php
vendored
Executable file
245
lib/symfony/vendor/creole/drivers/sqlite/SQLiteConnection.php
vendored
Executable file
@ -0,0 +1,245 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: SQLiteConnection.php,v 1.15 2006/01/17 19:44:41 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/Connection.php';
|
||||
require_once 'creole/common/ConnectionCommon.php';
|
||||
|
||||
/**
|
||||
* SQLite implementation of Connection.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @author Stig Bakken <ssb@fast.no>
|
||||
* @author Lukas Smith
|
||||
* @version $Revision: 1.15 $
|
||||
* @package creole.drivers.sqlite
|
||||
*/
|
||||
class SQLiteConnection extends ConnectionCommon implements Connection {
|
||||
|
||||
/**
|
||||
* The case to use for SQLite results.
|
||||
* (0=nochange, 1=upper, 2=lower)
|
||||
* This is set in each call to executeQuery() in order to ensure that different
|
||||
* Connections do not overwrite each other's settings
|
||||
*/
|
||||
private $sqliteAssocCase;
|
||||
|
||||
/**
|
||||
* @see Connection::connect()
|
||||
*/
|
||||
function connect($dsninfo, $flags = 0)
|
||||
{
|
||||
if (!extension_loaded('sqlite')) {
|
||||
throw new SQLException('sqlite extension not loaded');
|
||||
}
|
||||
|
||||
$file = $dsninfo['database'];
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$this->flags = $flags;
|
||||
|
||||
$persistent = ($flags & Creole::PERSISTENT === Creole::PERSISTENT);
|
||||
|
||||
if (PHP_VERSION == '5.0.4' || PHP_VERSION == '5.0.5') {
|
||||
$nochange = TRUE;
|
||||
} else {
|
||||
$nochange = !(($flags & Creole::COMPAT_ASSOC_LOWER) === Creole::COMPAT_ASSOC_LOWER);
|
||||
}
|
||||
|
||||
if ($nochange) {
|
||||
$this->sqliteAssocCase = 0;
|
||||
} else {
|
||||
$this->sqliteAssocCase = 2;
|
||||
}
|
||||
|
||||
if ($file === null) {
|
||||
throw new SQLException("No SQLite database specified.");
|
||||
}
|
||||
|
||||
$mode = (isset($dsninfo['mode']) && is_numeric($dsninfo['mode'])) ? $dsninfo['mode'] : 0644;
|
||||
|
||||
if ($file != ':memory:') {
|
||||
if (!file_exists($file)) {
|
||||
touch($file);
|
||||
chmod($file, $mode);
|
||||
if (!file_exists($file)) {
|
||||
throw new SQLException("Unable to create SQLite database.");
|
||||
}
|
||||
}
|
||||
if (!is_file($file)) {
|
||||
throw new SQLException("Unable to open SQLite database: not a valid file.");
|
||||
}
|
||||
if (!is_readable($file)) {
|
||||
throw new SQLException("Unable to read SQLite database.");
|
||||
}
|
||||
}
|
||||
|
||||
$connect_function = $persistent ? 'sqlite_popen' : 'sqlite_open';
|
||||
if (!($conn = @$connect_function($file, $mode, $errmsg) )) {
|
||||
throw new SQLException("Unable to connect to SQLite database", $errmsg);
|
||||
}
|
||||
|
||||
$this->dblink = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getDatabaseInfo()
|
||||
*/
|
||||
public function getDatabaseInfo()
|
||||
{
|
||||
require_once 'creole/drivers/sqlite/metadata/SQLiteDatabaseInfo.php';
|
||||
return new SQLiteDatabaseInfo($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getIdGenerator()
|
||||
*/
|
||||
public function getIdGenerator()
|
||||
{
|
||||
require_once 'creole/drivers/sqlite/SQLiteIdGenerator.php';
|
||||
return new SQLiteIdGenerator($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareStatement()
|
||||
*/
|
||||
public function prepareStatement($sql)
|
||||
{
|
||||
require_once 'creole/drivers/sqlite/SQLitePreparedStatement.php';
|
||||
return new SQLitePreparedStatement($this, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareCall()
|
||||
*/
|
||||
public function prepareCall($sql) {
|
||||
throw new SQLException('SQLite does not support stored procedures using CallableStatement.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::createStatement()
|
||||
*/
|
||||
public function createStatement()
|
||||
{
|
||||
require_once 'creole/drivers/sqlite/SQLiteStatement.php';
|
||||
return new SQLiteStatement($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::close()
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
$ret = @sqlite_close($this->dblink);
|
||||
$this->dblink = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::applyLimit()
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
if ( $limit > 0 ) {
|
||||
$sql .= " LIMIT " . $limit . ($offset > 0 ? " OFFSET " . $offset : "");
|
||||
} elseif ( $offset > 0 ) {
|
||||
$sql .= " LIMIT -1 OFFSET " . $offset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::executeQuery()
|
||||
*/
|
||||
public function executeQuery($sql, $fetchmode = null)
|
||||
{
|
||||
ini_set('sqlite.assoc_case', $this->sqliteAssocCase);
|
||||
$this->lastQuery = $sql;
|
||||
$result = @sqlite_query($this->dblink, $this->lastQuery);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not execute query', $php_errormsg, $this->lastQuery); //sqlite_error_string(sqlite_last_error($this->dblink))
|
||||
}
|
||||
require_once 'creole/drivers/sqlite/SQLiteResultSet.php';
|
||||
return new SQLiteResultSet($this, $result, $fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::executeUpdate()
|
||||
*/
|
||||
function executeUpdate($sql)
|
||||
{
|
||||
$this->lastQuery = $sql;
|
||||
$result = @sqlite_query($this->dblink, $this->lastQuery);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not execute update', $php_errormsg, $this->lastQuery); //sqlite_error_string(sqlite_last_error($this->dblink))
|
||||
}
|
||||
return (int) @sqlite_changes($this->dblink);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a database transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function beginTrans()
|
||||
{
|
||||
$result = @sqlite_query($this->dblink, 'BEGIN');
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not begin transaction', $php_errormsg); //sqlite_error_string(sqlite_last_error($this->dblink))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function commitTrans()
|
||||
{
|
||||
$result = @sqlite_query($this->dblink, 'COMMIT');
|
||||
if (!$result) {
|
||||
throw new SQLException('Can not commit transaction', $php_errormsg); // sqlite_error_string(sqlite_last_error($this->dblink))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll back (undo) the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function rollbackTrans()
|
||||
{
|
||||
$result = @sqlite_query($this->dblink, 'ROLLBACK');
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not rollback transaction', $php_errormsg); // sqlite_error_string(sqlite_last_error($this->dblink))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the data manipulation
|
||||
* query.
|
||||
*
|
||||
* @return int Number of rows affected by the last query.
|
||||
*/
|
||||
function getUpdateCount()
|
||||
{
|
||||
return (int) @sqlite_changes($this->dblink);
|
||||
}
|
||||
|
||||
}
|
||||
60
lib/symfony/vendor/creole/drivers/sqlite/SQLiteIdGenerator.php
vendored
Executable file
60
lib/symfony/vendor/creole/drivers/sqlite/SQLiteIdGenerator.php
vendored
Executable file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
require_once 'creole/IdGenerator.php';
|
||||
|
||||
/**
|
||||
* SQLite IdGenerator implimenation.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.4 $
|
||||
* @package creole.drivers.sqlite
|
||||
*/
|
||||
class SQLiteIdGenerator implements IdGenerator {
|
||||
|
||||
/** Connection object that instantiated this class */
|
||||
private $conn;
|
||||
|
||||
/**
|
||||
* Creates a new IdGenerator class, saves passed connection for use
|
||||
* later by getId() method.
|
||||
* @param Connection $conn
|
||||
*/
|
||||
public function __construct(Connection $conn)
|
||||
{
|
||||
$this->conn = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::isBeforeInsert()
|
||||
*/
|
||||
public function isBeforeInsert()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::isAfterInsert()
|
||||
*/
|
||||
public function isAfterInsert()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::getIdMethod()
|
||||
*/
|
||||
public function getIdMethod()
|
||||
{
|
||||
return self::AUTOINCREMENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::getId()
|
||||
*/
|
||||
public function getId($unused = null)
|
||||
{
|
||||
return sqlite_last_insert_rowid($this->conn->getResource());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
61
lib/symfony/vendor/creole/drivers/sqlite/SQLitePreparedStatement.php
vendored
Executable file
61
lib/symfony/vendor/creole/drivers/sqlite/SQLitePreparedStatement.php
vendored
Executable file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: SQLitePreparedStatement.php,v 1.7 2004/03/20 04:16:50 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/PreparedStatement.php';
|
||||
require_once 'creole/common/PreparedStatementCommon.php';
|
||||
|
||||
/**
|
||||
* MySQL subclass for prepared statements.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.7 $
|
||||
* @package creole.drivers.sqlite
|
||||
*/
|
||||
class SQLitePreparedStatement extends PreparedStatementCommon implements PreparedStatement {
|
||||
|
||||
/**
|
||||
* Quotes string using native sqlite_escape_string() function.
|
||||
* @see ResultSetCommon::escape()
|
||||
*/
|
||||
protected function escape($str)
|
||||
{
|
||||
return sqlite_escape_string($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies sqlite_udf_encode_binary() to ensure that binary contents will be handled correctly by sqlite.
|
||||
* @see PreparedStatement::setBlob()
|
||||
* @see ResultSet::getBlob()
|
||||
*/
|
||||
function setBlob($paramIndex, $blob)
|
||||
{
|
||||
if ($blob === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
// they took magic __toString() out of PHP5.0.0; this sucks
|
||||
if (is_object($blob)) {
|
||||
$blob = $blob->__toString();
|
||||
}
|
||||
$this->boundInVars[$paramIndex] = "'" . sqlite_udf_encode_binary( $blob ) . "'";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
120
lib/symfony/vendor/creole/drivers/sqlite/SQLiteResultSet.php
vendored
Executable file
120
lib/symfony/vendor/creole/drivers/sqlite/SQLiteResultSet.php
vendored
Executable file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: SQLiteResultSet.php,v 1.9 2004/11/29 13:41:24 micha Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/ResultSet.php';
|
||||
require_once 'creole/common/ResultSetCommon.php';
|
||||
|
||||
/**
|
||||
* SQLite implementation of ResultSet class.
|
||||
*
|
||||
* SQLite supports OFFSET / LIMIT natively; this means that no adjustments or checking
|
||||
* are performed. We will assume that if the lmitSQL() operation failed that an
|
||||
* exception was thrown, and that OFFSET/LIMIT will never be emulated for SQLite.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.9 $
|
||||
* @package creole.drivers.sqlite
|
||||
*/
|
||||
class SQLiteResultSet extends ResultSetCommon implements ResultSet {
|
||||
|
||||
/**
|
||||
* Gets optimized SQLiteResultSetIterator.
|
||||
* @return SQLiteResultSetIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
require_once 'creole/drivers/sqlite/SQLiteResultSetIterator.php';
|
||||
return new SQLiteResultSetIterator($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::seek()
|
||||
*/
|
||||
public function seek($rownum)
|
||||
{
|
||||
// MySQL rows start w/ 0, but this works, because we are
|
||||
// looking to move the position _before_ the next desired position
|
||||
if (!@sqlite_seek($this->result, $rownum)) {
|
||||
return false;
|
||||
}
|
||||
$this->cursorPos = $rownum;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::next()
|
||||
*/
|
||||
function next()
|
||||
{
|
||||
$this->fields = sqlite_fetch_array($this->result, $this->fetchmode); // (ResultSet::FETCHMODE_NUM = SQLITE_NUM, etc.)
|
||||
if (!$this->fields) {
|
||||
$errno = sqlite_last_error($this->conn->getResource());
|
||||
if (!$errno) {
|
||||
// We've advanced beyond end of recordset.
|
||||
$this->afterLast();
|
||||
return false;
|
||||
} else {
|
||||
throw new SQLException("Error fetching result", sqlite_error_string($errno));
|
||||
}
|
||||
}
|
||||
|
||||
// Advance cursor position
|
||||
$this->cursorPos++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getRecordCount()
|
||||
*/
|
||||
public function getRecordCount()
|
||||
{
|
||||
$rows = @sqlite_num_rows($this->result);
|
||||
if ($rows === null) {
|
||||
throw new SQLException("Error fetching num rows", sqlite_error_string(sqlite_last_error($this->conn->getResource())));
|
||||
}
|
||||
return (int) $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs sqlite_udf_decode_binary on binary data.
|
||||
* @see ResultSet::getBlob()
|
||||
*/
|
||||
public function getBlob($column)
|
||||
{
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
if ($this->fields[$idx] === null) { return null; }
|
||||
require_once 'creole/util/Blob.php';
|
||||
$b = new Blob();
|
||||
$b->setContents(sqlite_udf_decode_binary($this->fields[$idx]));
|
||||
return $b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply empties array as there is no result free method for sqlite.
|
||||
* @see ResultSet::close()
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->fields = array();
|
||||
$this->result = null;
|
||||
}
|
||||
}
|
||||
88
lib/symfony/vendor/creole/drivers/sqlite/SQLiteResultSetIterator.php
vendored
Executable file
88
lib/symfony/vendor/creole/drivers/sqlite/SQLiteResultSetIterator.php
vendored
Executable file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: SQLiteResultSetIterator.php,v 1.6 2004/12/03 16:57:54 gamr Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Optimized iterator for SQLite.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.6 $
|
||||
* @package creole.drivers.sqlite
|
||||
*/
|
||||
class SQLiteResultSetIterator implements Iterator {
|
||||
|
||||
private $result;
|
||||
private $pos = 0;
|
||||
private $fetchmode;
|
||||
private $row_count;
|
||||
|
||||
/**
|
||||
* Construct the iterator.
|
||||
* @param SQLiteResultSet $rs
|
||||
*/
|
||||
public function __construct(SQLiteResultSet $rs)
|
||||
{
|
||||
$this->result = $rs->getResource();
|
||||
$this->fetchmode = $rs->getFetchmode();
|
||||
$this->row_count = $rs->getRecordCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method actually has no effect, since we do not rewind ResultSet for iteration.
|
||||
*/
|
||||
function rewind()
|
||||
{
|
||||
sqlite_rewind($this->result);
|
||||
}
|
||||
|
||||
function valid()
|
||||
{
|
||||
return ( $this->pos < $this->row_count );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cursor position. Note that this will not necessarily
|
||||
* be 1 for the first row, since no rewind is performed at beginning
|
||||
* of iteration.
|
||||
* @return int
|
||||
*/
|
||||
function key()
|
||||
{
|
||||
return $this->pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the row (assoc array) at current cursor pos.
|
||||
* @return array
|
||||
*/
|
||||
function current()
|
||||
{
|
||||
return sqlite_fetch_array($this->result, $this->fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances internal cursor pos.
|
||||
*/
|
||||
function next()
|
||||
{
|
||||
$this->pos++;
|
||||
}
|
||||
|
||||
}
|
||||
34
lib/symfony/vendor/creole/drivers/sqlite/SQLiteStatement.php
vendored
Executable file
34
lib/symfony/vendor/creole/drivers/sqlite/SQLiteStatement.php
vendored
Executable file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: SQLiteStatement.php,v 1.1 2004/02/19 02:49:43 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/Statement.php';
|
||||
require_once 'creole/common/StatementCommon.php';
|
||||
|
||||
/**
|
||||
* SQLite Statement
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.1 $
|
||||
* @package creole.drivers.sqlite
|
||||
*/
|
||||
class SQLiteStatement extends StatementCommon implements Statement {
|
||||
|
||||
}
|
||||
108
lib/symfony/vendor/creole/drivers/sqlite/SQLiteTypes.php
vendored
Executable file
108
lib/symfony/vendor/creole/drivers/sqlite/SQLiteTypes.php
vendored
Executable file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* $Id: SQLiteTypes.php,v 1.3 2004/03/20 04:16:50 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/CreoleTypes.php';
|
||||
|
||||
/**
|
||||
* MySQL types / type map.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.3 $
|
||||
* @package creole.drivers.sqlite
|
||||
*/
|
||||
class SQLiteTypes extends CreoleTypes {
|
||||
|
||||
/**
|
||||
* Map some fake SQLite types CreoleTypes.
|
||||
* SQLite is typeless so this is really only for "hint" / readability
|
||||
* purposes.
|
||||
* @var array
|
||||
*/
|
||||
private static $typeMap = array(
|
||||
'tinyint' => CreoleTypes::TINYINT,
|
||||
'smallint' => CreoleTypes::SMALLINT,
|
||||
'mediumint' => CreoleTypes::SMALLINT,
|
||||
'int' => CreoleTypes::INTEGER,
|
||||
'integer' => CreoleTypes::INTEGER,
|
||||
'bigint' => CreoleTypes::BIGINT,
|
||||
'int24' => CreoleTypes::BIGINT,
|
||||
'real' => CreoleTypes::REAL,
|
||||
'float' => CreoleTypes::FLOAT,
|
||||
'decimal' => CreoleTypes::DECIMAL,
|
||||
'numeric' => CreoleTypes::NUMERIC,
|
||||
'double' => CreoleTypes::DOUBLE,
|
||||
'char' => CreoleTypes::CHAR,
|
||||
'varchar' => CreoleTypes::VARCHAR,
|
||||
'date' => CreoleTypes::DATE,
|
||||
'time' => CreoleTypes::TIME,
|
||||
'year' => CreoleTypes::YEAR,
|
||||
'datetime' => CreoleTypes::TIMESTAMP,
|
||||
'timestamp' => CreoleTypes::TIMESTAMP,
|
||||
'tinyblob' => CreoleTypes::BINARY,
|
||||
'blob' => CreoleTypes::VARBINARY,
|
||||
'mediumblob' => CreoleTypes::VARBINARY,
|
||||
'longblob' => CreoleTypes::VARBINARY,
|
||||
'tinytext' => CreoleTypes::VARCHAR,
|
||||
'mediumtext' => CreoleTypes::LONGVARCHAR,
|
||||
'text' => CreoleTypes::LONGVARCHAR,
|
||||
);
|
||||
|
||||
/** Reverse mapping, created on demand. */
|
||||
private static $reverseMap = null;
|
||||
|
||||
/**
|
||||
* This method returns the generic Creole (JDBC-like) type
|
||||
* when given the native db type. If no match is found then we just
|
||||
* return CreoleTypes::TEXT because SQLite is typeless.
|
||||
* @param string $nativeType DB native type (e.g. 'TEXT', 'byetea', etc.).
|
||||
* @return int Creole native type (e.g. CreoleTypes::LONGVARCHAR, CreoleTypes::BINARY, etc.).
|
||||
*/
|
||||
public static function getType($nativeType)
|
||||
{
|
||||
$t = strtolower($nativeType);
|
||||
if (isset(self::$typeMap[$t])) {
|
||||
return self::$typeMap[$t];
|
||||
} else {
|
||||
return CreoleTypes::TEXT; // because SQLite is typeless
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return a native type that corresponds to the specified
|
||||
* Creole (JDBC-like) type. Remember that this is really only for "hint" purposes
|
||||
* as SQLite is typeless.
|
||||
*
|
||||
* If there is more than one matching native type, then the LAST defined
|
||||
* native type will be returned.
|
||||
*
|
||||
* @param int $creoleType
|
||||
* @return string Native type string.
|
||||
*/
|
||||
public static function getNativeType($creoleType)
|
||||
{
|
||||
if (self::$reverseMap === null) {
|
||||
self::$reverseMap = array_flip(self::$typeMap);
|
||||
}
|
||||
return @self::$reverseMap[$creoleType];
|
||||
}
|
||||
|
||||
}
|
||||
64
lib/symfony/vendor/creole/drivers/sqlite/metadata/SQLiteDatabaseInfo.php
vendored
Executable file
64
lib/symfony/vendor/creole/drivers/sqlite/metadata/SQLiteDatabaseInfo.php
vendored
Executable file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: SQLiteDatabaseInfo.php,v 1.3 2004/03/20 04:16:50 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/metadata/DatabaseInfo.php';
|
||||
|
||||
/**
|
||||
* SQLite implementation of DatabaseInfo.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.3 $
|
||||
* @package creole.drivers.sqlite.metadata
|
||||
*/
|
||||
class SQLiteDatabaseInfo extends DatabaseInfo {
|
||||
|
||||
/**
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function initTables()
|
||||
{
|
||||
include_once 'creole/drivers/sqlite/metadata/SQLiteTableInfo.php';
|
||||
|
||||
$sql = "SELECT name FROM sqlite_master WHERE type='table' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='table' ORDER BY name;";
|
||||
$result = sqlite_query($this->dblink, $sql);
|
||||
|
||||
if (!$result) {
|
||||
throw new SQLException("Could not list tables", sqlite_last_error($this->dblink));
|
||||
}
|
||||
|
||||
while ($row = sqlite_fetch_array($result)) {
|
||||
$this->tables[strtoupper($row[0])] = new SQLiteTableInfo($this, $row[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SQLite does not support sequences.
|
||||
*
|
||||
* @return void
|
||||
* @throws SQLException
|
||||
*/
|
||||
protected function initSequences()
|
||||
{
|
||||
// throw new SQLException("MySQL does not support sequences natively.");
|
||||
}
|
||||
|
||||
}
|
||||
137
lib/symfony/vendor/creole/drivers/sqlite/metadata/SQLiteTableInfo.php
vendored
Executable file
137
lib/symfony/vendor/creole/drivers/sqlite/metadata/SQLiteTableInfo.php
vendored
Executable file
@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: SQLiteTableInfo.php,v 1.8 2005/10/18 02:27:50 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/metadata/TableInfo.php';
|
||||
|
||||
/**
|
||||
* MySQL implementation of TableInfo.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.8 $
|
||||
* @package creole.drivers.sqlite.metadata
|
||||
*/
|
||||
class SQLiteTableInfo extends TableInfo {
|
||||
|
||||
/** Loads the columns for this table. */
|
||||
protected function initColumns()
|
||||
{
|
||||
|
||||
include_once 'creole/metadata/ColumnInfo.php';
|
||||
include_once 'creole/metadata/PrimaryKeyInfo.php';
|
||||
include_once 'creole/drivers/sqlite/SQLiteTypes.php';
|
||||
|
||||
// To get all of the attributes we need, we'll actually do
|
||||
// two separate queries. The first gets names and default values
|
||||
// the second will fill in some more details.
|
||||
|
||||
$sql = "PRAGMA table_info('".$this->name."')";
|
||||
|
||||
$res = sqlite_query($this->conn->getResource(), $sql);
|
||||
|
||||
|
||||
while($row = sqlite_fetch_array($res, SQLITE_ASSOC)) {
|
||||
|
||||
$name = $row['name'];
|
||||
|
||||
$fulltype = $row['type'];
|
||||
$size = null;
|
||||
$precision = null;
|
||||
$scale = null;
|
||||
|
||||
if (preg_match('/^([^\(]+)\(\s*(\d+)\s*,\s*(\d+)\s*\)$/', $fulltype, $matches)) {
|
||||
$type = $matches[1];
|
||||
$precision = $matches[2];
|
||||
$scale = $matches[3]; // aka precision
|
||||
} elseif (preg_match('/^([^\(]+)\(\s*(\d+)\s*\)$/', $fulltype, $matches)) {
|
||||
$type = $matches[1];
|
||||
$size = $matches[2];
|
||||
} else {
|
||||
$type = $fulltype;
|
||||
}
|
||||
// If column is primary key and of type INTEGER, it is auto increment
|
||||
// See: http://sqlite.org/faq.html#q1
|
||||
$is_auto_increment = ($row['pk'] == 1 && $fulltype == 'INTEGER');
|
||||
$not_null = $row['notnull'];
|
||||
$is_nullable = !$not_null;
|
||||
|
||||
$default_val = $row['dflt_value'];
|
||||
|
||||
$this->columns[$name] = new ColumnInfo($this, $name, SQLiteTypes::getType($type), $type, $size, $precision, $scale, $is_nullable, $default_val);
|
||||
|
||||
if (($row['pk'] == 1) || (strtolower($type) == 'integer primary key')) {
|
||||
if ($this->primaryKey === null) {
|
||||
$this->primaryKey = new PrimaryKeyInfo($name);
|
||||
}
|
||||
$this->primaryKey->addColumn($this->columns[ $name ]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->colsLoaded = true;
|
||||
}
|
||||
|
||||
/** Loads the primary key information for this table. */
|
||||
protected function initPrimaryKey()
|
||||
{
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
// keys are loaded by initColumns() in this class.
|
||||
$this->pkLoaded = true;
|
||||
}
|
||||
|
||||
/** Loads the indexes for this table. */
|
||||
protected function initIndexes() {
|
||||
|
||||
include_once 'creole/metadata/IndexInfo.php';
|
||||
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
|
||||
$sql = "PRAGMA index_list('".$this->name."')";
|
||||
$res = sqlite_query($this->conn->getResource(), $sql);
|
||||
|
||||
while($row = sqlite_fetch_array($res, SQLITE_ASSOC)) {
|
||||
$name = $row['name'];
|
||||
$this->indexes[$name] = new IndexInfo($name);
|
||||
|
||||
// get columns for that index
|
||||
$res2 = sqlite_query($this->conn->getResource(), "PRAGMA index_info('$name')");
|
||||
while($row2 = sqlite_fetch_array($res2, SQLITE_ASSOC)) {
|
||||
$colname = $row2['name'];
|
||||
$this->indexes[$name]->addColumn($this->columns[ $colname ]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->indexesLoaded = true;
|
||||
}
|
||||
|
||||
/** Load foreign keys (unsupported in SQLite). */
|
||||
protected function initForeignKeys() {
|
||||
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
|
||||
// No fkeys in SQLite
|
||||
|
||||
$this->fksLoaded = true;
|
||||
}
|
||||
|
||||
}
|
||||
232
lib/symfony/vendor/creole/metadata/ColumnInfo.php
vendored
Executable file
232
lib/symfony/vendor/creole/metadata/ColumnInfo.php
vendored
Executable file
@ -0,0 +1,232 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* $Id: ColumnInfo.php,v 1.13 2005/02/25 15:47:02 pachanga Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a Column.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.13 $
|
||||
* @package creole.metadata
|
||||
*/
|
||||
class ColumnInfo {
|
||||
|
||||
// FIXME
|
||||
// - Currently all member attributes are public. This should be fixed
|
||||
// when PHP's magic __sleep() and __wakeup() functions & serialization support
|
||||
// handles protected/private members. (if ever)
|
||||
|
||||
/** Column name */
|
||||
public $name;
|
||||
|
||||
/** Column Creole type. */
|
||||
public $type;
|
||||
|
||||
/** Column native type */
|
||||
public $nativeType;
|
||||
|
||||
/** Column length */
|
||||
public $size;
|
||||
|
||||
/** Column presision */
|
||||
public $precision;
|
||||
|
||||
/** Column scale (number of digits after decimal ) */
|
||||
public $scale;
|
||||
|
||||
/** Is nullable? */
|
||||
public $isNullable;
|
||||
|
||||
/** Default value */
|
||||
public $defaultValue;
|
||||
|
||||
/** Is autoincrement? */
|
||||
public $isAutoIncrement;
|
||||
|
||||
/** Table */
|
||||
public $table;
|
||||
|
||||
/**
|
||||
* Additional and optional vendor specific information.
|
||||
* @var vendorSpecificInfo
|
||||
*/
|
||||
protected $vendorSpecificInfo = array();
|
||||
|
||||
/**
|
||||
* Construct a new ColumnInfo object.
|
||||
*
|
||||
* @param TableInfo $table The table that owns this column.
|
||||
* @param string $name Column name.
|
||||
* @param int $type Creole type.
|
||||
* @param string $nativeType Native type name.
|
||||
* @param int $size Column length.
|
||||
* @param int $scale Column scale (number of digits after decimal).
|
||||
* @param boolean $is_nullable Whether col is nullable.
|
||||
* @param mixed $default Default value.
|
||||
* @param boolean $is_auto_increment Whether col is of autoIncrement type.
|
||||
*/
|
||||
function __construct(TableInfo
|
||||
$table,
|
||||
$name,
|
||||
$type = null,
|
||||
$nativeType = null,
|
||||
$size = null,
|
||||
$precision=null,
|
||||
$scale = null,
|
||||
$is_nullable = null,
|
||||
$default = null,
|
||||
$is_auto_increment = null,
|
||||
$vendorInfo = array())
|
||||
{
|
||||
$this->table = $table;
|
||||
$this->name = $name;
|
||||
$this->type = $type;
|
||||
$this->nativeType = $nativeType;
|
||||
$this->size = $size;
|
||||
$this->precision = $precision;
|
||||
$this->scale = $scale;
|
||||
$this->isNullable = $is_nullable;
|
||||
$this->defaultValue = $default;
|
||||
$this->isAutoIncrement = $is_auto_increment;
|
||||
$this->vendorSpecificInfo = $vendorInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* This "magic" method is invoked upon serialize().
|
||||
* Because the Info class hierarchy is recursive, we must handle
|
||||
* the serialization and unserialization of this object.
|
||||
* @return array The class variables that should be serialized (all must be public!).
|
||||
*/
|
||||
function __sleep()
|
||||
{
|
||||
return array('name', 'type', 'nativeType', 'size', 'precision', 'isNullable', 'defaultValue');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column name.
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column type.
|
||||
* @return int
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the native type name.
|
||||
* @return string
|
||||
*/
|
||||
public function getNativeType()
|
||||
{
|
||||
return $this->nativeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column size.
|
||||
* @return int
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column precision.
|
||||
* @return int
|
||||
*/
|
||||
public function getPrecision()
|
||||
{
|
||||
return $this->precision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column scale.
|
||||
* Scale refers to number of digits after the decimal. Sometimes this is referred
|
||||
* to as precision, but precision is the total number of digits (i.e. length).
|
||||
* @return int
|
||||
*/
|
||||
public function getScale()
|
||||
{
|
||||
return $this->scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default value.
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDefaultValue()
|
||||
{
|
||||
return $this->defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is column nullable?
|
||||
* @return boolean
|
||||
*/
|
||||
public function isNullable()
|
||||
{
|
||||
return $this->isNullable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is column of autoincrement type?
|
||||
* @return boolean
|
||||
*/
|
||||
public function isAutoIncrement()
|
||||
{
|
||||
return $this->isAutoIncrement === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get vendor specific optional information for this column.
|
||||
* @return array vendorSpecificInfo[]
|
||||
*/
|
||||
public function getVendorSpecificInfo()
|
||||
{
|
||||
return $this->vendorSpecificInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parent table.
|
||||
* @return TableInfo
|
||||
*/
|
||||
public function getTable()
|
||||
{
|
||||
return $this->table;
|
||||
}
|
||||
|
||||
}
|
||||
207
lib/symfony/vendor/creole/metadata/DatabaseInfo.php
vendored
Executable file
207
lib/symfony/vendor/creole/metadata/DatabaseInfo.php
vendored
Executable file
@ -0,0 +1,207 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* $Id: DatabaseInfo.php,v 1.15 2005/11/08 04:24:50 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* "Info" metadata class for a database.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.15 $
|
||||
* @package creole.metadata
|
||||
*/
|
||||
abstract class DatabaseInfo {
|
||||
|
||||
protected $tables = array();
|
||||
|
||||
protected $sequences = array();
|
||||
|
||||
/** have tables been loaded */
|
||||
protected $tablesLoaded = false;
|
||||
|
||||
/** have sequences been loaded */
|
||||
protected $seqsLoaded = false;
|
||||
|
||||
/** additional vendor specific information */
|
||||
private $vendorSpecificInfo = array();
|
||||
|
||||
/**
|
||||
* The database Connection.
|
||||
* @var Connection
|
||||
*/
|
||||
protected $conn;
|
||||
|
||||
/** Database name. */
|
||||
protected $dbname;
|
||||
|
||||
/**
|
||||
* Database link
|
||||
* @var resource
|
||||
*/
|
||||
protected $dblink;
|
||||
|
||||
/**
|
||||
* @param Connection $dbh
|
||||
*/
|
||||
public function __construct(Connection $conn, $vendorInfo = array())
|
||||
{
|
||||
$this->conn = $conn;
|
||||
$this->dblink = $conn->getResource();
|
||||
$dsn = $conn->getDSN();
|
||||
$this->dbname = $dsn['database'];
|
||||
$this->vendorSpecificInfo = $vendorInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of database.
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->dbname;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked upon serialize().
|
||||
* Because the Info class hierarchy is recursive, we must handle
|
||||
* the serialization and unserialization of this object.
|
||||
* @return array The class variables that should be serialized (all must be public!).
|
||||
*/
|
||||
function __sleep()
|
||||
{
|
||||
return array('tables','sequences','conn');
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked upon unserialize().
|
||||
* This method re-hydrates the object and restores the recursive hierarchy.
|
||||
*/
|
||||
function __wakeup()
|
||||
{
|
||||
// Re-init vars from serialized connection
|
||||
$this->dbname = $conn->database;
|
||||
$this->dblink = $conn->connection;
|
||||
|
||||
// restore chaining
|
||||
foreach($this->tables as $tbl) {
|
||||
$tbl->database = $this;
|
||||
$tbl->dbname = $this->dbname;
|
||||
$tbl->dblink = $this->dblink;
|
||||
$tbl->schema = $this->schema;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Connection being used.
|
||||
* @return Connection
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the TableInfo object for specified table name.
|
||||
* @param string $name The name of the table to retrieve.
|
||||
* @return TableInfo
|
||||
* @throws SQLException - if table does not exist in this db.
|
||||
*/
|
||||
public function getTable($name)
|
||||
{
|
||||
if(!$this->tablesLoaded) $this->initTables();
|
||||
if (!isset($this->tables[strtoupper($name)])) {
|
||||
throw new SQLException("Database `".$this->dbname."` has no table `".$name."`");
|
||||
}
|
||||
return $this->tables[ strtoupper($name) ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether database contains specified table.
|
||||
* @param string $name The table name.
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasTable($name)
|
||||
{
|
||||
if(!$this->tablesLoaded) $this->initTables();
|
||||
return isset($this->tables[strtoupper($name)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets array of TableInfo objects.
|
||||
* @return array TableInfo[]
|
||||
*/
|
||||
public function getTables()
|
||||
{
|
||||
if(!$this->tablesLoaded) $this->initTables();
|
||||
return array_values($this->tables); //re-key [numerically]
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a table to this db.
|
||||
* Table name is case-insensitive.
|
||||
* @param TableInfo $table
|
||||
*/
|
||||
public function addTable(TableInfo $table)
|
||||
{
|
||||
$this->tables[strtoupper($table->getName())] = $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @throws SQLException
|
||||
*/
|
||||
abstract protected function initTables();
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @throws SQLException
|
||||
*/
|
||||
abstract protected function initSequences();
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function isSequence($key)
|
||||
{
|
||||
if(!$this->seqsLoaded) $this->initSequences();
|
||||
return isset($this->sequences[ strtoupper($key) ]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets array of ? objects.
|
||||
* @return array ?[]
|
||||
*/
|
||||
public function getSequences()
|
||||
{
|
||||
if(!$this->seqsLoaded) $this->initSequences();
|
||||
return array_values($this->sequences); //re-key [numerically]
|
||||
}
|
||||
|
||||
/**
|
||||
* Get vendor specific optional information for this primary key.
|
||||
* @return array vendorSpecificInfo[]
|
||||
*/
|
||||
public function getVendorSpecificInfo()
|
||||
{
|
||||
return $this->vendorSpecificInfo;
|
||||
}
|
||||
}
|
||||
|
||||
103
lib/symfony/vendor/creole/metadata/ForeignKeyInfo.php
vendored
Executable file
103
lib/symfony/vendor/creole/metadata/ForeignKeyInfo.php
vendored
Executable file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* $Id: ForeignKeyInfo.php,v 1.9 2005/08/02 14:42:36 sethr Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a foreign key.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.9 $
|
||||
* @package creole.metadata
|
||||
*/
|
||||
class ForeignKeyInfo {
|
||||
|
||||
private $name;
|
||||
private $references = array();
|
||||
|
||||
/**
|
||||
* Additional and optional vendor specific information.
|
||||
* @var vendorSpecificInfo
|
||||
*/
|
||||
protected $vendorSpecificInfo = array();
|
||||
|
||||
|
||||
const NONE = ""; // No "ON [ DELETE | UPDATE]" behaviour specified.
|
||||
const NOACTION = "NO ACTION";
|
||||
const CASCADE = "CASCADE";
|
||||
const RESTRICT = "RESTRICT";
|
||||
const SETDEFAULT = "SET DEFAULT";
|
||||
const SETNULL = "SET NULL";
|
||||
|
||||
/**
|
||||
* @param string $name The name of the foreign key.
|
||||
*/
|
||||
function __construct($name, $vendorInfo = array())
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->vendorSpecificInfo = $vendorInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get foreign key name.
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a foreign-local mapping.
|
||||
* @param ColumnInfo $local
|
||||
* @param ColumnInfo $foreign
|
||||
*/
|
||||
public function addReference(ColumnInfo $local, ColumnInfo $foreign, $onDelete = self::NONE, $onUpdate = self::NONE)
|
||||
{
|
||||
$this->references[] = array($local, $foreign, $onDelete, $onUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the local-foreign column mapping.
|
||||
* @return array array( [0] => array([0] => local ColumnInfo object, [1] => foreign ColumnInfo object, [2] => onDelete, [3] => onUpdate) )
|
||||
*/
|
||||
public function getReferences()
|
||||
{
|
||||
return $this->references;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get vendor specific optional information for this primary key.
|
||||
* @return array vendorSpecificInfo[]
|
||||
*/
|
||||
public function getVendorSpecificInfo()
|
||||
{
|
||||
return $this->vendorSpecificInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
}
|
||||
84
lib/symfony/vendor/creole/metadata/IndexInfo.php
vendored
Executable file
84
lib/symfony/vendor/creole/metadata/IndexInfo.php
vendored
Executable file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: IndexInfo.php,v 1.7 2005/02/25 15:47:02 pachanga Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents an index.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.7 $
|
||||
* @package creole.metadata
|
||||
*/
|
||||
class IndexInfo {
|
||||
|
||||
/** name of the index */
|
||||
private $name;
|
||||
|
||||
/** columns in this index */
|
||||
private $columns = array();
|
||||
|
||||
/** uniqueness flag */
|
||||
private $isUnique = false;
|
||||
|
||||
/** additional vendor specific information */
|
||||
private $vendorSpecificInfo = array();
|
||||
|
||||
function __construct($name, $isUnique = false, $vendorInfo = array())
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->isUnique = $isUnique;
|
||||
$this->vendorSpecificInfo = $vendorInfo;
|
||||
}
|
||||
|
||||
public function isUnique()
|
||||
{
|
||||
return $this->isUnique;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get vendor specific optional information for this index.
|
||||
* @return array vendorSpecificInfo[]
|
||||
*/
|
||||
public function getVendorSpecificInfo()
|
||||
{
|
||||
return $this->vendorSpecificInfo;
|
||||
}
|
||||
|
||||
public function addColumn($column)
|
||||
{
|
||||
$this->columns[] = $column;
|
||||
}
|
||||
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->columns;
|
||||
}
|
||||
|
||||
public function toString()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
}
|
||||
91
lib/symfony/vendor/creole/metadata/PrimaryKeyInfo.php
vendored
Executable file
91
lib/symfony/vendor/creole/metadata/PrimaryKeyInfo.php
vendored
Executable file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PrimaryKeyInfo.php,v 1.6 2005/02/25 15:47:02 pachanga Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a PrimaryKey
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.6 $
|
||||
* @package creole.metadata
|
||||
*/
|
||||
class PrimaryKeyInfo {
|
||||
|
||||
/** name of the primary key */
|
||||
private $name;
|
||||
|
||||
/** columns in the primary key */
|
||||
private $columns = array();
|
||||
|
||||
/** additional vendor specific information */
|
||||
private $vendorSpecificInfo = array();
|
||||
|
||||
/**
|
||||
* @param string $name The name of the foreign key.
|
||||
*/
|
||||
function __construct($name, $vendorInfo = array())
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->vendorSpecificInfo = $vendorInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get foreign key name.
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Column $column
|
||||
* @return void
|
||||
*/
|
||||
public function addColumn($column)
|
||||
{
|
||||
$this->columns[] = $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array Column[]
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get vendor specific optional information for this primary key.
|
||||
* @return array vendorSpecificInfo[]
|
||||
*/
|
||||
public function getVendorSpecificInfo()
|
||||
{
|
||||
return $this->vendorSpecificInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
305
lib/symfony/vendor/creole/metadata/TableInfo.php
vendored
Executable file
305
lib/symfony/vendor/creole/metadata/TableInfo.php
vendored
Executable file
@ -0,0 +1,305 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* $Id: TableInfo.php,v 1.16 2005/10/17 19:05:10 dlawson_mi Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a table.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.16 $
|
||||
* @package creole.metadata
|
||||
*/
|
||||
abstract class TableInfo {
|
||||
|
||||
protected $name;
|
||||
protected $columns = array();
|
||||
protected $foreignKeys = array();
|
||||
protected $indexes = array();
|
||||
protected $primaryKey;
|
||||
|
||||
protected $pkLoaded = false;
|
||||
protected $fksLoaded = false;
|
||||
protected $indexesLoaded = false;
|
||||
protected $colsLoaded = false;
|
||||
protected $vendorLoaded = false;
|
||||
|
||||
/**
|
||||
* Additional and optional vendor specific information.
|
||||
* @var vendorSpecificInfo
|
||||
*/
|
||||
protected $vendorSpecificInfo = array();
|
||||
|
||||
/**
|
||||
* Database Connection.
|
||||
* @var Connection
|
||||
*/
|
||||
protected $conn;
|
||||
|
||||
/**
|
||||
* The parent DatabaseInfo object.
|
||||
* @var DatabaseInfo
|
||||
*/
|
||||
protected $database;
|
||||
|
||||
/** Shortcut to db resource link id (needed by drivers for queries). */
|
||||
protected $dblink;
|
||||
|
||||
/** Shortcut to db name (needed by many drivers for queries). */
|
||||
protected $dbname;
|
||||
|
||||
/**
|
||||
* @param string $table The table name.
|
||||
* @param string $database The database name.
|
||||
* @param resource $dblink The db connection resource.
|
||||
*/
|
||||
function __construct(DatabaseInfo $database, $name) {
|
||||
$this->database = $database;
|
||||
$this->name = $name;
|
||||
$this->conn = $database->getConnection(); // shortcut because all drivers need this for the queries
|
||||
$this->dblink = $this->conn->getResource();
|
||||
$this->dbname = $database->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* This "magic" method is invoked upon serialize().
|
||||
* Because the Info class hierarchy is recursive, we must handle
|
||||
* the serialization and unserialization of this object.
|
||||
* @return array The class variables that should be serialized (all must be public!).
|
||||
*/
|
||||
function __sleep()
|
||||
{
|
||||
return array('name', 'columns', 'foreignKeys', 'indexes', 'primaryKey');
|
||||
}
|
||||
|
||||
/**
|
||||
* This "magic" method is invoked upon unserialize().
|
||||
* This method re-hydrates the object and restores the recursive hierarchy.
|
||||
*/
|
||||
function __wakeup()
|
||||
{
|
||||
// restore chaining
|
||||
foreach($this->columns as $col) {
|
||||
$col->table = $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the columns.
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function initColumns();
|
||||
|
||||
/**
|
||||
* Loads the primary key information for this table.
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function initPrimaryKey();
|
||||
|
||||
/**
|
||||
* Loads the foreign keys for this table.
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function initForeignKeys();
|
||||
|
||||
/**
|
||||
* Loads the indexes information for this table.
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function initIndexes();
|
||||
|
||||
/**
|
||||
* Loads the vendor specific information for this table.
|
||||
* @return void
|
||||
*/
|
||||
//it must be asbtract and be implemented in every vendor specific driver,
|
||||
//however since it's an experimental stuff it has an empty body in order
|
||||
//not to break BC
|
||||
/*abstract*/ protected function initVendorSpecificInfo(){}
|
||||
|
||||
/**
|
||||
* Get parimary key in this table.
|
||||
* @throws Exception - if foreign keys are unsupported by DB.
|
||||
* @return array ForeignKeyInfo[]
|
||||
*/
|
||||
public function getPrimaryKey()
|
||||
{
|
||||
if(!$this->pkLoaded) $this->initPrimaryKey();
|
||||
return $this->primaryKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ColumnInfo object for specified column.
|
||||
* @param string $name The column name.
|
||||
* @return ColumnInfo
|
||||
* @throws SQLException - if column does not exist for this table.
|
||||
*/
|
||||
public function getColumn($name)
|
||||
{
|
||||
if(!$this->colsLoaded) $this->initColumns();
|
||||
if (!isset($this->columns[$name])) {
|
||||
throw new SQLException("Table `".$this->name."` has no column `".$name."`");
|
||||
}
|
||||
return $this->columns[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether table contains specified column.
|
||||
* @param string $name The column name.
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasColumn($name)
|
||||
{
|
||||
if(!$this->colsLoaded) $this->initColumns();
|
||||
return isset($this->columns[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of columns for this table.
|
||||
* @return array ColumnInfo[]
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
if(!$this->colsLoaded) $this->initColumns();
|
||||
return array_values($this->columns); // re-key numerically
|
||||
}
|
||||
|
||||
/**
|
||||
* Get specified fk for this table.
|
||||
* @param string $name The foreign key name to retrieve.
|
||||
* @return ForeignKeyInfo
|
||||
* @throws SQLException - if fkey does not exist for this table.
|
||||
*/
|
||||
public function getForeignKey($name)
|
||||
{
|
||||
if(!$this->fksLoaded) $this->initForeignKeys();
|
||||
if (!isset($this->foreignKeys[$name])) {
|
||||
throw new SQLException("Table `".$this->name."` has no foreign key `".$name."`");
|
||||
}
|
||||
return $this->foreignKeys[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all foreign keys.
|
||||
* @return array ForeignKeyInfo[]
|
||||
*/
|
||||
public function getForeignKeys()
|
||||
{
|
||||
if(!$this->fksLoaded) $this->initForeignKeys();
|
||||
return array_values($this->foreignKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the IndexInfo object for a specified index.
|
||||
* @param string $name The index name to retrieve.
|
||||
* @return IndexInfo
|
||||
* @throws SQLException - if index does not exist for this table.
|
||||
*/
|
||||
public function getIndex($name)
|
||||
{
|
||||
if(!$this->indexesLoaded) $this->initIndexes();
|
||||
if (!isset($this->indexes[$name])) {
|
||||
throw new SQLException("Table `".$this->name."` has no index `".$name."`");
|
||||
}
|
||||
return $this->indexes[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of IndexInfo objects for this table.
|
||||
* @return array IndexInfo[]
|
||||
*/
|
||||
public function getIndexes()
|
||||
{
|
||||
if(!$this->indexesLoaded) $this->initIndexes();
|
||||
return array_values($this->indexes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for getIndexes() method.
|
||||
* @return array
|
||||
*/
|
||||
public function getIndices()
|
||||
{
|
||||
return $this->getIndexes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table name.
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/** Have foreign keys been loaded? */
|
||||
public function foreignKeysLoaded()
|
||||
{
|
||||
return $this->fksLoaded;
|
||||
}
|
||||
|
||||
/** Has primary key info been loaded? */
|
||||
public function primaryKeyLoaded()
|
||||
{
|
||||
return $this->pkLoaded;
|
||||
}
|
||||
|
||||
/** Have columns been loaded? */
|
||||
public function columnsLoaded()
|
||||
{
|
||||
return $this->colsLoaded;
|
||||
}
|
||||
|
||||
/** Has index information been loaded? */
|
||||
public function indexesLoaded()
|
||||
{
|
||||
return $this->indexesLoaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get vendor specific optional information for this table.
|
||||
* @return array vendorSpecificInfo[]
|
||||
*/
|
||||
public function getVendorSpecificInfo()
|
||||
{
|
||||
if(!$this->vendorLoaded) $this->initVendorSpecificInfo();
|
||||
return $this->vendorSpecificInfo;
|
||||
}
|
||||
|
||||
/** Adds a column to this table. */
|
||||
public function addColumn(ColumnInfo $column)
|
||||
{
|
||||
$this->columns[$column->getName()] = $column;
|
||||
}
|
||||
|
||||
/** Get the parent DatabaseInfo object. */
|
||||
public function getDatabase()
|
||||
{
|
||||
return $this->database;
|
||||
}
|
||||
}
|
||||
62
lib/symfony/vendor/creole/util/Blob.php
vendored
Executable file
62
lib/symfony/vendor/creole/util/Blob.php
vendored
Executable file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: Blob.php,v 1.5 2004/03/20 04:16:50 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/util/Lob.php';
|
||||
|
||||
/**
|
||||
* A class for handling binary LOBs.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.5 $
|
||||
* @package creole.util
|
||||
*/
|
||||
class Blob extends Lob {
|
||||
|
||||
/**
|
||||
* Dump the contents of the file using fpassthru().
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception if no file or contents.
|
||||
*/
|
||||
function dump()
|
||||
{
|
||||
if (!$this->data) {
|
||||
// hmmm .. must be a file that needs to read in
|
||||
if ($this->inFile) {
|
||||
$fp = @fopen($this->inFile, "rb");
|
||||
if (!$fp) {
|
||||
throw new Exception('Unable to open file: '.$this->inFile);
|
||||
}
|
||||
fpassthru($fp);
|
||||
@fclose($fp);
|
||||
} else {
|
||||
throw new Exception('No data to dump');
|
||||
}
|
||||
|
||||
} else {
|
||||
echo $this->data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
112
lib/symfony/vendor/creole/util/Clob.php
vendored
Executable file
112
lib/symfony/vendor/creole/util/Clob.php
vendored
Executable file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: Clob.php,v 1.6 2004/07/27 23:15:13 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/util/Lob.php';
|
||||
|
||||
/**
|
||||
* A class for handling character (ASCII) LOBs.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.6 $
|
||||
* @package creole.util
|
||||
*/
|
||||
class Clob extends Lob {
|
||||
|
||||
/**
|
||||
* Read LOB data from file.
|
||||
* @param string $file Filename may also be specified here (if not specified using setInputFile()).
|
||||
* @return void
|
||||
* @throws Exception - if no file specified or error on read.
|
||||
* @see setInputFile()
|
||||
*/
|
||||
public function readFromFile($file = null)
|
||||
{
|
||||
if ($file !== null) {
|
||||
$this->setInputFile($file);
|
||||
}
|
||||
if (!$this->inFile) {
|
||||
throw Exception('No file specified for read.');
|
||||
}
|
||||
$data = null;
|
||||
$file = fopen($this->inFile, "rt");
|
||||
while (!feof($file)) $data .= fgets($file, 4096);
|
||||
fclose($file);
|
||||
if ($data === false) {
|
||||
throw new Exception('Unable to read from file: '.$this->inFile);
|
||||
}
|
||||
$this->setContents($data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write LOB data to file.
|
||||
* @param string $file Filename may also be specified here (if not set using setOutputFile()).
|
||||
* @throws Exception - if no file specified, no contents to write, or error on write.
|
||||
* @see setOutputFile()
|
||||
*/
|
||||
public function writeToFile($file = null)
|
||||
{
|
||||
if ($file !== null) {
|
||||
$this->setOutputFile($file);
|
||||
}
|
||||
if (!$this->outFile) {
|
||||
throw new Exception('No file specified for write');
|
||||
}
|
||||
if ($this->data === null) {
|
||||
throw new Exception('No data to write to file');
|
||||
}
|
||||
$file = fopen($this->inFile, "wt");
|
||||
if (fputs($file, $this->data) === false)
|
||||
throw new Exception('Unable to write to file: '.$this->outFile);
|
||||
fclose($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump the contents of the file using fpassthru().
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception if no file or contents.
|
||||
*/
|
||||
function dump()
|
||||
{
|
||||
if (!$this->data) {
|
||||
|
||||
// is there a file name set?
|
||||
if ($this->inFile) {
|
||||
$fp = @fopen($this->inFile, "r");
|
||||
if (!$fp) {
|
||||
throw new Exception('Unable to open file: '.$this->inFile);
|
||||
}
|
||||
fpassthru($fp);
|
||||
@fclose($fp);
|
||||
} else {
|
||||
throw new Exception('No data to dump');
|
||||
}
|
||||
|
||||
} else {
|
||||
echo $this->data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
243
lib/symfony/vendor/creole/util/Lob.php
vendored
Executable file
243
lib/symfony/vendor/creole/util/Lob.php
vendored
Executable file
@ -0,0 +1,243 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: Lob.php,v 1.10 2004/03/20 04:16:50 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* An abstract class for handling LOB (Locator Object) columns.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.10 $
|
||||
* @package creole.util
|
||||
*/
|
||||
abstract class Lob {
|
||||
|
||||
/**
|
||||
* The contents of the Lob.
|
||||
* DO NOT SET DIRECTLY (or you will disrupt the
|
||||
* ability of isModified() to give accurate results).
|
||||
* @var string
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* File that blob should be written out to.
|
||||
* @var string
|
||||
*/
|
||||
protected $outFile;
|
||||
|
||||
/**
|
||||
* File that blob should be read in from
|
||||
* @var string
|
||||
*/
|
||||
protected $inFile;
|
||||
|
||||
/**
|
||||
* This is a 3-state value indicating whether column has been
|
||||
* modified.
|
||||
* Initially it is NULL. Once first call to setContents() is made
|
||||
* it is FALSE, because this will be initial state of Lob. Once
|
||||
* a subsequent call to setContents() is made it is TRUE.
|
||||
* @var boolean
|
||||
*/
|
||||
private $modified = null;
|
||||
|
||||
/**
|
||||
* Construct a new Lob.
|
||||
* @param sttring $data The data contents of the Lob.
|
||||
* @see setContents()
|
||||
*/
|
||||
public function __construct($data = null)
|
||||
{
|
||||
if ($data !== null) {
|
||||
$this->setContents($data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the contents of the LOB.
|
||||
* @return string The characters in this LOB.
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getContents()
|
||||
{
|
||||
if ($this->data === null && $this->isFromFile()) {
|
||||
$this->readFromFile();
|
||||
}
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the contents of this LOB.
|
||||
* Sets the modified flag to FALSE if this is the first call
|
||||
* to setContents() for this object. Sets the bit to TRUE if
|
||||
* this any subsequent call to setContents().
|
||||
* @param string $bytes
|
||||
*/
|
||||
public function setContents($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
|
||||
if ($this->modified === null) {
|
||||
// if modified bit hasn't been set yet,
|
||||
// then it should now be set to FALSE, since
|
||||
// we just did inital population
|
||||
$this->modified = false;
|
||||
} elseif ($this->modified === false) {
|
||||
// if it was already FALSE, then it should
|
||||
// now be set to TRUE, since this is a subsequent
|
||||
// modfiication.
|
||||
$this->modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump the contents of the file to stdout.
|
||||
* Must be implemented by subclasses so that binary status is handled
|
||||
* correctly. (i.e. ignored for Clob, handled for Blob)
|
||||
* @return void
|
||||
* @throws Exception if no file or contents.
|
||||
*/
|
||||
abstract public function dump();
|
||||
|
||||
/**
|
||||
* Specify the file that we want this LOB read from.
|
||||
* @param string $filePath The location of the file.
|
||||
* @return void
|
||||
*/
|
||||
public function setInputFile($filePath)
|
||||
{
|
||||
$this->inFile = $filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file that we want this LOB read from.
|
||||
* @return string The location of the file.
|
||||
*/
|
||||
public function getInputFile()
|
||||
{
|
||||
return $this->inFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the file that we want this LOB saved to.
|
||||
* @param string $filePath The location of the file.
|
||||
* @return void
|
||||
*/
|
||||
public function setOutputFile($filePath)
|
||||
{
|
||||
$this->outFile = $filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file that we want this LOB saved to.
|
||||
* @return string $filePath The location of the file.
|
||||
*/
|
||||
public function getOutputFile()
|
||||
{
|
||||
return $this->outFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this Lob is loaded from file.
|
||||
* This is useful for bypassing need to read in the contents of the Lob.
|
||||
* @return boolean Whether this LOB is to be read from a file.
|
||||
*/
|
||||
public function isFromFile()
|
||||
{
|
||||
return ($this->inFile !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read LOB data from file (binary safe).
|
||||
* (Implementation may need to be moved into Clob / Blob subclasses, but
|
||||
* since file_get_contents() is binary-safe, it hasn't been necessary so far.)
|
||||
* @param string $file Filename may also be specified here (if not specified using setInputFile()).
|
||||
* @return void
|
||||
* @throws Exception - if no file specified or error on read.
|
||||
* @see setInputFile()
|
||||
*/
|
||||
public function readFromFile($file = null)
|
||||
{
|
||||
if ($file !== null) {
|
||||
$this->setInputFile($file);
|
||||
}
|
||||
if (!$this->inFile) {
|
||||
throw Exception('No file specified for read.');
|
||||
}
|
||||
$data = @file_get_contents($this->inFile);
|
||||
if ($data === false) {
|
||||
throw new Exception('Unable to read from file: '.$this->inFile);
|
||||
}
|
||||
$this->setContents($data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write LOB data to file (binary safe).
|
||||
* (Impl may need to move into subclasses, but so far not necessary.)
|
||||
* @param string $file Filename may also be specified here (if not set using setOutputFile()).
|
||||
* @throws Exception - if no file specified, no contents to write, or error on write.
|
||||
* @see setOutputFile()
|
||||
*/
|
||||
public function writeToFile($file = null)
|
||||
{
|
||||
if ($file !== null) {
|
||||
$this->setOutputFile($file);
|
||||
}
|
||||
if (!$this->outFile) {
|
||||
throw new Exception('No file specified for write');
|
||||
}
|
||||
if ($this->data === null) {
|
||||
throw new Exception('No data to write to file');
|
||||
}
|
||||
if (false === @file_put_contents($this->outFile, $this->data)) {
|
||||
throw new Exception('Unable to write to file: '.$this->outFile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to get contents of LOB as string.
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getContents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether LOB contents have been modified after initial setting.
|
||||
* @param boolean $b
|
||||
*/
|
||||
public function setModified($b)
|
||||
{
|
||||
$this->modified = $b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether LOB contents have been modified after initial setting.
|
||||
* @return boolean TRUE if the contents have been modified after initial setting.
|
||||
* FALSE if contents have not been modified or if no contents have bene set.
|
||||
*/
|
||||
public function isModified()
|
||||
{
|
||||
// cast it so that NULL will also eval to false
|
||||
return (boolean) $this->modified;
|
||||
}
|
||||
}
|
||||
164
lib/symfony/vendor/creole/util/sql/SQLStatementExtractor.php
vendored
Executable file
164
lib/symfony/vendor/creole/util/sql/SQLStatementExtractor.php
vendored
Executable file
@ -0,0 +1,164 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: SQLStatementExtractor.php,v 1.5 2004/07/27 23:13:46 hlellelid Exp $
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Static class for extracting SQL statements from a string or file.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.5 $
|
||||
* @package creole.util.sql
|
||||
*/
|
||||
class SQLStatementExtractor {
|
||||
|
||||
protected static $delimiter = ';';
|
||||
|
||||
/**
|
||||
* Get SQL statements from file.
|
||||
*
|
||||
* @param string $filename Path to file to read.
|
||||
* @return array SQL statements
|
||||
*/
|
||||
public static function extractFile($filename) {
|
||||
$buffer = file_get_contents($filename);
|
||||
if ($buffer === false) {
|
||||
throw new Exception("Unable to read file: " . $filename);
|
||||
}
|
||||
return self::extractStatements(self::getLines($buffer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract statements from string.
|
||||
*
|
||||
* @param string $txt
|
||||
* @return array
|
||||
*/
|
||||
public static function extract($buffer) {
|
||||
return self::extractStatements(self::getLines($buffer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract SQL statements from array of lines.
|
||||
*
|
||||
* @param array $lines Lines of the read-in file.
|
||||
* @return string
|
||||
*/
|
||||
protected static function extractStatements($lines) {
|
||||
|
||||
$statements = array();
|
||||
$sql = "";
|
||||
|
||||
foreach($lines as $line) {
|
||||
|
||||
$line = trim($line);
|
||||
|
||||
if (self::startsWith("//", $line) ||
|
||||
self::startsWith("--", $line) ||
|
||||
self::startsWith("#", $line)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strlen($line) > 4 && strtoupper(substr($line,0, 4)) == "REM ") {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sql .= " " . $line;
|
||||
$sql = trim($sql);
|
||||
|
||||
// SQL defines "--" as a comment to EOL
|
||||
// and in Oracle it may contain a hint
|
||||
// so we cannot just remove it, instead we must end it
|
||||
if (strpos($line, "--") !== false) {
|
||||
$sql .= "\n";
|
||||
}
|
||||
|
||||
if (self::endsWith(self::$delimiter, $sql)) {
|
||||
$statements[] = self::substring($sql, 0, strlen($sql)-1 - strlen(self::$delimiter));
|
||||
$sql = "";
|
||||
}
|
||||
}
|
||||
return $statements;
|
||||
}
|
||||
|
||||
//
|
||||
// Some string helper methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Tests if a string starts with a given string.
|
||||
* @param string $check The substring to check.
|
||||
* @param string $string The string to check in (haystack).
|
||||
* @return boolean True if $string starts with $check, or they are equal, or $check is empty.
|
||||
*/
|
||||
protected static function startsWith($check, $string) {
|
||||
if ($check === "" || $check === $string) {
|
||||
return true;
|
||||
} else {
|
||||
return (strpos($string, $check) === 0) ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if a string ends with a given string.
|
||||
* @param string $check The substring to check.
|
||||
* @param string $string The string to check in (haystack).
|
||||
* @return boolean True if $string ends with $check, or they are equal, or $check is empty.
|
||||
*/
|
||||
protected static function endsWith($check, $string) {
|
||||
if ($check === "" || $check === $string) {
|
||||
return true;
|
||||
} else {
|
||||
return (strpos(strrev($string), strrev($check)) === 0) ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* a natural way of getting a subtring, php's circular string buffer and strange
|
||||
* return values suck if you want to program strict as of C or friends
|
||||
*/
|
||||
protected static function substring($string, $startpos, $endpos = -1) {
|
||||
$len = strlen($string);
|
||||
$endpos = (int) (($endpos === -1) ? $len-1 : $endpos);
|
||||
if ($startpos > $len-1 || $startpos < 0) {
|
||||
trigger_error("substring(), Startindex out of bounds must be 0<n<$len", E_USER_ERROR);
|
||||
}
|
||||
if ($endpos > $len-1 || $endpos < $startpos) {
|
||||
trigger_error("substring(), Endindex out of bounds must be $startpos<n<".($len-1), E_USER_ERROR);
|
||||
}
|
||||
if ($startpos === $endpos) {
|
||||
return (string) $string{$startpos};
|
||||
} else {
|
||||
$len = $endpos-$startpos;
|
||||
}
|
||||
return substr($string, $startpos, $len+1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string buffer into array of lines.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return array string[] lines of file.
|
||||
*/
|
||||
protected static function getLines($buffer) {
|
||||
$lines = preg_split("/\r?\n|\r/", $buffer);
|
||||
return $lines;
|
||||
}
|
||||
|
||||
}
|
||||
978
lib/symfony/vendor/lime/lime.php
vendored
Executable file
978
lib/symfony/vendor/lime/lime.php
vendored
Executable file
@ -0,0 +1,978 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Unit test library.
|
||||
*
|
||||
* @package lime
|
||||
* @author Fabien Potencier <fabien.potencier@gmail.com>
|
||||
* @version SVN: $Id: lime.php 4259 2007-06-19 07:24:40Z fabien $
|
||||
*/
|
||||
|
||||
class lime_test
|
||||
{
|
||||
public $plan = null;
|
||||
public $test_nb = 0;
|
||||
public $failed = 0;
|
||||
public $passed = 0;
|
||||
public $skipped = 0;
|
||||
public $output = null;
|
||||
|
||||
function __construct($plan = null, $output_instance = null)
|
||||
{
|
||||
$this->plan = $plan;
|
||||
$this->output = $output_instance ? $output_instance : new lime_output();
|
||||
|
||||
null !== $this->plan and $this->output->echoln(sprintf("1..%d", $this->plan));
|
||||
}
|
||||
|
||||
function __destruct()
|
||||
{
|
||||
$total = $this->passed + $this->failed + $this->skipped;
|
||||
|
||||
null === $this->plan and $this->plan = $total and $this->output->echoln(sprintf("1..%d", $this->plan));
|
||||
|
||||
if ($total > $this->plan)
|
||||
{
|
||||
$this->output->red_bar(sprintf(" Looks like you planned %d tests but ran %d extra.", $this->plan, $total - $this->plan));
|
||||
}
|
||||
elseif ($total < $this->plan)
|
||||
{
|
||||
$this->output->red_bar(sprintf(" Looks like you planned %d tests but only ran %d.", $this->plan, $total));
|
||||
}
|
||||
|
||||
if ($this->failed)
|
||||
{
|
||||
$this->output->red_bar(sprintf(" Looks like you failed %d tests of %d.", $this->failed, $this->plan));
|
||||
}
|
||||
else if ($total == $this->plan)
|
||||
{
|
||||
$this->output->green_bar(" Looks like everything went fine.");
|
||||
}
|
||||
|
||||
flush();
|
||||
}
|
||||
|
||||
function ok($exp, $message = '')
|
||||
{
|
||||
if ($result = (boolean) $exp)
|
||||
{
|
||||
++$this->passed;
|
||||
}
|
||||
else
|
||||
{
|
||||
++$this->failed;
|
||||
}
|
||||
$this->output->echoln(sprintf("%s %d%s", $result ? 'ok' : 'not ok', ++$this->test_nb, $message = $message ? sprintf('%s %s', 0 === strpos($message, '#') ? '' : ' -', $message) : ''));
|
||||
|
||||
if (!$result)
|
||||
{
|
||||
$traces = debug_backtrace();
|
||||
if ($_SERVER['PHP_SELF'])
|
||||
{
|
||||
$i = strstr($traces[0]['file'], $_SERVER['PHP_SELF']) ? 0 : (isset($traces[1]['file']) ? 1 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
$i = 0;
|
||||
}
|
||||
$this->output->diag(sprintf(' Failed test (%s at line %d)', str_replace(getcwd(), '.', $traces[$i]['file']), $traces[$i]['line']));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function is($exp1, $exp2, $message = '')
|
||||
{
|
||||
if (is_object($exp1) || is_object($exp2))
|
||||
{
|
||||
$value = $exp1 === $exp2;
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = $exp1 == $exp2;
|
||||
}
|
||||
|
||||
if (!$result = $this->ok($value, $message))
|
||||
{
|
||||
$this->output->diag(sprintf(" got: %s", str_replace("\n", '', var_export($exp1, true))), sprintf(" expected: %s", str_replace("\n", '', var_export($exp2, true))));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function isnt($exp1, $exp2, $message = '')
|
||||
{
|
||||
if (!$result = $this->ok($exp1 != $exp2, $message))
|
||||
{
|
||||
$this->output->diag(sprintf(" %s", str_replace("\n", '', var_export($exp1, true))), ' ne', sprintf(" %s", str_replace("\n", '', var_export($exp2, true))));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function like($exp, $regex, $message = '')
|
||||
{
|
||||
if (!$result = $this->ok(preg_match($regex, $exp), $message))
|
||||
{
|
||||
$this->output->diag(sprintf(" '%s'", $exp), sprintf(" doesn't match '%s'", $regex));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function unlike($exp, $regex, $message = '')
|
||||
{
|
||||
if (!$result = $this->ok(!preg_match($regex, $exp), $message))
|
||||
{
|
||||
$this->output->diag(sprintf(" '%s'", $exp), sprintf(" matches '%s'", $regex));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function cmp_ok($exp1, $op, $exp2, $message = '')
|
||||
{
|
||||
eval(sprintf("\$result = \$exp1 $op \$exp2;"));
|
||||
if (!$this->ok($result, $message))
|
||||
{
|
||||
$this->output->diag(sprintf(" %s", str_replace("\n", '', var_export($exp1, true))), sprintf(" %s", $op), sprintf(" %s", str_replace("\n", '', var_export($exp2, true))));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function can_ok($object, $methods, $message = '')
|
||||
{
|
||||
$result = true;
|
||||
$failed_messages = array();
|
||||
foreach ((array) $methods as $method)
|
||||
{
|
||||
if (!method_exists($object, $method))
|
||||
{
|
||||
$failed_messages[] = sprintf(" method '%s' does not exist", $method);
|
||||
$result = false;
|
||||
}
|
||||
}
|
||||
|
||||
!$this->ok($result, $message);
|
||||
|
||||
!$result and $this->output->diag($failed_messages);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function isa_ok($var, $class, $message = '')
|
||||
{
|
||||
$type = is_object($var) ? get_class($var) : gettype($var);
|
||||
if (!$result = $this->ok($type == $class, $message))
|
||||
{
|
||||
$this->output->diag(sprintf(" isa_ok isn't a '%s' it's a '%s'", $class, $type));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function is_deeply($exp1, $exp2, $message = '')
|
||||
{
|
||||
if (!$result = $this->ok($this->test_is_deeply($exp1, $exp2), $message))
|
||||
{
|
||||
$this->output->diag(sprintf(" got: %s", str_replace("\n", '', var_export($exp1, true))), sprintf(" expected: %s", str_replace("\n", '', var_export($exp2, true))));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function pass($message = '')
|
||||
{
|
||||
return $this->ok(true, $message);
|
||||
}
|
||||
|
||||
function fail($message = '')
|
||||
{
|
||||
return $this->ok(false, $message);
|
||||
}
|
||||
|
||||
function diag($message)
|
||||
{
|
||||
$this->output->diag($message);
|
||||
}
|
||||
|
||||
function skip($message = '', $nb_tests = 1)
|
||||
{
|
||||
for ($i = 0; $i < $nb_tests; $i++)
|
||||
{
|
||||
++$this->skipped and --$this->passed;
|
||||
$this->pass(sprintf("# SKIP%s", $message ? ' '.$message : ''));
|
||||
}
|
||||
}
|
||||
|
||||
function todo($message = '')
|
||||
{
|
||||
++$this->skipped and --$this->passed;
|
||||
$this->pass(sprintf("# TODO%s", $message ? ' '.$message : ''));
|
||||
}
|
||||
|
||||
function include_ok($file, $message = '')
|
||||
{
|
||||
if (!$result = $this->ok((@include($file)) == 1, $message))
|
||||
{
|
||||
$this->output->diag(sprintf(" Tried to include '%s'", $file));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function test_is_deeply($var1, $var2)
|
||||
{
|
||||
if (gettype($var1) != gettype($var2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_array($var1))
|
||||
{
|
||||
ksort($var1);
|
||||
ksort($var2);
|
||||
if (array_diff(array_keys($var1), array_keys($var2)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$is_equal = true;
|
||||
foreach ($var1 as $key => $value)
|
||||
{
|
||||
$is_equal = $this->test_is_deeply($var1[$key], $var2[$key]);
|
||||
if ($is_equal === false)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $is_equal;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $var1 === $var2;
|
||||
}
|
||||
}
|
||||
|
||||
function comment($message)
|
||||
{
|
||||
$this->output->comment($message);
|
||||
}
|
||||
|
||||
static function get_temp_directory()
|
||||
{
|
||||
if ('\\' == DIRECTORY_SEPARATOR)
|
||||
{
|
||||
foreach (array('TEMP', 'TMP', 'windir') as $dir)
|
||||
{
|
||||
if ($var = isset($_ENV[$dir]) ? $_ENV[$dir] : getenv($dir))
|
||||
{
|
||||
return $var;
|
||||
}
|
||||
}
|
||||
|
||||
return getenv('SystemRoot').'\temp';
|
||||
}
|
||||
|
||||
if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR'))
|
||||
{
|
||||
return $var;
|
||||
}
|
||||
|
||||
return '/tmp';
|
||||
}
|
||||
}
|
||||
|
||||
class lime_output
|
||||
{
|
||||
function diag()
|
||||
{
|
||||
$messages = func_get_args();
|
||||
foreach ($messages as $message)
|
||||
{
|
||||
array_map(array($this, 'comment'), (array) $message);
|
||||
}
|
||||
}
|
||||
|
||||
function comment($message)
|
||||
{
|
||||
echo "# $message\n";
|
||||
}
|
||||
|
||||
function echoln($message)
|
||||
{
|
||||
echo "$message\n";
|
||||
}
|
||||
|
||||
function green_bar($message)
|
||||
{
|
||||
echo "$message\n";
|
||||
}
|
||||
|
||||
function red_bar($message)
|
||||
{
|
||||
echo "$message\n";
|
||||
}
|
||||
}
|
||||
|
||||
class lime_output_color extends lime_output
|
||||
{
|
||||
public $colorizer = null;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->colorizer = new lime_colorizer();
|
||||
}
|
||||
|
||||
function diag()
|
||||
{
|
||||
$messages = func_get_args();
|
||||
foreach ($messages as $message)
|
||||
{
|
||||
echo $this->colorizer->colorize('# '.join("\n# ", (array) $message), 'COMMENT')."\n";
|
||||
}
|
||||
}
|
||||
|
||||
function comment($message)
|
||||
{
|
||||
echo $this->colorizer->colorize(sprintf('# %s', $message), 'COMMENT')."\n";
|
||||
}
|
||||
|
||||
function echoln($message, $colorizer_parameter = null)
|
||||
{
|
||||
$message = preg_replace('/(?:^|\.)((?:not ok|dubious) *\d*)\b/e', '$this->colorizer->colorize(\'$1\', \'ERROR\')', $message);
|
||||
$message = preg_replace('/(?:^|\.)(ok *\d*)\b/e', '$this->colorizer->colorize(\'$1\', \'INFO\')', $message);
|
||||
$message = preg_replace('/"(.+?)"/e', '$this->colorizer->colorize(\'$1\', \'PARAMETER\')', $message);
|
||||
$message = preg_replace('/(\->|\:\:)?([a-zA-Z0-9_]+?)\(\)/e', '$this->colorizer->colorize(\'$1$2()\', \'PARAMETER\')', $message);
|
||||
|
||||
echo ($colorizer_parameter ? $this->colorizer->colorize($message, $colorizer_parameter) : $message)."\n";
|
||||
}
|
||||
|
||||
function green_bar($message)
|
||||
{
|
||||
echo $this->colorizer->colorize($message.str_repeat(' ', 71 - min(71, strlen($message))), 'GREEN_BAR')."\n";
|
||||
}
|
||||
|
||||
function red_bar($message)
|
||||
{
|
||||
echo $this->colorizer->colorize($message.str_repeat(' ', 71 - min(71, strlen($message))), 'RED_BAR')."\n";
|
||||
}
|
||||
}
|
||||
|
||||
class lime_colorizer
|
||||
{
|
||||
static public $styles = array();
|
||||
|
||||
static function style($name, $options = array())
|
||||
{
|
||||
self::$styles[$name] = $options;
|
||||
}
|
||||
|
||||
static function colorize($text = '', $parameters = array())
|
||||
{
|
||||
// disable colors if not supported (windows or non tty console)
|
||||
if (DIRECTORY_SEPARATOR == '\\' || !function_exists('posix_isatty') || !@posix_isatty(STDOUT))
|
||||
{
|
||||
return $text;
|
||||
}
|
||||
|
||||
static $options = array('bold' => 1, 'underscore' => 4, 'blink' => 5, 'reverse' => 7, 'conceal' => 8);
|
||||
static $foreground = array('black' => 30, 'red' => 31, 'green' => 32, 'yellow' => 33, 'blue' => 34, 'magenta' => 35, 'cyan' => 36, 'white' => 37);
|
||||
static $background = array('black' => 40, 'red' => 41, 'green' => 42, 'yellow' => 43, 'blue' => 44, 'magenta' => 45, 'cyan' => 46, 'white' => 47);
|
||||
|
||||
!is_array($parameters) && isset(self::$styles[$parameters]) and $parameters = self::$styles[$parameters];
|
||||
|
||||
$codes = array();
|
||||
isset($parameters['fg']) and $codes[] = $foreground[$parameters['fg']];
|
||||
isset($parameters['bg']) and $codes[] = $background[$parameters['bg']];
|
||||
foreach ($options as $option => $value)
|
||||
{
|
||||
isset($parameters[$option]) && $parameters[$option] and $codes[] = $value;
|
||||
}
|
||||
|
||||
return "\033[".implode(';', $codes).'m'.$text."\033[0m";
|
||||
}
|
||||
}
|
||||
|
||||
lime_colorizer::style('ERROR', array('bg' => 'red', 'fg' => 'white', 'bold' => true));
|
||||
lime_colorizer::style('INFO', array('fg' => 'green', 'bold' => true));
|
||||
lime_colorizer::style('PARAMETER', array('fg' => 'cyan'));
|
||||
lime_colorizer::style('COMMENT', array('fg' => 'yellow'));
|
||||
|
||||
lime_colorizer::style('GREEN_BAR', array('fg' => 'white', 'bg' => 'green', 'bold' => true));
|
||||
lime_colorizer::style('RED_BAR', array('fg' => 'white', 'bg' => 'red', 'bold' => true));
|
||||
|
||||
class lime_harness extends lime_registration
|
||||
{
|
||||
public $php_cli = '';
|
||||
public $stats = array();
|
||||
public $output = null;
|
||||
|
||||
function __construct($output_instance, $php_cli = null)
|
||||
{
|
||||
if (getenv('PHP_PATH'))
|
||||
{
|
||||
$this->php_cli = getenv('PHP_PATH');
|
||||
|
||||
if (!is_executable($this->php_cli))
|
||||
{
|
||||
throw new Exception('The defined PHP_PATH environment variable is not a valid PHP executable.');
|
||||
}
|
||||
}
|
||||
|
||||
$this->php_cli = null === $php_cli ? PHP_BINDIR.DIRECTORY_SEPARATOR.'php' : $php_cli;
|
||||
|
||||
if (!is_executable($this->php_cli))
|
||||
{
|
||||
$this->php_cli = $this->find_php_cli();
|
||||
}
|
||||
|
||||
$this->output = $output_instance ? $output_instance : new lime_output();
|
||||
}
|
||||
|
||||
protected function find_php_cli()
|
||||
{
|
||||
$path = getenv('PATH') ? getenv('PATH') : getenv('Path');
|
||||
$exe_suffixes = DIRECTORY_SEPARATOR == '\\' ? (getenv('PATHEXT') ? explode(PATH_SEPARATOR, getenv('PATHEXT')) : array('.exe', '.bat', '.cmd', '.com')) : array('');
|
||||
foreach (array('php5', 'php') as $php_cli)
|
||||
{
|
||||
foreach ($exe_suffixes as $suffix)
|
||||
{
|
||||
foreach (explode(PATH_SEPARATOR, $path) as $dir)
|
||||
{
|
||||
$file = $dir.DIRECTORY_SEPARATOR.$php_cli.$suffix;
|
||||
if (is_executable($file))
|
||||
{
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception("Unable to find PHP executable.");
|
||||
}
|
||||
|
||||
function run()
|
||||
{
|
||||
if (!count($this->files))
|
||||
{
|
||||
throw new Exception('You must register some test files before running them!');
|
||||
}
|
||||
|
||||
// sort the files to be able to predict the order
|
||||
sort($this->files);
|
||||
|
||||
$this->stats =array(
|
||||
'_failed_files' => array(),
|
||||
'_failed_tests' => 0,
|
||||
'_nb_tests' => 0,
|
||||
);
|
||||
|
||||
foreach ($this->files as $file)
|
||||
{
|
||||
$this->stats[$file] = array(
|
||||
'plan' => null,
|
||||
'nb_tests' => 0,
|
||||
'failed' => array(),
|
||||
'passed' => array(),
|
||||
);
|
||||
$this->current_file = $file;
|
||||
$this->current_test = 0;
|
||||
$relative_file = $this->get_relative_file($file);
|
||||
|
||||
ob_start(array($this, 'process_test_output'));
|
||||
passthru(sprintf('%s -d html_errors=off -d open_basedir= -q "%s" 2>&1', $this->php_cli, $file), $return);
|
||||
ob_end_clean();
|
||||
|
||||
if ($return > 0)
|
||||
{
|
||||
$this->stats[$file]['status'] = 'dubious';
|
||||
$this->stats[$file]['status_code'] = $return;
|
||||
}
|
||||
else
|
||||
{
|
||||
$delta = $this->stats[$file]['plan'] - $this->stats[$file]['nb_tests'];
|
||||
if ($delta > 0)
|
||||
{
|
||||
$this->output->echoln(sprintf('%s%s%s', substr($relative_file, -min(67, strlen($relative_file))), str_repeat('.', 70 - min(67, strlen($relative_file))), $this->output->colorizer->colorize(sprintf('# Looks like you planned %d tests but only ran %d.', $this->stats[$file]['plan'], $this->stats[$file]['nb_tests']), 'COMMENT')));
|
||||
$this->stats[$file]['status'] = 'dubious';
|
||||
$this->stats[$file]['status_code'] = 255;
|
||||
$this->stats['_nb_tests'] += $delta;
|
||||
for ($i = 1; $i <= $delta; $i++)
|
||||
{
|
||||
$this->stats[$file]['failed'][] = $this->stats[$file]['nb_tests'] + $i;
|
||||
}
|
||||
}
|
||||
else if ($delta < 0)
|
||||
{
|
||||
$this->output->echoln(sprintf('%s%s%s', substr($relative_file, -min(67, strlen($relative_file))), str_repeat('.', 70 - min(67, strlen($relative_file))), $this->output->colorizer->colorize(sprintf('# Looks like you planned %s test but ran %s extra.', $this->stats[$file]['plan'], $this->stats[$file]['nb_tests'] - $this->stats[$file]['plan']), 'COMMENT')));
|
||||
$this->stats[$file]['status'] = 'dubious';
|
||||
$this->stats[$file]['status_code'] = 255;
|
||||
for ($i = 1; $i <= -$delta; $i++)
|
||||
{
|
||||
$this->stats[$file]['failed'][] = $this->stats[$file]['plan'] + $i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->stats[$file]['status_code'] = 0;
|
||||
$this->stats[$file]['status'] = $this->stats[$file]['failed'] ? 'not ok' : 'ok';
|
||||
}
|
||||
}
|
||||
|
||||
$this->output->echoln(sprintf('%s%s%s', substr($relative_file, -min(67, strlen($relative_file))), str_repeat('.', 70 - min(67, strlen($relative_file))), $this->stats[$file]['status']));
|
||||
if (($nb = count($this->stats[$file]['failed'])) || $return > 0)
|
||||
{
|
||||
if ($nb)
|
||||
{
|
||||
$this->output->echoln(sprintf(" Failed tests: %s", implode(', ', $this->stats[$file]['failed'])));
|
||||
}
|
||||
$this->stats['_failed_files'][] = $file;
|
||||
$this->stats['_failed_tests'] += $nb;
|
||||
}
|
||||
|
||||
if ('dubious' == $this->stats[$file]['status'])
|
||||
{
|
||||
$this->output->echoln(sprintf(' Test returned status %s', $this->stats[$file]['status_code']));
|
||||
}
|
||||
}
|
||||
|
||||
if (count($this->stats['_failed_files']))
|
||||
{
|
||||
$format = "%-30s %4s %5s %5s %s";
|
||||
$this->output->echoln(sprintf($format, 'Failed Test', 'Stat', 'Total', 'Fail', 'List of Failed'));
|
||||
$this->output->echoln("------------------------------------------------------------------");
|
||||
foreach ($this->stats as $file => $file_stat)
|
||||
{
|
||||
if (!in_array($file, $this->stats['_failed_files'])) continue;
|
||||
|
||||
$relative_file = $this->get_relative_file($file);
|
||||
$this->output->echoln(sprintf($format, substr($relative_file, -min(30, strlen($relative_file))), $file_stat['status_code'], count($file_stat['failed']) + count($file_stat['passed']), count($file_stat['failed']), implode(' ', $file_stat['failed'])));
|
||||
}
|
||||
|
||||
$this->output->red_bar(sprintf('Failed %d/%d test scripts, %.2f%% okay. %d/%d subtests failed, %.2f%% okay.',
|
||||
$nb_failed_files = count($this->stats['_failed_files']),
|
||||
$nb_files = count($this->files),
|
||||
($nb_files - $nb_failed_files) * 100 / $nb_files,
|
||||
$nb_failed_tests = $this->stats['_failed_tests'],
|
||||
$nb_tests = $this->stats['_nb_tests'],
|
||||
$nb_tests > 0 ? ($nb_tests - $nb_failed_tests) * 100 / $nb_tests : 0
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->output->green_bar(' All tests successful.');
|
||||
$this->output->green_bar(sprintf(' Files=%d, Tests=%d', count($this->files), $this->stats['_nb_tests']));
|
||||
}
|
||||
|
||||
return $this->stats['_failed_tests'] ? false : true;
|
||||
}
|
||||
|
||||
private function process_test_output($lines)
|
||||
{
|
||||
foreach (explode("\n", $lines) as $text)
|
||||
{
|
||||
if (false !== strpos($text, 'not ok '))
|
||||
{
|
||||
++$this->current_test;
|
||||
$test_number = (int) substr($text, 7);
|
||||
$this->stats[$this->current_file]['failed'][] = $test_number;
|
||||
|
||||
++$this->stats[$this->current_file]['nb_tests'];
|
||||
++$this->stats['_nb_tests'];
|
||||
}
|
||||
else if (false !== strpos($text, 'ok '))
|
||||
{
|
||||
++$this->stats[$this->current_file]['nb_tests'];
|
||||
++$this->stats['_nb_tests'];
|
||||
}
|
||||
else if (preg_match('/^1\.\.(\d+)/', $text, $match))
|
||||
{
|
||||
$this->stats[$this->current_file]['plan'] = $match[1];
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
class lime_coverage extends lime_registration
|
||||
{
|
||||
public $files = array();
|
||||
public $extension = '.php';
|
||||
public $base_dir = '';
|
||||
public $harness = null;
|
||||
public $verbose = false;
|
||||
|
||||
function __construct($harness)
|
||||
{
|
||||
$this->harness = $harness;
|
||||
}
|
||||
|
||||
function run()
|
||||
{
|
||||
if (!function_exists('xdebug_start_code_coverage'))
|
||||
{
|
||||
throw new Exception('You must install and enable xdebug before using lime coverage.');
|
||||
}
|
||||
|
||||
if (!ini_get('xdebug.extended_info'))
|
||||
{
|
||||
throw new Exception('You must set xdebug.extended_info to 1 in your php.ini to use lime coverage.');
|
||||
}
|
||||
|
||||
if (!count($this->harness->files))
|
||||
{
|
||||
throw new Exception('You must register some test files before running coverage!');
|
||||
}
|
||||
|
||||
if (!count($this->files))
|
||||
{
|
||||
throw new Exception('You must register some files to cover!');
|
||||
}
|
||||
|
||||
$coverage = array();
|
||||
$tmp_file = lime_test::get_temp_directory().DIRECTORY_SEPARATOR.'test.php';
|
||||
foreach ($this->harness->files as $file)
|
||||
{
|
||||
$tmp = <<<EOF
|
||||
<?php
|
||||
xdebug_start_code_coverage();
|
||||
ob_start();
|
||||
include('$file');
|
||||
ob_end_clean();
|
||||
echo '<PHP_SER>'.serialize(xdebug_get_code_coverage()).'</PHP_SER>';
|
||||
EOF;
|
||||
file_put_contents($tmp_file, $tmp);
|
||||
ob_start();
|
||||
passthru(sprintf('%s -d html_errors=off -d open_basedir= -q "%s" 2>&1', $this->harness->php_cli, $tmp_file), $return);
|
||||
$retval = ob_get_clean();
|
||||
if (0 == $return)
|
||||
{
|
||||
if (false === $cov = unserialize(substr($retval, strpos($retval, '<PHP_SER>') + 9, strpos($retval, '</PHP_SER>') - 9)))
|
||||
{
|
||||
throw new Exception(sprintf('Unable to unserialize coverage for file "%s"', $file));
|
||||
}
|
||||
|
||||
foreach ($cov as $file => $lines)
|
||||
{
|
||||
if (!isset($coverage[$file]))
|
||||
{
|
||||
$coverage[$file] = array();
|
||||
}
|
||||
|
||||
foreach ($lines as $line => $count)
|
||||
{
|
||||
if (!isset($coverage[$file][$line]))
|
||||
{
|
||||
$coverage[$file][$line] = 0;
|
||||
}
|
||||
$coverage[$file][$line] = $coverage[$file][$line] + $count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
unlink($tmp_file);
|
||||
|
||||
ksort($coverage);
|
||||
$total_php_lines = 0;
|
||||
$total_covered_lines = 0;
|
||||
foreach ($this->files as $file)
|
||||
{
|
||||
$cov = isset($coverage[$file]) ? $coverage[$file] : array();
|
||||
|
||||
list($cov, $php_lines) = $this->compute(file_get_contents($file), $cov);
|
||||
|
||||
$output = $this->harness->output;
|
||||
$percent = count($php_lines) ? count($cov) * 100 / count($php_lines) : 100;
|
||||
|
||||
$total_php_lines += count($php_lines);
|
||||
$total_covered_lines += count($cov);
|
||||
|
||||
$relative_file = $this->get_relative_file($file);
|
||||
$output->echoln(sprintf("%-70s %3.0f%%", substr($relative_file, -min(70, strlen($relative_file))), $percent), $percent == 100 ? 'INFO' : ($percent > 90 ? 'PARAMETER' : ($percent < 20 ? 'ERROR' : '')));
|
||||
if ($this->verbose && $percent != 100)
|
||||
{
|
||||
$output->comment(sprintf("missing: %s", $this->format_range(array_keys(array_diff_key($php_lines, $cov)))));
|
||||
}
|
||||
}
|
||||
|
||||
$output->echoln(sprintf("TOTAL COVERAGE: %3.0f%%", $total_covered_lines * 100 / $total_php_lines));
|
||||
}
|
||||
|
||||
static function get_php_lines($content)
|
||||
{
|
||||
if (is_file($content))
|
||||
{
|
||||
$content = file_get_contents($content);
|
||||
}
|
||||
|
||||
$tokens = token_get_all($content);
|
||||
$php_lines = array();
|
||||
$current_line = 1;
|
||||
$in_class = false;
|
||||
$in_function = false;
|
||||
$in_function_declaration = false;
|
||||
$end_of_current_expr = true;
|
||||
$open_braces = 0;
|
||||
foreach ($tokens as $token)
|
||||
{
|
||||
if (is_string($token))
|
||||
{
|
||||
switch ($token)
|
||||
{
|
||||
case '=':
|
||||
if (false === $in_class || (false !== $in_function && !$in_function_declaration))
|
||||
{
|
||||
$php_lines[$current_line] = true;
|
||||
}
|
||||
break;
|
||||
case '{':
|
||||
++$open_braces;
|
||||
$in_function_declaration = false;
|
||||
break;
|
||||
case ';':
|
||||
$in_function_declaration = false;
|
||||
$end_of_current_expr = true;
|
||||
break;
|
||||
case '}':
|
||||
$end_of_current_expr = true;
|
||||
--$open_braces;
|
||||
if ($open_braces == $in_class)
|
||||
{
|
||||
$in_class = false;
|
||||
}
|
||||
if ($open_braces == $in_function)
|
||||
{
|
||||
$in_function = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
list($id, $text) = $token;
|
||||
|
||||
switch ($id)
|
||||
{
|
||||
case T_CURLY_OPEN:
|
||||
case T_DOLLAR_OPEN_CURLY_BRACES:
|
||||
++$open_braces;
|
||||
break;
|
||||
case T_WHITESPACE:
|
||||
case T_OPEN_TAG:
|
||||
case T_CLOSE_TAG:
|
||||
$end_of_current_expr = true;
|
||||
$current_line += count(explode("\n", $text)) - 1;
|
||||
break;
|
||||
case T_COMMENT:
|
||||
case T_DOC_COMMENT:
|
||||
$current_line += count(explode("\n", $text)) - 1;
|
||||
break;
|
||||
case T_CLASS:
|
||||
$in_class = $open_braces;
|
||||
break;
|
||||
case T_FUNCTION:
|
||||
$in_function = $open_braces;
|
||||
$in_function_declaration = true;
|
||||
break;
|
||||
case T_AND_EQUAL:
|
||||
case T_CASE:
|
||||
case T_CATCH:
|
||||
case T_CLONE:
|
||||
case T_CONCAT_EQUAL:
|
||||
case T_CONTINUE:
|
||||
case T_DEC:
|
||||
case T_DECLARE:
|
||||
case T_DEFAULT:
|
||||
case T_DIV_EQUAL:
|
||||
case T_DO:
|
||||
case T_ECHO:
|
||||
case T_ELSEIF:
|
||||
case T_EMPTY:
|
||||
case T_ENDDECLARE:
|
||||
case T_ENDFOR:
|
||||
case T_ENDFOREACH:
|
||||
case T_ENDIF:
|
||||
case T_ENDSWITCH:
|
||||
case T_ENDWHILE:
|
||||
case T_EVAL:
|
||||
case T_EXIT:
|
||||
case T_FOR:
|
||||
case T_FOREACH:
|
||||
case T_GLOBAL:
|
||||
case T_IF:
|
||||
case T_INC:
|
||||
case T_INCLUDE:
|
||||
case T_INCLUDE_ONCE:
|
||||
case T_INSTANCEOF:
|
||||
case T_ISSET:
|
||||
case T_IS_EQUAL:
|
||||
case T_IS_GREATER_OR_EQUAL:
|
||||
case T_IS_IDENTICAL:
|
||||
case T_IS_NOT_EQUAL:
|
||||
case T_IS_NOT_IDENTICAL:
|
||||
case T_IS_SMALLER_OR_EQUAL:
|
||||
case T_LIST:
|
||||
case T_LOGICAL_AND:
|
||||
case T_LOGICAL_OR:
|
||||
case T_LOGICAL_XOR:
|
||||
case T_MINUS_EQUAL:
|
||||
case T_MOD_EQUAL:
|
||||
case T_MUL_EQUAL:
|
||||
case T_NEW:
|
||||
case T_OBJECT_OPERATOR:
|
||||
case T_OR_EQUAL:
|
||||
case T_PLUS_EQUAL:
|
||||
case T_PRINT:
|
||||
case T_REQUIRE:
|
||||
case T_REQUIRE_ONCE:
|
||||
case T_RETURN:
|
||||
case T_SL:
|
||||
case T_SL_EQUAL:
|
||||
case T_SR:
|
||||
case T_SR_EQUAL:
|
||||
case T_THROW:
|
||||
case T_TRY:
|
||||
case T_UNSET:
|
||||
case T_UNSET_CAST:
|
||||
case T_USE:
|
||||
case T_WHILE:
|
||||
case T_XOR_EQUAL:
|
||||
$php_lines[$current_line] = true;
|
||||
$end_of_current_expr = false;
|
||||
break;
|
||||
default:
|
||||
if (false === $end_of_current_expr)
|
||||
{
|
||||
$php_lines[$current_line] = true;
|
||||
}
|
||||
//print "$current_line: ".token_name($id)."\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $php_lines;
|
||||
}
|
||||
|
||||
function compute($content, $cov)
|
||||
{
|
||||
$php_lines = self::get_php_lines($content);
|
||||
|
||||
// we remove from $cov non php lines
|
||||
foreach (array_diff_key($cov, $php_lines) as $line => $tmp)
|
||||
{
|
||||
unset($cov[$line]);
|
||||
}
|
||||
|
||||
return array($cov, $php_lines);
|
||||
}
|
||||
|
||||
function format_range($lines)
|
||||
{
|
||||
sort($lines);
|
||||
$formatted = '';
|
||||
$first = -1;
|
||||
$last = -1;
|
||||
foreach ($lines as $line)
|
||||
{
|
||||
if ($last + 1 != $line)
|
||||
{
|
||||
if ($first != -1)
|
||||
{
|
||||
$formatted .= $first == $last ? "$first " : "[$first - $last] ";
|
||||
}
|
||||
$first = $line;
|
||||
$last = $line;
|
||||
}
|
||||
else
|
||||
{
|
||||
$last = $line;
|
||||
}
|
||||
}
|
||||
if ($first != -1)
|
||||
{
|
||||
$formatted .= $first == $last ? "$first " : "[$first - $last] ";
|
||||
}
|
||||
|
||||
return $formatted;
|
||||
}
|
||||
}
|
||||
|
||||
class lime_registration
|
||||
{
|
||||
public $files = array();
|
||||
public $extension = '.php';
|
||||
public $base_dir = '';
|
||||
|
||||
function register($files_or_directories)
|
||||
{
|
||||
foreach ((array) $files_or_directories as $f_or_d)
|
||||
{
|
||||
if (is_file($f_or_d))
|
||||
{
|
||||
$this->files[] = realpath($f_or_d);
|
||||
}
|
||||
elseif (is_dir($f_or_d))
|
||||
{
|
||||
$this->register_dir($f_or_d);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(sprintf('The file or directory "%s" does not exist.', $f_or_d));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function register_glob($glob)
|
||||
{
|
||||
if ($dirs = glob($glob))
|
||||
{
|
||||
foreach ($dirs as $file)
|
||||
{
|
||||
$this->files[] = realpath($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function register_dir($directory)
|
||||
{
|
||||
if (!is_dir($directory))
|
||||
{
|
||||
throw new Exception(sprintf('The directory "%s" does not exist.', $directory));
|
||||
}
|
||||
|
||||
$files = array();
|
||||
|
||||
$current_dir = opendir($directory);
|
||||
while ($entry = readdir($current_dir))
|
||||
{
|
||||
if ($entry == '.' || $entry == '..') continue;
|
||||
|
||||
if (is_dir($entry))
|
||||
{
|
||||
$this->register_dir($entry);
|
||||
}
|
||||
elseif (preg_match('#'.$this->extension.'$#', $entry))
|
||||
{
|
||||
$files[] = realpath($directory.DIRECTORY_SEPARATOR.$entry);
|
||||
}
|
||||
}
|
||||
|
||||
$this->files = array_merge($this->files, $files);
|
||||
}
|
||||
|
||||
protected function get_relative_file($file)
|
||||
{
|
||||
return str_replace(DIRECTORY_SEPARATOR, '/', str_replace(array(realpath($this->base_dir).DIRECTORY_SEPARATOR, $this->extension), '', $file));
|
||||
}
|
||||
}
|
||||
458
lib/symfony/vendor/pake/pakeApp.class.php
vendored
Executable file
458
lib/symfony/vendor/pake/pakeApp.class.php
vendored
Executable file
@ -0,0 +1,458 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeApp.class.php 4623 2007-07-16 12:34:38Z fabien $
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* main pake class.
|
||||
*
|
||||
* This class is a singleton.
|
||||
*
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeApp.class.php 4623 2007-07-16 12:34:38Z fabien $
|
||||
*/
|
||||
class pakeApp
|
||||
{
|
||||
const VERSION = '1.1.DEV';
|
||||
|
||||
private static $MAX_LINE_SIZE = 65;
|
||||
private static $PROPERTIES = array();
|
||||
private static $PAKEFILES = array('pakefile', 'Pakefile', 'pakefile.php', 'Pakefile.php');
|
||||
private static $PLUGINDIRS = array();
|
||||
private static $OPTIONS = array(
|
||||
array('--dry-run', '-n', pakeGetopt::NO_ARGUMENT, "Do a dry run without executing actions."),
|
||||
array('--help', '-H', pakeGetopt::NO_ARGUMENT, "Display this help message."),
|
||||
array('--libdir', '-I', pakeGetopt::REQUIRED_ARGUMENT, "Include LIBDIR in the search path for required modules."),
|
||||
array('--nosearch', '-N', pakeGetopt::NO_ARGUMENT, "Do not search parent directories for the pakefile."),
|
||||
array('--prereqs', '-P', pakeGetopt::NO_ARGUMENT, "Display the tasks and dependencies, then exit."),
|
||||
array('--quiet', '-q', pakeGetopt::NO_ARGUMENT, "Do not log messages to standard output."),
|
||||
array('--pakefile', '-f', pakeGetopt::REQUIRED_ARGUMENT, "Use FILE as the pakefile."),
|
||||
array('--require', '-r', pakeGetopt::REQUIRED_ARGUMENT, "Require MODULE before executing pakefile."),
|
||||
array('--tasks', '-T', pakeGetopt::NO_ARGUMENT, "Display the tasks and dependencies, then exit."),
|
||||
array('--trace', '-t', pakeGetopt::NO_ARGUMENT, "Turn on invoke/execute tracing, enable full backtrace."),
|
||||
array('--usage', '-h', pakeGetopt::NO_ARGUMENT, "Display usage."),
|
||||
array('--verbose', '-v', pakeGetopt::NO_ARGUMENT, "Log message to standard output (default)."),
|
||||
array('--version', '-V', pakeGetopt::NO_ARGUMENT, "Display the program version."),
|
||||
);
|
||||
|
||||
private $opt = null;
|
||||
private $nosearch = false;
|
||||
private $trace = false;
|
||||
private $verbose = true;
|
||||
private $dryrun = false;
|
||||
private $nowrite = false;
|
||||
private $show_tasks = false;
|
||||
private $show_prereqs = false;
|
||||
private $pakefile = '';
|
||||
private static $instance = null;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
self::$PLUGINDIRS[] = dirname(__FILE__).'/tasks';
|
||||
}
|
||||
|
||||
public static function get_plugin_dirs()
|
||||
{
|
||||
return self::$PLUGINDIRS;
|
||||
}
|
||||
|
||||
public function get_properties()
|
||||
{
|
||||
return self::$PROPERTIES;
|
||||
}
|
||||
|
||||
public function set_properties($properties)
|
||||
{
|
||||
self::$PROPERTIES = $properties;
|
||||
}
|
||||
|
||||
public static function get_instance()
|
||||
{
|
||||
if (!self::$instance) self::$instance = new pakeApp();
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function get_verbose()
|
||||
{
|
||||
return $this->verbose;
|
||||
}
|
||||
|
||||
public function get_trace()
|
||||
{
|
||||
return $this->trace;
|
||||
}
|
||||
|
||||
public function get_dryrun()
|
||||
{
|
||||
return $this->dryrun;
|
||||
}
|
||||
|
||||
public function run($pakefile = null, $options = null, $load_pakefile = true)
|
||||
{
|
||||
if ($pakefile)
|
||||
{
|
||||
pakeApp::$PAKEFILES = array($pakefile);
|
||||
}
|
||||
|
||||
$this->handle_options($options);
|
||||
if ($load_pakefile)
|
||||
{
|
||||
$this->load_pakefile();
|
||||
}
|
||||
|
||||
if ($this->show_tasks)
|
||||
{
|
||||
$this->display_tasks_and_comments();
|
||||
}
|
||||
else if ($this->show_prereqs)
|
||||
{
|
||||
$this->display_prerequisites();
|
||||
}
|
||||
else
|
||||
{
|
||||
$args = $this->opt->get_arguments();
|
||||
$task = array_shift($args);
|
||||
|
||||
$options = array();
|
||||
for ($i = 0, $max = count($args); $i < $max; $i++)
|
||||
{
|
||||
if (0 === strpos($args[$i], '--'))
|
||||
{
|
||||
if (false !== $pos = strpos($args[$i], '='))
|
||||
{
|
||||
$key = substr($args[$i], 2, $pos - 2);
|
||||
$value = substr($args[$i], $pos + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$key = substr($args[$i], 2);
|
||||
$value = true;
|
||||
}
|
||||
if ('[]' == substr($key, -2))
|
||||
{
|
||||
if (!isset($options[$key]))
|
||||
{
|
||||
$options[$key] = array();
|
||||
}
|
||||
$options[$key][] = $value;
|
||||
}
|
||||
else
|
||||
{
|
||||
$options[$key] = $value;
|
||||
}
|
||||
unset($args[$i]);
|
||||
}
|
||||
}
|
||||
$args = array_values($args);
|
||||
|
||||
$abbrev_options = $this->abbrev(array_keys(pakeTask::get_tasks()));
|
||||
$task = pakeTask::get_full_task_name($task);
|
||||
if (!$task)
|
||||
{
|
||||
$task = 'default';
|
||||
}
|
||||
|
||||
if (!array_key_exists($task, $abbrev_options))
|
||||
{
|
||||
throw new pakeException(sprintf('Task "%s" is not defined.', $task));
|
||||
}
|
||||
else if (count($abbrev_options[$task]) > 1)
|
||||
{
|
||||
throw new pakeException(sprintf('Task "%s" is ambiguous (%s).', $task, implode(', ', $abbrev_options[$task])));
|
||||
}
|
||||
else
|
||||
{
|
||||
return pakeTask::get($abbrev_options[$task][0])->invoke($args, $options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read and handle the command line options.
|
||||
public function handle_options($options = null)
|
||||
{
|
||||
$this->opt = new pakeGetopt(pakeApp::$OPTIONS);
|
||||
$this->opt->parse($options);
|
||||
foreach ($this->opt->get_options() as $opt => $value)
|
||||
{
|
||||
$this->do_option($opt, $value);
|
||||
}
|
||||
}
|
||||
|
||||
// True if one of the files in RAKEFILES is in the current directory.
|
||||
// If a match is found, it is copied into @pakefile.
|
||||
public function have_pakefile()
|
||||
{
|
||||
foreach (pakeApp::$PAKEFILES as $file)
|
||||
{
|
||||
if (file_exists($file))
|
||||
{
|
||||
$this->pakefile = $file;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function load_pakefile()
|
||||
{
|
||||
$here = getcwd();
|
||||
while (!$this->have_pakefile())
|
||||
{
|
||||
chdir('..');
|
||||
if (getcwd() == $here || $this->nosearch)
|
||||
{
|
||||
throw new pakeException(sprintf('No pakefile found (looking for: %s)', join(', ', pakeApp::$PAKEFILES))."\n");
|
||||
}
|
||||
|
||||
$here = getcwd();
|
||||
}
|
||||
|
||||
require_once($this->pakefile);
|
||||
}
|
||||
|
||||
// Do the option defined by +opt+ and +value+.
|
||||
public function do_option($opt, $value)
|
||||
{
|
||||
switch ($opt)
|
||||
{
|
||||
case 'dry-run':
|
||||
$this->verbose = true;
|
||||
$this->nowrite = true;
|
||||
$this->dryrun = true;
|
||||
$this->trace = true;
|
||||
break;
|
||||
case 'help':
|
||||
$this->help();
|
||||
exit();
|
||||
case 'libdir':
|
||||
set_include_path($value.PATH_SEPARATOR.get_include_path());
|
||||
break;
|
||||
case 'nosearch':
|
||||
$this->nosearch = true;
|
||||
break;
|
||||
case 'prereqs':
|
||||
$this->show_prereqs = true;
|
||||
break;
|
||||
case 'quiet':
|
||||
$this->verbose = false;
|
||||
break;
|
||||
case 'pakefile':
|
||||
pakeApp::$PAKEFILES = array($value);
|
||||
break;
|
||||
case 'require':
|
||||
require $value;
|
||||
break;
|
||||
case 'tasks':
|
||||
$this->show_tasks = true;
|
||||
break;
|
||||
case 'trace':
|
||||
$this->trace = true;
|
||||
$this->verbose = true;
|
||||
break;
|
||||
case 'usage':
|
||||
$this->usage();
|
||||
exit();
|
||||
case 'verbose':
|
||||
$this->verbose = true;
|
||||
break;
|
||||
case 'version':
|
||||
echo sprintf('pake version %s', pakeColor::colorize(pakeApp::VERSION, 'INFO'))."\n";
|
||||
exit();
|
||||
default:
|
||||
throw new pakeException(sprintf("Unknown option: %s", $opt));
|
||||
}
|
||||
}
|
||||
|
||||
// Display the program usage line.
|
||||
public function usage()
|
||||
{
|
||||
echo "pake [-f pakefile] {options} targets...\n".pakeColor::colorize("Try pake -H for more information", 'INFO')."\n";
|
||||
}
|
||||
|
||||
// Display the rake command line help.
|
||||
public function help()
|
||||
{
|
||||
$this->usage();
|
||||
echo "\n";
|
||||
echo "available options:";
|
||||
echo "\n";
|
||||
|
||||
foreach (pakeApp::$OPTIONS as $option)
|
||||
{
|
||||
list($long, $short, $mode, $comment) = $option;
|
||||
if ($mode == pakeGetopt::REQUIRED_ARGUMENT)
|
||||
{
|
||||
if (preg_match('/\b([A-Z]{2,})\b/', $comment, $match))
|
||||
$long .= '='.$match[1];
|
||||
}
|
||||
printf(" %-20s (%s)\n", pakeColor::colorize($long, 'INFO'), pakeColor::colorize($short, 'INFO'));
|
||||
printf(" %s\n", $comment);
|
||||
}
|
||||
}
|
||||
|
||||
// Display the tasks and dependencies.
|
||||
public function display_tasks_and_comments()
|
||||
{
|
||||
$width = 0;
|
||||
$tasks = pakeTask::get_tasks();
|
||||
foreach ($tasks as $name => $task)
|
||||
{
|
||||
$w = strlen(pakeTask::get_mini_task_name($name));
|
||||
if ($w > $width) $width = $w;
|
||||
}
|
||||
$width += strlen(pakeColor::colorize(' ', 'INFO'));
|
||||
|
||||
echo "available pake tasks:\n";
|
||||
|
||||
// display tasks
|
||||
$has_alias = false;
|
||||
ksort($tasks);
|
||||
foreach ($tasks as $name => $task)
|
||||
{
|
||||
if ($task->get_alias())
|
||||
{
|
||||
$has_alias = true;
|
||||
}
|
||||
|
||||
if (!$task->get_alias() && $task->get_comment())
|
||||
{
|
||||
$mini_name = pakeTask::get_mini_task_name($name);
|
||||
printf(' %-'.$width.'s > %s'."\n", pakeColor::colorize($mini_name, 'INFO'), $task->get_comment().($mini_name != $name ? ' ['.$name.']' : ''));
|
||||
}
|
||||
}
|
||||
|
||||
if ($has_alias)
|
||||
{
|
||||
print("\ntask aliases:\n");
|
||||
|
||||
// display aliases
|
||||
foreach ($tasks as $name => $task)
|
||||
{
|
||||
if ($task->get_alias())
|
||||
{
|
||||
$mini_name = pakeTask::get_mini_task_name($name);
|
||||
printf(' %-'.$width.'s = pake %s'."\n", pakeColor::colorize(pakeTask::get_mini_task_name($name), 'INFO'), $task->get_alias().($mini_name != $name ? ' ['.$name.']' : ''));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Display the tasks and prerequisites
|
||||
public function display_prerequisites()
|
||||
{
|
||||
foreach (pakeTask::get_tasks() as $name => $task)
|
||||
{
|
||||
echo "pake ".pakeTask::get_mini_task_name($name)."\n";
|
||||
foreach ($task->get_prerequisites() as $prerequisite)
|
||||
{
|
||||
echo " $prerequisite\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_files_from_argument($arg, $target_dir = '', $relative = false)
|
||||
{
|
||||
$files = array();
|
||||
if (is_array($arg))
|
||||
{
|
||||
$files = $arg;
|
||||
}
|
||||
else if (is_string($arg))
|
||||
{
|
||||
$files[] = $arg;
|
||||
}
|
||||
else if ($arg instanceof pakeFinder)
|
||||
{
|
||||
$files = $arg->in($target_dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new pakeException('Wrong argument type (must be a list, a string or a pakeFinder object).');
|
||||
}
|
||||
|
||||
if ($relative && $target_dir)
|
||||
{
|
||||
$files = preg_replace('/^'.preg_quote(realpath($target_dir), '/').'/', '', $files);
|
||||
|
||||
// remove leading /
|
||||
$files = array_map(create_function('$f', 'return 0 === strpos($f, DIRECTORY_SEPARATOR) ? substr($f, 1) : $f;'), $files);
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
public static function excerpt($text, $size = null)
|
||||
{
|
||||
if (!$size)
|
||||
{
|
||||
$size = self::$MAX_LINE_SIZE;
|
||||
}
|
||||
|
||||
if (strlen($text) < $size)
|
||||
{
|
||||
return $text;
|
||||
}
|
||||
|
||||
$subsize = floor(($size - 3) / 2);
|
||||
|
||||
return substr($text, 0, $subsize).pakeColor::colorize('...', 'INFO').substr($text, -$subsize);
|
||||
}
|
||||
|
||||
/* see perl Text::Abbrev module */
|
||||
private function abbrev($options)
|
||||
{
|
||||
$abbrevs = array();
|
||||
$table = array();
|
||||
|
||||
foreach ($options as $option)
|
||||
{
|
||||
$option = pakeTask::get_mini_task_name($option);
|
||||
|
||||
for ($len = (strlen($option)) - 1; $len > 0; --$len)
|
||||
{
|
||||
$abbrev = substr($option, 0, $len);
|
||||
if (!array_key_exists($abbrev, $table))
|
||||
$table[$abbrev] = 1;
|
||||
else
|
||||
++$table[$abbrev];
|
||||
|
||||
$seen = $table[$abbrev];
|
||||
if ($seen == 1)
|
||||
{
|
||||
// we're the first word so far to have this abbreviation.
|
||||
$abbrevs[$abbrev] = array($option);
|
||||
}
|
||||
else if ($seen == 2)
|
||||
{
|
||||
// we're the second word to have this abbreviation, so we can't use it.
|
||||
//unset($abbrevs[$abbrev]);
|
||||
$abbrevs[$abbrev][] = $option;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we're the third word to have this abbreviation, so skip to the next word.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Non-abbreviations always get entered, even if they aren't unique
|
||||
foreach ($options as $option)
|
||||
{
|
||||
$abbrevs[$option] = array($option);
|
||||
}
|
||||
|
||||
return $abbrevs;
|
||||
}
|
||||
}
|
||||
72
lib/symfony/vendor/pake/pakeColor.class.php
vendored
Executable file
72
lib/symfony/vendor/pake/pakeColor.class.php
vendored
Executable file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeColor.class.php 2990 2006-12-09 11:10:59Z fabien $
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* main pake class.
|
||||
*
|
||||
* This class is a singleton.
|
||||
*
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeColor.class.php 2990 2006-12-09 11:10:59Z fabien $
|
||||
*/
|
||||
class pakeColor
|
||||
{
|
||||
static public $styles = array();
|
||||
|
||||
static function style($name, $options = array())
|
||||
{
|
||||
self::$styles[$name] = $options;
|
||||
}
|
||||
|
||||
static function colorize($text = '', $parameters = array(), $stream = STDOUT)
|
||||
{
|
||||
// disable colors if not supported (windows or non tty console)
|
||||
if (DIRECTORY_SEPARATOR == '\\' || !function_exists('posix_isatty') || !@posix_isatty($stream))
|
||||
{
|
||||
return $text;
|
||||
}
|
||||
|
||||
static $options = array('bold' => 1, 'underscore' => 4, 'blink' => 5, 'reverse' => 7, 'conceal' => 8);
|
||||
static $foreground = array('black' => 30, 'red' => 31, 'green' => 32, 'yellow' => 33, 'blue' => 34, 'magenta' => 35, 'cyan' => 36, 'white' => 37);
|
||||
static $background = array('black' => 40, 'red' => 41, 'green' => 42, 'yellow' => 43, 'blue' => 44, 'magenta' => 45, 'cyan' => 46, 'white' => 47);
|
||||
|
||||
if (!is_array($parameters) && isset(self::$styles[$parameters]))
|
||||
{
|
||||
$parameters = self::$styles[$parameters];
|
||||
}
|
||||
|
||||
$codes = array();
|
||||
if (isset($parameters['fg']))
|
||||
{
|
||||
$codes[] = $foreground[$parameters['fg']];
|
||||
}
|
||||
if (isset($parameters['bg']))
|
||||
{
|
||||
$codes[] = $background[$parameters['bg']];
|
||||
}
|
||||
foreach ($options as $option => $value)
|
||||
{
|
||||
if (isset($parameters[$option]) && $parameters[$option])
|
||||
{
|
||||
$codes[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return "\033[".implode(';', $codes).'m'.$text."\033[0m";
|
||||
}
|
||||
}
|
||||
|
||||
pakeColor::style('ERROR', array('bg' => 'red', 'fg' => 'white', 'bold' => true));
|
||||
pakeColor::style('INFO', array('fg' => 'green', 'bold' => true));
|
||||
pakeColor::style('COMMENT', array('fg' => 'yellow'));
|
||||
91
lib/symfony/vendor/pake/pakeException.class.php
vendored
Executable file
91
lib/symfony/vendor/pake/pakeException.class.php
vendored
Executable file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the pake package.
|
||||
* (c) 2004, 2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* pakeException is the base class for all pake related exceptions and
|
||||
* provides an additional method for printing up a detailed view of an
|
||||
* exception.
|
||||
*
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: pakeException.class.php 2795 2006-11-23 19:51:21Z fabien $
|
||||
*/
|
||||
class pakeException extends Exception
|
||||
{
|
||||
public static function strlen($string)
|
||||
{
|
||||
return function_exists('mb_strlen') ? mb_strlen($string) : strlen($string);
|
||||
}
|
||||
|
||||
function render($e)
|
||||
{
|
||||
$title = ' ['.get_class($e).'] ';
|
||||
$len = self::strlen($title);
|
||||
$lines = array();
|
||||
foreach (explode("\n", $e->getMessage()) as $line)
|
||||
{
|
||||
$lines[] = ' '.$line.' ';
|
||||
$len = max(self::strlen($line) + 4, $len);
|
||||
}
|
||||
$messages = array(
|
||||
str_repeat(' ', $len),
|
||||
$title.str_repeat(' ', $len - self::strlen($title)),
|
||||
);
|
||||
|
||||
foreach ($lines as $line)
|
||||
{
|
||||
$messages[] = $line.str_repeat(' ', $len - self::strlen($line));
|
||||
}
|
||||
|
||||
$messages[] = str_repeat(' ', $len);
|
||||
|
||||
fwrite(STDERR, "\n");
|
||||
foreach ($messages as $message)
|
||||
{
|
||||
fwrite(STDERR, pakeColor::colorize($message, 'ERROR', STDERR)."\n");
|
||||
}
|
||||
fwrite(STDERR, "\n");
|
||||
|
||||
$pake = pakeApp::get_instance();
|
||||
|
||||
if ($pake->get_trace())
|
||||
{
|
||||
fwrite(STDERR, "exception trace:\n");
|
||||
|
||||
$trace = $this->trace($e);
|
||||
for ($i = 0, $count = count($trace); $i < $count; $i++)
|
||||
{
|
||||
$class = (isset($trace[$i]['class']) ? $trace[$i]['class'] : '');
|
||||
$type = (isset($trace[$i]['type']) ? $trace[$i]['type'] : '');
|
||||
$function = $trace[$i]['function'];
|
||||
$file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a';
|
||||
$line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a';
|
||||
|
||||
fwrite(STDERR, sprintf(" %s%s%s at %s:%s\n", $class, $type, $function, pakeColor::colorize($file, 'INFO', STDERR), pakeColor::colorize($line, 'INFO', STDERR)));
|
||||
}
|
||||
}
|
||||
|
||||
fwrite(STDERR, "\n");
|
||||
}
|
||||
|
||||
function trace($exception)
|
||||
{
|
||||
// exception related properties
|
||||
$trace = $exception->getTrace();
|
||||
array_unshift($trace, array(
|
||||
'function' => '',
|
||||
'file' => ($exception->getFile() != null) ? $exception->getFile() : 'n/a',
|
||||
'line' => ($exception->getLine() != null) ? $exception->getLine() : 'n/a',
|
||||
'args' => array(),
|
||||
));
|
||||
|
||||
return $trace;
|
||||
}
|
||||
}
|
||||
64
lib/symfony/vendor/pake/pakeFileTask.class.php
vendored
Executable file
64
lib/symfony/vendor/pake/pakeFileTask.class.php
vendored
Executable file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeFileTask.class.php 1791 2006-08-23 21:17:06Z fabien $
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* .
|
||||
*
|
||||
* .
|
||||
*
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeFileTask.class.php 1791 2006-08-23 21:17:06Z fabien $
|
||||
*/
|
||||
class pakeFileTask extends pakeTask
|
||||
{
|
||||
public function is_needed()
|
||||
{
|
||||
if (!file_exists($this->get_name())) return true;
|
||||
$latest_prereq = 0;
|
||||
foreach ($this->prerequisites as $prerequisite)
|
||||
{
|
||||
$t = pakeTask::get($prerequisite)->timestamp();
|
||||
if ($t > $latest_prereq)
|
||||
{
|
||||
$latest_prereq = $t;
|
||||
}
|
||||
}
|
||||
|
||||
if ($latest_prereq == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ($this->timestamp() < $latest_prereq);
|
||||
}
|
||||
|
||||
public function timestamp()
|
||||
{
|
||||
if (!file_exists($this->get_name()))
|
||||
{
|
||||
throw new pakeException(sprintf('File "%s" does not exist!', $this->get_name()));
|
||||
}
|
||||
|
||||
$stats = stat($this->get_name());
|
||||
|
||||
return $stats['mtime'];
|
||||
}
|
||||
|
||||
public static function define_task($name, $deps = null)
|
||||
{
|
||||
$task = pakeTask::lookup($name, 'pakeFileTask');
|
||||
$task->add_comment();
|
||||
$task->enhance($deps);
|
||||
}
|
||||
}
|
||||
538
lib/symfony/vendor/pake/pakeFinder.class.php
vendored
Executable file
538
lib/symfony/vendor/pake/pakeFinder.class.php
vendored
Executable file
@ -0,0 +1,538 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeFinder.class.php 3268 2007-01-13 20:19:33Z fabien $
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__).'/pakeGlobToRegex.class.php';
|
||||
require_once dirname(__FILE__).'/pakeNumberCompare.class.php';
|
||||
|
||||
if (class_exists('pakeFinder'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Allow to build rules to find files and directories.
|
||||
*
|
||||
* All rules may be invoked several times, except for ->in() method.
|
||||
* Some rules are cumulative (->name() for example) whereas others are destructive
|
||||
* (most recent value is used, ->maxdepth() method for example).
|
||||
*
|
||||
* All methods return the current pakeFinder object to allow easy chaining:
|
||||
*
|
||||
* $files = pakeFinder::type('file')->name('*.php')->in(.);
|
||||
*
|
||||
* Interface loosely based on perl File::Find::Rule module.
|
||||
*
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeFinder.class.php 3268 2007-01-13 20:19:33Z fabien $
|
||||
*/
|
||||
class pakeFinder
|
||||
{
|
||||
private $type = 'file';
|
||||
private $names = array();
|
||||
private $prunes = array();
|
||||
private $discards = array();
|
||||
private $execs = array();
|
||||
private $mindepth = 0;
|
||||
private $sizes = array();
|
||||
private $maxdepth = 1000000;
|
||||
private $relative = false;
|
||||
private $follow_link = false;
|
||||
private $search_dir = '';
|
||||
|
||||
/**
|
||||
* Sets maximum directory depth.
|
||||
*
|
||||
* Finder will descend at most $level levels of directories below the starting point.
|
||||
*
|
||||
* @param integer level
|
||||
* @return object current pakeFinder object
|
||||
*/
|
||||
public function maxdepth($level)
|
||||
{
|
||||
$this->maxdepth = $level;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets minimum directory depth.
|
||||
*
|
||||
* Finder will start applying tests at level $level.
|
||||
*
|
||||
* @param integer level
|
||||
* @return object current pakeFinder object
|
||||
*/
|
||||
public function mindepth($level)
|
||||
{
|
||||
$this->mindepth = $level;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function get_type()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of elements to returns.
|
||||
*
|
||||
* @param string directory or file or any (for both file and directory)
|
||||
* @return object new pakeFinder object
|
||||
*/
|
||||
public static function type($name)
|
||||
{
|
||||
$finder = new pakeFinder();
|
||||
|
||||
if (strtolower(substr($name, 0, 3)) == 'dir')
|
||||
{
|
||||
$finder->type = 'directory';
|
||||
}
|
||||
else if (strtolower($name) == 'any')
|
||||
{
|
||||
$finder->type = 'any';
|
||||
}
|
||||
else
|
||||
{
|
||||
$finder->type = 'file';
|
||||
}
|
||||
|
||||
return $finder;
|
||||
}
|
||||
|
||||
/*
|
||||
* glob, patterns (must be //) or strings
|
||||
*/
|
||||
private function to_regex($str)
|
||||
{
|
||||
if ($str[0] == '/' && $str[strlen($str) - 1] == '/')
|
||||
{
|
||||
return $str;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pakeGlobToRegex::glob_to_regex($str);
|
||||
}
|
||||
}
|
||||
|
||||
private function args_to_array($arg_list, $not = false)
|
||||
{
|
||||
$list = array();
|
||||
|
||||
for ($i = 0; $i < count($arg_list); $i++)
|
||||
{
|
||||
if (is_array($arg_list[$i]))
|
||||
{
|
||||
foreach ($arg_list[$i] as $arg)
|
||||
{
|
||||
$list[] = array($not, $this->to_regex($arg));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$list[] = array($not, $this->to_regex($arg_list[$i]));
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds rules that files must match.
|
||||
*
|
||||
* You can use patterns (delimited with / sign), globs or simple strings.
|
||||
*
|
||||
* $finder->name('*.php')
|
||||
* $finder->name('/\.php$/') // same as above
|
||||
* $finder->name('test.php')
|
||||
*
|
||||
* @param list a list of patterns, globs or strings
|
||||
* @return object current pakeFinder object
|
||||
*/
|
||||
public function name()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$this->names = array_merge($this->names, $this->args_to_array($args));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds rules that files must not match.
|
||||
*
|
||||
* @see ->name()
|
||||
* @param list a list of patterns, globs or strings
|
||||
* @return object current pakeFinder object
|
||||
*/
|
||||
public function not_name()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$this->names = array_merge($this->names, $this->args_to_array($args, true));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds tests for file sizes.
|
||||
*
|
||||
* $finder->size('> 10K');
|
||||
* $finder->size('<= 1Ki');
|
||||
* $finder->size(4);
|
||||
*
|
||||
* @param list a list of comparison strings
|
||||
* @return object current pakeFinder object
|
||||
*/
|
||||
public function size()
|
||||
{
|
||||
$args = func_get_args();
|
||||
for ($i = 0; $i < count($args); $i++)
|
||||
{
|
||||
$this->sizes[] = new pakeNumberCompare($args[$i]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses no further.
|
||||
*
|
||||
* @param list a list of patterns, globs to match
|
||||
* @return object current pakeFinder object
|
||||
*/
|
||||
public function prune()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$this->prunes = array_merge($this->prunes, $this->args_to_array($args));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards elements that matches.
|
||||
*
|
||||
* @param list a list of patterns, globs to match
|
||||
* @return object current pakeFinder object
|
||||
*/
|
||||
public function discard()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$this->discards = array_merge($this->discards, $this->args_to_array($args));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignores version control directories.
|
||||
*
|
||||
* Currently supports subversion, CVS, DARCS, Gnu Arch, Monotone, Bazaar-NG
|
||||
*
|
||||
* @return object current pakeFinder object
|
||||
*/
|
||||
public function ignore_version_control()
|
||||
{
|
||||
$ignores = array('.svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr');
|
||||
|
||||
return $this->discard($ignores)->prune($ignores);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes function or method for each element.
|
||||
*
|
||||
* Element match if functino or method returns true.
|
||||
*
|
||||
* $finder->exec('myfunction');
|
||||
* $finder->exec(array($object, 'mymethod'));
|
||||
*
|
||||
* @param mixed function or method to call
|
||||
* @return object current pakeFinder object
|
||||
*/
|
||||
public function exec()
|
||||
{
|
||||
$args = func_get_args();
|
||||
for ($i = 0; $i < count($args); $i++)
|
||||
{
|
||||
if (is_array($args[$i]) && !method_exists($args[$i][0], $args[$i][1]))
|
||||
{
|
||||
throw new pakeException(sprintf("Method %s does not exist for object %s.", $args[$i][1], $args[$i][0]));
|
||||
}
|
||||
else if (!is_array($args[$i]) && !function_exists($args[$i]))
|
||||
{
|
||||
throw new pakeException(sprintf("Function %s does not exist.", $args[$i]));
|
||||
}
|
||||
|
||||
$this->execs[] = $args[$i];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns relative paths for all files and directories.
|
||||
*
|
||||
* @return object current pakeFinder object
|
||||
*/
|
||||
public function relative()
|
||||
{
|
||||
$this->relative = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Symlink following.
|
||||
*
|
||||
* @return object current sfFinder object
|
||||
*/
|
||||
public function follow_link()
|
||||
{
|
||||
$this->follow_link = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches files and directories which match defined rules.
|
||||
*
|
||||
* @return array list of files and directories
|
||||
*/
|
||||
public function in()
|
||||
{
|
||||
$files = array();
|
||||
$here_dir = getcwd();
|
||||
$numargs = func_num_args();
|
||||
$arg_list = func_get_args();
|
||||
|
||||
// first argument is an array?
|
||||
if ($numargs == 1 && is_array($arg_list[0]))
|
||||
{
|
||||
$arg_list = $arg_list[0];
|
||||
$numargs = count($arg_list);
|
||||
}
|
||||
|
||||
$dirs = array();
|
||||
for ($i = 0; $i < $numargs; $i++)
|
||||
{
|
||||
if ($argDirs = glob($arg_list[$i]))
|
||||
{
|
||||
$dirs = array_merge($dirs, $argDirs);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($dirs as $dir)
|
||||
{
|
||||
$real_dir = realpath($dir);
|
||||
|
||||
// absolute path?
|
||||
if (!self::isPathAbsolute($real_dir))
|
||||
{
|
||||
$dir = $here_dir.DIRECTORY_SEPARATOR.$real_dir;
|
||||
}
|
||||
else
|
||||
{
|
||||
$dir = $real_dir;
|
||||
}
|
||||
|
||||
if (!is_dir($real_dir))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->search_dir = $dir;
|
||||
|
||||
if ($this->relative)
|
||||
{
|
||||
$files = array_merge($files, str_replace($dir.DIRECTORY_SEPARATOR, '', $this->search_in($dir)));
|
||||
}
|
||||
else
|
||||
{
|
||||
$files = array_merge($files, $this->search_in($dir));
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique($files);
|
||||
}
|
||||
|
||||
private function search_in($dir, $depth = 0)
|
||||
{
|
||||
if ($depth > $this->maxdepth)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
if (is_link($dir) && !$this->follow_link)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
$files = array();
|
||||
|
||||
if (is_dir($dir))
|
||||
{
|
||||
$current_dir = opendir($dir);
|
||||
while (false !== $entryname = readdir($current_dir))
|
||||
{
|
||||
if ($entryname == '.' || $entryname == '..') continue;
|
||||
|
||||
$current_entry = $dir.DIRECTORY_SEPARATOR.$entryname;
|
||||
if (is_link($current_entry) && !$this->follow_link)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_dir($current_entry))
|
||||
{
|
||||
if (($this->type == 'directory' || $this->type == 'any') && ($depth >= $this->mindepth) && !$this->is_discarded($dir, $entryname) && $this->match_names($dir, $entryname) && $this->exec_ok($dir, $entryname))
|
||||
{
|
||||
$files[] = realpath($current_entry);
|
||||
}
|
||||
|
||||
if (!$this->is_pruned($dir, $entryname))
|
||||
{
|
||||
$files = array_merge($files, $this->search_in($current_entry, $depth + 1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (($this->type != 'directory' || $this->type == 'any') && ($depth >= $this->mindepth) && !$this->is_discarded($dir, $entryname) && $this->match_names($dir, $entryname) && $this->size_ok($dir, $entryname) && $this->exec_ok($dir, $entryname))
|
||||
{
|
||||
$files[] = realpath($current_entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($current_dir);
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
private function match_names($dir, $entry)
|
||||
{
|
||||
if (!count($this->names)) return true;
|
||||
|
||||
// we must match one "not_name" rules to be ko
|
||||
$one_not_name_rule = false;
|
||||
foreach ($this->names as $args)
|
||||
{
|
||||
list($not, $regex) = $args;
|
||||
if ($not)
|
||||
{
|
||||
$one_not_name_rule = true;
|
||||
if (preg_match($regex, $entry))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$one_name_rule = false;
|
||||
// we must match one "name" rules to be ok
|
||||
foreach ($this->names as $args)
|
||||
{
|
||||
list($not, $regex) = $args;
|
||||
if (!$not)
|
||||
{
|
||||
$one_name_rule = true;
|
||||
if (preg_match($regex, $entry))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($one_not_name_rule && $one_name_rule)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if ($one_not_name_rule)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if ($one_name_rule)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private function size_ok($dir, $entry)
|
||||
{
|
||||
if (!count($this->sizes)) return true;
|
||||
|
||||
if (!is_file($dir.DIRECTORY_SEPARATOR.$entry)) return true;
|
||||
|
||||
$filesize = filesize($dir.DIRECTORY_SEPARATOR.$entry);
|
||||
foreach ($this->sizes as $number_compare)
|
||||
{
|
||||
if (!$number_compare->test($filesize)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function is_pruned($dir, $entry)
|
||||
{
|
||||
if (!count($this->prunes)) return false;
|
||||
|
||||
foreach ($this->prunes as $args)
|
||||
{
|
||||
$regex = $args[1];
|
||||
if (preg_match($regex, $entry)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function is_discarded($dir, $entry)
|
||||
{
|
||||
if (!count($this->discards)) return false;
|
||||
|
||||
foreach ($this->discards as $args)
|
||||
{
|
||||
$regex = $args[1];
|
||||
if (preg_match($regex, $entry)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function exec_ok($dir, $entry)
|
||||
{
|
||||
if (!count($this->execs)) return true;
|
||||
|
||||
foreach ($this->execs as $exec)
|
||||
{
|
||||
if (!call_user_func_array($exec, array($dir, $entry))) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function isPathAbsolute($path)
|
||||
{
|
||||
if ($path{0} == '/' || $path{0} == '\\' ||
|
||||
(strlen($path) > 3 && ctype_alpha($path{0}) &&
|
||||
$path{1} == ':' &&
|
||||
($path{2} == '\\' || $path{2} == '/')
|
||||
)
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
429
lib/symfony/vendor/pake/pakeFunction.php
vendored
Executable file
429
lib/symfony/vendor/pake/pakeFunction.php
vendored
Executable file
@ -0,0 +1,429 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeFunction.php 3263 2007-01-13 14:20:52Z fabien $
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__).'/pakeException.class.php';
|
||||
require_once dirname(__FILE__).'/pakeYaml.class.php';
|
||||
require_once dirname(__FILE__).'/pakeGetopt.class.php';
|
||||
require_once dirname(__FILE__).'/pakeFinder.class.php';
|
||||
require_once dirname(__FILE__).'/pakeTask.class.php';
|
||||
require_once dirname(__FILE__).'/pakeFileTask.class.php';
|
||||
require_once dirname(__FILE__).'/pakeColor.class.php';
|
||||
require_once dirname(__FILE__).'/pakeApp.class.php';
|
||||
|
||||
function pake_import($name, $import_default_tasks = true)
|
||||
{
|
||||
$class_name = 'pake'.ucfirst(strtolower($name)).'Task';
|
||||
|
||||
if (!class_exists($class_name))
|
||||
{
|
||||
// plugin available?
|
||||
$plugin_path = '';
|
||||
foreach (pakeApp::get_plugin_dirs() as $dir)
|
||||
{
|
||||
if (file_exists($dir.DIRECTORY_SEPARATOR.$class_name.'.class.php'))
|
||||
{
|
||||
$plugin_path = $dir.DIRECTORY_SEPARATOR.$class_name.'.class.php';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($plugin_path)
|
||||
{
|
||||
require_once $plugin_path;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new pakeException(sprintf('Plugin "%s" does not exist.', $name));
|
||||
}
|
||||
}
|
||||
|
||||
if ($import_default_tasks && is_callable($class_name, 'import_default_tasks'))
|
||||
{
|
||||
call_user_func(array($class_name, 'import_default_tasks'));
|
||||
}
|
||||
}
|
||||
|
||||
function pake_task($name)
|
||||
{
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
pakeTask::define_task($name, $args);
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
function pake_alias($alias, $name)
|
||||
{
|
||||
pakeTask::define_alias($alias, $name);
|
||||
|
||||
return $alias;
|
||||
}
|
||||
|
||||
function pake_desc($comment)
|
||||
{
|
||||
pakeTask::define_comment($comment);
|
||||
}
|
||||
|
||||
function pake_properties($property_file)
|
||||
{
|
||||
$file = $property_file;
|
||||
if (!pakeFinder::isPathAbsolute($file))
|
||||
{
|
||||
$file = getcwd().DIRECTORY_SEPARATOR.$property_file;
|
||||
}
|
||||
|
||||
if (file_exists($file))
|
||||
{
|
||||
pakeApp::get_instance()->set_properties(parse_ini_file($file, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new pakeException('Properties file does not exist.');
|
||||
}
|
||||
}
|
||||
|
||||
function pake_file($name)
|
||||
{
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
pakeFileTask::define_task($name, $args);
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
function pake_mkdirs($path, $mode = 0777)
|
||||
{
|
||||
if (is_dir($path))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
pake_echo_action('dir+', $path);
|
||||
|
||||
return @mkdir($path, $mode, true);
|
||||
}
|
||||
|
||||
/*
|
||||
override => boolean
|
||||
*/
|
||||
function pake_copy($origin_file, $target_file, $options = array())
|
||||
{
|
||||
if (!array_key_exists('override', $options))
|
||||
{
|
||||
$options['override'] = false;
|
||||
}
|
||||
|
||||
// we create target_dir if needed
|
||||
if (!is_dir(dirname($target_file)))
|
||||
{
|
||||
pake_mkdirs(dirname($target_file));
|
||||
}
|
||||
|
||||
$most_recent = false;
|
||||
if (file_exists($target_file))
|
||||
{
|
||||
$stat_target = stat($target_file);
|
||||
$stat_origin = stat($origin_file);
|
||||
$most_recent = ($stat_origin['mtime'] > $stat_target['mtime']) ? true : false;
|
||||
}
|
||||
|
||||
if ($options['override'] || !file_exists($target_file) || $most_recent)
|
||||
{
|
||||
pake_echo_action('file+', $target_file);
|
||||
copy($origin_file, $target_file);
|
||||
}
|
||||
}
|
||||
|
||||
function pake_rename($origin, $target, $options = array())
|
||||
{
|
||||
// we check that target does not exist
|
||||
if (is_readable($target))
|
||||
{
|
||||
throw new pakeException(sprintf('Cannot rename because the target "%" already exist.', $target));
|
||||
}
|
||||
|
||||
pake_echo_action('rename', $origin.' > '.$target);
|
||||
rename($origin, $target);
|
||||
}
|
||||
|
||||
function pake_mirror($arg, $origin_dir, $target_dir, $options = array())
|
||||
{
|
||||
$files = pakeApp::get_files_from_argument($arg, $origin_dir, true);
|
||||
|
||||
foreach ($files as $file)
|
||||
{
|
||||
if (is_dir($origin_dir.DIRECTORY_SEPARATOR.$file))
|
||||
{
|
||||
pake_mkdirs($target_dir.DIRECTORY_SEPARATOR.$file);
|
||||
}
|
||||
else if (is_file($origin_dir.DIRECTORY_SEPARATOR.$file))
|
||||
{
|
||||
pake_copy($origin_dir.DIRECTORY_SEPARATOR.$file, $target_dir.DIRECTORY_SEPARATOR.$file, $options);
|
||||
}
|
||||
else if (is_link($origin_dir.DIRECTORY_SEPARATOR.$file))
|
||||
{
|
||||
pake_symlink($origin_dir.DIRECTORY_SEPARATOR.$file, $target_dir.DIRECTORY_SEPARATOR.$file);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new pakeException(sprintf('Unable to determine "%s" type', $file));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function pake_remove($arg, $target_dir)
|
||||
{
|
||||
$files = array_reverse(pakeApp::get_files_from_argument($arg, $target_dir));
|
||||
|
||||
foreach ($files as $file)
|
||||
{
|
||||
if (is_dir($file) && !is_link($file))
|
||||
{
|
||||
pake_echo_action('dir-', $file);
|
||||
|
||||
rmdir($file);
|
||||
}
|
||||
else
|
||||
{
|
||||
pake_echo_action(is_link($file) ? 'link-' : 'file-', $file);
|
||||
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function pake_touch($arg, $target_dir)
|
||||
{
|
||||
$files = pakeApp::get_files_from_argument($arg, $target_dir);
|
||||
|
||||
foreach ($files as $file)
|
||||
{
|
||||
pake_echo_action('file+', $file);
|
||||
|
||||
touch($file);
|
||||
}
|
||||
}
|
||||
|
||||
function pake_replace_tokens($arg, $target_dir, $begin_token, $end_token, $tokens)
|
||||
{
|
||||
$files = pakeApp::get_files_from_argument($arg, $target_dir, true);
|
||||
|
||||
foreach ($files as $file)
|
||||
{
|
||||
$replaced = false;
|
||||
$content = file_get_contents($target_dir.DIRECTORY_SEPARATOR.$file);
|
||||
foreach ($tokens as $key => $value)
|
||||
{
|
||||
$content = str_replace($begin_token.$key.$end_token, $value, $content, $count);
|
||||
if ($count) $replaced = true;
|
||||
}
|
||||
|
||||
pake_echo_action('tokens', $target_dir.DIRECTORY_SEPARATOR.$file);
|
||||
|
||||
file_put_contents($target_dir.DIRECTORY_SEPARATOR.$file, $content);
|
||||
}
|
||||
}
|
||||
|
||||
function pake_symlink($origin_dir, $target_dir, $copy_on_windows = false)
|
||||
{
|
||||
if (!function_exists('symlink') && $copy_on_windows)
|
||||
{
|
||||
$finder = pakeFinder::type('any')->ignore_version_control();
|
||||
pake_mirror($finder, $origin_dir, $target_dir);
|
||||
return;
|
||||
}
|
||||
|
||||
$ok = false;
|
||||
if (is_link($target_dir))
|
||||
{
|
||||
if (readlink($target_dir) != $origin_dir)
|
||||
{
|
||||
unlink($target_dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
$ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$ok)
|
||||
{
|
||||
pake_echo_action('link+', $target_dir);
|
||||
symlink($origin_dir, $target_dir);
|
||||
}
|
||||
}
|
||||
|
||||
function pake_chmod($arg, $target_dir, $mode, $umask = 0000)
|
||||
{
|
||||
$current_umask = umask();
|
||||
umask($umask);
|
||||
|
||||
$files = pakeApp::get_files_from_argument($arg, $target_dir, true);
|
||||
|
||||
foreach ($files as $file)
|
||||
{
|
||||
pake_echo_action(sprintf('chmod %o', $mode), $target_dir.DIRECTORY_SEPARATOR.$file);
|
||||
chmod($target_dir.DIRECTORY_SEPARATOR.$file, $mode);
|
||||
}
|
||||
|
||||
umask($current_umask);
|
||||
}
|
||||
|
||||
function pake_sh($cmd)
|
||||
{
|
||||
$verbose = pakeApp::get_instance()->get_verbose();
|
||||
pake_echo_action('exec ', $cmd);
|
||||
|
||||
ob_start();
|
||||
passthru($cmd.' 2>&1', $return);
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
if ($return > 0)
|
||||
{
|
||||
throw new pakeException(sprintf('Problem executing command %s', $verbose ? "\n".$content : ''));
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
function pake_strip_php_comments($arg)
|
||||
{
|
||||
/* T_ML_COMMENT does not exist in PHP 5.
|
||||
* The following three lines define it in order to
|
||||
* preserve backwards compatibility.
|
||||
*
|
||||
* The next two lines define the PHP 5-only T_DOC_COMMENT,
|
||||
* which we will mask as T_ML_COMMENT for PHP 4.
|
||||
*/
|
||||
if (!defined('T_ML_COMMENT'))
|
||||
{
|
||||
define('T_ML_COMMENT', T_COMMENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!defined('T_DOC_COMMENT')) define('T_DOC_COMMENT', T_ML_COMMENT);
|
||||
}
|
||||
|
||||
$files = pakeApp::get_files_from_argument($arg);
|
||||
|
||||
foreach ($files as $file)
|
||||
{
|
||||
if (!is_file($file)) continue;
|
||||
|
||||
$source = file_get_contents($file);
|
||||
$output = '';
|
||||
|
||||
$tokens = token_get_all($source);
|
||||
foreach ($tokens as $token)
|
||||
{
|
||||
if (is_string($token))
|
||||
{
|
||||
// simple 1-character token
|
||||
$output .= $token;
|
||||
}
|
||||
else
|
||||
{
|
||||
// token array
|
||||
list($id, $text) = $token;
|
||||
switch ($id)
|
||||
{
|
||||
case T_COMMENT:
|
||||
case T_ML_COMMENT: // we've defined this
|
||||
case T_DOC_COMMENT: // and this
|
||||
// no action on comments
|
||||
break;
|
||||
default:
|
||||
// anything else -> output "as is"
|
||||
$output .= $text;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file_put_contents($file, $output);
|
||||
}
|
||||
}
|
||||
|
||||
function pake_format_action($section, $text, $size = null)
|
||||
{
|
||||
if (pakeApp::get_instance()->get_verbose())
|
||||
{
|
||||
$width = 9 + strlen(pakeColor::colorize('', 'INFO'));
|
||||
return sprintf('>> %-'.$width.'s %s', pakeColor::colorize($section, 'INFO'), pakeApp::excerpt($text, $size))."\n";
|
||||
}
|
||||
}
|
||||
|
||||
function pake_echo_action($section, $text)
|
||||
{
|
||||
echo pake_format_action($section, $text);
|
||||
}
|
||||
|
||||
function pake_excerpt($text)
|
||||
{
|
||||
if (pakeApp::get_instance()->get_verbose())
|
||||
{
|
||||
echo pakeApp::excerpt($text)."\n";
|
||||
}
|
||||
}
|
||||
|
||||
function pake_echo($text)
|
||||
{
|
||||
if (pakeApp::get_instance()->get_verbose())
|
||||
{
|
||||
echo $text."\n";
|
||||
}
|
||||
}
|
||||
|
||||
function pake_echo_comment($text)
|
||||
{
|
||||
if (pakeApp::get_instance()->get_verbose())
|
||||
{
|
||||
echo sprintf(pakeColor::colorize(' # %s', 'COMMENT'), $text)."\n";
|
||||
}
|
||||
}
|
||||
|
||||
// register our default exception handler
|
||||
function pake_exception_default_handler($exception)
|
||||
{
|
||||
$e = new pakeException();
|
||||
$e->render($exception);
|
||||
exit(1);
|
||||
}
|
||||
set_exception_handler('pake_exception_default_handler');
|
||||
|
||||
// fix php behavior if using cgi php
|
||||
// from http://www.sitepoint.com/article/php-command-line-1/3
|
||||
if (false !== strpos(PHP_SAPI, 'cgi'))
|
||||
{
|
||||
// handle output buffering
|
||||
@ob_end_flush();
|
||||
ob_implicit_flush(true);
|
||||
|
||||
// PHP ini settings
|
||||
set_time_limit(0);
|
||||
ini_set('track_errors', true);
|
||||
ini_set('html_errors', false);
|
||||
ini_set('magic_quotes_runtime', false);
|
||||
|
||||
// define stream constants
|
||||
define('STDIN', fopen('php://stdin', 'r'));
|
||||
define('STDOUT', fopen('php://stdout', 'w'));
|
||||
define('STDERR', fopen('php://stderr', 'w'));
|
||||
|
||||
// change directory
|
||||
if (isset($_SERVER['PWD']))
|
||||
{
|
||||
chdir($_SERVER['PWD']);
|
||||
}
|
||||
|
||||
// close the streams on script termination
|
||||
register_shutdown_function(create_function('', 'fclose(STDIN); fclose(STDOUT); fclose(STDERR); return true;'));
|
||||
}
|
||||
274
lib/symfony/vendor/pake/pakeGetopt.class.php
vendored
Executable file
274
lib/symfony/vendor/pake/pakeGetopt.class.php
vendored
Executable file
@ -0,0 +1,274 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeGetopt.class.php 1791 2006-08-23 21:17:06Z fabien $
|
||||
*/
|
||||
|
||||
if (class_exists('pakeGetopt'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Console options parsing class.
|
||||
*
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeGetopt.class.php 1791 2006-08-23 21:17:06Z fabien $
|
||||
*/
|
||||
class pakeGetopt
|
||||
{
|
||||
const NO_ARGUMENT = 0;
|
||||
const REQUIRED_ARGUMENT = 1;
|
||||
const OPTIONAL_ARGUMENT = 2;
|
||||
private $short_options = array();
|
||||
private $long_options = array();
|
||||
private $args = '';
|
||||
private $options = array();
|
||||
private $arguments = array();
|
||||
|
||||
public function __construct($options)
|
||||
{
|
||||
$this->args = '';
|
||||
foreach ($options as $option)
|
||||
{
|
||||
if (!$option[0])
|
||||
{
|
||||
throw new pakeException(sprintf("pakeGetopt: You must define a long option name! for option %s (%s).", $option[1], $option[3]));
|
||||
}
|
||||
|
||||
$this->add_option($option[0], $option[1], $option[2], $option[3]);
|
||||
}
|
||||
}
|
||||
|
||||
public function add_option($long_opt, $short_opt, $mode = self::NO_ARGUMENT, $comment = '')
|
||||
{
|
||||
if ($long_opt{0} == '-' && $long_opt{1} == '-')
|
||||
{
|
||||
$long_opt = substr($long_opt, 2);
|
||||
}
|
||||
|
||||
if ($short_opt)
|
||||
{
|
||||
if ($short_opt{0} == '-')
|
||||
{
|
||||
$short_opt = substr($short_opt, 1);
|
||||
}
|
||||
$this->short_options[$short_opt] = array('mode' => $mode, 'comment' => $comment, 'name' => $long_opt);
|
||||
}
|
||||
|
||||
$this->long_options[$long_opt] = array('mode' => $mode, 'comment' => $comment, 'name' => $long_opt);
|
||||
}
|
||||
|
||||
public function parse($args = null)
|
||||
{
|
||||
if (is_string($args))
|
||||
{
|
||||
// hack to split arguments with spaces : --test="with some spaces"
|
||||
$args = preg_replace('/(\'|")(.+?)\\1/e', "str_replace(' ', '=PLACEHOLDER=', '\\2')", $args);
|
||||
$args = preg_split('/\s+/', $args);
|
||||
$args = str_replace('=PLACEHOLDER=', ' ', $args);
|
||||
}
|
||||
else if (!$args)
|
||||
{
|
||||
$args = $this->read_php_argv();
|
||||
|
||||
// we strip command line program
|
||||
if (isset($args[0]) && $args[0]{0} != '-')
|
||||
{
|
||||
array_shift($args);
|
||||
}
|
||||
}
|
||||
|
||||
$this->args = $args;
|
||||
|
||||
$this->options = array();
|
||||
$this->arguments = array();
|
||||
|
||||
while ($arg = array_shift($this->args))
|
||||
{
|
||||
/* '--' stop options parsing. */
|
||||
if ($arg == '--')
|
||||
{
|
||||
$this->arguments = array_merge($this->arguments, $this->args);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$this->long_options))
|
||||
{
|
||||
$this->arguments = array_merge($this->arguments, array($arg), $this->args);
|
||||
break;
|
||||
}
|
||||
elseif (strlen($arg) > 1 && $arg{1} == '-')
|
||||
{
|
||||
$this->parse_long_option(substr($arg, 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->parse_short_option(substr($arg, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function has_option($option)
|
||||
{
|
||||
return (array_key_exists($option, $this->options) ? true : false);
|
||||
}
|
||||
|
||||
public function get_option($option)
|
||||
{
|
||||
// is it a long option?
|
||||
if (array_key_exists($option, $this->long_options) && $this->long_options[$option]['mode'] != self::NO_ARGUMENT)
|
||||
{
|
||||
return (array_key_exists($option, $this->options) ? $this->options[$option] : '');
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new pakeException('pakeGetopt: You cannot get a value for a NO_ARGUMENT option.');
|
||||
}
|
||||
}
|
||||
|
||||
public function get_options()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
public function get_arguments()
|
||||
{
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
private function parse_short_option($arg)
|
||||
{
|
||||
for ($i = 0; $i < strlen($arg); $i++)
|
||||
{
|
||||
$opt = $arg{$i};
|
||||
$opt_arg = true;
|
||||
|
||||
/* option exists? */
|
||||
if (!array_key_exists($opt, $this->short_options))
|
||||
{
|
||||
throw new pakeException(sprintf("pakeGetopt: unrecognized option -%s.", $opt));
|
||||
}
|
||||
|
||||
/* required or optional argument? */
|
||||
if ($this->short_options[$opt]['mode'] == self::REQUIRED_ARGUMENT)
|
||||
{
|
||||
if ($i + 1 < strlen($arg))
|
||||
{
|
||||
$this->options[$this->short_options[$opt]['name']] = substr($arg, $i + 1);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// take next element as argument (if it doesn't start with a -)
|
||||
if (count($this->args) && $this->args[0]{0} != '-')
|
||||
{
|
||||
$this->options[$this->short_options[$opt]['name']] = array_shift($this->args);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new pakeException(sprintf("pakeGetopt: option -%s requires an argument", $opt));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($this->short_options[$opt]['mode'] == self::OPTIONAL_ARGUMENT)
|
||||
{
|
||||
if (substr($arg, $i + 1) != '')
|
||||
{
|
||||
$this->options[$this->short_options[$opt]['name']] = substr($arg, $i + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// take next element as argument (if it doesn't start with a -)
|
||||
if (count($this->args) && $this->args[0]{0} != '-')
|
||||
{
|
||||
$this->options[$this->short_options[$opt]['name']] = array_shift($this->args);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->options[$this->short_options[$opt]['name']] = true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$this->options[$this->short_options[$opt]['name']] = $opt_arg;
|
||||
}
|
||||
}
|
||||
|
||||
private function parse_long_option($arg)
|
||||
{
|
||||
@list($opt, $opt_arg) = explode('=', $arg);
|
||||
|
||||
if (!$opt_arg)
|
||||
{
|
||||
$opt_arg = true;
|
||||
}
|
||||
|
||||
/* option exists? */
|
||||
if (!array_key_exists($opt, $this->long_options))
|
||||
{
|
||||
throw new pakeException(sprintf("pakeGetopt: unrecognized option --%s.", $opt));
|
||||
}
|
||||
|
||||
/* required or optional argument? */
|
||||
if ($this->long_options[$opt]['mode'] == self::REQUIRED_ARGUMENT)
|
||||
{
|
||||
if ($opt_arg)
|
||||
{
|
||||
$this->options[$this->long_options[$opt]['name']] = $opt_arg;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new pakeException(sprintf("pakeGetopt: option --%s requires an argument.", $opt));
|
||||
}
|
||||
}
|
||||
else if ($this->long_options[$opt]['mode'] == self::OPTIONAL_ARGUMENT)
|
||||
{
|
||||
$this->options[$this->long_options[$opt]['name']] = $opt_arg;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->options[$this->long_options[$opt]['name']] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function from PEAR::Console_Getopt.
|
||||
* Safely read the $argv PHP array across different PHP configurations.
|
||||
* Will take care on register_globals and register_argc_argv ini directives
|
||||
*
|
||||
* @access public
|
||||
* @return mixed the $argv PHP array
|
||||
*/
|
||||
private function read_php_argv()
|
||||
{
|
||||
global $argv;
|
||||
if (!is_array($argv))
|
||||
{
|
||||
if (!@is_array($_SERVER['argv']))
|
||||
{
|
||||
if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv']))
|
||||
{
|
||||
throw new pakeException("pakeGetopt: Could not read cmd args (register_argc_argv=Off?).");
|
||||
}
|
||||
|
||||
return $GLOBALS['HTTP_SERVER_VARS']['argv'];
|
||||
}
|
||||
return $_SERVER['argv'];
|
||||
}
|
||||
return $argv;
|
||||
}
|
||||
}
|
||||
139
lib/symfony/vendor/pake/pakeGlobToRegex.class.php
vendored
Executable file
139
lib/symfony/vendor/pake/pakeGlobToRegex.class.php
vendored
Executable file
@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com> php port
|
||||
* @author Richard Clamp <richardc@unixbeard.net> perl version
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2002 Richard Clamp <richardc@unixbeard.net>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeGlobToRegex.class.php 1791 2006-08-23 21:17:06Z fabien $
|
||||
*/
|
||||
|
||||
if (class_exists('pakeGlobToRegex'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Match globbing patterns against text.
|
||||
*
|
||||
* if match_glob("foo.*", "foo.bar") echo "matched\n";
|
||||
*
|
||||
* // prints foo.bar and foo.baz
|
||||
* $regex = glob_to_regex("foo.*");
|
||||
* for (array('foo.bar', 'foo.baz', 'foo', 'bar') as $t)
|
||||
* {
|
||||
* if (/$regex/) echo "matched: $car\n";
|
||||
* }
|
||||
*
|
||||
* pakeGlobToRegex implements glob(3) style matching that can be used to match
|
||||
* against text, rather than fetching names from a filesystem.
|
||||
*
|
||||
* based on perl Text::Glob module.
|
||||
*
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com> php port
|
||||
* @author Richard Clamp <richardc@unixbeard.net> perl version
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2002 Richard Clamp <richardc@unixbeard.net>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeGlobToRegex.class.php 1791 2006-08-23 21:17:06Z fabien $
|
||||
*/
|
||||
class pakeGlobToRegex
|
||||
{
|
||||
private static $strict_leading_dot = true;
|
||||
private static $strict_wildcard_slash = true;
|
||||
|
||||
public static function setStrictLeadingDot($boolean)
|
||||
{
|
||||
self::$strict_leading_dot = $boolean;
|
||||
}
|
||||
|
||||
public static function setStrictWildcardSlash($boolean)
|
||||
{
|
||||
self::$strict_wildcard_slash = $boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a compiled regex which is the equiavlent of the globbing pattern.
|
||||
*
|
||||
* @param string glob pattern
|
||||
* @return string regex
|
||||
*/
|
||||
public static function glob_to_regex($glob)
|
||||
{
|
||||
$first_byte = true;
|
||||
$escaping = false;
|
||||
$in_curlies = 0;
|
||||
$regex = '';
|
||||
for ($i = 0; $i < strlen($glob); $i++)
|
||||
{
|
||||
$car = $glob[$i];
|
||||
if ($first_byte)
|
||||
{
|
||||
if (self::$strict_leading_dot && $car != '.')
|
||||
{
|
||||
$regex .= '(?=[^\.])';
|
||||
}
|
||||
|
||||
$first_byte = false;
|
||||
}
|
||||
|
||||
if ($car == '/')
|
||||
{
|
||||
$first_byte = true;
|
||||
}
|
||||
|
||||
if ($car == '.' || $car == '(' || $car == ')' || $car == '|' || $car == '+' || $car == '^' || $car == '$')
|
||||
{
|
||||
$regex .= "\\$car";
|
||||
}
|
||||
else if ($car == '*')
|
||||
{
|
||||
$regex .= ($escaping ? "\\*" : (self::$strict_wildcard_slash ? "[^/]*" : ".*"));
|
||||
}
|
||||
else if ($car == '?')
|
||||
{
|
||||
$regex .= ($escaping ? "\\?" : (self::$strict_wildcard_slash ? "[^/]" : "."));
|
||||
}
|
||||
else if ($car == '{')
|
||||
{
|
||||
$regex .= ($escaping ? "\\{" : "(");
|
||||
if (!$escaping) ++$in_curlies;
|
||||
}
|
||||
else if ($car == '}' && $in_curlies)
|
||||
{
|
||||
$regex .= ($escaping ? "}" : ")");
|
||||
if (!$escaping) --$in_curlies;
|
||||
}
|
||||
else if ($car == ',' && $in_curlies)
|
||||
{
|
||||
$regex .= ($escaping ? "," : "|");
|
||||
}
|
||||
else if ($car == "\\")
|
||||
{
|
||||
if ($escaping)
|
||||
{
|
||||
$regex .= "\\\\";
|
||||
$escaping = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$escaping = true;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
$regex .= $car;
|
||||
$escaping = false;
|
||||
}
|
||||
$escaping = false;
|
||||
}
|
||||
|
||||
return "#^$regex$#";
|
||||
}
|
||||
}
|
||||
120
lib/symfony/vendor/pake/pakeNumberCompare.class.php
vendored
Executable file
120
lib/symfony/vendor/pake/pakeNumberCompare.class.php
vendored
Executable file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com> php port
|
||||
* @author Richard Clamp <richardc@unixbeard.net> perl version
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2002 Richard Clamp <richardc@unixbeard.net>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeNumberCompare.class.php 1791 2006-08-23 21:17:06Z fabien $
|
||||
*/
|
||||
|
||||
if (class_exists('pakeNumberCompare'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Numeric comparisons.
|
||||
*
|
||||
* sfNumberCompare compiles a simple comparison to an anonymous
|
||||
* subroutine, which you can call with a value to be tested again.
|
||||
|
||||
* Now this would be very pointless, if sfNumberCompare didn't understand
|
||||
* magnitudes.
|
||||
|
||||
* The target value may use magnitudes of kilobytes (C<k>, C<ki>),
|
||||
* megabytes (C<m>, C<mi>), or gigabytes (C<g>, C<gi>). Those suffixed
|
||||
* with an C<i> use the appropriate 2**n version in accordance with the
|
||||
* IEC standard: http://physics.nist.gov/cuu/Units/binary.html
|
||||
*
|
||||
* based on perl Number::Compare module.
|
||||
*
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com> php port
|
||||
* @author Richard Clamp <richardc@unixbeard.net> perl version
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2002 Richard Clamp <richardc@unixbeard.net>
|
||||
* @see http://physics.nist.gov/cuu/Units/binary.html
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeNumberCompare.class.php 1791 2006-08-23 21:17:06Z fabien $
|
||||
*/
|
||||
class pakeNumberCompare
|
||||
{
|
||||
private $test = '';
|
||||
|
||||
public function __construct($test)
|
||||
{
|
||||
$this->test = $test;
|
||||
}
|
||||
|
||||
public function test($number)
|
||||
{
|
||||
if (!preg_match('{^([<>]=?)?(.*?)([kmg]i?)?$}i', $this->test, $matches))
|
||||
{
|
||||
throw new pakeException(sprintf('Don\'t understand "%s" as a test.', $this->test));
|
||||
}
|
||||
|
||||
$target = array_key_exists(2, $matches) ? $matches[2] : '';
|
||||
$magnitude = array_key_exists(3, $matches) ? $matches[3] : '';
|
||||
if (strtolower($magnitude) == 'k') $target *= 1000;
|
||||
if (strtolower($magnitude) == 'ki') $target *= 1024;
|
||||
if (strtolower($magnitude) == 'm') $target *= 1000000;
|
||||
if (strtolower($magnitude) == 'mi') $target *= 1024*1024;
|
||||
if (strtolower($magnitude) == 'g') $target *= 1000000000;
|
||||
if (strtolower($magnitude) == 'gi') $target *= 1024*1024*1024;
|
||||
|
||||
$comparison = array_key_exists(1, $matches) ? $matches[1] : '==';
|
||||
if ($comparison == '==' || $comparison == '')
|
||||
{
|
||||
return ($number == $target);
|
||||
}
|
||||
else if ($comparison == '>')
|
||||
{
|
||||
return ($number > $target);
|
||||
}
|
||||
else if ($comparison == '>=')
|
||||
{
|
||||
return ($number >= $target);
|
||||
}
|
||||
else if ($comparison == '<')
|
||||
{
|
||||
return ($number < $target);
|
||||
}
|
||||
else if ($comparison == '<=')
|
||||
{
|
||||
return ($number <= $target);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=head1 SYNOPSIS
|
||||
|
||||
Number::Compare->new(">1Ki")->test(1025); # is 1025 > 1024
|
||||
|
||||
my $c = Number::Compare->new(">1M");
|
||||
$c->(1_200_000); # slightly terser invocation
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=head2 ->new( $test )
|
||||
|
||||
Returns a new object that compares the specified test.
|
||||
|
||||
=head2 ->test( $value )
|
||||
|
||||
A longhanded version of $compare->( $value ). Predates blessed
|
||||
subroutine reference implementation.
|
||||
|
||||
=head2 ->parse_to_perl( $test )
|
||||
|
||||
Returns a perl code fragment equivalent to the test.
|
||||
*/
|
||||
310
lib/symfony/vendor/pake/pakeTask.class.php
vendored
Executable file
310
lib/symfony/vendor/pake/pakeTask.class.php
vendored
Executable file
@ -0,0 +1,310 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeTask.class.php 4358 2007-06-25 10:04:03Z fabien $
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* .
|
||||
*
|
||||
* .
|
||||
*
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeTask.class.php 4358 2007-06-25 10:04:03Z fabien $
|
||||
*/
|
||||
class pakeTask
|
||||
{
|
||||
protected static $TASKS = array();
|
||||
protected static $ALIAS = array();
|
||||
protected static $last_comment = '';
|
||||
protected $prerequisites = array();
|
||||
protected $name = '';
|
||||
protected $comment = '';
|
||||
protected $already_invoked = false;
|
||||
protected $trace = null;
|
||||
protected $verbose = null;
|
||||
protected $dryrun = null;
|
||||
protected $alias = '';
|
||||
|
||||
public function __construct($task_name)
|
||||
{
|
||||
$this->name = $task_name;
|
||||
$this->comment = '';
|
||||
$this->prerequisites = array();
|
||||
$this->already_invoked = false;
|
||||
$pake = pakeApp::get_instance();
|
||||
$this->trace = $pake->get_trace();
|
||||
$this->dryrun = $pake->get_dryrun();
|
||||
$this->verbose = $pake->get_verbose();
|
||||
}
|
||||
|
||||
public function is_verbose()
|
||||
{
|
||||
return $this->verbose;
|
||||
}
|
||||
|
||||
public function enhance($deps = null)
|
||||
{
|
||||
if (!$deps) return;
|
||||
|
||||
if (is_array($deps))
|
||||
{
|
||||
$this->prerequisites = array_merge($this->prerequisites, $deps);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->prerequisites[] = $deps;
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_tasks()
|
||||
{
|
||||
$tasks = pakeTask::$TASKS;
|
||||
// we merge tasks and aliases
|
||||
foreach (pakeTask::$ALIAS as $alias => $name)
|
||||
{
|
||||
if (!array_key_exists($name, $tasks))
|
||||
{
|
||||
throw new pakeException(sprintf('Task "%s" cannot be cloned to "%s" because it does not exist.', $name, $alias));
|
||||
}
|
||||
|
||||
$alias_task = clone $tasks[$name];
|
||||
$alias_task->alias = $name;
|
||||
$alias_task->name = $alias;
|
||||
$tasks[$alias] = $alias_task;
|
||||
}
|
||||
|
||||
return $tasks;
|
||||
}
|
||||
|
||||
public function get_property($name, $section = null)
|
||||
{
|
||||
$properties = pakeApp::get_instance()->get_properties();
|
||||
|
||||
if ($section)
|
||||
{
|
||||
if (!array_key_exists($section, $properties) || !array_key_exists($name, $properties[$section]))
|
||||
{
|
||||
throw new pakeException(sprintf('Property "%s/%s" does not exist.', $section, $name));
|
||||
}
|
||||
else
|
||||
{
|
||||
return $properties[$section][$name];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!array_key_exists($name, $properties))
|
||||
{
|
||||
throw new pakeException(sprintf('Property "%s" does not exist.', $name));
|
||||
}
|
||||
else
|
||||
{
|
||||
return $properties[$name];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function get_alias()
|
||||
{
|
||||
return $this->alias;
|
||||
}
|
||||
|
||||
public function get_prerequisites()
|
||||
{
|
||||
return $this->prerequisites;
|
||||
}
|
||||
|
||||
public function get_name()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function get_comment()
|
||||
{
|
||||
return $this->comment;
|
||||
}
|
||||
|
||||
// Format the trace flags for display.
|
||||
private function format_trace_flags()
|
||||
{
|
||||
$flags = array();
|
||||
if (!$this->already_invoked)
|
||||
{
|
||||
$flags[] = 'first_time';
|
||||
}
|
||||
if (!$this->is_needed())
|
||||
{
|
||||
$flags[] = 'not_needed';
|
||||
}
|
||||
|
||||
return (count($flags)) ? '('.join(', ', $flags).')' : '';
|
||||
}
|
||||
|
||||
public function invoke($args, $options)
|
||||
{
|
||||
if ($this->trace)
|
||||
{
|
||||
pake_echo_action('invoke', $this->name.' '.$this->format_trace_flags());
|
||||
}
|
||||
|
||||
// return if already invoked
|
||||
if ($this->already_invoked) return;
|
||||
$this->already_invoked = true;
|
||||
|
||||
// run prerequisites
|
||||
$tasks = self::get_tasks();
|
||||
foreach ($this->prerequisites as $prerequisite)
|
||||
{
|
||||
$real_prerequisite = self::get_full_task_name($prerequisite);
|
||||
if (array_key_exists($real_prerequisite, $tasks))
|
||||
{
|
||||
$tasks[$real_prerequisite]->invoke($args, $options);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new pakeException(sprintf('Prerequisite "%s" does not exist.', $prerequisite));
|
||||
}
|
||||
}
|
||||
|
||||
// only run if needed
|
||||
if ($this->is_needed())
|
||||
{
|
||||
return $this->execute($args, $options);
|
||||
}
|
||||
}
|
||||
|
||||
public function execute($args, $options)
|
||||
{
|
||||
if ($this->dryrun)
|
||||
{
|
||||
pake_echo_action('execute', '(dry run) '.$this->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->trace)
|
||||
{
|
||||
pake_echo_action('execute', $this->name);
|
||||
}
|
||||
|
||||
// action to run
|
||||
$function = ($this->get_alias() ? $this->get_alias() : $this->get_name());
|
||||
if ($pos = strpos($function, '::'))
|
||||
{
|
||||
$function = array(substr($function, 0, $pos), preg_replace('/\-/', '_', 'run_'.strtolower(substr($function, $pos + 2))));
|
||||
if (!is_callable($function))
|
||||
{
|
||||
throw new pakeException(sprintf('Task "%s" is defined but with no action defined.', $function[1]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$function = preg_replace('/\-/', '_', 'run_'.strtolower($function));
|
||||
if (!function_exists($function))
|
||||
{
|
||||
throw new pakeException(sprintf('Task "%s" is defined but with no action defined.', $this->name));
|
||||
}
|
||||
}
|
||||
|
||||
// execute action
|
||||
return call_user_func_array($function, array($this, $args, $options));
|
||||
}
|
||||
|
||||
public function is_needed()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function timestamp()
|
||||
{
|
||||
$max = 0;
|
||||
foreach ($this->prerequisites as $prerequisite)
|
||||
{
|
||||
$t = pakeTask::get($prerequisite)->timestamp();
|
||||
if ($t > $max) $max = $t;
|
||||
}
|
||||
|
||||
return ($max ? $max : time());
|
||||
}
|
||||
|
||||
public static function define_task($name, $deps = null)
|
||||
{
|
||||
$task = pakeTask::lookup($name, 'pakeTask');
|
||||
$task->add_comment();
|
||||
$task->enhance($deps);
|
||||
}
|
||||
|
||||
public static function define_alias($alias, $name)
|
||||
{
|
||||
self::$ALIAS[$alias] = $name;
|
||||
}
|
||||
|
||||
public static function lookup($task_name, $class = 'pakeTask')
|
||||
{
|
||||
$tasks = self::get_tasks();
|
||||
$task_name = self::get_full_task_name($task_name);
|
||||
if (!array_key_exists($task_name, $tasks))
|
||||
{
|
||||
pakeTask::$TASKS[$task_name] = new $class($task_name);
|
||||
}
|
||||
|
||||
return pakeTask::$TASKS[$task_name];
|
||||
}
|
||||
|
||||
public static function get($task_name)
|
||||
{
|
||||
$tasks = self::get_tasks();
|
||||
$task_name = self::get_full_task_name($task_name);
|
||||
if (!array_key_exists($task_name, $tasks))
|
||||
{
|
||||
throw new pakeException(sprintf('Task "%s" is not defined.', $task_name));
|
||||
}
|
||||
|
||||
return $tasks[$task_name];
|
||||
}
|
||||
|
||||
public static function get_full_task_name($task_name)
|
||||
{
|
||||
foreach (self::get_tasks() as $task)
|
||||
{
|
||||
$mini_task_name = self::get_mini_task_name($task->get_name());
|
||||
if ($mini_task_name == $task_name)
|
||||
{
|
||||
return $task->get_name();
|
||||
}
|
||||
}
|
||||
|
||||
return $task_name;
|
||||
}
|
||||
|
||||
public static function get_mini_task_name($task_name)
|
||||
{
|
||||
$is_method_task = strpos($task_name, '::');
|
||||
return ($is_method_task ? substr($task_name, $is_method_task + 2) : $task_name);
|
||||
}
|
||||
|
||||
public static function define_comment($comment)
|
||||
{
|
||||
pakeTask::$last_comment = $comment;
|
||||
}
|
||||
|
||||
public function add_comment()
|
||||
{
|
||||
if (!pakeTask::$last_comment) return;
|
||||
if ($this->comment)
|
||||
{
|
||||
$this->comment .= ' / ';
|
||||
}
|
||||
|
||||
$this->comment .= pakeTask::$last_comment;
|
||||
pakeTask::$last_comment = '';
|
||||
}
|
||||
}
|
||||
890
lib/symfony/vendor/pake/pakeYaml.class.php
vendored
Executable file
890
lib/symfony/vendor/pake/pakeYaml.class.php
vendored
Executable file
@ -0,0 +1,890 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package pake
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @license see the LICENSE file included in the distribution
|
||||
* @version SVN: $Id: pakeYaml.class.php 2978 2006-12-08 19:15:44Z fabien $
|
||||
*/
|
||||
|
||||
class pakeYaml
|
||||
{
|
||||
public static function load($input)
|
||||
{
|
||||
// syck is prefered over spyc
|
||||
if (function_exists('syck_load')) {
|
||||
if (!empty($input) && is_readable($input))
|
||||
{
|
||||
$input = file_get_contents($input);
|
||||
}
|
||||
|
||||
return syck_load($input);
|
||||
}
|
||||
else
|
||||
{
|
||||
$spyc = new pakeSpyc();
|
||||
|
||||
return $spyc->load($input);
|
||||
}
|
||||
}
|
||||
|
||||
public static function dump($array)
|
||||
{
|
||||
$spyc = new pakeSpyc();
|
||||
|
||||
return $spyc->dump($array);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Spyc -- A Simple PHP YAML Class
|
||||
* @version 0.2.2 -- 2006-01-29
|
||||
* @author Chris Wanstrath <chris@ozmm.org>
|
||||
* @link http://spyc.sourceforge.net/
|
||||
* @copyright Copyright 2005-2006 Chris Wanstrath
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
* @package Spyc
|
||||
*/
|
||||
|
||||
/**
|
||||
* A node, used by Spyc for parsing YAML.
|
||||
* @package Spyc
|
||||
*/
|
||||
class pakeYAMLNode {
|
||||
/**#@+
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $parent;
|
||||
public $id;
|
||||
/**#@+*/
|
||||
/**
|
||||
* @access public
|
||||
* @var mixed
|
||||
*/
|
||||
public $data;
|
||||
/**
|
||||
* @access public
|
||||
* @var int
|
||||
*/
|
||||
public $indent;
|
||||
/**
|
||||
* @access public
|
||||
* @var bool
|
||||
*/
|
||||
public $children = false;
|
||||
|
||||
/**
|
||||
* The constructor assigns the node a unique ID.
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function pakeYAMLNode() {
|
||||
$this->id = uniqid('');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Simple PHP YAML Class.
|
||||
*
|
||||
* This class can be used to read a YAML file and convert its contents
|
||||
* into a PHP array. It currently supports a very limited subsection of
|
||||
* the YAML spec.
|
||||
*
|
||||
* Usage:
|
||||
* <code>
|
||||
* $parser = new Spyc;
|
||||
* $array = $parser->load($file);
|
||||
* </code>
|
||||
* @package Spyc
|
||||
*/
|
||||
class pakeSpyc {
|
||||
|
||||
/**
|
||||
* Load YAML into a PHP array statically
|
||||
*
|
||||
* The load method, when supplied with a YAML stream (string or file),
|
||||
* will do its best to convert YAML in a file into a PHP array. Pretty
|
||||
* simple.
|
||||
* Usage:
|
||||
* <code>
|
||||
* $array = Spyc::YAMLLoad('lucky.yml');
|
||||
* print_r($array);
|
||||
* </code>
|
||||
* @access public
|
||||
* @return array
|
||||
* @param string $input Path of YAML file or string containing YAML
|
||||
*/
|
||||
public function YAMLLoad($input) {
|
||||
$spyc = new pakeSpyc;
|
||||
return $spyc->load($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump YAML from PHP array statically
|
||||
*
|
||||
* The dump method, when supplied with an array, will do its best
|
||||
* to convert the array into friendly YAML. Pretty simple. Feel free to
|
||||
* save the returned string as nothing.yml and pass it around.
|
||||
*
|
||||
* Oh, and you can decide how big the indent is and what the wordwrap
|
||||
* for folding is. Pretty cool -- just pass in 'false' for either if
|
||||
* you want to use the default.
|
||||
*
|
||||
* Indent's default is 2 spaces, wordwrap's default is 40 characters. And
|
||||
* you can turn off wordwrap by passing in 0.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
* @param array $array PHP array
|
||||
* @param int $indent Pass in false to use the default, which is 2
|
||||
* @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
|
||||
*/
|
||||
public function YAMLDump($array,$indent = false,$wordwrap = false) {
|
||||
$spyc = new pakeSpyc;
|
||||
return $spyc->dump($array,$indent,$wordwrap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load YAML into a PHP array from an instantiated object
|
||||
*
|
||||
* The load method, when supplied with a YAML stream (string or file path),
|
||||
* will do its best to convert the YAML into a PHP array. Pretty simple.
|
||||
* Usage:
|
||||
* <code>
|
||||
* $parser = new Spyc;
|
||||
* $array = $parser->load('lucky.yml');
|
||||
* print_r($array);
|
||||
* </code>
|
||||
* @access public
|
||||
* @return array
|
||||
* @param string $input Path of YAML file or string containing YAML
|
||||
*/
|
||||
public function load($input) {
|
||||
// See what type of input we're talking about
|
||||
// If it's not a file, assume it's a string
|
||||
if (!empty($input) && (strpos($input, "\n") === false)
|
||||
&& file_exists($input)) {
|
||||
$yaml = file($input);
|
||||
} else {
|
||||
$yaml = explode("\n",$input);
|
||||
}
|
||||
// Initiate some objects and values
|
||||
$base = new pakeYAMLNode;
|
||||
$base->indent = 0;
|
||||
$this->_lastIndent = 0;
|
||||
$this->_lastNode = $base->id;
|
||||
$this->_inBlock = false;
|
||||
$this->_isInline = false;
|
||||
|
||||
foreach ($yaml as $linenum => $line) {
|
||||
$ifchk = trim($line);
|
||||
|
||||
// If the line starts with a tab (instead of a space), throw a fit.
|
||||
if (preg_match('/^(\t)+(\w+)/', $line)) {
|
||||
$err = 'ERROR: Line '. ($linenum + 1) .' in your input YAML begins'.
|
||||
' with a tab. YAML only recognizes spaces. Please reformat.';
|
||||
throw new Exception($err);
|
||||
}
|
||||
|
||||
if ($this->_inBlock === false && empty($ifchk)) {
|
||||
continue;
|
||||
} elseif ($this->_inBlock == true && empty($ifchk)) {
|
||||
$last =& $this->_allNodes[$this->_lastNode];
|
||||
$last->data[key($last->data)] .= "\n";
|
||||
} elseif ($ifchk{0} != '#' && substr($ifchk,0,3) != '---') {
|
||||
// Create a new node and get its indent
|
||||
$node = new pakeYAMLNode;
|
||||
$node->indent = $this->_getIndent($line);
|
||||
|
||||
// Check where the node lies in the hierarchy
|
||||
if ($this->_lastIndent == $node->indent) {
|
||||
// If we're in a block, add the text to the parent's data
|
||||
if ($this->_inBlock === true) {
|
||||
$parent =& $this->_allNodes[$this->_lastNode];
|
||||
$parent->data[key($parent->data)] .= trim($line).$this->_blockEnd;
|
||||
} else {
|
||||
// The current node's parent is the same as the previous node's
|
||||
if (isset($this->_allNodes[$this->_lastNode])) {
|
||||
$node->parent = $this->_allNodes[$this->_lastNode]->parent;
|
||||
}
|
||||
}
|
||||
} elseif ($this->_lastIndent < $node->indent) {
|
||||
if ($this->_inBlock === true) {
|
||||
$parent =& $this->_allNodes[$this->_lastNode];
|
||||
$parent->data[key($parent->data)] .= trim($line).$this->_blockEnd;
|
||||
} elseif ($this->_inBlock === false) {
|
||||
// The current node's parent is the previous node
|
||||
$node->parent = $this->_lastNode;
|
||||
|
||||
// If the value of the last node's data was > or | we need to
|
||||
// start blocking i.e. taking in all lines as a text value until
|
||||
// we drop our indent.
|
||||
$parent =& $this->_allNodes[$node->parent];
|
||||
$this->_allNodes[$node->parent]->children = true;
|
||||
if (is_array($parent->data)) {
|
||||
$chk = $parent->data[key($parent->data)];
|
||||
if ($chk === '>') {
|
||||
$this->_inBlock = true;
|
||||
$this->_blockEnd = ' ';
|
||||
$parent->data[key($parent->data)] =
|
||||
str_replace('>','',$parent->data[key($parent->data)]);
|
||||
$parent->data[key($parent->data)] .= trim($line).' ';
|
||||
$this->_allNodes[$node->parent]->children = false;
|
||||
$this->_lastIndent = $node->indent;
|
||||
} elseif ($chk === '|') {
|
||||
$this->_inBlock = true;
|
||||
$this->_blockEnd = "\n";
|
||||
$parent->data[key($parent->data)] =
|
||||
str_replace('|','',$parent->data[key($parent->data)]);
|
||||
$parent->data[key($parent->data)] .= trim($line)."\n";
|
||||
$this->_allNodes[$node->parent]->children = false;
|
||||
$this->_lastIndent = $node->indent;
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($this->_lastIndent > $node->indent) {
|
||||
// Any block we had going is dead now
|
||||
if ($this->_inBlock === true) {
|
||||
$this->_inBlock = false;
|
||||
if ($this->_blockEnd = "\n") {
|
||||
$last =& $this->_allNodes[$this->_lastNode];
|
||||
$last->data[key($last->data)] =
|
||||
trim($last->data[key($last->data)]);
|
||||
}
|
||||
}
|
||||
|
||||
// We don't know the parent of the node so we have to find it
|
||||
// foreach ($this->_allNodes as $n) {
|
||||
foreach ($this->_indentSort[$node->indent] as $n) {
|
||||
if ($n->indent == $node->indent) {
|
||||
$node->parent = $n->parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->_inBlock === false) {
|
||||
// Set these properties with information from our current node
|
||||
$this->_lastIndent = $node->indent;
|
||||
// Set the last node
|
||||
$this->_lastNode = $node->id;
|
||||
// Parse the YAML line and return its data
|
||||
$node->data = $this->_parseLine($line);
|
||||
// Add the node to the master list
|
||||
$this->_allNodes[$node->id] = $node;
|
||||
// Add a reference to the node in an indent array
|
||||
$this->_indentSort[$node->indent][] =& $this->_allNodes[$node->id];
|
||||
// Add a reference to the node in a References array if this node
|
||||
// has a YAML reference in it.
|
||||
if (
|
||||
( (is_array($node->data)) &&
|
||||
isset($node->data[key($node->data)]) &&
|
||||
(!is_array($node->data[key($node->data)])) )
|
||||
&&
|
||||
( (preg_match('/^&([^ ]+)/',$node->data[key($node->data)]))
|
||||
||
|
||||
(preg_match('/^\*([^ ]+)/',$node->data[key($node->data)])) )
|
||||
) {
|
||||
$this->_haveRefs[] =& $this->_allNodes[$node->id];
|
||||
} elseif (
|
||||
( (is_array($node->data)) &&
|
||||
isset($node->data[key($node->data)]) &&
|
||||
(is_array($node->data[key($node->data)])) )
|
||||
) {
|
||||
// Incomplete reference making code. Ugly, needs cleaned up.
|
||||
foreach ($node->data[key($node->data)] as $d) {
|
||||
if ( !is_array($d) &&
|
||||
( (preg_match('/^&([^ ]+)/',$d))
|
||||
||
|
||||
(preg_match('/^\*([^ ]+)/',$d)) )
|
||||
) {
|
||||
$this->_haveRefs[] =& $this->_allNodes[$node->id];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($node);
|
||||
|
||||
// Here we travel through node-space and pick out references (& and *)
|
||||
$this->_linkReferences();
|
||||
|
||||
// Build the PHP array out of node-space
|
||||
$trunk = $this->_buildArray();
|
||||
return $trunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump PHP array to YAML
|
||||
*
|
||||
* The dump method, when supplied with an array, will do its best
|
||||
* to convert the array into friendly YAML. Pretty simple. Feel free to
|
||||
* save the returned string as tasteful.yml and pass it around.
|
||||
*
|
||||
* Oh, and you can decide how big the indent is and what the wordwrap
|
||||
* for folding is. Pretty cool -- just pass in 'false' for either if
|
||||
* you want to use the default.
|
||||
*
|
||||
* Indent's default is 2 spaces, wordwrap's default is 40 characters. And
|
||||
* you can turn off wordwrap by passing in 0.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
* @param array $array PHP array
|
||||
* @param int $indent Pass in false to use the default, which is 2
|
||||
* @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
|
||||
*/
|
||||
public function dump($array,$indent = false,$wordwrap = false) {
|
||||
// Dumps to some very clean YAML. We'll have to add some more features
|
||||
// and options soon. And better support for folding.
|
||||
|
||||
// New features and options.
|
||||
if ($indent === false or !is_numeric($indent)) {
|
||||
$this->_dumpIndent = 2;
|
||||
} else {
|
||||
$this->_dumpIndent = $indent;
|
||||
}
|
||||
|
||||
if ($wordwrap === false or !is_numeric($wordwrap)) {
|
||||
$this->_dumpWordWrap = 40;
|
||||
} else {
|
||||
$this->_dumpWordWrap = $wordwrap;
|
||||
}
|
||||
|
||||
// New YAML document
|
||||
$string = "---\n";
|
||||
|
||||
// Start at the base of the array and move through it.
|
||||
foreach ($array as $key => $value) {
|
||||
$string .= $this->_yamlize($key,$value,0);
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**** Private Properties ****/
|
||||
|
||||
/**#@+
|
||||
* @access private
|
||||
* @var mixed
|
||||
*/
|
||||
private $_haveRefs;
|
||||
private $_allNodes;
|
||||
private $_lastIndent;
|
||||
private $_lastNode;
|
||||
private $_inBlock;
|
||||
private $_isInline;
|
||||
private $_dumpIndent;
|
||||
private $_dumpWordWrap;
|
||||
/**#@+*/
|
||||
|
||||
/**** Private Methods ****/
|
||||
|
||||
/**
|
||||
* Attempts to convert a key / value array item to YAML
|
||||
* @access private
|
||||
* @return string
|
||||
* @param $key The name of the key
|
||||
* @param $value The value of the item
|
||||
* @param $indent The indent of the current node
|
||||
*/
|
||||
private function _yamlize($key,$value,$indent) {
|
||||
if (is_array($value)) {
|
||||
// It has children. What to do?
|
||||
// Make it the right kind of item
|
||||
$string = $this->_dumpNode($key,NULL,$indent);
|
||||
// Add the indent
|
||||
$indent += $this->_dumpIndent;
|
||||
// Yamlize the array
|
||||
$string .= $this->_yamlizeArray($value,$indent);
|
||||
} elseif (!is_array($value)) {
|
||||
// It doesn't have children. Yip.
|
||||
$string = $this->_dumpNode($key,$value,$indent);
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to convert an array to YAML
|
||||
* @access private
|
||||
* @return string
|
||||
* @param $array The array you want to convert
|
||||
* @param $indent The indent of the current level
|
||||
*/
|
||||
private function _yamlizeArray($array,$indent) {
|
||||
if (is_array($array)) {
|
||||
$string = '';
|
||||
foreach ($array as $key => $value) {
|
||||
$string .= $this->_yamlize($key,$value,$indent);
|
||||
}
|
||||
return $string;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns YAML from a key and a value
|
||||
* @access private
|
||||
* @return string
|
||||
* @param $key The name of the key
|
||||
* @param $value The value of the item
|
||||
* @param $indent The indent of the current node
|
||||
*/
|
||||
private function _dumpNode($key,$value,$indent) {
|
||||
// do some folding here, for blocks
|
||||
if (strpos($value,"\n")) {
|
||||
$value = $this->_doLiteralBlock($value,$indent);
|
||||
} else {
|
||||
$value = $this->_doFolding($value,$indent);
|
||||
}
|
||||
|
||||
$spaces = str_repeat(' ',$indent);
|
||||
|
||||
if (is_int($key)) {
|
||||
// It's a sequence
|
||||
$string = $spaces.'- '.$value."\n";
|
||||
} else {
|
||||
// It's mapped
|
||||
$string = $spaces.$key.': '.$value."\n";
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a literal block for dumping
|
||||
* @access private
|
||||
* @return string
|
||||
* @param $value
|
||||
* @param $indent int The value of the indent
|
||||
*/
|
||||
private function _doLiteralBlock($value,$indent) {
|
||||
$exploded = explode("\n",$value);
|
||||
$newValue = '|';
|
||||
$indent += $this->_dumpIndent;
|
||||
$spaces = str_repeat(' ',$indent);
|
||||
foreach ($exploded as $line) {
|
||||
$newValue .= "\n" . $spaces . trim($line);
|
||||
}
|
||||
return $newValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Folds a string of text, if necessary
|
||||
* @access private
|
||||
* @return string
|
||||
* @param $value The string you wish to fold
|
||||
*/
|
||||
private function _doFolding($value,$indent) {
|
||||
// Don't do anything if wordwrap is set to 0
|
||||
if ($this->_dumpWordWrap === 0) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (strlen($value) > $this->_dumpWordWrap) {
|
||||
$indent += $this->_dumpIndent;
|
||||
$indent = str_repeat(' ',$indent);
|
||||
$wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent");
|
||||
$value = ">\n".$indent.$wrapped;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/* Methods used in loading */
|
||||
|
||||
/**
|
||||
* Finds and returns the indentation of a YAML line
|
||||
* @access private
|
||||
* @return int
|
||||
* @param string $line A line from the YAML file
|
||||
*/
|
||||
private function _getIndent($line) {
|
||||
preg_match('/^\s{1,}/',$line,$match);
|
||||
if (!empty($match[0])) {
|
||||
$indent = substr_count($match[0],' ');
|
||||
} else {
|
||||
$indent = 0;
|
||||
}
|
||||
return $indent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses YAML code and returns an array for a node
|
||||
* @access private
|
||||
* @return array
|
||||
* @param string $line A line from the YAML file
|
||||
*/
|
||||
private function _parseLine($line) {
|
||||
$line = trim($line);
|
||||
|
||||
$array = array();
|
||||
|
||||
if (preg_match('/^-(.*):$/',$line)) {
|
||||
// It's a mapped sequence
|
||||
$key = trim(substr(substr($line,1),0,-1));
|
||||
$array[$key] = '';
|
||||
} elseif ($line[0] == '-' && substr($line,0,3) != '---') {
|
||||
// It's a list item but not a new stream
|
||||
if (strlen($line) > 1) {
|
||||
$value = trim(substr($line,1));
|
||||
// Set the type of the value. Int, string, etc
|
||||
$value = $this->_toType($value);
|
||||
$array[] = $value;
|
||||
} else {
|
||||
$array[] = array();
|
||||
}
|
||||
} elseif (preg_match('/^(.+):/',$line,$key)) {
|
||||
// It's a key/value pair most likely
|
||||
// If the key is in double quotes pull it out
|
||||
if (preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) {
|
||||
$value = trim(str_replace($matches[1],'',$line));
|
||||
$key = $matches[2];
|
||||
} else {
|
||||
// Do some guesswork as to the key and the value
|
||||
$explode = explode(':',$line);
|
||||
$key = trim($explode[0]);
|
||||
array_shift($explode);
|
||||
$value = trim(implode(':',$explode));
|
||||
}
|
||||
|
||||
// Set the type of the value. Int, string, etc
|
||||
$value = $this->_toType($value);
|
||||
if (empty($key)) {
|
||||
$array[] = $value;
|
||||
} else {
|
||||
$array[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the type of the passed value, returns the value as the new type.
|
||||
* @access private
|
||||
* @param string $value
|
||||
* @return mixed
|
||||
*/
|
||||
private function _toType($value) {
|
||||
if (preg_match('/^("(.*)"|\'(.*)\')/',$value,$matches)) {
|
||||
$value = (string)preg_replace('/(\'\'|\\\\\')/',"'",end($matches));
|
||||
$value = preg_replace('/\\\\"/','"',$value);
|
||||
} elseif (preg_match('/^\\[(.+)\\]$/',$value,$matches)) {
|
||||
// Inline Sequence
|
||||
|
||||
// Take out strings sequences and mappings
|
||||
$explode = $this->_inlineEscape($matches[1]);
|
||||
|
||||
// Propogate value array
|
||||
$value = array();
|
||||
foreach ($explode as $v) {
|
||||
$value[] = $this->_toType($v);
|
||||
}
|
||||
} elseif (strpos($value,': ')!==false && !preg_match('/^{(.+)/',$value)) {
|
||||
// It's a map
|
||||
$array = explode(': ',$value);
|
||||
$key = trim($array[0]);
|
||||
array_shift($array);
|
||||
$value = trim(implode(': ',$array));
|
||||
$value = $this->_toType($value);
|
||||
$value = array($key => $value);
|
||||
} elseif (preg_match("/{(.+)}$/",$value,$matches)) {
|
||||
// Inline Mapping
|
||||
|
||||
// Take out strings sequences and mappings
|
||||
$explode = $this->_inlineEscape($matches[1]);
|
||||
|
||||
// Propogate value array
|
||||
$array = array();
|
||||
foreach ($explode as $v) {
|
||||
$array = $array + $this->_toType($v);
|
||||
}
|
||||
$value = $array;
|
||||
} elseif (strtolower($value) == 'null' or $value == '' or $value == '~') {
|
||||
$value = NULL;
|
||||
} elseif (ctype_digit($value)) {
|
||||
$value = (int)$value;
|
||||
} elseif (in_array(strtolower($value),
|
||||
array('true', 'on', '+', 'yes', 'y'))) {
|
||||
$value = TRUE;
|
||||
} elseif (in_array(strtolower($value),
|
||||
array('false', 'off', '-', 'no', 'n'))) {
|
||||
$value = FALSE;
|
||||
} elseif (is_numeric($value)) {
|
||||
$value = (float)$value;
|
||||
} else {
|
||||
// Just a normal string, right?
|
||||
$value = trim(preg_replace('/#(.+)$/','',$value));
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in inlines to check for more inlines or quoted strings
|
||||
* @access private
|
||||
* @return array
|
||||
*/
|
||||
private function _inlineEscape($inline) {
|
||||
// There's gotta be a cleaner way to do this...
|
||||
// While pure sequences seem to be nesting just fine,
|
||||
// pure mappings and mappings with sequences inside can't go very
|
||||
// deep. This needs to be fixed.
|
||||
|
||||
// Check for strings
|
||||
$regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/';
|
||||
if (preg_match_all($regex,$inline,$strings)) {
|
||||
$strings = $strings[2];
|
||||
$inline = preg_replace($regex,'YAMLString',$inline);
|
||||
}
|
||||
unset($regex);
|
||||
|
||||
// Check for sequences
|
||||
if (preg_match_all('/\[(.+)\]/U',$inline,$seqs)) {
|
||||
$inline = preg_replace('/\[(.+)\]/U','YAMLSeq',$inline);
|
||||
$seqs = $seqs[0];
|
||||
}
|
||||
|
||||
// Check for mappings
|
||||
if (preg_match_all('/{(.+)}/U',$inline,$maps)) {
|
||||
$inline = preg_replace('/{(.+)}/U','YAMLMap',$inline);
|
||||
$maps = $maps[0];
|
||||
}
|
||||
|
||||
$explode = explode(', ',$inline);
|
||||
|
||||
// Re-add the strings
|
||||
if (!empty($strings)) {
|
||||
$i = 0;
|
||||
foreach ($explode as $key => $value) {
|
||||
if ($value == 'YAMLString') {
|
||||
$explode[$key] = $strings[$i];
|
||||
++$i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Re-add the sequences
|
||||
if (!empty($seqs)) {
|
||||
$i = 0;
|
||||
foreach ($explode as $key => $value) {
|
||||
if (strpos($value,'YAMLSeq') !== false) {
|
||||
$explode[$key] = str_replace('YAMLSeq',$seqs[$i],$value);
|
||||
++$i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Re-add the mappings
|
||||
if (!empty($maps)) {
|
||||
$i = 0;
|
||||
foreach ($explode as $key => $value) {
|
||||
if (strpos($value,'YAMLMap') !== false) {
|
||||
$explode[$key] = str_replace('YAMLMap',$maps[$i],$value);
|
||||
++$i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $explode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the PHP array from all the YAML nodes we've gathered
|
||||
* @access private
|
||||
* @return array
|
||||
*/
|
||||
private function _buildArray() {
|
||||
$trunk = array();
|
||||
|
||||
if (!isset($this->_indentSort[0])) {
|
||||
return $trunk;
|
||||
}
|
||||
|
||||
foreach ($this->_indentSort[0] as $n) {
|
||||
if (empty($n->parent)) {
|
||||
$this->_nodeArrayizeData($n);
|
||||
// Check for references and copy the needed data to complete them.
|
||||
$this->_makeReferences($n);
|
||||
// Merge our data with the big array we're building
|
||||
$trunk = $this->_array_kmerge($trunk,$n->data);
|
||||
}
|
||||
}
|
||||
|
||||
return $trunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses node-space and sets references (& and *) accordingly
|
||||
* @access private
|
||||
* @return bool
|
||||
*/
|
||||
private function _linkReferences() {
|
||||
if (is_array($this->_haveRefs)) {
|
||||
foreach ($this->_haveRefs as $node) {
|
||||
if (!empty($node->data)) {
|
||||
$key = key($node->data);
|
||||
// If it's an array, don't check.
|
||||
if (is_array($node->data[$key])) {
|
||||
foreach ($node->data[$key] as $k => $v) {
|
||||
$this->_linkRef($node,$key,$k,$v);
|
||||
}
|
||||
} else {
|
||||
$this->_linkRef($node,$key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function _linkRef(&$n,$key,$k = NULL,$v = NULL) {
|
||||
if (empty($k) && empty($v)) {
|
||||
// Look for &refs
|
||||
if (preg_match('/^&([^ ]+)/',$n->data[$key],$matches)) {
|
||||
// Flag the node so we know it's a reference
|
||||
$this->_allNodes[$n->id]->ref = substr($matches[0],1);
|
||||
$this->_allNodes[$n->id]->data[$key] =
|
||||
substr($n->data[$key],strlen($matches[0])+1);
|
||||
// Look for *refs
|
||||
} elseif (preg_match('/^\*([^ ]+)/',$n->data[$key],$matches)) {
|
||||
$ref = substr($matches[0],1);
|
||||
// Flag the node as having a reference
|
||||
$this->_allNodes[$n->id]->refKey = $ref;
|
||||
}
|
||||
} elseif (!empty($k) && !empty($v)) {
|
||||
if (preg_match('/^&([^ ]+)/',$v,$matches)) {
|
||||
// Flag the node so we know it's a reference
|
||||
$this->_allNodes[$n->id]->ref = substr($matches[0],1);
|
||||
$this->_allNodes[$n->id]->data[$key][$k] =
|
||||
substr($v,strlen($matches[0])+1);
|
||||
// Look for *refs
|
||||
} elseif (preg_match('/^\*([^ ]+)/',$v,$matches)) {
|
||||
$ref = substr($matches[0],1);
|
||||
// Flag the node as having a reference
|
||||
$this->_allNodes[$n->id]->refKey = $ref;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the children of a node and aids in the building of the PHP array
|
||||
* @access private
|
||||
* @param int $nid The id of the node whose children we're gathering
|
||||
* @return array
|
||||
*/
|
||||
private function _gatherChildren($nid) {
|
||||
$return = array();
|
||||
$node =& $this->_allNodes[$nid];
|
||||
foreach ($this->_allNodes as $z) {
|
||||
if ($z->parent == $node->id) {
|
||||
// We found a child
|
||||
$this->_nodeArrayizeData($z);
|
||||
// Check for references
|
||||
$this->_makeReferences($z);
|
||||
// Merge with the big array we're returning
|
||||
// The big array being all the data of the children of our parent node
|
||||
$return = $this->_array_kmerge($return,$z->data);
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns a node's data and its children's data into a PHP array
|
||||
*
|
||||
* @access private
|
||||
* @param array $node The node which you want to arrayize
|
||||
* @return boolean
|
||||
*/
|
||||
private function _nodeArrayizeData(&$node) {
|
||||
if (is_array($node->data) && $node->children == true) {
|
||||
// This node has children, so we need to find them
|
||||
$childs = $this->_gatherChildren($node->id);
|
||||
// We've gathered all our children's data and are ready to use it
|
||||
$key = key($node->data);
|
||||
$key = empty($key) ? 0 : $key;
|
||||
// If it's an array, add to it of course
|
||||
if (is_array($node->data[$key])) {
|
||||
$node->data[$key] = $this->_array_kmerge($node->data[$key],$childs);
|
||||
} else {
|
||||
$node->data[$key] = $childs;
|
||||
}
|
||||
} elseif (!is_array($node->data) && $node->children == true) {
|
||||
// Same as above, find the children of this node
|
||||
$childs = $this->_gatherChildren($node->id);
|
||||
$node->data = array();
|
||||
$node->data[] = $childs;
|
||||
}
|
||||
|
||||
// We edited $node by reference, so just return true
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses node-space and copies references to / from this object.
|
||||
* @access private
|
||||
* @param object $z A node whose references we wish to make real
|
||||
* @return bool
|
||||
*/
|
||||
private function _makeReferences(&$z) {
|
||||
// It is a reference
|
||||
if (isset($z->ref)) {
|
||||
$key = key($z->data);
|
||||
// Copy the data to this object for easy retrieval later
|
||||
$this->ref[$z->ref] =& $z->data[$key];
|
||||
// It has a reference
|
||||
} elseif (isset($z->refKey)) {
|
||||
if (isset($this->ref[$z->refKey])) {
|
||||
$key = key($z->data);
|
||||
// Copy the data from this object to make the node a real reference
|
||||
$z->data[$key] =& $this->ref[$z->refKey];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Merges arrays and maintains numeric keys.
|
||||
*
|
||||
* An ever-so-slightly modified version of the array_kmerge() function posted
|
||||
* to php.net by mail at nospam dot iaindooley dot com on 2004-04-08.
|
||||
*
|
||||
* http://us3.php.net/manual/en/function.array-merge.php#41394
|
||||
*
|
||||
* @access private
|
||||
* @param array $arr1
|
||||
* @param array $arr2
|
||||
* @return array
|
||||
*/
|
||||
private function _array_kmerge($arr1,$arr2) {
|
||||
if(!is_array($arr1))
|
||||
$arr1 = array();
|
||||
|
||||
if(!is_array($arr2))
|
||||
$arr2 = array();
|
||||
|
||||
$keys1 = array_keys($arr1);
|
||||
$keys2 = array_keys($arr2);
|
||||
$keys = array_merge($keys1,$keys2);
|
||||
$vals1 = array_values($arr1);
|
||||
$vals2 = array_values($arr2);
|
||||
$vals = array_merge($vals1,$vals2);
|
||||
$ret = array();
|
||||
|
||||
foreach($keys as $key) {
|
||||
list($unused,$val) = each($vals);
|
||||
// This is the good part! If a key already exists, but it's part of a
|
||||
// sequence (an int), just keep addin numbers until we find a fresh one.
|
||||
if (isset($ret[$key]) and is_int($key)) {
|
||||
while (array_key_exists($key, $ret)) {
|
||||
$key++;
|
||||
}
|
||||
}
|
||||
$ret[$key] = $val;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user