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

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

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

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

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

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

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