Skip to content

Commit

Permalink
Adding interfaces for more capable storage sources. (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
fmizzell authored Mar 11, 2019
1 parent 6da5ee4 commit 7028273
Show file tree
Hide file tree
Showing 8 changed files with 256 additions and 4 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# SAE (Services API Engine)
# Contracts
![CircleCI (all branches)](https://img.shields.io/circleci/project/github/fmizzell/contracts.svg)
[![Maintainability](https://api.codeclimate.com/v1/badges/3790fc0eeeb9dac4f0cb/maintainability)](https://codeclimate.com/github/fmizzell/contracts/maintainability)
[![Test Coverage](https://api.codeclimate.com/v1/badges/3790fc0eeeb9dac4f0cb/test_coverage)](https://codeclimate.com/github/fmizzell/contracts/test_coverage)
[![GPLv3 license](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0.en.html)


A set of interfaces.
A set of interfaces.
9 changes: 9 additions & 0 deletions src/Conditioner.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace Contracts;


interface Conditioner
{
public function conditionByIsEqualTo(string $property, string $value);
}
8 changes: 8 additions & 0 deletions src/Limiter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Contracts;

interface Limiter
{
public function limitTo(int $number_of_items);
}
127 changes: 127 additions & 0 deletions src/Mock/Storage/JsonObjectMemory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<?php

namespace Contracts\Mock\Storage;

use Contracts\Sorter;
use Contracts\Conditioner;
use Contracts\Offsetter;
use Contracts\Limiter;

class JsonObjectMemory extends Memory implements Sorter, Conditioner, Offsetter, Limiter
{
private $offset = 0;
private $limit = 0;

private $sorts = [
'ascend' => [],
'descend' => [],
];

private $conditions = [];

public function retrieveAll(): array
{
$results = parent::retrieveAll();
$results = $this->applyFilters($results);
$this->resetFilters();
return $results;
}

public function store(string $data, string $id = NULL): string
{
$this->validate($data);
return parent::store($data, $id);
}

public function conditionByIsEqualTo(string $property, string $value)
{
$this->conditions[$property][] = $value;
}

public function limitTo(int $number_of_items)
{
$this->limit = $number_of_items;
}

public function offsetBy(int $offset)
{
$this->offset = $offset;
}

public function sortByAscending(string $property)
{
$this->sorts['ascend'][] = $property;
}

public function sortByDescending(string $property)
{
$this->sorts['descend'][] = $property;
}

private function applyFilters(array $results) {

if (!empty($this->conditions)) {
$results2 = [];

foreach ($this->conditions as $property => $values) {
foreach ($values as $value) {
foreach ($results as $key => $result) {
$obj = json_decode($result);
if ($obj->{$property} == $value) {
$results2[$key] = $result;
}
}
}
}

$results = $results2;
}


foreach ($this->sorts as $type => $properties) {
foreach ($properties as $property) {
usort($results, function ($a, $b) use ($property) {
return $this->compare($a, $b, $property);
});

if ($type == 'descend') {
$results = array_reverse($results);
}
}
}

if ($this->limit > 0 || $this->offset > 0) {
$results = array_slice($results, $this->offset, $this->limit);
}

return $results;
}

private function resetFilters() {
$this->offset = 0;
$this->limit = 0;

$this->sorts = [
'ascend' => [],
'descend' => [],
];

$this->conditions = [];
}

private function validate(string $data) {
$decoded = json_decode($data);
if (is_null($decoded)) {
throw new \Exception("Only JSON strings can be stored");
}
if (!is_object($decoded)) {
throw new \Exception("Only strings with JSON objects can be stored");
}
}

private function compare($a, $b, $property) {
$a = json_decode($a);
$b = json_decode($b);
return strnatcmp($a->{$property}, $b->{$property});
}
}
9 changes: 7 additions & 2 deletions src/Mock/Storage/Memory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

namespace Contracts\Mock\Storage;

class Memory implements \Contracts\Storage, \Contracts\BulkRetriever {
use Contracts\Storage;
use Contracts\BulkRetriever;

class Memory implements Storage, BulkRetriever {

private $storage = [];

public function retrieve(string $id): ?string
Expand All @@ -20,7 +24,7 @@ public function retrieveAll(): array

public function store(string $data, string $id = NULL): string
{
if (!$id) {
if (!isset($id)) {
throw new \Exception("An id is required to store the data.");
}
if (!isset($this->storage[$id])) {
Expand All @@ -39,4 +43,5 @@ public function remove(string $id)
}
return FALSE;
}

}
8 changes: 8 additions & 0 deletions src/Offsetter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Contracts;

interface Offsetter
{
public function offsetBy(int $offset);
}
9 changes: 9 additions & 0 deletions src/Sorter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace Contracts;

interface Sorter
{
public function sortByAscending(string $property);
public function sortByDescending(string $property);
}
86 changes: 86 additions & 0 deletions tests/MockTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,90 @@ public function testStorageMemory() {
$this->assertNull($store->retrieve("1"));
}

public function testStorageJsonObjectMemory() {
$objects = [];
$objects[] = <<<JSON
{
"first": "Gerardo",
"last": "Gonzalez"
}
JSON;

$objects[] = <<<JSON
{
"first": "Pedro",
"last": "Gonzalez"
}
JSON;

$objects[] = <<<JSON
{
"first": "Gerardo",
"last": "Lopez"
}
JSON;

$objects[] = <<<JSON
{
"first": "Jhonny",
"last": "Five"
}
JSON;

$store = new \Contracts\Mock\Storage\JsonObjectMemory();


foreach ($objects as $index => $object) {
$store->store($object, "{$index}");
}

$this->assertEquals(4, count($store->retrieveAll()));

$store->offsetBy(1);
$store->limitTo(1);

foreach ($store->retrieveAll() as $string) {
$this->assertEquals($objects[1], $string);
}

$store->offsetBy(3);

foreach ($store->retrieveAll() as $string) {
$this->assertEquals($objects[3], $string);
}

$store->limitTo(1);

foreach ($store->retrieveAll() as $string) {
$this->assertEquals($objects[0], $string);
}

$store->sortByAscending("first");

$order = [0, 2, 3, 1];
$order_index = 0;
foreach ($store->retrieveAll() as $string) {
$this->assertEquals($objects[$order[$order_index]], $string);
$order_index++;
}

$store->sortByDescending("first");

$order = [1, 3, 2, 0];
$order_index = 0;
foreach ($store->retrieveAll() as $string) {
$this->assertEquals($objects[$order[$order_index]], $string);
$order_index++;
}

$store->conditionByIsEqualTo("first", "Gerardo");

$order = [0, 2];
$order_index = 0;
foreach ($store->retrieveAll() as $string) {
$this->assertEquals($objects[$order[$order_index]], $string);
$order_index++;
}
}

}

0 comments on commit 7028273

Please sign in to comment.