diff --git a/README.md b/README.md index 53721ba0417dbf2c3ed616f3b14717c2496f8034..8619251b59d0278d39f06e82fa0fd5ee9260f67e 100644 --- a/README.md +++ b/README.md @@ -292,16 +292,16 @@ $changeSet = $table->new( ); ``` -The method returns a change set which you can further modify, and eventually save: +The method returns a change set which you can further modify, and eventually insert: ```php $changeSet->modifyText('Post text'); -$table->save($changeSet); +$table->insert($changeSet); ``` ### Update -To update a record in the table, first you need to get an instance of change set for the specific record. You can get one for any given primary key or row: +To update a record in the table, you need to get an instance of change set for the specific record. You can get one for any given primary key or row: ```php $changeSet = $table->edit(ArticlePrimaryKey::from($articleId)); @@ -309,11 +309,20 @@ $changeSet = $table->edit(ArticlePrimaryKey::from($articleId)); $changeSet = $table->edit($articleRow); ``` -Then you can add modifications to the change set and finally save it: +You can use named parameters to provide the values to update right within the method call: + +```php +$changeSet = $table->edit( + $articleRow, + deletedAt: \Brick\DateTime\Instant::now(), +); +``` + +As before, you can also add modifications to the change set afterward, and finally save it: ```php $changeSet->modifyDeletedAt(\Brick\DateTime\Instant::now()); -$table->save($changeSet); +$table->update($changeSet); ``` ### Delete diff --git a/composer.json b/composer.json index e09500511f7ce8b5a501feabbbacdb528b7bf9cf..6f141889c4538810117757663bfffbeed3b08d89 100644 --- a/composer.json +++ b/composer.json @@ -53,6 +53,7 @@ "src/exceptions.php" ], "files": [ + "src/constants.php", "src/functions.php", "src/Conditions/functions.php", "src/Types/functions.php" diff --git a/src/DefaultOrExistingValue.php b/src/DefaultOrExistingValue.php new file mode 100644 index 0000000000000000000000000000000000000000..fe4bf0e113b0769c93018305299533a06c2862d8 --- /dev/null +++ b/src/DefaultOrExistingValue.php @@ -0,0 +1,12 @@ +<?php + +declare(strict_types=1); + +namespace Grifart\Tables; + +/** + * @internal + */ +final class DefaultOrExistingValue +{ +} diff --git a/src/Scaffolding/TableImplementation.php b/src/Scaffolding/TableImplementation.php index b91e25326527f6818fd218f7dddd94581cfd1f70..cebcfa562b809e2edb0d5f535ded03434186d8cc 100644 --- a/src/Scaffolding/TableImplementation.php +++ b/src/Scaffolding/TableImplementation.php @@ -8,14 +8,18 @@ use Grifart\ClassScaffolder\Capabilities\Capability; use Grifart\ClassScaffolder\ClassInNamespace; use Grifart\ClassScaffolder\Definition\ClassDefinition; use Grifart\ClassScaffolder\Definition\Types\Type as PhpType; +use Grifart\ClassScaffolder\Definition\Types\UnionType; use Grifart\Tables\CaseConversion; use Grifart\Tables\Column; use Grifart\Tables\ColumnMetadata; use Grifart\Tables\ColumnNotFound; use Grifart\Tables\Conditions\Condition; +use Grifart\Tables\DefaultOrExistingValue; use Grifart\Tables\Expression; +use Grifart\Tables\GivenSearchCriteriaHaveNotMatchedAnyRows; use Grifart\Tables\RowNotFound; use Grifart\Tables\OrderBy\OrderBy; +use Grifart\Tables\RowWithGivenPrimaryKeyAlreadyExists; use Grifart\Tables\Table; use Grifart\Tables\TableManager; use Grifart\Tables\TooManyRowsFound; @@ -23,6 +27,9 @@ use Grifart\Tables\Type; use Grifart\Tables\TypeResolver; use Nette\PhpGenerator as Code; use Nette\Utils\Paginator; +use function Functional\map; +use function Grifart\ClassScaffolder\Definition\Types\resolve; +use function usort; final class TableImplementation implements Capability { @@ -63,7 +70,7 @@ final class TableImplementation implements Capability // column info: $namespace->addUse(ColumnMetadata::class); - $columnsDefinitions = []; // name => PhpLiteral + $columnsDefinitions = []; // name => Literal $columnsArrayTemplate = []; foreach($this->columnMetadata as $column) { $columnsArrayTemplate[] = "\t? => new ColumnMetadata(?, ?, ?, ?)"; @@ -96,7 +103,7 @@ final class TableImplementation implements Capability '$row = $this->tableManager->find($this, $primaryKey);' . "\n" . '\assert($row instanceof ? || $row === NULL);' . "\n" . 'return $row;', - [new Code\PhpLiteral($namespace->simplifyName($this->rowClass))] + [new Code\Literal($namespace->simplifyName($this->rowClass))] ); $namespace->addUse(RowNotFound::class); @@ -129,7 +136,7 @@ final class TableImplementation implements Capability "/** @var ?[] \$result */\n" . "\$result = \$this->tableManager->getAll(\$this, \$orderBy, \$paginator);\n" . 'return $result;', - [new Code\PhpLiteral($namespace->simplifyName($this->rowClass))], + [new Code\Literal($namespace->simplifyName($this->rowClass))], ); $namespace->addUse(Condition::class); @@ -145,7 +152,7 @@ final class TableImplementation implements Capability ->addComment('@param array<OrderBy|Expression<mixed>> $orderBy') ->addComment('@return ' . $namespace->simplifyName($this->rowClass) . '[]') ->setReturnType('array') - ->addBody('/** @var ?[] $result */', [new Code\PhpLiteral($namespace->simplifyName($this->rowClass))]) + ->addBody('/** @var ?[] $result */', [new Code\Literal($namespace->simplifyName($this->rowClass))]) ->addBody('$result = $this->tableManager->findBy($this, $conditions, $orderBy, $paginator);') ->addBody('return $result;'); @@ -165,65 +172,117 @@ final class TableImplementation implements Capability ->addBody('return $result[0];'); - $classType->addMethod('newEmpty') - ->setReturnType($this->modificationClass) - ->setBody( - 'return ?::new();', - [new Code\PhpLiteral($namespace->simplifyName($this->modificationClass))], - ); - $newMethod = $classType->addMethod('new') ->setReturnType($this->modificationClass) ->addBody( '$modifications = ?::new();', - [new Code\PhpLiteral($namespace->simplifyName($this->modificationClass))], + [new Code\Literal($namespace->simplifyName($this->modificationClass))], ); - foreach ($this->columnMetadata as $columnMetadata) { - if ( ! $columnMetadata->hasDefaultValue()) { + $editMethod = $classType->addMethod('edit') + ->setReturnType($this->modificationClass) + ->setParameters([ + (new Code\Parameter('rowOrKey'))->setType($this->rowClass . '|' . $this->primaryKeyClass), + ]) + ->addBody('$primaryKey = $rowOrKey instanceof ? \? $rowOrKey : ?::fromRow($rowOrKey);', [ + new Code\Literal($namespace->simplifyName($this->primaryKeyClass)), + new Code\Literal($namespace->simplifyName($this->primaryKeyClass)), + ]) + ->addBody('$modifications = ?::update($primaryKey);', [new Code\Literal($namespace->simplifyName($this->modificationClass))]); + + $columns = $this->columnMetadata; + usort($columns, fn (ColumnMetadata $a, ColumnMetadata $b) => $a->hasDefaultValue() <=> $b->hasDefaultValue()); + + foreach ([$newMethod, $editMethod] as $method) { + foreach ($columns as $columnMetadata) { + $isEditMethod = $method === $editMethod; + $hasDefaultValue = $columnMetadata->hasDefaultValue() || $isEditMethod; + $fieldName = $columnMetadata->getName(); $fieldType = $this->columnPhpTypes[$fieldName]; + $isNullable = $fieldType->isNullable(); + + if ($hasDefaultValue) { + $namespace->addUse(DefaultOrExistingValue::class); + $fieldType = new UnionType($fieldType, resolve(DefaultOrExistingValue::class)); + } - $newMethod->addParameter($fieldName) + + $parameter = $method->addParameter($fieldName) ->setType($fieldType->getTypeHint()) - ->setNullable($fieldType->isNullable()); + ->setNullable($isNullable); + + if ($hasDefaultValue) { + $parameter->setDefaultValue( + new Code\Literal( + $namespace->simplifyName( + $isEditMethod ? 'Grifart\Tables\Unchanged' : 'Grifart\Tables\DefaultValue', + $namespace::NameConstant, + ), + ), + ); + } if ($fieldType->requiresDocComment()) { - $newMethod->addComment(\sprintf( + $method->addComment(\sprintf( '@param %s $%s', $fieldType->getDocCommentType($namespace), $fieldName, )); } - $newMethod->addBody( - '$modifications->modify' . \ucfirst($fieldName) . '(?);', - [new Code\PhpLiteral('$' . $fieldName)], + if ($hasDefaultValue) { + $method->addBody( + 'if (!? instanceof ?) {', + [new Code\Literal('$' . $fieldName), new Code\Literal($namespace->simplifyName(DefaultOrExistingValue::class))], + ); + } + + $method->addBody( + ($hasDefaultValue ? "\t" : '') . '$modifications->modify' . \ucfirst($fieldName) . '(?);', + [new Code\Literal('$' . $fieldName)], ); + + if ($hasDefaultValue) { + $method->addBody('}'); + } } - } - $newMethod->addBody('return $modifications;'); + $method->addBody('return $modifications;'); + } + $namespace->addUse(RowWithGivenPrimaryKeyAlreadyExists::class); + $namespace->addUse(GivenSearchCriteriaHaveNotMatchedAnyRows::class); - $classType->addMethod('edit') - ->setReturnType($this->modificationClass) + $classType->addMethod('save') + ->addComment('@throws RowWithGivenPrimaryKeyAlreadyExists') + ->addComment('@throws GivenSearchCriteriaHaveNotMatchedAnyRows') + ->setReturnType('void') ->setParameters([ - (new Code\Parameter('rowOrKey'))->setType($this->rowClass . '|' . $this->primaryKeyClass), + (new Code\Parameter('changes'))->setType($this->modificationClass) ]) - ->addBody('$primaryKey = $rowOrKey instanceof ? \? $rowOrKey : ?::fromRow($rowOrKey);', [ - new Code\PhpLiteral($namespace->simplifyName($this->primaryKeyClass)), - new Code\PhpLiteral($namespace->simplifyName($this->primaryKeyClass)), + ->setBody( + '$this->tableManager->save($this, $changes);' + ); + + $classType->addMethod('insert') + ->addComment('@throws RowWithGivenPrimaryKeyAlreadyExists') + ->setReturnType('void') + ->setParameters([ + (new Code\Parameter('changes'))->setType($this->modificationClass), ]) - ->addBody('return ?::update($primaryKey);', [new Code\PhpLiteral($namespace->simplifyName($this->modificationClass))]); + ->setBody( + '$this->tableManager->insert($this, $changes);', + ); - $classType->addMethod('save') + $classType->addMethod('update') + ->addComment('@throws GivenSearchCriteriaHaveNotMatchedAnyRows') ->setReturnType('void') ->setParameters([ - (new Code\Parameter('changes'))->setType($this->modificationClass) + (new Code\Parameter('changes'))->setType($this->modificationClass), ]) ->setBody( - '$this->tableManager->save($this, $changes);' + '$this->tableManager->update($this, $changes);', ); $classType->addMethod('delete') @@ -232,8 +291,8 @@ final class TableImplementation implements Capability (new Code\Parameter('rowOrKey'))->setType($this->rowClass . '|' . $this->primaryKeyClass) ]) ->addBody('$primaryKey = $rowOrKey instanceof ? \? $rowOrKey : ?::fromRow($rowOrKey);', [ - new Code\PhpLiteral($namespace->simplifyName($this->primaryKeyClass)), - new Code\PhpLiteral($namespace->simplifyName($this->primaryKeyClass)), + new Code\Literal($namespace->simplifyName($this->primaryKeyClass)), + new Code\Literal($namespace->simplifyName($this->primaryKeyClass)), ]) ->addBody('$this->tableManager->delete($this, $primaryKey);'); @@ -273,7 +332,7 @@ final class TableImplementation implements Capability $constructor->addBody(\sprintf('/** @var Column<self, %s> $%s */', $docCommentType, $columnName)); $constructor->addBody('$? = Column::from($this, self::getDatabaseColumns()[?], $this->typeResolver);', [$columnName, $columnName]); - $columnInitializers[$columnName] = new Code\PhpLiteral('$?', [$columnName]); + $columnInitializers[$columnName] = new Code\Literal('$?', [$columnName]); } $columnsProperty->addComment(\sprintf('@var array{%s}', \implode(', ', $columnsShape))); @@ -297,7 +356,7 @@ final class TableImplementation implements Capability private function implementConfigMethodReturningClass(Code\PhpNamespace $namespace, Code\ClassType $classType, string $name, string $class): void { $namespace->addUse($class); - $this->implementConfigMethod($classType, $name, new Code\PhpLiteral($namespace->simplifyName($class) . '::class')); + $this->implementConfigMethod($classType, $name, new Code\Literal($namespace->simplifyName($class) . '::class')); } private function implementConfigMethod(Code\ClassType $classType, string $name, mixed $value): void diff --git a/src/Scaffolding/TablesDefinitions.php b/src/Scaffolding/TablesDefinitions.php index 652051ace024fb2c8b1c229995ef3d6d8839bb93..06f31a212b1aa0a33d5911828a339693b056640d 100644 --- a/src/Scaffolding/TablesDefinitions.php +++ b/src/Scaffolding/TablesDefinitions.php @@ -11,6 +11,7 @@ use Grifart\Tables\Database\Identifier; use Grifart\Tables\Row; use Grifart\Tables\Type; use Grifart\Tables\TypeResolver; +use function array_keys; use function Functional\map; use function Grifart\ClassScaffolder\Capabilities\constructorWithPromotedProperties; use function Grifart\ClassScaffolder\Capabilities\getters; diff --git a/src/TableManager.php b/src/TableManager.php index 75bd5ea5d3d0be8e3e25ff639ab0d9061214eadf..0915cf0e9f46c01fc1d36dfbe0da942c15bc16ad 100644 --- a/src/TableManager.php +++ b/src/TableManager.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Grifart\Tables; use Dibi\Connection; +use Dibi\UniqueConstraintViolationException; use Grifart\Tables\Conditions\Composite; use Grifart\Tables\Conditions\Condition; use Grifart\Tables\OrderBy\OrderBy; @@ -26,18 +27,25 @@ final class TableManager * @template TableType of Table * @param TableType $table * @param Modifications<TableType> $changes + * @throws RowWithGivenPrimaryKeyAlreadyExists */ public function insert(Table $table, Modifications $changes): void { \assert($changes->getPrimaryKey() === NULL); - $this->connection->query( - 'INSERT', - 'INTO %n.%n', $table::getSchema(), $table::getTableName(), - map( - $changes->getModifications(), - static fn(mixed $value, string $columnName) => $value !== null ? $table->getTypeOf($columnName)->toDatabase($value) : null, - ), - ); + + try { + $this->connection->query( + 'INSERT', + 'INTO %n.%n', $table::getSchema(), $table::getTableName(), + map( + $changes->getModifications(), + static fn(mixed $value, string $columnName) => $value !== null ? $table->getTypeOf($columnName)->toDatabase($value) : null, + ), + ); + } catch (UniqueConstraintViolationException $e) { + throw new RowWithGivenPrimaryKeyAlreadyExists(previous: $e); + } + \assert($this->connection->getAffectedRows() === 1); } @@ -177,6 +185,7 @@ final class TableManager * @template TableType of Table * @param TableType $table * @param Modifications<TableType> $changes + * @throws RowWithGivenPrimaryKeyAlreadyExists * @throws GivenSearchCriteriaHaveNotMatchedAnyRows */ public function save(Table $table, Modifications $changes): void { diff --git a/src/constants.php b/src/constants.php new file mode 100644 index 0000000000000000000000000000000000000000..93fb528fc90e99a29139dc64402d36e7f35be52b --- /dev/null +++ b/src/constants.php @@ -0,0 +1,8 @@ +<?php + +declare(strict_types=1); + +namespace Grifart\Tables; + +const DefaultValue = new DefaultOrExistingValue(); +const Unchanged = new DefaultOrExistingValue(); diff --git a/src/exceptions.php b/src/exceptions.php index b209bea166059deed76cce8d4aa037e849cf68c0..696803a932472af5b25cc2f92faaaf0e3ed6a31b 100644 --- a/src/exceptions.php +++ b/src/exceptions.php @@ -66,6 +66,6 @@ final class ColumnNotFound extends UsageException { } final class GivenSearchCriteriaHaveNotMatchedAnyRows extends RuntimeException {} - +final class RowWithGivenPrimaryKeyAlreadyExists extends RuntimeException {} final class RowNotFound extends RuntimeException {} final class TooManyRowsFound extends UsageException {} diff --git a/tests/CompositeTypeIntegrationTest.php b/tests/CompositeTypeIntegrationTest.php index 2939933c92633c63549057ffc3783697e239feda..c8c5a59e519a11d84cb147e63ea2dffaeb149cf8 100644 --- a/tests/CompositeTypeIntegrationTest.php +++ b/tests/CompositeTypeIntegrationTest.php @@ -20,8 +20,9 @@ $table = new PackagesTable( TestFixtures::createTypeResolver($connection), ); -$package = $table->new('grifart/tables', [0, 8, 0], [new Version(0, 7, 0)]); -$table->save($package); +$table->insert( + $table->new('grifart/tables', [0, 8, 0], [new Version(0, 7, 0)]), +); $byVersion = $table->findBy([ $table->version()->is([0, 8, 0]), diff --git a/tests/Fixtures/PackagesTable.php b/tests/Fixtures/PackagesTable.php index a0db34901e80a7acdc9c7121a61dce92e31e4fbc..bc570ff8a946660e37adccb004db2d7c55ab9108 100644 --- a/tests/Fixtures/PackagesTable.php +++ b/tests/Fixtures/PackagesTable.php @@ -12,9 +12,12 @@ use Grifart\Tables\Column; use Grifart\Tables\ColumnMetadata; use Grifart\Tables\ColumnNotFound; use Grifart\Tables\Conditions\Condition; +use Grifart\Tables\DefaultOrExistingValue; use Grifart\Tables\Expression; +use Grifart\Tables\GivenSearchCriteriaHaveNotMatchedAnyRows; use Grifart\Tables\OrderBy\OrderBy; use Grifart\Tables\RowNotFound; +use Grifart\Tables\RowWithGivenPrimaryKeyAlreadyExists; use Grifart\Tables\Table; use Grifart\Tables\TableManager; use Grifart\Tables\TooManyRowsFound; @@ -135,12 +138,6 @@ final class PackagesTable implements Table } - public function newEmpty(): PackageModifications - { - return PackageModifications::new(); - } - - /** * @param array{int, int, int} $version * @param Version[] $previousVersions @@ -155,19 +152,60 @@ final class PackagesTable implements Table } - public function edit(PackageRow|PackagePrimaryKey $rowOrKey): PackageModifications + /** + * @param array{int, int, int}|DefaultOrExistingValue $version + * @param Version[]|DefaultOrExistingValue $previousVersions + */ + public function edit( + PackageRow|PackagePrimaryKey $rowOrKey, + string|DefaultOrExistingValue $name = \Grifart\Tables\Unchanged, + array|DefaultOrExistingValue $version = \Grifart\Tables\Unchanged, + array|DefaultOrExistingValue $previousVersions = \Grifart\Tables\Unchanged, + ): PackageModifications { $primaryKey = $rowOrKey instanceof PackagePrimaryKey ? $rowOrKey : PackagePrimaryKey::fromRow($rowOrKey); - return PackageModifications::update($primaryKey); + $modifications = PackageModifications::update($primaryKey); + if (!$name instanceof DefaultOrExistingValue) { + $modifications->modifyName($name); + } + if (!$version instanceof DefaultOrExistingValue) { + $modifications->modifyVersion($version); + } + if (!$previousVersions instanceof DefaultOrExistingValue) { + $modifications->modifyPreviousVersions($previousVersions); + } + return $modifications; } + /** + * @throws RowWithGivenPrimaryKeyAlreadyExists + * @throws GivenSearchCriteriaHaveNotMatchedAnyRows + */ public function save(PackageModifications $changes): void { $this->tableManager->save($this, $changes); } + /** + * @throws RowWithGivenPrimaryKeyAlreadyExists + */ + public function insert(PackageModifications $changes): void + { + $this->tableManager->insert($this, $changes); + } + + + /** + * @throws GivenSearchCriteriaHaveNotMatchedAnyRows + */ + public function update(PackageModifications $changes): void + { + $this->tableManager->update($this, $changes); + } + + public function delete(PackageRow|PackagePrimaryKey $rowOrKey): void { $primaryKey = $rowOrKey instanceof PackagePrimaryKey ? $rowOrKey : PackagePrimaryKey::fromRow($rowOrKey); diff --git a/tests/Fixtures/TestsTable.php b/tests/Fixtures/TestsTable.php index 57f773a4f3ab6205a988126f4fd435a086fac761..5e00e4aa4937cdb1f054e2295881940bd0da0778 100644 --- a/tests/Fixtures/TestsTable.php +++ b/tests/Fixtures/TestsTable.php @@ -12,9 +12,12 @@ use Grifart\Tables\Column; use Grifart\Tables\ColumnMetadata; use Grifart\Tables\ColumnNotFound; use Grifart\Tables\Conditions\Condition; +use Grifart\Tables\DefaultOrExistingValue; use Grifart\Tables\Expression; +use Grifart\Tables\GivenSearchCriteriaHaveNotMatchedAnyRows; use Grifart\Tables\OrderBy\OrderBy; use Grifart\Tables\RowNotFound; +use Grifart\Tables\RowWithGivenPrimaryKeyAlreadyExists; use Grifart\Tables\Table; use Grifart\Tables\TableManager; use Grifart\Tables\TooManyRowsFound; @@ -135,34 +138,72 @@ final class TestsTable implements Table } - public function newEmpty(): TestModifications - { - return TestModifications::new(); - } - - - public function new(Uuid $id, int $score): TestModifications + public function new( + Uuid $id, + int $score, + string|DefaultOrExistingValue|null $details = \Grifart\Tables\DefaultValue, + ): TestModifications { $modifications = TestModifications::new(); $modifications->modifyId($id); $modifications->modifyScore($score); + if (!$details instanceof DefaultOrExistingValue) { + $modifications->modifyDetails($details); + } return $modifications; } - public function edit(TestRow|TestPrimaryKey $rowOrKey): TestModifications + public function edit( + TestRow|TestPrimaryKey $rowOrKey, + Uuid|DefaultOrExistingValue $id = \Grifart\Tables\Unchanged, + int|DefaultOrExistingValue $score = \Grifart\Tables\Unchanged, + string|DefaultOrExistingValue|null $details = \Grifart\Tables\Unchanged, + ): TestModifications { $primaryKey = $rowOrKey instanceof TestPrimaryKey ? $rowOrKey : TestPrimaryKey::fromRow($rowOrKey); - return TestModifications::update($primaryKey); + $modifications = TestModifications::update($primaryKey); + if (!$id instanceof DefaultOrExistingValue) { + $modifications->modifyId($id); + } + if (!$score instanceof DefaultOrExistingValue) { + $modifications->modifyScore($score); + } + if (!$details instanceof DefaultOrExistingValue) { + $modifications->modifyDetails($details); + } + return $modifications; } + /** + * @throws RowWithGivenPrimaryKeyAlreadyExists + * @throws GivenSearchCriteriaHaveNotMatchedAnyRows + */ public function save(TestModifications $changes): void { $this->tableManager->save($this, $changes); } + /** + * @throws RowWithGivenPrimaryKeyAlreadyExists + */ + public function insert(TestModifications $changes): void + { + $this->tableManager->insert($this, $changes); + } + + + /** + * @throws GivenSearchCriteriaHaveNotMatchedAnyRows + */ + public function update(TestModifications $changes): void + { + $this->tableManager->update($this, $changes); + } + + public function delete(TestRow|TestPrimaryKey $rowOrKey): void { $primaryKey = $rowOrKey instanceof TestPrimaryKey ? $rowOrKey : TestPrimaryKey::fromRow($rowOrKey); diff --git a/tests/TableTest.php b/tests/TableTest.php index edfccfa0d1f0f648d7b7887dc230a2cac4a047ec..e4db509f51999f83d788b406c04fd97483286343 100644 --- a/tests/TableTest.php +++ b/tests/TableTest.php @@ -37,9 +37,9 @@ Assert::count(2, $all); $all2 = $table->findBy([]); Assert::equal($all, $all2); -$changeSet = $table->new(new Uuid('9493decd-4b9c-45d6-9960-0c94dc9be353'), -5); -$changeSet->modifyDetails('👎'); -$table->save($changeSet); +$table->insert( + $table->new(new Uuid('9493decd-4b9c-45d6-9960-0c94dc9be353'), -5, details: '👎') +); $all = $table->getAll(); Assert::count(3, $all); @@ -115,12 +115,14 @@ Assert::same(0, $nullDetails[0]->getScore()); $unique = $table->getBy($table->score()->is(42)); Assert::same(42, $unique->getScore()); -$zero = $table->get(TestPrimaryKey::from(new Uuid('2bec3f23-a210-455c-b907-bb69a99d07b2'))); -$zeroChangeSet = $table->edit($zero); -$zeroChangeSet->modifyDetails('nada'); -$table->save($zeroChangeSet); +$table->update($table->edit( + TestPrimaryKey::from(new Uuid('2bec3f23-a210-455c-b907-bb69a99d07b2')), + details: 'nada', +)); $updatedZero = $table->get(TestPrimaryKey::from(new Uuid('2bec3f23-a210-455c-b907-bb69a99d07b2'))); + +Assert::same(0, $updatedZero->getScore()); Assert::same('nada', $updatedZero->getDetails()); $table->delete(TestPrimaryKey::fromRow($updatedZero));