Skip to content
This repository was archived by the owner on May 12, 2022. It is now read-only.

Commit 96bdca8

Browse files
author
Nik Barham
committed
Medium Rebuild of Fake data layer to work for multiple schemas, and cross-schema joins
1 parent c13bc99 commit 96bdca8

File tree

8 files changed

+237
-97
lines changed

8 files changed

+237
-97
lines changed

src/DataLayer/Fake/Connection.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ public function getLogger()
2121
public $schemaGenerator;
2222
public $schemaName;
2323
public $dataAccess;
24-
public function __construct($data, $schemaname)
24+
public $store;
25+
public function __construct(DataStore $datastore, $schemaname)
2526
{
26-
$this->data = $data;
27+
$this->store = $datastore;
28+
$this->data = $datastore->getData($schemaname);
2729
$this->schemaName = $schemaname;
2830
$this->schemaGenerator = new SchemaGenerator($this);
2931
$this->dataAccess = new DataAccess($this);
@@ -45,6 +47,7 @@ public function disconnect()
4547
*/
4648
public function connect()
4749
{
50+
$this->data->generateData($this);
4851
return $this->data;
4952
}
5053

@@ -57,4 +60,9 @@ public function getSchemaGenerator() : SchemaGeneratorInterface
5760
{
5861
return $this->schemaGenerator;
5962
}
63+
64+
public function getDataStore() : DataStore
65+
{
66+
return $this->store;
67+
}
6068
}

src/DataLayer/Fake/Data.php

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
<?php
2+
namespace Automatorm\DataLayer\Fake;
3+
4+
use Automatorm\Interfaces\Connection as ConnectionInterface;
5+
use Automatorm\Interfaces\DataAccess as DataAccessInterface;
6+
use Automatorm\Orm\Schema;
7+
use Automatorm\OperatorParser;
8+
9+
class Data
10+
{
11+
public $connection;
12+
public $data;
13+
public $schemaName;
14+
public $tabledata = [];
15+
public $crossschema = [];
16+
17+
public function __construct($data, $schemaName = 'default')
18+
{
19+
$this->schemaName = $schemaName;
20+
$this->data = $data;
21+
}
22+
23+
public function generateData($connection)
24+
{
25+
list($schema, $database) = $connection->getSchemaGenerator()->generate();
26+
27+
$currentTable = null;
28+
$currentTableName = null;
29+
30+
foreach(preg_split('~[\r\n]+~', $this->data) as $line) {
31+
if (empty($line) or ctype_space($line)) {
32+
continue;
33+
}
34+
35+
$matches = [];
36+
$clean = trim(strtolower($line));
37+
if (preg_match('/^\s*([a-z_]+)\s*\|/', $clean, $matches)) {
38+
// Table Declaration
39+
$tableName = trim($matches[1]);
40+
$currentTableName = Schema::normaliseCase($tableName);
41+
$currentTable = $schema[$currentTableName];
42+
} elseif (preg_match('/^\s*([a-z_]+)\s*->/', $clean, $matches)) {
43+
// Skip foreign key declaration
44+
} elseif ($rowdata = str_getcsv(trim($line), ',', '\'')) {
45+
// If we have a parsable csv string, a tablename, and a matching number of columns
46+
if ($currentTableName) {
47+
if (count($rowdata) == count($currentTable['columns'])) {
48+
$combined = array_combine(array_keys($currentTable['columns']), $rowdata);
49+
/* Special case '*null' as null */
50+
foreach ($combined as $key => $value) {
51+
if (strtolower($value) === '*null') {
52+
$combined[$key] = null;
53+
}
54+
if (substr(strtolower($value), 0, 6) == '**null') {
55+
$combined[$key] = substr($value, 1);
56+
}
57+
}
58+
if (isset($combined['id'])) {
59+
$this->tabledata[$currentTableName][$combined['id']] = $combined;
60+
} else {
61+
$this->tabledata[$currentTableName][] = $combined;
62+
}
63+
}
64+
}
65+
}
66+
}
67+
}
68+
69+
public function addCrossSchemaForeignKey($table, $type, $column, $data)
70+
{
71+
$this->crossschema[] = [
72+
'table' => $table,
73+
'type' => $type,
74+
'column' => $column,
75+
'data' => $data
76+
];
77+
}
78+
79+
public function getCrossSchemaForeignKeys() : array
80+
{
81+
return $this->crossschema;
82+
}
83+
84+
public function getData()
85+
{
86+
return $this->tabledata;
87+
}
88+
89+
public function getTable($table)
90+
{
91+
return $this->tabledata[$table];
92+
}
93+
94+
public function getRow($table, $id)
95+
{
96+
return $this->tabledata[$table][$id];
97+
}
98+
99+
public function delete($table, $id)
100+
{
101+
unset($this->tabledata[$table][$id]);
102+
}
103+
104+
public function autoincrementId($table)
105+
{
106+
return max(array_keys($this->tabledata[$table])) + 1;
107+
}
108+
109+
public function addData($table, $id, $column, $value)
110+
{
111+
return $this->tabledata[$table][$id][$column] = $value;
112+
}
113+
114+
public function addRow($table, $id, $data)
115+
{
116+
if (is_null($id)) {
117+
$id = $this->autoincrementId($table);
118+
}
119+
return $this->tabledata[$table][$id] = $data;
120+
}
121+
}

src/DataLayer/Fake/DataAccess.php

Lines changed: 11 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -10,87 +10,32 @@ class DataAccess implements DataAccessInterface
1010
{
1111
public $connection;
1212
public $data;
13-
public $tabledata = [];
1413

1514
public function __construct(ConnectionInterface $connection)
1615
{
1716
$this->connection = $connection;
1817
$this->data = $connection->connect();
19-
$this->generateData();
20-
}
21-
22-
protected function generateData()
23-
{
24-
list($schema, $database) = $this->connection->getSchemaGenerator()->generate();
25-
26-
$currentTable = null;
27-
$currentTableName = null;
28-
29-
foreach(preg_split('~[\r\n]+~', $this->data) as $line) {
30-
if (empty($line) or ctype_space($line)) {
31-
continue;
32-
}
33-
34-
$matches = [];
35-
$clean = trim(strtolower($line));
36-
if (preg_match('/^\s*([a-z_]+)\s*\|/', $clean, $matches)) {
37-
// Table Declaration
38-
$tableName = trim($matches[1]);
39-
$currentTableName = Schema::normaliseCase($tableName);
40-
$currentTable = $schema[$currentTableName];
41-
} elseif (preg_match('/^\s*([a-z_]+)\s*->/', $clean, $matches)) {
42-
// Skip foreign key declaration
43-
} elseif ($rowdata = str_getcsv(trim($line), ',', '\'')) {
44-
// If we have a parsable csv string, a tablename, and a matching number of columns
45-
if ($currentTableName) {
46-
if (count($rowdata) == count($currentTable['columns'])) {
47-
$combined = array_combine(array_keys($currentTable['columns']), $rowdata);
48-
/* Special case '*null' as null */
49-
foreach ($combined as $key => $value) {
50-
if (strtolower($value) === '*null') {
51-
$combined[$key] = null;
52-
}
53-
if (substr(strtolower($value), 0, 6) == '**null') {
54-
$combined[$key] = substr($value, 1);
55-
}
56-
}
57-
if (isset($combined['id'])) {
58-
$this->tabledata[$currentTableName][$combined['id']] = $combined;
59-
} else {
60-
$this->tabledata[$currentTableName][] = $combined;
61-
}
62-
}
63-
}
64-
}
65-
}
6618
}
6719

6820
public function commit($mode, $table, $id, $data, $externalData, $schema) : int
6921
{
7022
if ($mode == 'delete') {
71-
unset($this->tabledata[$table][$id]);
23+
$this->data->delete($table, $id);
7224
return $id;
7325
}
7426

7527
if ($mode == 'insert') {
76-
$id = max(array_keys($this->tabledata[$table])) + 1;
77-
$data['id'] = $id;
28+
$data['id'] = $id = $this->data->autoincrementId($table);
7829
}
7930

8031
if ($mode == 'insert' || $mode == 'update') {
8132
foreach ($schema['columns'] as $column => $type) {
8233
if ($type == 'datetime' and array_key_exists($column, $data) and $data[$column] instanceof \DateTimeInterface) {
83-
$this->tabledata[$table][$id][$column] = $data[$column]->format('c');
34+
$this->data->addData($table, $id, $column, $data[$column]->format('c'));
8435
} else {
85-
$this->tabledata[$table][$id][$column] =
86-
array_key_exists($column, $data) ?
87-
$data[$column] :
88-
(
89-
array_key_exists($column, $this->tabledata[$table][$id]) ?
90-
$this->tabledata[$table][$id][$column] :
91-
null
92-
)
93-
;
36+
if (array_key_exists($column, $data)) {
37+
$this->data->addData($table, $id, $column, $data[$column]);
38+
}
9439
}
9540
}
9641
}
@@ -111,18 +56,18 @@ public function commit($mode, $table, $id, $data, $externalData, $schema) : int
11156
$tablename = Schema::normaliseCase($pivot['pivot']);
11257

11358
// Clear out any existing data for this object - this is safe because we are in an atomic transaction.
114-
foreach ($this->tabledata[$tablename] as $key => $row) {
59+
foreach ($this->data->getTable($tablename) as $key => $row) {
11560
if ($row[$pivot['id']] == $id) {
116-
unset($this->tabledata[$tablename][$key]);
61+
$this->data->delete($tablename, $key);
11762
}
11863
}
11964

12065
// Loops through the list of objects to link to this table
12166
foreach ($value as $object) {
122-
$this->tabledata[$tablename][] = [
67+
$this->data->addRow($tablename, null, [
12368
$pivot['id'] => $id,
12469
$pivot['connections'][0]['column'] => $object->id
125-
];
70+
]);
12671
}
12772
}
12873

@@ -167,7 +112,7 @@ protected function getTableData($table, $where)
167112
{
168113
$returnData = [];
169114

170-
foreach ($this->tabledata[$table] as $id => $row) {
115+
foreach ($this->data->getTable($table) as $id => $row) {
171116
foreach ($where as $column => $clause) {
172117
list($affix, $column) = OperatorParser::extractAffix($column, true);
173118
$data = is_string($row[$column]) ? strtolower($row[$column]) : $row[$column];

src/DataLayer/Fake/DataStore.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
namespace Automatorm\DataLayer\Fake;
3+
4+
use Automatorm\Interfaces\Connection as ConnectionInterface;
5+
use Automatorm\Interfaces\DataAccess as DataAccessInterface;
6+
use Automatorm\Orm\Schema;
7+
use Automatorm\OperatorParser;
8+
9+
class DataStore
10+
{
11+
protected $store = [];
12+
13+
public function __construct(array $stores = [])
14+
{
15+
foreach ($stores as $store) {
16+
$this->addData($store);
17+
}
18+
}
19+
20+
public function addData(Data $data)
21+
{
22+
$this->store[$data->schemaName] = $data;
23+
}
24+
25+
public function getData($schemaName)
26+
{
27+
return $this->store[$schemaName];
28+
}
29+
}

0 commit comments

Comments
 (0)