Skip to content

Commit

Permalink
[#14733] - Connection and connection locator; Fixes for the abstract …
Browse files Browse the repository at this point in the history
…class
  • Loading branch information
niden committed Feb 8, 2020
1 parent d5a385f commit 4bde759
Show file tree
Hide file tree
Showing 7 changed files with 564 additions and 22 deletions.
163 changes: 163 additions & 0 deletions phalcon/DM/Pdo/Connection.zep
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/**
* This file is part of the Phalcon Framework.
*
* (c) Phalcon Team <[email protected]>
*
* For the full copyright and license information, please view the LICENSE.txt
* file that was distributed with this source code.
*
* Implementation of this file has been influenced by AtlasPHP
*
* @link https://github.com/atlasphp/Atlas.Pdo
* @license https://github.com/atlasphp/Atlas.Pdo/blob/1.x/LICENSE.md
*/

namespace Phalcon\DM\Pdo;

use InvalidArgumentException;
use Phalcon\DM\Pdo\Connection\AbstractConnection;
use Phalcon\DM\Pdo\Parser\ParserInterface;
use Phalcon\DM\Pdo\Profiler\Profiler;
use Phalcon\DM\Pdo\Profiler\ProfilerInterface;

/**
* Provides array quoting, profiling, a new `perform()` method, new `fetch*()`
* methods
*
* @property array $args
* @property ParserInterface $parser
* @property PDO $pdo
* @property ProfilerInterface $profiler
*/
class Connection extends AbstractConnection
{
/**
* @var array
*/
protected arguments = [];

/**
* Constructor.
*
* This overrides the parent so that it can take connection attributes as a
* constructor parameter, and set them after connection.
*
* @param string $dsn
* @param string $username
* @param string $password
* @param array $options
* @param array $queries
* @param ProfilerInterface $profiler
*/
public function __construct(
string dsn,
string username = null,
string password = null,
array options = [],
array queries = [],
<ProfilerInterface> profiler = null
) {
var parser, parts;
array available;

let parts = explode(":", dsn),
available = [
"mysql" : true,
"pgsql" : true,
"sqlite" : true,
"mssql" : true
];

if !isset available[parts[0]] {
throw new InvalidArgumentException(
"Driver not supported [" . parts[0] . "]"
);
}


// if no error mode is specified, use exceptions
if !isset options[\PDO::ATTR_ERRMODE] {
let options[\PDO::ATTR_ERRMODE] = \PDO::ERRMODE_EXCEPTION;
}

// Arguments store
let this->args = [
dsn,
username,
password,
options,
queries
];

// Create a new profiler if none has been passed
if profiler === null {
let profiler = new Profiler();
}
this->setProfiler(profiler);

// Set the new Query parser
let parser = this->newParser(parts[0]);
this->setParser(parser);

// Quotes
let this->quote = this->getQuoteNames(parts[0]);
}

/**
* The purpose of this method is to hide sensitive data from stack traces.
*
* @return array
*/
public function __debugInfo() -> array
{
return [
"arguments" : [
this->arguments[0],
"****",
"****",
this->arguments[3],
this->arguments[4]
]
];
}

/**
* Connects to the database.
*/
public function connect() -> void
{
var dsn, options, password, query, queries, username;

if !this->pdo {
// connect
this->profiler->start(__FUNCTION__);

let dsn = this->arguments[0],
username = this->arguments[1],
password = this->arguments[2],
options = this->arguments[3],
queries = this->arguments[4];

let this->pdo = new \PDO(dsn, username, password, options);

this->profiler->finish();

// connection-time queries
for query in queries {
this->exec(query);
}
}
}

/**
* Disconnects from the database.
*/
public function disconnect() -> void
{
this->profiler->start(__FUNCTION__);

let this->pdo = null;

this->profiler->finish();
}
}
31 changes: 19 additions & 12 deletions phalcon/DM/Pdo/Connection/AbstractConnection.zep
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
namespace Phalcon\DM\Pdo\Connection;

use BadMethodCallException;
use PDO;
use PDOStatement;
use Phalcon\DM\Pdo\Exception\CannotBindValue;
use Phalcon\DM\Pdo\Parser\ParserInterface;
Expand Down Expand Up @@ -237,8 +236,10 @@ abstract class AbstractConnection implements ConnectionInterface
let data = [],
sth = this->perform(statement, values);

while (row = sth->$fetch(\PDO::FETCH_ASSOC)) {
let row = sth->$fetch(\PDO::FETCH_ASSOC);
while (row) {
let data[current(row)] = row;
let row = sth->$fetch(\PDO::FETCH_ASSOC);
}

return data;
Expand Down Expand Up @@ -415,7 +416,7 @@ abstract class AbstractConnection implements ConnectionInterface
*
* @return PDO
*/
public function getAdapter() -> <PDO>
public function getAdapter() -> <\PDO>
{
this->connect();

Expand Down Expand Up @@ -488,6 +489,7 @@ abstract class AbstractConnection implements ConnectionInterface
public function getQuoteNames(string driver = "") -> array
{
var option;
array quotes;

let option = driver;
if empty option {
Expand All @@ -496,29 +498,34 @@ abstract class AbstractConnection implements ConnectionInterface

switch option {
case "mysql":
return [
let quotes = [
"prefix" : "`",
"suffix" : "`",
"find" : "`",
"replace" : "``",
"replace" : "``"
];
break;

case "sqlsrv":
return [
let quotes = [
"prefix" : "[",
"suffix" : "]",
"find" : "]",
"replace" : "][",
"replace" : "]["
];
break;

default:
return [
let quotes = [
"prefix" : "\"",
"suffix" : "\"",
"find" : "\"",
"replace" : "\"\"",
"replace" : "\"\""
];
break;
}

return quotes;
}

/**
Expand Down Expand Up @@ -587,7 +594,7 @@ abstract class AbstractConnection implements ConnectionInterface
* @return PDOStatement
* @throws CannotBindValue
*/
public function perform(string statement, array values = []) -> <PDOStatement>
public function perform(string statement, array values = []) -> <\PDOStatement>
{
var sth;

Expand Down Expand Up @@ -630,7 +637,7 @@ abstract class AbstractConnection implements ConnectionInterface
* @return PDOStatement|false
* @throws CannotBindValue
*/
public function prepareWithValues(string statement, array values = []) -> <PDOStatement>
public function prepareWithValues(string statement, array values = []) -> <\PDOStatement>
{
var key, parser, parts, statement, value, values;
array valueNames = [];
Expand Down Expand Up @@ -844,7 +851,7 @@ abstract class AbstractConnection implements ConnectionInterface
* @return bool
* @throws CannotBindValue
*/
protected function bindValue(<PDOStatement> statement, var key, var value) -> bool
protected function bindValue(<\PDOStatement> statement, var key, var value) -> bool
{
var type;

Expand Down
6 changes: 2 additions & 4 deletions phalcon/DM/Pdo/Connection/ConnectionInterface.zep
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@

namespace Phalcon\DM\Pdo\Connection;

use PDO;
use PDOStatement;
use Phalcon\DM\Pdo\Exception\CannotBindValue;
use Phalcon\DM\Pdo\Parser\ParserInterface;
use Phalcon\DM\Pdo\Profiler\ProfilerInterface;
Expand Down Expand Up @@ -187,7 +185,7 @@ interface ConnectionInterface extends PdoInterface
*
* @return PDO
*/
public function getAdapter() -> <PDO>;
public function getAdapter() -> <\PDO>;

/**
* Returns the Parser instance.
Expand Down Expand Up @@ -222,7 +220,7 @@ interface ConnectionInterface extends PdoInterface
* @return PDOStatement
* @throws CannotBindValue
*/
public function perform(string statement, array values = []) -> <PDOStatement>;
public function perform(string statement, array values = []) -> <\PDOStatement>;

/**
* Sets the Parser instance.
Expand Down
75 changes: 75 additions & 0 deletions phalcon/DM/Pdo/Connection/Decorated.zep
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@

/**
* This file is part of the Phalcon Framework.
*
* (c) Phalcon Team <[email protected]>
*
* For the full copyright and license information, please view the LICENSE.txt
* file that was distributed with this source code.
*
* Implementation of this file has been influenced by AtlasPHP
*
* @link https://github.com/atlasphp/Atlas.Pdo
* @license https://github.com/atlasphp/Atlas.Pdo/blob/1.x/LICENSE.md
*/

namespace Phalcon\DM\Pdo\Connection;

use Phalcon\DM\Pdo\Exception\CannotDisconnect;
use Phalcon\DM\Pdo\Profiler\Profiler;
use Phalcon\DM\Pdo\Profiler\ProfilerInterface;

/**
* Decorates an existing PDO instance with the extended methods.
*/
class Decorated extends AbstractConnection
{
/**
*
* Constructor.
*
* This overrides the parent so that it can take an existing PDO instance
* and decorate it with the extended methods.
*
* @param PDO $pdo
* @param ProfilerInterface|null $profiler
*
*/
public function __construct(<\PDO> pdo, <ProfilerInterface> profiler = null)
{
var driver;

let this->pdo = pdo;

if null === profiler {
let profiler = new Profiler();
}
this->setProfiler(profiler);

let driver = pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);

this->setParser(this->newParser(driver));

let this->quote = this->getQuoteNames(driver);
}

/**
* Connects to the database.
*/
public function connect() -> void
{
// already connected
}

/**
* Disconnects from the database; disallowed with decorated PDO connections.
*
* @throws CannotDisconnect
*/
public function disconnect() -> void
{
throw new CannotDisconnect(
"Cannot disconnect a Decorated connection instance"
);
}
}
Loading

0 comments on commit 4bde759

Please sign in to comment.