$charset, 'MultipleActiveResultSets' => $multiResultSets ); if( !(defined('MSSQL_USE_WINDOWS_AUTHENTICATION') && MSSQL_USE_WINDOWS_AUTHENTICATION == true) && empty($parameters['windowsauthentication']) ) { $options['UID'] = $parameters['username']; $options['PWD'] = $parameters['password']; } // Required by MS Azure database if($selectDB && !empty($parameters['database'])) { $options['Database'] = $parameters['database']; } $this->dbConn = sqlsrv_connect($parameters['server'], $options); if(empty($this->dbConn)) { $this->databaseError("Couldn't connect to SQL Server database"); } elseif($selectDB && !empty($parameters['database'])) { // Check selected database (Azure) $this->selectedDatabase = $parameters['database']; } } /** * Start transaction. READ ONLY not supported. */ public function transactionStart(){ $result = sqlsrv_begin_transaction($this->dbConn); if (!$result) { $this->databaseError("Couldn't start the transaction."); } } /** * Commit everything inside this transaction so far */ public function transactionEnd() { $result = sqlsrv_commit($this->dbConn); if (!$result) { $this->databaseError("Couldn't commit the transaction."); } } /** * Rollback or revert to a savepoint if your queries encounter problems * If you encounter a problem at any point during a transaction, you may * need to rollback that particular query, or return to a savepoint */ public function transactionRollback(){ $result = sqlsrv_rollback($this->dbConn); if (!$result) { $this->databaseError("Couldn't rollback the transaction."); } } public function affectedRows() { return $this->lastAffectedRows; } public function getLastError() { $errorMessages = array(); $errors = sqlsrv_errors(); if($errors) foreach($errors as $info) { $errorMessages[] = implode(', ', array($info['SQLSTATE'], $info['code'], $info['message'])); } return implode('; ', $errorMessages); } public function isActive() { return $this->dbConn && $this->selectedDatabase; } public function preparedQuery($sql, $parameters, $errorLevel = E_USER_ERROR) { // Check if we should only preview this query if ($this->previewWrite($sql)) return; $parsedParameters = $this->parameterValues($parameters); // Benchmark query $dbConn = $this->dbConn; $handle = $this->benchmarkQuery($sql, function($sql) use($dbConn, $parsedParameters) { if(empty($parsedParameters)) { return sqlsrv_query($dbConn, $sql); } else { return sqlsrv_query($dbConn, $sql, $parsedParameters); } }); if($handle) { $this->lastAffectedRows = sqlsrv_rows_affected($handle); } else { $this->databaseError($this->getLastError(), $errorLevel, $sql, $parsedParameters); return null; } return new SQLServerQuery($this, $handle); } public function query($sql, $errorLevel = E_USER_ERROR) { return $this->preparedQuery($sql, array(), $errorLevel); } public function selectDatabase($name) { $this->query("USE \"$name\""); $this->selectedDatabase = $name; return true; } public function __destruct() { if(is_resource($this->dbConn)) { sqlsrv_close($this->dbConn); } } public function getVersion() { // @todo - use sqlsrv_server_info? return trim($this->query("SELECT CONVERT(char(15), SERVERPROPERTY('ProductVersion'))")->value()); } public function getGeneratedID($table) { return $this->query("SELECT IDENT_CURRENT('$table')")->value(); } public function getSelectedDatabase() { return $this->selectedDatabase; } public function unloadDatabase() { $this->selectDatabase('Master'); $this->selectedDatabase = null; } /** * Quotes a string, including the "N" prefix so unicode * strings are saved to the database correctly. * * @param string $string String to be encoded * @return string Processed string ready for DB */ public function quoteString($value) { return "N'" . $this->escapeString($value) . "'"; } public function escapeString($value) { $value = str_replace("'", "''", $value); $value = str_replace("\0", "[NULL]", $value); return $value; } }