diff --git a/src/core/etl/src/Flow/ETL/Row/Entry.php b/src/core/etl/src/Flow/ETL/Row/Entry.php index 04d97c48b..1ec8348f6 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry.php @@ -39,4 +39,9 @@ public function type() : Type; * @return TValue */ public function value(); + + /** + * @param TValue $value + */ + public function withValue(mixed $value) : self; } diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/ArrayEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/ArrayEntry.php index 4c844d11b..aa57920a7 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/ArrayEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/ArrayEntry.php @@ -111,4 +111,9 @@ public function value() : ?array { return $this->value; } + + public function withValue(mixed $value) : Entry + { + return new self($this->name, $value); + } } diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/BooleanEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/BooleanEntry.php index fa0039e64..d8ea6e24e 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/BooleanEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/BooleanEntry.php @@ -92,4 +92,9 @@ public function value() : ?bool { return $this->value; } + + public function withValue(mixed $value) : Entry + { + return new self($this->name, $value); + } } diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/DateTimeEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/DateTimeEntry.php index 1f26c9b80..6e6f8102c 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/DateTimeEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/DateTimeEntry.php @@ -105,4 +105,9 @@ public function value() : ?\DateTimeInterface { return $this->value; } + + public function withValue(mixed $value) : Entry + { + return new self($this->name, $value); + } } diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/EnumEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/EnumEntry.php index 45d280127..dd54e7868 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/EnumEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/EnumEntry.php @@ -90,4 +90,9 @@ public function value() : ?\UnitEnum { return $this->value; } + + public function withValue(mixed $value) : Entry + { + return new self($this->name, $value); + } } diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/FloatEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/FloatEntry.php index 8c049acb1..bf4b84d70 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/FloatEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/FloatEntry.php @@ -118,4 +118,9 @@ public function value() : ?float { return $this->value; } + + public function withValue(mixed $value) : Entry + { + return new self($this->name, $value); + } } diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/IntegerEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/IntegerEntry.php index 9050b92f2..ccd1d8164 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/IntegerEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/IntegerEntry.php @@ -92,4 +92,9 @@ public function value() : ?int { return $this->value; } + + public function withValue(mixed $value) : Entry + { + return new self($this->name, $value); + } } diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/JsonEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/JsonEntry.php index 719e2323b..3361d318b 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/JsonEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/JsonEntry.php @@ -162,4 +162,9 @@ public function value() : ?string return \json_encode($this->value, JSON_THROW_ON_ERROR); } + + public function withValue(mixed $value) : Entry + { + return new self($this->name, $value); + } } diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/ListEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/ListEntry.php index 9433da4d0..a73f8b6d4 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/ListEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/ListEntry.php @@ -120,4 +120,9 @@ public function value() : ?array { return $this->value; } + + public function withValue(mixed $value) : Entry + { + return new self($this->name, $value, $this->type); + } } diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/MapEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/MapEntry.php index 4284e689d..f0aac3125 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/MapEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/MapEntry.php @@ -123,4 +123,9 @@ public function value() : ?array { return $this->value; } + + public function withValue(mixed $value) : Entry + { + return new self($this->name, $value, $this->type); + } } diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/ObjectEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/ObjectEntry.php index 4ffe5e6b0..5b51b17f1 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/ObjectEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/ObjectEntry.php @@ -95,4 +95,9 @@ public function value() : ?object { return $this->value; } + + public function withValue(mixed $value) : Entry + { + return new self($this->name, $value); + } } diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/StringEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/StringEntry.php index 6422ba339..25ee2b8de 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/StringEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/StringEntry.php @@ -110,4 +110,9 @@ public function value() : ?string { return $this->value; } + + public function withValue(mixed $value) : Entry + { + return new self($this->name, $value); + } } diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/StructureEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/StructureEntry.php index f3ce66043..71f1e56fe 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/StructureEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/StructureEntry.php @@ -117,4 +117,9 @@ public function value() : ?array { return $this->value; } + + public function withValue(mixed $value) : Entry + { + return new self($this->name, $value, $this->type); + } } diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/UuidEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/UuidEntry.php index 54389efb8..a26066104 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/UuidEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/UuidEntry.php @@ -117,4 +117,9 @@ public function value() : ?Uuid { return $this->value; } + + public function withValue(mixed $value) : Entry + { + return new self($this->name, $value); + } } diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/XMLElementEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/XMLElementEntry.php index 9b8e53650..24577ffc2 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/XMLElementEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/XMLElementEntry.php @@ -145,4 +145,9 @@ public function value() : ?\DOMElement { return $this->value; } + + public function withValue(mixed $value) : Entry + { + return new self($this->name, $value); + } } diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/XMLEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/XMLEntry.php index 2f9e6f7b9..4b667d82e 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/XMLEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/XMLEntry.php @@ -146,4 +146,9 @@ public function value() : ?\DOMDocument { return $this->value; } + + public function withValue(mixed $value) : Entry + { + return new self($this->name, $value); + } } diff --git a/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/MapTest.php b/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/MapTest.php new file mode 100644 index 000000000..ea6209fa9 --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/MapTest.php @@ -0,0 +1,73 @@ +read( + from_array( + [ + ['id' => 1, 'tags' => ['A', 'B']], + ['id' => 2, 'tags' => null], + ['id' => 3, 'tags' => ['D']], + ] + )->withSchema( + schema( + int_schema('id'), + list_schema('tags', type_list(type_string(), true)) + ) + ) + ) + ->map( + fn (Row $row) : Row => $row->map(fn (Row\Entry $e) => $e->value() === null && $e->is('tags') ? $e->withValue([]) : $e) + ) + ->fetch(); + + self::assertEquals( + [ + ['id' => 1, 'tags' => ['A', 'B']], + ['id' => 2, 'tags' => []], + ['id' => 3, 'tags' => ['D']], + ], + $rows->toArray() + ); + } + + public function test_using_map_to_replace_nulls() : void + { + $rows = df() + ->read(from_array([ + ['id' => 1, 'name' => 'John'], + ['id' => 2, 'name' => null], + ['id' => 3, 'name' => 'Doe'], + ])) + ->map( + fn (Row $row) : Row => $row->map(fn (Row\Entry $e) => $e->value() === null && $e->is('name') ? $e->withValue('N/A') : $e) + ) + ->fetch(); + + self::assertEquals( + [ + ['id' => 1, 'name' => 'John'], + ['id' => 2, 'name' => 'N/A'], + ['id' => 3, 'name' => 'Doe'], + ], + $rows->toArray() + ); + } +}