Skip to content

Commit 9ab4b13

Browse files
author
Cyril Mizzi
committed
appends cache to EloquentModel in order to improves SQL performances
1 parent a41dec1 commit 9ab4b13

File tree

1 file changed

+101
-87
lines changed

1 file changed

+101
-87
lines changed

src/Traits/EloquentModel.php

Lines changed: 101 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -10,65 +10,75 @@
1010
* Implements method `getRelations` and `getColumns`
1111
*/
1212
trait EloquentModel {
13+
/** @var array $columns */
14+
private $columns = null;
15+
16+
/** @var array $relationships */
17+
private $relationships = null;
18+
1319
/**
1420
* Return model relationships
1521
*
1622
* @return array
1723
*/
1824
public function getRelationship() {
19-
$relations = [];
20-
$reflection = new ReflectionClass($this);
21-
$traits = $reflection->getTraits();
22-
$exclude = [];
23-
24-
// Get traits methods and append them to the excluded methods
25-
foreach ($traits as $trait) {
26-
foreach ($trait->getMethods() as $method) {
27-
$exclude[$method->getName()] = true;
28-
}
29-
}
30-
31-
foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
32-
if ($method->class !== get_class($this)) {
33-
continue;
34-
}
35-
36-
// We don't want method with parameters (relationship doesn't have
37-
// parameter)
38-
if (!empty($method->getParameters())) {
39-
continue;
25+
if (is_null($this->relationships)) {
26+
$relations = [];
27+
$reflection = new ReflectionClass($this);
28+
$traits = $reflection->getTraits();
29+
$exclude = [];
30+
31+
// Get traits methods and append them to the excluded methods
32+
foreach ($traits as $trait) {
33+
foreach ($trait->getMethods() as $method) {
34+
$exclude[$method->getName()] = true;
35+
}
4036
}
4137

42-
// We don't want parsing this current method
43-
if (array_key_exists($method->getName(), $exclude)) {
44-
continue;
45-
}
38+
foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
39+
if ($method->class !== get_class($this)) {
40+
continue;
41+
}
4642

47-
try {
48-
$return = $method->invoke($this);
43+
// We don't want method with parameters (relationship doesn't
44+
// have parameter)
45+
if (!empty($method->getParameters())) {
46+
continue;
47+
}
4948

50-
// Get only method that returned Relation instance
51-
if ($return instanceof Relation) {
52-
$name = $method->getName();
53-
$type = with(new ReflectionClass($return))->getShortName();
54-
$model = with(new ReflectionClass($return->getRelated()));
49+
// We don't want parsing this current method
50+
if (array_key_exists($method->getName(), $exclude)) {
51+
continue;
52+
}
5553

56-
// Assert that relationship field handle this trait :
57-
// otherwise, we cannot check columns and relationships
58-
if (!array_key_exists(__TRAIT__, $model->getTraits())) {
59-
continue;
54+
try {
55+
$return = $method->invoke($this);
56+
57+
// Get only method that returned Relation instance
58+
if ($return instanceof Relation) {
59+
$name = $method->getName();
60+
$type = with(new ReflectionClass($return))->getShortName();
61+
$model = with(new ReflectionClass($return->getRelated()));
62+
63+
// Assert that relationship field handle this trait :
64+
// otherwise, we cannot check columns and relationships
65+
if (!array_key_exists(__TRAIT__, $model->getTraits())) {
66+
continue;
67+
}
68+
69+
$relations[$name] = [
70+
'field' => $method->getName(),
71+
'type' => $type,
72+
'model' => $model->getName()
73+
];
6074
}
75+
} catch (ErrorException $e) {}
76+
}
6177

62-
$relations[$name] = [
63-
'field' => $method->getName(),
64-
'type' => $type,
65-
'model' => $model->getName()
66-
];
67-
}
68-
} catch (ErrorException $e) {}
78+
$this->relationships = $relations;
6979
}
7080

71-
return $relations;
81+
return $this->relationships;
7282
}
7383

7484
/**
@@ -78,54 +88,58 @@ public function getRelationship() {
7888
* @return array
7989
*/
8090
public function getColumns() {
81-
$data = [];
82-
$table = $this->getTable();
83-
$connection = $this->getConnection();
84-
$primary = $this->getKeyName();
85-
$columns = $connection->getSchemaBuilder()->getColumnListing($table);
86-
87-
// Remove hidden columns : we don't want show or update them. Also
88-
// append relationships virtual columns
89-
$related = $this->getRelationship();
90-
$columns = array_diff($columns, $this->getHidden());
91-
$columns = array_merge(array_keys($related), $columns);
92-
93-
foreach (array_unique($columns) as $column) {
94-
try {
95-
$type = $connection->getDoctrineColumn($table, $column);
96-
$type = $type->getType();
97-
} catch (SchemaException $e) {
98-
// There's nothing left to do (it's a virtual field or, it
99-
// also could append with PostgreSQL multiple schemas)
100-
$data[$column] = null;
101-
continue;
102-
}
91+
if (is_null($this->columns)) {
92+
$data = [];
93+
$table = $this->getTable();
94+
$connection = $this->getConnection();
95+
$primary = $this->getKeyName();
96+
$columns = $connection->getSchemaBuilder()->getColumnListing($table);
97+
98+
// Remove hidden columns : we don't want show or update them. Also
99+
// append relationships virtual columns
100+
$related = $this->getRelationship();
101+
$columns = array_diff($columns, $this->getHidden());
102+
$columns = array_merge(array_keys($related), $columns);
103+
104+
foreach (array_unique($columns) as $column) {
105+
try {
106+
$type = $connection->getDoctrineColumn($table, $column);
107+
$type = $type->getType();
108+
} catch (SchemaException $e) {
109+
// There's nothing left to do (it's a virtual field or, it
110+
// also could append with PostgreSQL multiple schemas)
111+
$data[$column] = null;
112+
continue;
113+
}
103114

104-
// Parse each available database data type and call is related
105-
// GraphQL type
106-
switch ($type->getName()) {
107-
case 'smallint' :
108-
case 'bigint' :
109-
case 'integer' : $type = GraphQLType::int() ; break;
110-
case 'decimal' :
111-
case 'float' : $type = GraphQLType::float() ; break;
112-
case 'date' :
113-
case 'datetimetz' :
114-
case 'time' :
115-
case 'datetime' : $type = \GraphQL::scalar('timestamp') ; break;
116-
case 'array' :
117-
case 'simple_array' : $type = GraphQLType::listOf(GraphQLType::string()) ; break;
118-
default : $type = GraphQLType::string() ; break;
119-
}
115+
// Parse each available database data type and call is related
116+
// GraphQL type
117+
switch ($type->getName()) {
118+
case 'smallint' :
119+
case 'bigint' :
120+
case 'integer' : $type = GraphQLType::int() ; break;
121+
case 'decimal' :
122+
case 'float' : $type = GraphQLType::float() ; break;
123+
case 'date' :
124+
case 'datetimetz' :
125+
case 'time' :
126+
case 'datetime' : $type = \GraphQL::scalar('timestamp') ; break;
127+
case 'array' :
128+
case 'simple_array' : $type = GraphQLType::listOf(GraphQLType::string()) ; break;
129+
default : $type = GraphQLType::string() ; break;
130+
}
131+
132+
// Assert primary key is an id
133+
if ($column === $primary) {
134+
$type = GraphQLType::id();
135+
}
120136

121-
// Assert primary key is an id
122-
if ($column === $primary) {
123-
$type = GraphQLType::id();
137+
$data[$column] = $type;
124138
}
125139

126-
$data[$column] = $type;
140+
$this->columns = $data;
127141
}
128142

129-
return $data;
143+
return $this->columns;
130144
}
131145
}

0 commit comments

Comments
 (0)