1414use Patchlevel \EventSourcing \Aggregate \AggregateChanged ;
1515use Patchlevel \EventSourcing \Aggregate \AggregateRoot ;
1616
17+ use function array_key_exists ;
18+ use function array_keys ;
1719use function array_map ;
18- use function array_pop ;
19- use function explode ;
20- use function preg_replace ;
2120use function sprintf ;
22- use function strtolower ;
2321
2422final class MultiTableStore implements Store
2523{
2624 private Connection $ connection ;
2725
28- /** @var list <class-string<AggregateRoot>> */
26+ /** @var array <class-string<AggregateRoot>, string > */
2927 private array $ aggregates ;
3028
3129 /**
32- * @param list <class-string<AggregateRoot>> $aggregates
30+ * @param array <class-string<AggregateRoot>, string > $aggregates
3331 */
3432 public function __construct (Connection $ eventConnection , array $ aggregates )
3533 {
@@ -44,7 +42,7 @@ public function __construct(Connection $eventConnection, array $aggregates)
4442 */
4543 public function load (string $ aggregate , string $ id , int $ fromPlayhead = -1 ): array
4644 {
47- $ tableName = self :: tableName ($ aggregate );
45+ $ tableName = $ this -> tableName ($ aggregate );
4846
4947 $ sql = $ this ->connection ->createQueryBuilder ()
5048 ->select ('* ' )
@@ -78,7 +76,7 @@ static function (array $data) use ($platform) {
7876 */
7977 public function has (string $ aggregate , string $ id ): bool
8078 {
81- $ tableName = self :: tableName ($ aggregate );
79+ $ tableName = $ this -> tableName ($ aggregate );
8280
8381 $ sql = $ this ->connection ->createQueryBuilder ()
8482 ->select ('COUNT(*) ' )
@@ -101,7 +99,7 @@ public function has(string $aggregate, string $id): bool
10199 */
102100 public function saveBatch (string $ aggregate , string $ id , array $ events ): void
103101 {
104- $ tableName = self :: tableName ($ aggregate );
102+ $ tableName = $ this -> tableName ($ aggregate );
105103
106104 $ this ->connection ->transactional (
107105 static function (Connection $ connection ) use ($ tableName , $ id , $ events ): void {
@@ -138,7 +136,7 @@ public function prepare(): void
138136
139137 public function drop (): void
140138 {
141- foreach ($ this ->aggregates as $ aggregate ) {
139+ foreach (array_keys ( $ this ->aggregates ) as $ aggregate ) {
142140 $ this ->dropTableForAggregate ($ aggregate );
143141 }
144142 }
@@ -148,7 +146,7 @@ public function drop(): void
148146 */
149147 public function dropTableForAggregate (string $ aggregate ): void
150148 {
151- $ tableName = self :: tableName ($ aggregate );
149+ $ tableName = $ this -> tableName ($ aggregate );
152150
153151 $ this ->connection ->executeQuery (sprintf ('DROP TABLE IF EXISTS %s; ' , $ tableName ));
154152 }
@@ -157,19 +155,15 @@ private function schema(): Schema
157155 {
158156 $ schema = new Schema ([], [], $ this ->connection ->getSchemaManager ()->createSchemaConfig ());
159157
160- foreach ($ this ->aggregates as $ aggregateClass ) {
161- $ this ->addTableToSchema ($ schema , $ aggregateClass );
158+ foreach ($ this ->aggregates as $ tableName ) {
159+ $ this ->addTableToSchema ($ schema , $ tableName );
162160 }
163161
164162 return $ schema ;
165163 }
166164
167- /**
168- * @param class-string<AggregateRoot> $aggregateClass
169- */
170- private function addTableToSchema (Schema $ schema , $ aggregateClass ): void
165+ private function addTableToSchema (Schema $ schema , string $ tableName ): void
171166 {
172- $ tableName = self ::tableName ($ aggregateClass );
173167 $ table = $ schema ->createTable ($ tableName );
174168
175169 $ table ->addColumn ('id ' , Types::BIGINT )
@@ -191,33 +185,12 @@ private function addTableToSchema(Schema $schema, $aggregateClass): void
191185 $ table ->addUniqueIndex (['aggregateId ' , 'playhead ' ]);
192186 }
193187
194- /**
195- * @param class-string<AggregateRoot> $name
196- */
197- private static function tableName (string $ name ): string
198- {
199- $ parts = explode ('\\' , $ name );
200- $ shortName = array_pop ($ parts );
201-
202- if (!$ shortName ) {
203- throw new StoreException (sprintf ('%s is not a valid classname ' , $ name ));
204- }
205-
206- $ string = (string )preg_replace ('/(?<=[a-z])([A-Z])/ ' , '_$1 ' , $ shortName );
207-
208- if (!$ string ) {
209- throw new StoreException (sprintf ('%s is not a valid table name ' , $ string ));
210- }
211-
212- return strtolower ($ string );
213- }
214-
215188 /**
216189 * @param array<string, mixed> $result
217190 *
218191 * @return array<string, mixed>
219192 */
220- public static function normalizeResult (AbstractPlatform $ platform , array $ result ): array
193+ private static function normalizeResult (AbstractPlatform $ platform , array $ result ): array
221194 {
222195 if (!$ result ['recordedOn ' ]) {
223196 return $ result ;
@@ -236,4 +209,16 @@ public static function normalizeResult(AbstractPlatform $platform, array $result
236209
237210 return $ result ;
238211 }
212+
213+ /**
214+ * @param class-string<AggregateRoot> $aggregate
215+ */
216+ private function tableName (string $ aggregate ): string
217+ {
218+ if (!array_key_exists ($ aggregate , $ this ->aggregates )) {
219+ throw new AggregateNotDefined ($ aggregate );
220+ }
221+
222+ return $ this ->aggregates [$ aggregate ];
223+ }
239224}
0 commit comments