@@ -39,8 +39,7 @@ public function fill(array $records, array $references): void
39
39
throw new \InvalidArgumentException ('The provided list of records did not share the same schema ' );
40
40
}
41
41
42
- $ recordId = $ this ->getRecordId ($ schema , $ record ->getDatabaseValues ());
43
- $ this ->cache [$ schemaId ][$ recordId ] = $ record ;
42
+ $ this ->cacheRecord ($ schemaId , $ record );
44
43
}
45
44
46
45
$ this ->fillReferences ($ records , $ references );
@@ -65,21 +64,43 @@ private function fillReferences(array $records, array $references): void
65
64
throw new \RuntimeException ('Filling references for composite foreign keys is not supported ' );
66
65
}
67
66
67
+ $ isPrimaryReference = $ fields === $ parent ->getPrimaryKeys ();
68
68
$ key = array_pop ($ keys );
69
69
$ field = array_pop ($ fields );
70
70
$ options = [];
71
+ $ sorted = [];
71
72
72
73
foreach ($ records as $ record ) {
73
- $ options [] = $ record [$ key ];
74
+ $ value = $ record [$ key ];
75
+
76
+ if ($ record ->isReferenceLoaded ($ name )) {
77
+ $ sorted [$ value ] = $ record ->getReference ($ name );
78
+
79
+ foreach ($ sorted [$ value ] as $ referencedRecord ) {
80
+ $ this ->cacheRecord ($ schemaId , $ referencedRecord );
81
+ }
82
+
83
+ continue ;
84
+ }
85
+
86
+ if ($ isPrimaryReference && isset ($ this ->cache [$ schemaId ][$ value ])) {
87
+ $ sorted [$ value ] = [$ this ->cache [$ schemaId ][$ value ]];
88
+ continue ;
89
+ }
90
+
91
+ $ options [$ value ] = true ;
74
92
}
75
93
76
- $ result = $ this ->connection ->select ($ parent ->getFields (), $ parent ->getTable (), [$ field => $ options ]);
77
- $ result ->setFetchMode (\PDO ::FETCH_ASSOC );
78
- $ sorted = [];
94
+ $ options = array_keys (array_diff_key ($ options , $ sorted ));
79
95
80
- foreach ($ result as $ row ) {
81
- $ record = $ this ->getCachedRecord ($ schemaId , $ parent , $ row );
82
- $ sorted [$ record [$ field ]][] = $ record ;
96
+ if ($ options ) {
97
+ $ result = $ this ->connection ->select ($ parent ->getFields (), $ parent ->getTable (), [$ field => $ options ]);
98
+ $ result ->setFetchMode (\PDO ::FETCH_ASSOC );
99
+
100
+ foreach ($ result as $ row ) {
101
+ $ record = $ this ->getCachedRecord ($ schemaId , $ parent , $ row );
102
+ $ sorted [$ record [$ field ]][] = $ record ;
103
+ }
83
104
}
84
105
85
106
foreach ($ records as $ record ) {
@@ -111,9 +132,21 @@ private function parseReferences(array $references): array
111
132
return $ subReferences ;
112
133
}
113
134
135
+ private function cacheRecord (string $ schemaId , Record $ record ): void
136
+ {
137
+ $ recordId = implode ('- ' , $ record ->getPrimaryKeys ());
138
+ $ this ->cache [$ schemaId ][$ recordId ] = $ record ;
139
+ }
140
+
114
141
private function getCachedRecord (string $ schemaId , Schema $ schema , array $ row ): Record
115
142
{
116
- $ recordId = $ this ->getRecordId ($ schema , $ row );
143
+ $ primaryKey = [];
144
+
145
+ foreach ($ schema ->getPrimaryKeys () as $ key ) {
146
+ $ primaryKey [] = $ row [$ key ];
147
+ }
148
+
149
+ $ recordId = implode ('- ' , $ primaryKey );
117
150
118
151
if (isset ($ this ->cache [$ schemaId ][$ recordId ])) {
119
152
return $ this ->cache [$ schemaId ][$ recordId ];
@@ -128,19 +161,4 @@ private function getSchemaId(Schema $schema): string
128
161
{
129
162
return spl_object_hash ($ schema );
130
163
}
131
-
132
- private function getRecordId (Schema $ schema , array $ row )
133
- {
134
- $ values = [];
135
-
136
- foreach ($ schema ->getPrimaryKeys () as $ key ) {
137
- if (!isset ($ row [$ key ])) {
138
- throw new \RuntimeException ('Cannot determine cache id for record ' );
139
- }
140
-
141
- $ values [] = $ row [$ key ];
142
- }
143
-
144
- return implode ('- ' , $ values );
145
- }
146
164
}
0 commit comments