private function createAggregate(
        Identity $identity,
        object $entity,
        Query $query
    ): Query {
        $meta = ($this->metadata)(\get_class($entity));
        $data = ($this->extract)($entity);
        $varName = $this->name->sprintf(\md5($identity->value()));

        $query = $query->create(
            (string) $varName,
            $meta->labels()->toPrimitive()
        );
        $paramKey = $varName->append('_props');
        $properties = $this->buildProperties(
            $meta->properties(),
            $paramKey
        );
        $keysToKeep = $data->keys()->intersect($properties->keys());

        $query = $query
            ->withProperty(
                $meta->identity()->property(),
                (string) $paramKey
                    ->prepend('{')
                    ->append('}.')
                    ->append($meta->identity()->property())
            )
            ->withProperties($properties->reduce(
                [],
                static function(array $carry, string $property, string $cypher): array {
                    $carry[$property] = $cypher;

                    return $carry;
                }
            ))
            ->withParameter(
                (string) $paramKey,
                $data
                    ->filter(static function(string $key) use ($keysToKeep): bool {
                        return $keysToKeep->contains($key);
                    })
                    ->put(
                        $meta->identity()->property(),
                        $identity->value()
                    )
                    ->reduce(
                        [],
                        static function(array $carry, string $key, $value): array {
                            $carry[$key] = $value;

                            return $carry;
                        }
                    )
            );

        $query = $meta
            ->children()
            ->reduce(
                $query,
                function(Query $carry, string $property, Child $child) use ($varName, $data): Query {
                    return $this->createAggregateChild(
                        $child,
                        $varName,
                        $data->get($property),
                        $carry
                    );
                }
            );
        $this->variables = $this->variables->add((string) $varName);

        return $query;
    }
private function createAggregate(
        Identity $identity,
        object $entity,
        Query $query
    ): Query {
        $meta = ($this->metadata)(\get_class($entity));
        $data = ($this->extract)($entity);
        $varName = $this->name->sprintf(\md5($identity->value()));

        $query = $query->create(
            (string) $varName,
            $meta->labels()->toPrimitive()
        );
        $paramKey = $varName->append('_props');
        $properties = $this->buildProperties(
            $meta->properties(),
            $paramKey
        );
        $keysToKeep = $data->keys()->intersect($properties->keys());

        $query = $query
            ->withProperty(
                $meta->identity()->property(),
                (string) $paramKey
                    ->prepend('{')
                    ->append('}.')
                    ->append($meta->identity()->property())
            )
            ->withProperties($properties->reduce(
                [],
                static function(array $carry, string $property, string $cypher): array {
                    $carry[$property] = $cypher;

                    return $carry;
                }
            ))
            ->withParameter(
                (string) $paramKey,
                $data
                    ->filter(static function(string $key) use ($keysToKeep): bool {
                        return $keysToKeep->contains($key);
                    })
                    ->put(
                        $meta->identity()->property(),
                        $identity->value()
                    )
                    ->reduce(
                        [],
                        static function(array $carry, string $key, $value): array {
                            $carry[$key] = $value;

                            return $carry;
                        }
                    )
            );

        $query = $meta
            ->children()
            ->reduce(
                $query,
                function(Query $carry, string $property, Child $child) use ($varName, $data): Query {
                    return $this->createAggregateChild(
                        $child,
                        $varName,
                        $data->get($property),
                        $carry
                    );
                }
            );
        $this->variables = $this->variables->add((string) $varName);

        return $query;
    }
private function createAggregate ( Identity $ identity , object $ entity , Query $ query ) : Query { $ meta = ( $ this -> metadata ) ( \ get_class ( $ entity ) ) ; $ data = ( $ this -> extract ) ( $ entity ) ; $ varName = $ this -> name -> sprintf ( \ md5 ( $ identity -> value ( ) ) ) ; $ query = $ query -> create ( ( string ) $ varName , $ meta -> labels ( ) -> toPrimitive ( ) ) ; $ paramKey = $ varName -> append ( '_props' ) ; $ properties = $ this -> buildProperties ( $ meta -> properties ( ) , $ paramKey ) ; $ keysToKeep = $ data -> keys ( ) -> intersect ( $ properties -> keys ( ) ) ; $ query = $ query -> withProperty ( $ meta -> identity ( ) -> property ( ) , ( string ) $ paramKey -> prepend ( '{' ) -> append ( '}.' ) -> append ( $ meta -> identity ( ) -> property ( ) ) ) -> withProperties ( $ properties -> reduce ( [ ] , static function ( array $ carry , string $ property , string $ cypher ) : array { $ carry [ $ property ] = $ cypher ; return $ carry ; } ) ) -> withParameter ( ( string ) $ paramKey , $ data -> filter ( static function ( string $ key ) use ( $ keysToKeep ) : bool { return $ keysToKeep -> contains ( $ key ) ; } ) -> put ( $ meta -> identity ( ) -> property ( ) , $ identity -> value ( ) ) -> reduce ( [ ] , static function ( array $ carry , string $ key , $ value ) : array { $ carry [ $ key ] = $ value ; return $ carry ; } ) ) ; $ query = $ meta -> children ( ) -> reduce ( $ query , function ( Query $ carry , string $ property , Child $ child ) use ( $ varName , $ data ) : Query { return $ this -> createAggregateChild ( $ child , $ varName , $ data -> get ( $ property ) , $ carry ) ; } ) ; $ this -> variables = $ this -> variables -> add ( ( string ) $ varName ) ; return $ query ; }
Add the cypher clause to create the node corresponding to the root of the aggregate
Add the cypher clause to create the node corresponding to the root of the aggregate