-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add SAP Sybase SQL Anywhere database vendor #293
Changes from 12 commits
d0c9ef8
bfbc1e2
2d1c970
0779db9
9f6a405
9c042ee
edf42f1
7d408fc
acb3603
56e8e09
11bbb16
0083774
87049d6
617b824
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
<?php | ||
/* | ||
* 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 MIT license. For more information, see | ||
* <http://www.doctrine-project.org>. | ||
*/ | ||
|
||
namespace Doctrine\DBAL\Driver\SQLAnywhere; | ||
|
||
use Doctrine\DBAL\Connection; | ||
use Doctrine\DBAL\Platforms\SQLAnywhere12Platform; | ||
use Doctrine\DBAL\Schema\SQLAnywhereSchemaManager; | ||
|
||
/** | ||
* A Doctrine DBAL driver for the SAP Sybase SQL Anywhere PHP extension. | ||
* | ||
* @author Steve Müller <[email protected]> | ||
* @link www.doctrine-project.org | ||
* @since 2.5 | ||
*/ | ||
class Driver implements \Doctrine\DBAL\Driver | ||
{ | ||
/** | ||
* Build the connection string for given connection parameters and driver options. | ||
* | ||
* @param string $host Host address to connect to. | ||
* @param integer $port Port to use for the connection (default to SQL Anywhere standard port 2683). | ||
* @param string $server Database server name on the host to connect to. | ||
* SQL Anywhere allows multiple database server instances on the same host, | ||
* therefore specifying the server instance name to use is mandatory. | ||
* @param string $dbname Name of the database on the server instance to connect to. | ||
* @param string $username User name to use for connection authentication. | ||
* @param string $password Password to use for connection authentication. | ||
* @param array $driverOptions Additional parameters to use for the connection. | ||
* | ||
* @return string | ||
*/ | ||
public function buildDsn($host, $port, $server, $dbname, $username = null, $password = null, array $driverOptions = array()) | ||
{ | ||
$port = $port ?: 2683; | ||
|
||
return | ||
'LINKS=tcpip(HOST=' . $host . ';PORT=' . $port . ';DoBroadcast=Direct)' . | ||
';ServerName=' . $server . | ||
';DBN=' . $dbname . | ||
';UID=' . $username . | ||
';PWD=' . $password . | ||
';' . implode( | ||
';', | ||
array_map(function ($key, $value) { | ||
return $key . '=' . $value; | ||
}, array_keys($driverOptions), $driverOptions) | ||
); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
* | ||
* @throws SQLAnywhereException | ||
*/ | ||
public function connect(array $params, $username = null, $password = null, array $driverOptions = array()) | ||
{ | ||
if ( ! isset($params['host'])) { | ||
throw new SQLAnywhereException("Missing 'host' in configuration for sqlanywhere driver."); | ||
} | ||
|
||
if ( ! isset($params['server'])) { | ||
throw new SQLAnywhereException("Missing 'server' in configuration for sqlanywhere driver."); | ||
} | ||
|
||
if ( ! isset($params['dbname'])) { | ||
throw new SQLAnywhereException("Missing 'dbname' in configuration for sqlanywhere driver."); | ||
} | ||
|
||
return new SQLAnywhereConnection( | ||
$this->buildDsn( | ||
$params['host'], | ||
isset($params['port']) ? $params['port'] : null, | ||
$params['server'], | ||
$params['dbname'], | ||
$username, | ||
$password, | ||
$driverOptions | ||
), | ||
isset($params['persistent']) ? $params['persistent'] : false | ||
); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getDatabase(Connection $conn) | ||
{ | ||
$params = $conn->getParams(); | ||
|
||
return $params['dbname']; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getDatabasePlatform() | ||
{ | ||
return new SQLAnywhere12Platform(); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getName() | ||
{ | ||
return 'sqlanywhere'; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getSchemaManager(Connection $conn) | ||
{ | ||
return new SQLAnywhereSchemaManager($conn); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. EOF EOL |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
<?php | ||
/* | ||
* 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 MIT license. For more information, see | ||
* <http://www.doctrine-project.org>. | ||
*/ | ||
|
||
namespace Doctrine\DBAL\Driver\SQLAnywhere; | ||
|
||
use Doctrine\DBAL\Driver\Connection; | ||
|
||
/** | ||
* SAP Sybase SQL Anywhere implementation of the Connection interface. | ||
* | ||
* @author Steve Müller <[email protected]> | ||
* @link www.doctrine-project.org | ||
* @since 2.5 | ||
*/ | ||
class SQLAnywhereConnection implements Connection | ||
{ | ||
/** | ||
* @var resource The SQL Anywhere connection resource. | ||
*/ | ||
private $conn; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the abbreviation necessary? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No I think I adopted the notation from other drivers back then. I can change that to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair enuff - I think it's readable as it is, so ok |
||
|
||
/** | ||
* Constructor. | ||
* | ||
* Connects to database with given connection string. | ||
* | ||
* @param string $dsn The connection string. | ||
* @param boolean $persistent Whether or not to establish a persistent connection. | ||
* | ||
* @throws SQLAnywhereException | ||
*/ | ||
public function __construct($dsn, $persistent = false) | ||
{ | ||
$this->conn = $persistent ? @sasql_pconnect($dsn) : @sasql_connect($dsn); | ||
|
||
if ( ! is_resource($this->conn) || get_resource_type($this->conn) != 'SQLAnywhere connection') { | ||
throw SQLAnywhereException::fromSQLAnywhereError(); | ||
} | ||
|
||
/** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not docblocks - use single-line comments |
||
* Disable PHP warnings on error | ||
*/ | ||
if ( ! sasql_set_option($this->conn, 'verbose_errors', false)) { | ||
throw SQLAnywhereException::fromSQLAnywhereError($this->conn); | ||
} | ||
|
||
/** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not docblocks - use single-line comments |
||
* Enable auto committing by default | ||
*/ | ||
if ( ! sasql_set_option($this->conn, 'auto_commit', 'on')) { | ||
throw SQLAnywhereException::fromSQLAnywhereError($this->conn); | ||
} | ||
|
||
/** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not docblocks - use single-line comments |
||
* Enable exact, non-approximated row count retrieval | ||
*/ | ||
if ( ! sasql_set_option($this->conn, 'row_counts', true)) { | ||
throw SQLAnywhereException::fromSQLAnywhereError($this->conn); | ||
} | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
* | ||
* @throws SQLAnywhereException | ||
*/ | ||
public function beginTransaction() | ||
{ | ||
if ( ! sasql_set_option($this->conn, 'auto_commit', 'off')) { | ||
throw SQLAnywhereException::fromSQLAnywhereError($this->conn); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
* | ||
* @throws SQLAnywhereException | ||
*/ | ||
public function commit() | ||
{ | ||
if ( ! sasql_commit($this->conn)) { | ||
throw SQLAnywhereException::fromSQLAnywhereError($this->conn); | ||
} | ||
|
||
$this->endTransaction(); | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function errorCode() | ||
{ | ||
return sasql_errorcode($this->conn); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function errorInfo() | ||
{ | ||
return sasql_error($this->conn); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function exec($statement) | ||
{ | ||
$stmt = $this->prepare($statement); | ||
$stmt->execute(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Newline before this line |
||
|
||
return $stmt->rowCount(); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function lastInsertId($name = null) | ||
{ | ||
if ($name === null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't have a guideline on this, but I prefer yoda style comparisons |
||
return sasql_insert_id($this->conn); | ||
} | ||
|
||
return $this->query('SELECT ' . $name . '.CURRVAL')->fetchColumn(); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function prepare($prepareString) | ||
{ | ||
return new SQLAnywhereStatement($this->conn, $prepareString); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function query() | ||
{ | ||
$args = func_get_args(); | ||
$stmt = $this->prepare($args[0]); | ||
$stmt->execute(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. newline before this line |
||
|
||
return $stmt; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function quote($input, $type = \PDO::PARAM_STR) | ||
{ | ||
if (is_int($input) || is_float($input)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought doubles and floats are the same in PHP? Am I missing something? Besides that this if checks could be left out I think as it quotes all kind of strings with the driver function. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yep, my mistake - Marco Pivetta On 12 November 2013 00:39, Steve Müller [email protected] wrote:
|
||
return $input; | ||
} | ||
|
||
return "'" . sasql_escape_string($this->conn, $input) . "'"; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
* | ||
* @throws SQLAnywhereException | ||
*/ | ||
public function rollBack() | ||
{ | ||
if ( ! sasql_rollback($this->conn)) { | ||
throw SQLAnywhereException::fromSQLAnywhereError($this->conn); | ||
} | ||
|
||
$this->endTransaction(); | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* Ends transactional mode and enables auto commit again. | ||
* | ||
* @throws SQLAnywhereException | ||
* | ||
* @return boolean Whether or not ending transactional mode succeeded. | ||
*/ | ||
private function endTransaction() | ||
{ | ||
if ( ! sasql_set_option($this->conn, 'auto_commit', 'on')) { | ||
throw SQLAnywhereException::fromSQLAnywhereError($this->conn); | ||
} | ||
|
||
return true; | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. EOF EOL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cast to
(int)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that necessary? It will be concatenated to the DSN-String anyways...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering about what happens if someone passes in
foo