Skip to content

Commit

Permalink
Merge pull request #31 from koriym/named
Browse files Browse the repository at this point in the history
NamedPdoModule supports replication
  • Loading branch information
koriym authored Mar 7, 2017
2 parents 5548eaa + 2eb69b1 commit 9480407
Show file tree
Hide file tree
Showing 17 changed files with 164 additions and 77 deletions.
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ before_script:
- if [ -z "$dependencies" ]; then composer install; fi;
- if [ "$dependencies" = "lowest" ]; then composer update --prefer-lowest; fi;
script:
- if [ "$TRAVIS_PHP_VERSION" != "7.1" ]; then phpunit; fi
- if [ "$TRAVIS_PHP_VERSION" == "7.1" ]; then phpunit --coverage-text --coverage-clover=coverage.clover; fi
- if [ "$TRAVIS_PHP_VERSION" == "hhvm" ]; then phpunit; fi
- if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then phpunit --coverage-text --coverage-clover=coverage.clover; fi
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- if [ "$TRAVIS_PHP_VERSION" == "7.1" ]; then php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi
- if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi
12 changes: 12 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,17 @@
"tests/Fake/"
]
}
},
"scripts": {
"test": [
"phpmd src text ./phpmd.xml",
"phpcs src tests",
"phpunit"
],
"cs-fix": [
"php-cs-fixer fix --config-file=./.php_cs",
"phpcbf src"
],
"clean": "rm -rf var/tmp/* var/log/* tests/tmp/*"
}
}
5 changes: 1 addition & 4 deletions src/AuraSqlConnectionInterceptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,7 @@ private function getConnection(MethodInvocation $invocation)
if (in_array($methodName, $this->readsMethods)) {
return $this->connectionLocator->getRead();
}
if (in_array($methodName, $this->writeMethods)) {
return $this->connectionLocator->getWrite();
}

return $this->connectionLocator->getDefault();
return $this->connectionLocator->getWrite();
}
}
8 changes: 1 addition & 7 deletions src/AuraSqlModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,9 @@ private function configureMasterSlaveDsn()
private function changeHost($dsn, $host)
{
preg_match(self::PARSE_PDO_DSN_REGEX, $dsn, $parts);
if (empty($parts)) {
if (! $parts) {
return $dsn;
}
// [
// 0 => 'mysql:host=localhost;port=3307;dbname=testdb',
// 1 => 'mysql',
// 2 => 'host',
// 3 => 'port=3307;dbname=testdb'
// ]
$dsn = sprintf('%s:%s=%s;%s', $parts[1], $parts[2], $host, $parts[3]);

return $dsn;
Expand Down
53 changes: 0 additions & 53 deletions src/AuraSqlProvider.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/AuraSqlReplicationDbProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class AuraSqlReplicationDbProvider implements ProviderInterface, SetContextInter
private $connectionLocator;

/**
* @param ConnectionLocatorInterface $connectionLocator
* @param InjectorInterface $injector
*/
public function __construct(InjectorInterface $injector)
{
Expand Down
52 changes: 46 additions & 6 deletions src/NamedPdoModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

namespace Ray\AuraSqlModule;

use Aura\Sql\ConnectionLocator;
use Aura\Sql\ExtendedPdo;
use Aura\Sql\ExtendedPdoInterface;
use Ray\Di\AbstractModule;

class NamedPdoModule extends AbstractModule
{
const PARSE_PDO_DSN_REGEX = '/(.*?)\:(host|server)=.*?;(.*)/i';

/**
* @var string
*/
Expand All @@ -26,20 +29,25 @@ class NamedPdoModule extends AbstractModule
/**
* @var string
*/
private $pass;
private $password;

/**
* @var string
*/
private $slave;
/**
* @param string $qualifer
* @param string $dsn
* @param string $user
* @param string $pass
*/
public function __construct($qualifer, $dsn, $user = '', $pass = '')
public function __construct($qualifer, $dsn, $user = '', $pass = '', $slave = '')
{
$this->qualifer = $qualifer;
$this->dsn = $dsn;
$this->user = $user;
$this->pass = $pass;
$this->password = $pass;
$this->slave = $slave;
parent::__construct();
}

Expand All @@ -48,10 +56,11 @@ public function __construct($qualifer, $dsn, $user = '', $pass = '')
*/
protected function configure()
{
$this->bindNamedPdo($this->qualifer, $this->dsn, $this->user, $this->pass);
$this->slave ? $this->configureMasterSlaveDsn($this->qualifer, $this->dsn, $this->user, $this->password, $this->slave)
: $this->configureSingleDsn($this->qualifer, $this->dsn, $this->user, $this->password);
}

private function bindNamedPdo($qualifer, $dsn, $user, $pass)
private function configureSingleDsn($qualifer, $dsn, $user, $password)
{
$this->bind(ExtendedPdoInterface::class)
->annotatedWith($qualifer)
Expand All @@ -61,6 +70,37 @@ private function bindNamedPdo($qualifer, $dsn, $user, $pass)
);
$this->bind()->annotatedWith("{$qualifer}_dsn")->toInstance($dsn);
$this->bind()->annotatedWith("{$qualifer}_username")->toInstance($user);
$this->bind()->annotatedWith("{$qualifer}_password")->toInstance($pass);
$this->bind()->annotatedWith("{$qualifer}_password")->toInstance($password);
}

private function configureMasterSlaveDsn($qualifer, $dsn, $user, $password, $slaveList)
{
$locator = new ConnectionLocator();
$locator->setWrite('master', new Connection($dsn, $user, $password));
$i = 1;
$slaves = explode(',', $slaveList);
foreach ($slaves as $slave) {
$slaveDsn = $this->changeHost($dsn, $slave);
$name = 'slave' . (string) $i++;
$locator->setRead($name, new Connection($slaveDsn, $user, $password));
}
$this->install(new AuraSqlReplicationModule($locator, $qualifer));
}

/**
* @param string $dsn
* @param string $host
*
* @return string
*/
private function changeHost($dsn, $host)
{
preg_match(self::PARSE_PDO_DSN_REGEX, $dsn, $parts);
if (! $parts) {
return $dsn;
}
$dsn = sprintf('%s:%s=%s;%s', $parts[1], $parts[2], $host, $parts[3]);

return $dsn;
}
}
4 changes: 1 addition & 3 deletions src/Pagerfanta/AuraSqlQueryPager.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,10 @@ public function offsetGet($page)
}

$countQueryBuilderModifier = function (SelectInterface $select) {
if (!$select instanceof Select) {
throw new NotInitialized();
}
foreach (array_keys($select->getCols()) as $key) {
$select->removeCol($key);
}

return $select->cols(['COUNT(*) AS total_results'])->limit(1);
};
$pagerfanta = new Pagerfanta(new AuraSqlQueryAdapter($this->pdo, $this->select, $countQueryBuilderModifier));
Expand Down
1 change: 1 addition & 0 deletions src/TransactionalInterceptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public function invoke(MethodInvocation $invocation)
* @param string $prop the name of pdo property
*
* @return \Pdo
*
* @throws InvalidTransactionalPropertyException
*/
private function beginTransaction($object, $prop)
Expand Down
7 changes: 7 additions & 0 deletions tests/AuraSqlModuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,11 @@ public function testSlaveModule()
$dsn = $read->getDsn();
$this->assertContains($dsn, ['mysql:host=slave1;dbname=testdb', 'mysql:host=slave2;dbname=testdb']);
}

public function testNoHost()
{
$instance = (new Injector(new FakeQualifierModule, $_ENV['TMP_DIR']))->getInstance(ExtendedPdoInterface::class);
/* @var $instance ExtendedPdo */
$this->assertSame('sqlite::memory:', $instance->getDsn());
}
}
4 changes: 4 additions & 0 deletions tests/AuraSqlReplicationModuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public function connectionProvider()
*/
public function testLocatorSlave(ConnectionLocator $locator, ExtendedPdo $masterPdo, ExtendedPdo $slavePdo)
{
unset($masterPdo);
$_SERVER['REQUEST_METHOD'] = 'GET';
/* @var $model FakeRepModel */
$model = (new Injector(new AuraSqlReplicationModule($locator), $_ENV['TMP_DIR']))->getInstance(FakeRepModel::class);
Expand All @@ -54,6 +55,7 @@ public function testLocatorSlave(ConnectionLocator $locator, ExtendedPdo $master
*/
public function testLocatorMaster(ConnectionLocator $locator, ExtendedPdo $masterPdo, ExtendedPdo $slavePdo)
{
unset($slavePdo);
$_SERVER['REQUEST_METHOD'] = 'POST';
/* @var $model FakeRepModel */
$model = (new Injector(new AuraSqlReplicationModule($locator), $_ENV['TMP_DIR']))->getInstance(FakeRepModel::class);
Expand All @@ -66,6 +68,8 @@ public function testLocatorMaster(ConnectionLocator $locator, ExtendedPdo $maste
*/
public function testLocatorMasterWithQualifer(ConnectionLocator $locator, ExtendedPdo $masterPdo, ExtendedPdo $slavePdo)
{
unset($masterPdo);
unset($slavePdo);
$_SERVER['REQUEST_METHOD'] = 'POST';
/* @var $db1Master ExtendedPdo */
/* @var $db2Master ExtendedPdo */
Expand Down
16 changes: 16 additions & 0 deletions tests/Fake/FakeNamedQualifierModule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Ray\AuraSqlModule;

use Ray\Di\AbstractModule;

class FakeNamedQualifierModule extends AbstractModule
{
/**
* {@inheritdoc}
*/
protected function configure()
{
$this->install(new NamedPdoModule('log_db', 'sqlite::memory:', '', '', 'slave1'));
}
}
18 changes: 18 additions & 0 deletions tests/Fake/FakeNamedReplicationModule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Ray\AuraSqlModule;

use Ray\Di\AbstractModule;

class FakeNamedReplicationModule extends AbstractModule
{
/**
* {@inheritdoc}
*/
protected function configure()
{
$user = $password = '';
$slave = 'slave1,slave2,slave2';
$this->install(new NamedPdoModule('log_db', 'mysql:host=localhost;dbname=db', $user, $password, $slave));
}
}
16 changes: 16 additions & 0 deletions tests/Fake/FakeQualifierModule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Ray\AuraSqlModule;

use Ray\Di\AbstractModule;

class FakeQualifierModule extends AbstractModule
{
/**
* {@inheritdoc}
*/
protected function configure()
{
$this->install(new AuraSqlModule('sqlite::memory:', '', '', 'slave1'));
}
}
28 changes: 28 additions & 0 deletions tests/NamedPdoModuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,32 @@ public function testFakeName()
$this->assertInstanceOf(ExtendedPdo::class, $fakeName->pdoAnno);
$this->assertInstanceOf(ExtendedPdo::class, $fakeName->pdoSetterInject);
}

public function testReplicationMaster()
{
$_SERVER['REQUEST_METHOD'] = 'POST';
$qualifer = 'log_db';
$instance = (new Injector(new FakeNamedReplicationModule, $_ENV['TMP_DIR']))->getInstance(ExtendedPdoInterface::class, $qualifer);
$this->assertInstanceOf(ExtendedPdo::class, $instance);
/* @var $instance ExtendedPdo */
$this->assertSame('mysql:host=localhost;dbname=db', $instance->getDsn());
}

public function testReplicationSlave()
{
$_SERVER['REQUEST_METHOD'] = 'GET';
$qualifer = 'log_db';
$instance = (new Injector(new FakeNamedReplicationModule, $_ENV['TMP_DIR']))->getInstance(ExtendedPdoInterface::class, $qualifer);
$this->assertInstanceOf(ExtendedPdo::class, $instance);
/* @var $instance ExtendedPdo */
$this->assertContains('mysql:host=slave', $instance->getDsn());
}

public function testNoHost()
{
$qualifer = 'log_db';
$instance = (new Injector(new FakeNamedQualifierModule, $_ENV['TMP_DIR']))->getInstance(ExtendedPdoInterface::class, $qualifer);
/* @var $instance ExtendedPdo */
$this->assertSame('sqlite::memory:', $instance->getDsn());
}
}
1 change: 1 addition & 0 deletions tests/Pagerfanta/AuraSqlQueryAdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ private function createAdapterToTestGetNbResults()
foreach (array_keys($select->getCols()) as $key) {
$select->removeCol($key);
}

return $select->cols(['COUNT(*) AS total_results'])->limit(1);
};

Expand Down
8 changes: 8 additions & 0 deletions tests/Pagerfanta/AuraSqlQueryPagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,12 @@ public function testOffsetGet()
$expected = [['username' => 'Jon Doe']];
$this->assertSame($expected, $post->data);
}

public function estOffsetGetWithoutInit()
{
$this->select = $this->qf->newSelect();
$this->select->cols(['p.username'])->from('posts as p');
$pager = new AuraSqlQueryPager(new DefaultView, []);
$post = $pager[2];
}
}

0 comments on commit 9480407

Please sign in to comment.