.
*/
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:
*
* ini_set('mssql.textsize', 2147483647);
* ini_set('mssql.textlimit', 2147483647);
*
* 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
* @author Stig Bakken
* @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);
}
}