initial commit

This commit is contained in:
Chris Sewell
2012-11-28 03:55:08 -05:00
parent 7adb399b2e
commit cf140a2e97
3247 changed files with 492437 additions and 0 deletions

View 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);
}
}

View 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());
}
}

View 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 ) . "'";
}
}
}

View 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;
}
}

View 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++;
}
}

View 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 {
}

View 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];
}
}

View 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.");
}
}

View 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;
}
}