Skip to content
This repository has been archived by the owner on Dec 3, 2024. It is now read-only.

Commit

Permalink
Improving code (freitasmurillo#5)
Browse files Browse the repository at this point in the history
freitasmurillo authored Mar 7, 2018
1 parent 0917864 commit fcf55c7
Showing 4 changed files with 107 additions and 78 deletions.
42 changes: 30 additions & 12 deletions src/Commands/MigrateCommand.php
Original file line number Diff line number Diff line change
@@ -29,37 +29,37 @@ class MigrateCommand extends Command
protected function configure()
{
$this->setName('migrate')
->setDescription('Creates and versions dynamoDB tables.')
;
->setDescription('Creates and versions dynamoDB tables.');
}

/**
* @param InputInterface $input
* @param OutputInterface $output
* @return int|null|void
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
try {
$classes = $this->getClasses($this->directory);
$this->runMigration($classes);

} catch(\Exception $e) {
echo "Migration Error: {$e->getMessage()}".PHP_EOL;
exit();
} catch (\Exception $e) {
echo "Migration Error: {$e->getMessage()}" . PHP_EOL;
}
}

/**
* Handle the "migrate" command.
*
* @param $classes
* @throws \Exception
*/
private function runMigration($classes)
{
$this->dynamoDBClient = DynamoDbClient::factory($this->getConfig());
$this->dynamoDBClient = new DynamoDbClient($this->getConfig());

if (!$this->isMigrationsTableExist())
if (!$this->isMigrationsTableExist()) {
$this->createMigrationTable();
}

$ranMigrations = $this->getRanMigrations();
$pendingMigrations = $this->getPendingMigrations($classes, $ranMigrations);
@@ -76,19 +76,28 @@ private function runMigration($classes)
}
}

/**
* @param $classes
* @param $ranMigrations
* @return mixed
*/
private function getPendingMigrations($classes, $ranMigrations)
{
foreach ($ranMigrations as $ranMigration) {
$key = array_search($ranMigration, $classes);
if ($key !== FALSE)
if ($key !== false) {
unset($classes[$key]);
}
}
return $classes;
}

/**
* @return array
*/
private function getRanMigrations()
{
$result = $this->dynamoDBClient->scan([
$result = $this->dynamoDBClient->scan([
'TableName' => 'migrations'
]);

@@ -101,12 +110,18 @@ private function getRanMigrations()
return $ranMigrations;
}

/**
* @return bool
*/
private function isMigrationsTableExist()
{
$tables = $this->dynamoDBClient->listTables();
return in_array('migrations', $tables['TableNames']);
}

/**
*
*/
private function createMigrationTable()
{
$this->dynamoDBClient->createTable([
@@ -120,16 +135,19 @@ private function createMigrationTable()
'KeySchema' => [
[
'AttributeName' => 'migration',
'KeyType' => 'HASH'
'KeyType' => 'HASH'
]
],
'ProvisionedThroughput' => [
'ReadCapacityUnits' => 100,
'ReadCapacityUnits' => 100,
'WriteCapacityUnits' => 100
]
]);
}

/**
* @param $migration
*/
private function addToRanMigrations($migration)
{
$this->dynamoDBClient->putItem([
23 changes: 7 additions & 16 deletions src/Commands/SeedCommand.php
Original file line number Diff line number Diff line change
@@ -6,8 +6,6 @@
use Aws\DynamoDb\Marshaler;
use Aws\DynamoDb\DynamoDbClient;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class SeedCommand extends Command
{
@@ -25,23 +23,16 @@ protected function configure()
{
$this
->setName('seed')
->setDescription('Seeds dynamoDb tables with sample data.')
;
->setDescription('Seeds dynamoDb tables with sample data.');
}

/**
* @param InputInterface $input
* @param OutputInterface $output
*/
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute()
{
try {
$classes = $this->getClasses($this->directory);
$this->runSeeder($classes);

} catch(\Exception $e) {
echo "Seed Error: {$e->getMessage()}".PHP_EOL;
exit();
} catch (\Exception $e) {
echo "Seed Error: {$e->getMessage()}" . PHP_EOL;
}
}

@@ -53,10 +44,10 @@ protected function execute(InputInterface $input, OutputInterface $output)
*/
private function runSeeder($classes)
{
$dynamoDbClient = DynamoDbClient::factory($this->getConfig());
$dynamoDbClient = new DynamoDbClient($this->getConfig());
$transformer = new Marshaler();
foreach($classes as $class) {

foreach ($classes as $class) {
$migration = new $class($dynamoDbClient, $transformer);
$migration->seed();
}
60 changes: 39 additions & 21 deletions src/Migration.php
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
<?php
<?php

namespace Rumble;

abstract class Migration
{
/**
Dynamodb table params placeholder.
**/
* Dynamodb table params placeholder.
**/
private $tableParams = [];

/**
AWS DynamoDbClient.
**/
* AWS DynamoDbClient.
**/
private $dynamoDBClient;

/**
@@ -40,7 +41,8 @@ protected function table($name)
protected function addAttribute(string $name, string $dataType)
{
$this->setAttributeDefinitions();
array_push($this->tableParams['AttributeDefinitions'], ['AttributeName' => $name,'AttributeType' => $dataType]);
array_push($this->tableParams['AttributeDefinitions'],
['AttributeName' => $name, 'AttributeType' => $dataType]);
return $this;
}

@@ -62,7 +64,7 @@ protected function addHash(string $attributeName)
protected function addRange(string $attributeName)
{
$this->setKeySchema();
array_push($this->tableParams['KeySchema'], ['AttributeName' => $attributeName, 'KeyType' => 'HASH']);
array_push($this->tableParams['KeySchema'], ['AttributeName' => $attributeName, 'KeyType' => 'HASH']);
return $this;
}

@@ -88,13 +90,15 @@ protected function setRCU(int $unit)
return $this;
}

/**
* Set the AttributeDefinition to an empty array.
* This will make setting the attributes easier.
/**
* Set the AttributeDefinition to an empty array.
* This will make setting the attributes easier.
*/
private function setAttributeDefinitions()
{
if (!isset($this->tableParams['AttributeDefinitions'])) $this->tableParams['AttributeDefinitions'] = [];
if (!isset($this->tableParams['AttributeDefinitions'])) {
$this->tableParams['AttributeDefinitions'] = [];
}
}

/**
@@ -103,42 +107,51 @@ private function setAttributeDefinitions()
*/
private function setKeySchema()
{
if (!isset($this->tableParams['KeySchema'])) $this->tableParams['KeySchema'] = [];
if (!isset($this->tableParams['KeySchema'])) {
$this->tableParams['KeySchema'] = [];
}
}

/**
* Verify that the TableName param is set.
* This is a mandatory param, just like the hash key.
* @throws \Exception
*/
private function isTableNameSet()
{
if (!isset($this->tableParams['TableName']))
if (!isset($this->tableParams['TableName'])) {
throw new \Exception('Error: DynamoDB requires table name to be specified.');
}
}

/**
* Very that a valid primary key was added with a corresponding valid
* attribute name.
* @throws \Exception
*/
private function isHashSet()
{
$hashKeysFound = [];
foreach ($this->tableParams['KeySchema'] as $key) {
if ('HASH' == $key['KeyType'])
if ('HASH' == $key['KeyType']) {
$hashKeysFound[] = $key;
}
}

if (count($hashKeysFound) != 1)
if (count($hashKeysFound) != 1) {
throw new \Exception('Error: DynamoDB requires at least a simple primary key.');

}

$attributesFound = [];
foreach ($this->tableParams['AttributeDefinitions'] as $definition) {
if ($hashKeysFound[0]['AttributeName'] == $definition['AttributeName'])
if ($hashKeysFound[0]['AttributeName'] == $definition['AttributeName']) {
$attributesFound[] = $definition;
}
}

if (count($attributesFound) != 1)
throw new \Exception('Error: DynamoDB requires a matching attribute for a hash(primary) key.');
if (count($attributesFound) != 1) {
throw new \Exception('Error: DynamoDB requires a matching attribute for a hash(primary) key.');
}
}

/**
@@ -147,7 +160,9 @@ private function isHashSet()
*/
private function setProvisionedThroughput()
{
if(!isset($this->tableParams['ProvisionedThroughput'])) $this->tableParams['ProvisionedThroughput'] = [];
if (!isset($this->tableParams['ProvisionedThroughput'])) {
$this->tableParams['ProvisionedThroughput'] = [];
}
}

/**
@@ -156,7 +171,7 @@ private function setProvisionedThroughput()
private function displayCompletionMessage()
{
$className = get_class($this);
echo "{$className} Migrated successfully".PHP_EOL;
echo "{$className} Migrated successfully" . PHP_EOL;
return true;
}

@@ -172,6 +187,7 @@ private function tableExist($table)

/**
* Create a new DynamoDB Table.
* @throws \Exception
*/
protected function create()
{
@@ -187,6 +203,7 @@ protected function create()

/**
* Delete DynamoDB Table.
* @throws \Exception
*/
protected function delete()
{
@@ -198,6 +215,7 @@ protected function delete()

/**
* Update dynamoDB Table.
* @throws \Exception
*/
protected function update()
{
60 changes: 31 additions & 29 deletions src/Seeder.php
Original file line number Diff line number Diff line change
@@ -54,8 +54,8 @@ protected function addItem($data)
$attibutes = $this->marshaler->marshalItem($data);

$item = [];
foreach($attibutes as $attribute => $value) {
$item[$attribute] = $value;
foreach ($attibutes as $attribute => $value) {
$item[$attribute] = $value;
}
$this->items[] = $item;
return $this;
@@ -68,17 +68,20 @@ protected function addItem($data)
*/
private function isTableNameSet()
{
if (!$this->table)
if (!$this->table) {
throw new \Exception('Error: DynamoDB requires table name to be specified.');
}
}

/**
* Verify that at least one item is added.
* @throws \Exception
*/
private function atLeastOneItemExist()
{
if (count($this->items) == 0)
if (count($this->items) == 0) {
throw new \Exception('Error: No data to be seeded.');
}
}

/**
@@ -97,6 +100,7 @@ private function tableExist($table)

/**
* Check if there are multiple items.
* return bool
*/
private function isBatchRequest()
{
@@ -105,11 +109,13 @@ private function isBatchRequest()

/**
* Check to make sure batch items is not over limit (100).
* @throws \Exception
*/
private function validateBatchItemsLimit()
{
if(count($this->items) > 100)
if (count($this->items) > 100) {
throw new \Exception('Maximum items that can be bacthed add is 100, limit exceeded.');
}
}

/**
@@ -118,7 +124,7 @@ private function validateBatchItemsLimit()
private function displayCompletionMessage()
{
$className = get_class($this);
echo "{$className} seeded successfully". PHP_EOL;
echo "{$className} seeded successfully" . PHP_EOL;
return true;
}

@@ -127,39 +133,35 @@ private function displayCompletionMessage()
* If a single item is added, a simple putItem is used.
* If multiple items are added, then the batchWriteItem is used.
* NB: batchWriteItem can take maximum of 100 items per call.
* @throws \Exception
*/
protected function save()
{
$this->isTableNameSet();
$this->atLeastOneItemExist();
$this->tableExist($this->table);

if ($this->isBatchRequest()) {
$this->validateBatchItemsLimit();

$items = [];
foreach ($this->items as $item) {
$items[$this->table][] = [
'PutRequest' => [
'Item' => $item
]
];
}

$this->dynamoDBClient->batchWriteItem(
[
'RequestItems' => $items
]
);
} else {
$this->dynamoDBClient->putItem(
[
'TableName' => $this->table,
'Item' => $this->items[0]
if (!$this->isBatchRequest()) {
$this->dynamoDBClient->putItem([
'TableName' => $this->table,
'Item' => $this->items[0]
]);
return $this->displayCompletionMessage();
}


$this->validateBatchItemsLimit();
$items = [];
foreach ($this->items as $item) {
$items[$this->table][] = [
'PutRequest' => [
'Item' => $item
]
);
];
}
$this->dynamoDBClient->batchWriteItem(['RequestItems' => $items]);
return $this->displayCompletionMessage();

}

/**

0 comments on commit fcf55c7

Please sign in to comment.