Skip to content

Commit

Permalink
Merge branch 'bartoszherba-feature/sql' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
chevli committed Jan 22, 2018
2 parents ab26680 + 1057be0 commit 2d8e2df
Show file tree
Hide file tree
Showing 10 changed files with 323 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ before_script:
script:
- sh -c "if [ '$TEST_SUITE' = 'phpcs' ]; then php vendor/bin/phpcs --standard=PSR2 Model/ Console/ Test/ Component/ Api/ Exception/; fi"
- sh -c "if [ '$TEST_SUITE' = 'phpcs' ]; then php vendor/bin/phpmd Model/,Console/,Test/,Component/,Api/,Exception/ text cleancode,codesize,controversial,design,naming,unusedcode; fi"
- sh -c "if [ '$TEST_SUITE' = 'phpcs' ]; then php vendor/bin/phpcpd Model/ Console/ Test/ Component/ Api/ Exception/; fi"
- sh -c "if [ '$TEST_SUITE' = 'phpcs' ]; then php vendor/bin/phpcpd Model/ Console/ Component/ Api/ Exception/; fi"
- sh -c "if [ '$TEST_SUITE' = 'unit' ]; then php vendor/bin/phpunit --coverage-clover build/logs/clover.xml Test/Unit/; fi"
- sh -c "if [ '$TEST_SUITE' = 'configurator' ]; then ./Test/Integration/run-configurator.sh; fi"
notifications:
Expand Down
95 changes: 95 additions & 0 deletions Component/Processor/SqlSplitProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php
/**
* @package CtiDigital\Configurator
* @author Bartosz Herba <[email protected]>
* @copyright 2017 CtiDigital
*/

namespace CtiDigital\Configurator\Component\Processor;

use CtiDigital\Configurator\Api\LoggerInterface;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Adapter\AdapterInterface;

/**
* Class SqlSplitProcessor
*/
class SqlSplitProcessor
{
/**
* @var LoggerInterface
*/
private $log;

/**
* @var ResourceConnection
*/
private $resource;

/**
* @var AdapterInterface
*/
private $connection;
/**
* @param LoggerInterface $log
* @param ResourceConnection $resource
*/
public function __construct(
LoggerInterface $log,
ResourceConnection $resource
) {
$this->log = $log;
$this->resource = $resource;
$this->connection = $resource->getConnection();
}

/**
* @param string $name
* @param string $fileContent
*
* return void
*/
public function process($name, $fileContent)
{
$this->log->logInfo("- Processing file '$name'");

$queries = $this->extractQueriesFromFile($fileContent);

$totalSqlCnt = count($queries);
$cnt = 1;

if ($totalSqlCnt === 0) {
$this->log->logInfo('No queries has been found in file.');

return;
}

$this->connection->beginTransaction();

try {
foreach ($queries as $query) {
$this->log->logComment($query, 1);
$this->connection->query($query);
$this->log->logInfo("[{$cnt}/$totalSqlCnt] queries executed.", 1);
$cnt++;
}

$this->connection->commit();
} catch (\Exception $ex) {
$this->log->logError($ex->getMessage());
$this->connection->rollBack();
}
}

/**
* Split file content string into separate queries
*
* @param string $fileContent
*
* @return array
*/
private function extractQueriesFromFile($fileContent)
{
return preg_split("/\\r\\n|\\r|\\n/", $fileContent, -1, PREG_SPLIT_NO_EMPTY);
}
}
82 changes: 82 additions & 0 deletions Component/Sql.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php
/**
* @package CtiDigital\Configurator
* @author Bartosz Herba <[email protected]>
* @copyright 2017 CtiDigital
*/

namespace CtiDigital\Configurator\Component;

use CtiDigital\Configurator\Api\LoggerInterface;
use CtiDigital\Configurator\Component\Processor\SqlSplitProcessor;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\ObjectManagerInterface;

/**
* Class Sql
*/
class Sql extends YamlComponentAbstract
{
/**
* @var string
*/
protected $alias = 'sql';

/**
* @var string
*/
protected $name = 'Custom Sql';

/**
* @var string
*/
protected $description = 'Component for an execution of custom queries';

/**
* @var SqlSplitProcessor
*/
private $processor;

/**
* {@inheritdoc}
*
* @param LoggerInterface $log
* @param ResourceConnection $resource
* @param ObjectManagerInterface $objectManager
*/
public function __construct(
LoggerInterface $log,
ObjectManagerInterface $objectManager,
SqlSplitProcessor $processor
) {
parent::__construct($log, $objectManager);

$this->processor = $processor;
}

/**
* This method should be used to process the data and populate the Magento Database.
*
* @param mixed $data
*
* @return void
*/
protected function processData($data = null)
{
if (!isset($data['sql'])) {
return;
}

$this->log->logInfo('Beginning of custom queries configuration:');
foreach ($data['sql'] as $name => $sqlFile) {
$path = BP . '/' . $sqlFile;
if (false === file_exists($path)) {
$this->log->logError("{$path} does not exist. Skipping.");
continue;
}
$fileContent = file_get_contents($path);
$this->processor->process($name, $fileContent);
}
}
}
2 changes: 1 addition & 1 deletion Console/Command/ListCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$count = 1;
foreach ($this->configInterface->getAllComponents() as $component) {

/* @var \CtiDigital\Configurator\Model\Component\ComponentAbstract $componentClass */
/* @var \CtiDigital\Configurator\Component\ComponentAbstract $componentClass */
$componentClass = $this->objectManagerInterface->create($component['class']);
$comment =
str_pad($count.') ', 4)
Expand Down
2 changes: 2 additions & 0 deletions Samples/Components/Sql/sitemap.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DELETE FROM `sitemap`;
INSERT INTO `sitemap` (`sitemap_id`, `sitemap_type`, `sitemap_filename`, `sitemap_path`, `sitemap_time`, `store_id`) VALUES (1, NULL, 'sitemap.xml', '/', '2015-08-21 15:13:24', 1);
2 changes: 2 additions & 0 deletions Samples/Components/Sql/sql.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
sql:
sitemap: ../configurator/Sql/sitemap.sql
7 changes: 6 additions & 1 deletion Samples/master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,9 @@ customers:
enabled: 1
method: code
sources:
- ../configurator/Customers/customers.csv
- ../configurator/Customers/customers.csv
sql:
enabled: 1
method: code
sources:
- ../configurator/Sql/sql.yaml
25 changes: 25 additions & 0 deletions Test/Unit/Component/SqlTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace CtiDigital\Configurator\Test\Unit\Component;

use CtiDigital\Configurator\Component\Processor\SqlSplitProcessor;
use CtiDigital\Configurator\Component\Sql;

class SqlTest extends ComponentAbstractTestCase
{
protected function componentSetUp()
{
/** @var SqlSplitProcessor|\PHPUnit_Framework_MockObject_MockObject $mockSqlSplitProc */
$mockSqlSplitProc = $this->getMockBuilder(SqlSplitProcessor::class)
->disableOriginalConstructor()
->getMock();

$this->component = new Sql(
$this->logInterface,
$this->objectManager,
$mockSqlSplitProc
);

$this->className = Sql::class;
}
}
107 changes: 107 additions & 0 deletions Test/Unit/Processor/SqlSplitProcessorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php
/**
* @package CtiDigital\Configurator
* @author Bartosz Herba <[email protected]>
* @copyright 2017 CtiDigital
*/

namespace CtiDigital\Configurator\Test\Unit\Processor;

use CtiDigital\Configurator\Api\LoggerInterface;
use CtiDigital\Configurator\Component\Processor\SqlSplitProcessor;
use CtiDigital\Configurator\Model\Logging;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\DB\Adapter\Pdo\Mysql;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;

/**
* Class SqlSplitProcessorTest
* @codingStandardsIgnoreStart
*/
class SqlSplitProcessorTest extends \PHPUnit_Framework_TestCase
{
/**
* @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $mockLogger;

/**
* @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject
*/
protected $mockResource;

/**
* @var AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $mockConnection;

/**
* @var SqlSplitProcessor
*/
protected $processor;

/**
* @var ObjectManager
*/
private $objectManager;

public function setUp()
{
$this->objectManager = new ObjectManager($this);
$this->mockLogger = $this->getMockBuilder(Logging::class)
->disableOriginalConstructor()
->setMethods(['logInfo', 'logError'])
->getMock();
$this->mockResource = $this->getMockBuilder(ResourceConnection::class)
->disableOriginalConstructor()
->setMethods(['getConnection'])
->getMock();

$this->mockConnection = $this->getMockBuilder(Mysql::class)
->disableOriginalConstructor()
->setMethods(['beginTransaction', 'query', 'rollBack', 'commit'])
->getMock();

$this->mockResource->expects($this->once())
->method('getConnection')
->willReturn($this->mockConnection);

$this->processor = $this->objectManager->getObject(SqlSplitProcessor::class, [
'log' => $this->mockLogger,
'resource' => $this->mockResource,
]);
}

public function sqlDataProvider()
{
return [
['sitemap', "SELECT * FROM sitemap;\nANOTHER QUERY;", 2],
['another', 'DELETE from store;', 1],
['empty', '', 0],
];
}

public function testExceptionHandling()
{
$name = 'name1';
$fileContent = 'SELECT * FROM unknown';
$exMsg = 'exception message';

$this->mockConnection
->expects($this->any())
->method('query')
->willThrowException(new \Exception($exMsg));

$this->mockLogger
->expects($this->at(1))
->method('logError')
->with($exMsg);

$this->mockConnection
->expects($this->once())
->method('rollBack');

$this->processor->process($name, $fileContent);
}
}
3 changes: 2 additions & 1 deletion etc/configurator.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@
<component name="review_rating" class="CtiDigital\Configurator\Component\ReviewRating" />
<component name="product_links" class="CtiDigital\Configurator\Component\ProductLinks" />
<component name="customers" class="CtiDigital\Configurator\Component\Customers" />
</config>
<component name="sql" class="CtiDigital\Configurator\Component\Sql" />
</config>

0 comments on commit 2d8e2df

Please sign in to comment.