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

Commit e137d9e

Browse files
author
Nik Barham
committed
Extracting out Cache interface
1 parent e328bf3 commit e137d9e

File tree

3 files changed

+149
-103
lines changed

3 files changed

+149
-103
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Automatorm\Cache;
4+
5+
interface CacheInterface
6+
{
7+
public function get($key);
8+
public function put($key, $value, $timeout = 60 * 60 * 24 * 7);
9+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Automatorm\Cache;
4+
5+
use HodgePodge\Core\Cache as HPCache;
6+
7+
class HodgePodgeCache implements CacheInterface
8+
{
9+
public function get($key) {
10+
$cache = new HPCache($key, 'cache');
11+
return $cache->get();
12+
}
13+
14+
public function put($key, $value, $timeout = 60 * 60 * 24 * 7) {
15+
HPCache::lifetime($timeout, 'cache');
16+
$cache = new HPCache($key, 'cache');
17+
return $cache->save($value);
18+
}
19+
}

src/Automatorm/Orm/Schema.php

Lines changed: 121 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use Automatorm\Exception;
66
use Automatorm\Database\Query;
77
use Automatorm\Database\Connection;
8-
8+
use Automatorm\Cache\CacheInterface;
99
use HodgePodge\Core\Cache;
1010

1111
class Schema
@@ -34,134 +34,152 @@ protected function __construct($model, $database, $namespace) {
3434
$this->namespace = $namespace;
3535
$this->version = static::CURRENT_VERSION;
3636
}
37-
37+
38+
protected static $cache = '\\Automatorm\\Cache\\HodgePodgeCache';
39+
public static function registerCache($cache)
40+
{
41+
static::$cache = $cache;
42+
}
43+
3844
public static function generate($dbconnection = 'default', $namespace = 'models', $cachebust = false)
3945
{
40-
Cache::lifetime(60 * 60 * 24 * 7, 'model'); // Cache model weekly
46+
$key = 'schema_' . md5($dbconnection . $namespace . $db->database . static::CURRENT_VERSION);
4147

4248
$db = Connection::get($dbconnection);
43-
$cache = new Cache('schema_' . md5($dbconnection . $namespace . $db->database . static::CURRENT_VERSION), 'model');
49+
if (is_object(static::$cache)) {
50+
$cache = static::$cache;
51+
} else {
52+
$cache = new static::$cache;
53+
}
4454

45-
$obj = $cache();
55+
$obj = $cache->get($key);
4656

4757
if ($obj && $obj->version != static::CURRENT_VERSION)
4858
{
4959
unset($obj);
5060
}
5161

5262
if ($cachebust or !$obj) {
53-
// Get a list of all foreign keys in this database
54-
$query = new Query($dbconnection);
55-
$query->sql("
56-
SELECT b.table_name, b.column_name, b.referenced_table_name, b.referenced_column_name
57-
FROM information_schema.table_constraints a
58-
JOIN information_schema.key_column_usage b
59-
ON a.table_schema = b.table_schema AND a.constraint_name = b.constraint_name
60-
WHERE a.table_schema = database() AND a.constraint_type = 'FOREIGN KEY'
61-
ORDER BY b.table_name, b.constraint_name;"
62-
);
63-
$query->sql("
64-
SELECT table_name, column_name, data_type FROM information_schema.columns where table_schema = database();
65-
");
66-
67-
list($keys, $schema) = $query->execute();
63+
$model = static::generateSchema($dbconnection);
64+
$obj = new static($model, $dbconnection, $namespace);
65+
$cache->put($key, $obj, 60 * 60 * 24 * 7);
66+
}
67+
68+
return static::$object_list[$dbconnection] = $obj;
69+
}
70+
71+
public static function generateSchema($dbconnection)
72+
{
73+
$model = [];
74+
75+
// Get a list of all foreign keys in this database
76+
$query = new Query($dbconnection);
77+
$query->sql("
78+
SELECT b.table_name, b.column_name, b.referenced_table_name, b.referenced_column_name
79+
FROM information_schema.table_constraints a
80+
JOIN information_schema.key_column_usage b
81+
ON a.table_schema = b.table_schema AND a.constraint_name = b.constraint_name
82+
WHERE a.table_schema = database() AND a.constraint_type = 'FOREIGN KEY'
83+
ORDER BY b.table_name, b.constraint_name;"
84+
);
85+
$query->sql("
86+
SELECT table_name, column_name, data_type FROM information_schema.columns where table_schema = database();
87+
");
88+
89+
list($keys, $schema) = $query->execute();
90+
91+
// Assemble list of table columns by table
92+
foreach ($schema as $row) {
93+
$table_name = self::normaliseCase($row['table_name']);
6894

69-
// Assemble list of table columns by table
70-
foreach ($schema as $row) {
71-
$table_name = self::normaliseCase($row['table_name']);
72-
73-
$model[$table_name]['table_name'] = $row['table_name'];
74-
// All tables default to type 'table' - can also be 'pivot' or 'foreign' as detected later
75-
$model[$table_name]['type'] = 'table';
76-
// List all columns for this table
77-
$model[$table_name]['columns'][$row['column_name']] = $row['data_type'];
78-
}
95+
$model[$table_name]['table_name'] = $row['table_name'];
96+
// All tables default to type 'table' - can also be 'pivot' or 'foreign' as detected later
97+
$model[$table_name]['type'] = 'table';
98+
// List all columns for this table
99+
$model[$table_name]['columns'][$row['column_name']] = $row['data_type'];
100+
}
101+
102+
// Loop over every foreign key definition
103+
foreach ($keys as $row) {
104+
$table_name = self::normaliseCase($row['table_name']);
105+
$ref_table_name = self::normaliseCase($row['referenced_table_name']);
79106

80-
// Loop over every foreign key definition
81-
foreach ($keys as $row) {
82-
$table_name = self::normaliseCase($row['table_name']);
83-
$ref_table_name = self::normaliseCase($row['referenced_table_name']);
84-
85-
if ($row['referenced_column_name'] == 'id' and $row['column_name'] == 'id') {
86-
// If both columns in the key are 'id' then this is a 1 to 1 relationship.
87-
// Create a link in both objects to each other
88-
$model[$ref_table_name]['one-to-one'][self::underscoreCase($table_name)] = $table_name;
89-
$model[$table_name]['one-to-one'][self::underscoreCase($ref_table_name)] = $ref_table_name;
90-
$model[$table_name]['type'] = 'foreign';
91-
} elseif ($row['referenced_column_name'] == 'id') {
92-
// if this foreign key points at one 'id' column then this is a usable foreign 'key'
93-
if (substr($row['column_name'], -3) == '_id') {
94-
$column_root = substr($row['column_name'], 0, -3);
95-
$model[$table_name]['many-to-one'][$column_root] = $ref_table_name;
96-
97-
// Add the key constraint in reverse, trying to make a sensible name.
98-
// If the column name was derived from the table name, just use the table name.
99-
// (e.g "my_account" table and "my_account_id" -> my_account)
100-
// Otherwise, append the column name to the table name to make sure it is unique.
101-
// (e.g "your_account" table and "my_account_id" -> your_account_my_account)
102-
if ($column_root == $row['referenced_table_name']) {
103-
$property_name = self::underscoreCase($table_name);
104-
} else {
105-
$property_name = self::underscoreCase($table_name) . '_' . $column_root;
106-
}
107-
108-
$model[$ref_table_name]['one-to-many'][$property_name] = array('table' => $table_name, 'column_name' => $row['column_name']);
107+
if ($row['referenced_column_name'] == 'id' and $row['column_name'] == 'id') {
108+
// If both columns in the key are 'id' then this is a 1 to 1 relationship.
109+
// Create a link in both objects to each other
110+
$model[$ref_table_name]['one-to-one'][self::underscoreCase($table_name)] = $table_name;
111+
$model[$table_name]['one-to-one'][self::underscoreCase($ref_table_name)] = $ref_table_name;
112+
$model[$table_name]['type'] = 'foreign';
113+
} elseif ($row['referenced_column_name'] == 'id') {
114+
// if this foreign key points at one 'id' column then this is a usable foreign 'key'
115+
if (substr($row['column_name'], -3) == '_id') {
116+
$column_root = substr($row['column_name'], 0, -3);
117+
$model[$table_name]['many-to-one'][$column_root] = $ref_table_name;
118+
119+
// Add the key constraint in reverse, trying to make a sensible name.
120+
// If the column name was derived from the table name, just use the table name.
121+
// (e.g "my_account" table and "my_account_id" -> my_account)
122+
// Otherwise, append the column name to the table name to make sure it is unique.
123+
// (e.g "your_account" table and "my_account_id" -> your_account_my_account)
124+
if ($column_root == $row['referenced_table_name']) {
125+
$property_name = self::underscoreCase($table_name);
126+
} else {
127+
$property_name = self::underscoreCase($table_name) . '_' . $column_root;
109128
}
129+
130+
$model[$ref_table_name]['one-to-many'][$property_name] = array('table' => $table_name, 'column_name' => $row['column_name']);
110131
}
111132
}
112-
113-
// Now look for pivot tables
114-
foreach ($model as $pivottablename => $pivot) {
115-
// If we have found a table with only foreign keys then this must be a pivot table
116-
if (count($pivot['many-to-one']) > 1 and count($pivot['columns']) == count($pivot['many-to-one'])) {
117-
// Grab all foreign keys and rearrange them into arrays.
118-
$tableinfo = array();
119-
foreach($pivot['many-to-one'] as $column => $tablename) {
120-
$tableinfo[] = array('column' => $column . '_id', 'column_raw' => $column, 'table' => $tablename);
133+
}
134+
135+
// Now look for pivot tables
136+
foreach ($model as $pivottablename => $pivot) {
137+
// If we have found a table with only foreign keys then this must be a pivot table
138+
if (count($pivot['many-to-one']) > 1 and count($pivot['columns']) == count($pivot['many-to-one'])) {
139+
// Grab all foreign keys and rearrange them into arrays.
140+
$tableinfo = array();
141+
foreach($pivot['many-to-one'] as $column => $tablename) {
142+
$tableinfo[] = array('column' => $column . '_id', 'column_raw' => $column, 'table' => $tablename);
143+
}
144+
145+
// For each foreign key, store details in the table it point to on how to get to the OTHER table in the "Many to Many" relationship
146+
foreach ($tableinfo as $i => $table)
147+
{
148+
// If the column name is named based on the foreign table name, then use the pivot table name as the property name
149+
// This is the normal/usual case
150+
if ($table['column'] == self::underscoreCase($table['table']) . '_id') {
151+
$property_name = self::underscoreCase($pivottablename);
152+
} else {
153+
// Else append the column name to the pivot table name.
154+
// This is mostly for when a pivot table references the same table twice, and so
155+
// needs to have a unique name for at least one of the columns (which is not based on the table name)
156+
$property_name = self::underscoreCase($pivottablename) . '_' . $table['column_raw'];
121157
}
122158

123-
// For each foreign key, store details in the table it point to on how to get to the OTHER table in the "Many to Many" relationship
124-
foreach ($tableinfo as $i => $table)
125-
{
126-
// If the column name is named based on the foreign table name, then use the pivot table name as the property name
127-
// This is the normal/usual case
128-
if ($table['column'] == Schema::underscoreCase($table['table']) . '_id') {
129-
$property_name = Schema::underscoreCase($pivottablename);
130-
} else {
131-
// Else append the column name to the pivot table name.
132-
// This is mostly for when a pivot table references the same table twice, and so
133-
// needs to have a unique name for at least one of the columns (which is not based on the table name)
134-
$property_name = Schema::underscoreCase($pivottablename) . '_' . $table['column_raw'];
135-
}
136-
137-
// Outersect of tables to create an array of all OTHER foreign keys in this table, for this foreign key.
138-
$othertables = array_values(array_diff_assoc($tableinfo, array($i => $table)));
139-
140-
$model[ $table['table'] ][ 'many-to-many' ][ $property_name ] = array(
141-
'pivot' => $pivottablename,
142-
'connections' => $othertables,
143-
'id' => $table['column'],
144-
);
145-
146-
}
159+
// Outersect of tables to create an array of all OTHER foreign keys in this table, for this foreign key.
160+
$othertables = array_values(array_diff_assoc($tableinfo, array($i => $table)));
147161

148-
$model[$pivottablename]['type'] = 'pivot';
162+
$model[ $table['table'] ][ 'many-to-many' ][ $property_name ] = array(
163+
'pivot' => $pivottablename,
164+
'connections' => $othertables,
165+
'id' => $table['column'],
166+
);
149167

150-
// Remove the M-1 keys for these tables to fully encapsulate the M-M scheme.
151-
foreach ($tableinfo as $table)
152-
{
153-
foreach((array) $model[ $table['table'] ][ 'one-to-many' ] as $key => $val) {
154-
if ($val['table'] == $pivottablename) unset ($model[ $table['table'] ][ 'one-to-many' ][$key]);
155-
}
168+
}
169+
170+
$model[$pivottablename]['type'] = 'pivot';
171+
172+
// Remove the M-1 keys for these tables to fully encapsulate the M-M scheme.
173+
foreach ($tableinfo as $table)
174+
{
175+
foreach((array) $model[ $table['table'] ][ 'one-to-many' ] as $key => $val) {
176+
if ($val['table'] == $pivottablename) unset ($model[ $table['table'] ][ 'one-to-many' ][$key]);
156177
}
157178
}
158179
}
159-
160-
$obj = new static($model, $dbconnection, $namespace);
161-
$cache($obj);
162180
}
163181

164-
return static::$object_list[$dbconnection] = $obj;
182+
return $model;
165183
}
166184

167185
// Normalised an under_scored or CamelCased phrase to "under scored" or "camel cased"

0 commit comments

Comments
 (0)