diff --git a/src/Schema/Blueprint.php b/src/Schema/Blueprint.php index fbc5ec3..5efc19b 100644 --- a/src/Schema/Blueprint.php +++ b/src/Schema/Blueprint.php @@ -2,10 +2,13 @@ namespace Dew\Tablestore\Schema; +use Protos\CapacityUnit; use Protos\DefinedColumnType; use Protos\PrimaryKeyType; +use Protos\ReservedThroughput; use Protos\SSEKeyType; use Protos\SSESpecification; +use Protos\TableOptions; class Blueprint { @@ -17,38 +20,14 @@ class Blueprint public array $columns = []; /** - * The throughput reservations for reading in capacity unit. - * - * @var non-negative-int|null - */ - public ?int $reservedRead = null; - - /** - * The throughput reservations for writing in capacity unit. - * - * @var non-negative-int|null - */ - public ?int $reservedWrite = null; - - /** - * The number of seconds that data can exist. - */ - public ?int $ttl = null; - - /** - * The maximum versions to persist. - */ - public ?int $maxVersions = null; - - /** - * The version offset limit. + * The throughput reservations. */ - public ?int $versionOffset = null; + public ?ReservedThroughput $throughput = null; /** - * Determine if the existing row can be updated. + * The table options. */ - public ?bool $allowsUpdate = null; + public ?TableOptions $options = null; /** * Determine if the data should be encrypted. @@ -123,7 +102,9 @@ public function binary(string $column): Keyable */ public function reserveRead(int $capacityUnit): self { - $this->reservedRead = $capacityUnit; + $this->throughput = (new ReservedThroughput)->setCapacityUnit( + $this->throughputCu()->setRead($capacityUnit) + ); return $this; } @@ -135,7 +116,9 @@ public function reserveRead(int $capacityUnit): self */ public function reserveWrite(int $capacityUnit): self { - $this->reservedWrite = $capacityUnit; + $this->throughput = (new ReservedThroughput)->setCapacityUnit( + $this->throughputCu()->setWrite($capacityUnit) + ); return $this; } @@ -145,7 +128,7 @@ public function reserveWrite(int $capacityUnit): self */ public function ttl(int $seconds): self { - $this->ttl = $seconds; + $this->options = $this->options()->setTimeToLive($seconds); return $this; } @@ -163,7 +146,7 @@ public function forever(): self */ public function maxVersions(int $versions): self { - $this->maxVersions = $versions; + $this->options = $this->options()->setMaxVersions($versions); return $this; } @@ -173,7 +156,8 @@ public function maxVersions(int $versions): self */ public function versionOffsetIn(int $seconds): self { - $this->versionOffset = $seconds; + $this->options = $this->options() + ->setDeviationCellVersionInSec($seconds); return $this; } @@ -183,7 +167,7 @@ public function versionOffsetIn(int $seconds): self */ public function allowUpdate(bool $allows = true): self { - $this->allowsUpdate = $allows; + $this->options = $this->options()->setAllowUpdate($allows); return $this; } @@ -226,4 +210,20 @@ public function withoutEncryption(): self return $this; } + + /** + * Get the current throughput reservations or create a new one. + */ + protected function throughputCu(): CapacityUnit + { + return $this->throughput?->getCapacityUnit() ?? new CapacityUnit; + } + + /** + * Get the current table options or create a new one. + */ + protected function options(): TableOptions + { + return $this->options ?? new TableOptions; + } } diff --git a/src/Schema/SchemaHandler.php b/src/Schema/SchemaHandler.php index 1e29a36..a1185ac 100644 --- a/src/Schema/SchemaHandler.php +++ b/src/Schema/SchemaHandler.php @@ -5,7 +5,6 @@ use Dew\Tablestore\Concerns\InteractsWithRequest; use Dew\Tablestore\Tablestore; use InvalidArgumentException; -use Protos\CapacityUnit; use Protos\CreateTableRequest; use Protos\CreateTableResponse; use Protos\DefinedColumnSchema; @@ -67,8 +66,14 @@ public function createTable(string $name, Blueprint $table): CreateTableResponse { $request = new CreateTableRequest; $request->setTableMeta($this->toTableMeta($table)->setTableName($name)); - $request->setReservedThroughput($this->toReservedThroughput($table)); - $request->setTableOptions($this->toTableOptions($table)); + + if ($table->throughput instanceof ReservedThroughput) { + $request->setReservedThroughput($table->throughput); + } + + if ($table->options instanceof TableOptions) { + $request->setTableOptions($table->options); + } if ($table->encryption instanceof SSESpecification) { $request->setSseSpec($table->encryption); @@ -87,12 +92,12 @@ public function updateTable(string $name, Blueprint $table): UpdateTableResponse { $request = (new UpdateTableRequest)->setTableName($name); - if ($this->hasReservedThroughputUpdate($table)) { - $request->setReservedThroughput($this->toReservedThroughput($table)); + if ($table->throughput instanceof ReservedThroughput) { + $request->setReservedThroughput($table->throughput); } - if ($this->hasTableOptionsUpdate($table)) { - $request->setTableOptions($this->toTableOptions($table)); + if ($table->options instanceof TableOptions) { + $request->setTableOptions($table->options); } $response = new UpdateTableResponse; @@ -137,67 +142,4 @@ public function toTableMeta(Blueprint $table): TableMeta ->setPrimaryKey($pks) ->setDefinedColumn($cols); } - - /** - * Create a throughput reservations Protobuf message. - */ - public function toReservedThroughput(Blueprint $table): ReservedThroughput - { - $cu = new CapacityUnit; - - if (is_int($table->reservedRead)) { - $cu->setRead($table->reservedRead); - } - - if (is_int($table->reservedWrite)) { - $cu->setWrite($table->reservedWrite); - } - - return (new ReservedThroughput)->setCapacityUnit($cu); - } - - /** - * Determine if the throughput reservations have been changed. - */ - public function hasReservedThroughputUpdate(Blueprint $table): bool - { - return $table->reservedRead !== null || $table->reservedWrite !== null; - } - - /** - * Create a table options Protobuf message. - */ - public function toTableOptions(Blueprint $table): TableOptions - { - $options = new TableOptions; - - if (is_int($table->ttl)) { - $options->setTimeToLive($table->ttl); - } - - if (is_int($table->maxVersions)) { - $options->setMaxVersions($table->maxVersions); - } - - if (is_int($table->versionOffset)) { - $options->setDeviationCellVersionInSec($table->versionOffset); - } - - if (is_bool($table->allowsUpdate)) { - $options->setAllowUpdate($table->allowsUpdate); - } - - return $options; - } - - /** - * Determine if the table options have been modified. - */ - public function hasTableOptionsUpdate(Blueprint $table): bool - { - return $table->ttl !== null - || $table->maxVersions !== null - || $table->versionOffset !== null - || $table->allowsUpdate !== null; - } } diff --git a/tests/BlueprintTest.php b/tests/BlueprintTest.php index cfa78a5..22cda01 100644 --- a/tests/BlueprintTest.php +++ b/tests/BlueprintTest.php @@ -1,8 +1,67 @@ reserveRead(2); + expect($table->throughput)->toBeInstanceOf(ReservedThroughput::class) + ->and($table->throughput->getCapacityUnit()->getRead())->toBe(2) + ->and($table->throughput->getCapacityUnit()->hasWrite())->toBeFalse(); +}); + +test('throughput reserves write', function () { + $table = (new Blueprint)->reserveWrite(1); + expect($table->throughput)->toBeInstanceOf(ReservedThroughput::class) + ->and($table->throughput->getCapacityUnit()->getWrite())->toBe(1) + ->and($table->throughput->getCapacityUnit()->hasRead())->toBeFalse(); +}); + +test('throughput reservations', function () { + $table = (new Blueprint)->reserveRead(2)->reserveWrite(1); + expect($table->throughput)->toBeInstanceOf(ReservedThroughput::class) + ->and($table->throughput->getCapacityUnit()->getRead())->toBe(2) + ->and($table->throughput->getCapacityUnit()->getWrite())->toBe(1); +}); + +test('table option configures time-to-live', function () { + $table = (new Blueprint)->ttl(86400); + expect($table->options)->toBeInstanceOf(TableOptions::class) + ->and($table->options->getTimeToLive())->toBe(86400); +}); + +test('table option configures data that is stored permanently', function () { + $table = (new Blueprint)->forever(); + expect($table->options)->toBeInstanceOf(TableOptions::class) + ->and($table->options->getTimeToLive())->toBe(-1); +}); + +test('table option defines max versions to persist', function () { + $table = (new Blueprint)->maxVersions(2); + expect($table->options)->toBeInstanceOf(TableOptions::class) + ->and($table->options->getMaxVersions())->toBe(2); +}); + +test('table option limits version offset', function () { + $table = (new Blueprint)->versionOffsetIn(86400 * 2); // 2 days + expect($table->options)->toBeInstanceOf(TableOptions::class) + ->and($table->options->getDeviationCellVersionInSec())->toBe(86400 * 2); +}); + +test('table option allows update', function () { + $table = (new Blueprint)->allowUpdate(); + expect($table->options)->toBeInstanceOf(TableOptions::class) + ->and($table->options->getAllowUpdate())->toBeTrue(); +}); + +test('table option denies update', function () { + $table = (new Blueprint)->allowUpdate(false); + expect($table->options)->toBeInstanceOf(TableOptions::class) + ->and($table->options->getAllowUpdate())->toBeFalse(); +}); test('sse encrypts with kms', function () { $table = (new Blueprint)->encryptWithKms(); diff --git a/tests/SchemaHandlerTest.php b/tests/SchemaHandlerTest.php index d754118..7e0c39d 100644 --- a/tests/SchemaHandlerTest.php +++ b/tests/SchemaHandlerTest.php @@ -55,68 +55,3 @@ ->and($cols[4]->getName())->toBe('blob') ->and($cols[4]->getType())->toBe(DefinedColumnType::DCT_BLOB); }); - -test('throughput reserves read', function () { - $table = (new Blueprint)->reserveRead(2); - $handler = new SchemaHandler(Mockery::mock(Tablestore::class)); - expect($handler->toReservedThroughput($table)->getCapacityUnit()->getRead())->toBe(2); -}); - -test('throughput reserves write', function () { - $table = (new Blueprint)->reserveRead(1); - $handler = new SchemaHandler(Mockery::mock(Tablestore::class)); - expect($handler->toReservedThroughput($table)->getCapacityUnit()->getRead())->toBe(1); -}); - -test('table option configures time-to-live', function () { - $table = (new Blueprint)->ttl(86400); - $handler = new SchemaHandler(Mockery::mock(Tablestore::class)); - expect($handler->toTableOptions($table)->getTimeToLive())->toBe(86400); -}); - -test('table option configures data that is stored permanently', function () { - $table = (new Blueprint)->forever(); - $handler = new SchemaHandler(Mockery::mock(Tablestore::class)); - expect($handler->toTableOptions($table)->getTimeToLive())->toBe(-1); -}); - -test('table option defines max versions to persist', function () { - $table = (new Blueprint)->maxVersions(2); - $handler = new SchemaHandler(Mockery::mock(Tablestore::class)); - expect($handler->toTableOptions($table)->getMaxVersions())->toBe(2); -}); - -test('table option limits version offset', function () { - $table = (new Blueprint)->versionOffsetIn(86400 * 2); // 2 days - $handler = new SchemaHandler(Mockery::mock(Tablestore::class)); - expect($handler->toTableOptions($table)->getDeviationCellVersionInSec())->toBe(86400 * 2); -}); - -test('table option allows update', function () { - $table = (new Blueprint)->allowUpdate(); - $handler = new SchemaHandler(Mockery::mock(Tablestore::class)); - expect($handler->toTableOptions($table)->getAllowUpdate())->toBeTrue(); -}); - -test('table option denies update', function () { - $table = (new Blueprint)->allowUpdate(false); - $handler = new SchemaHandler(Mockery::mock(Tablestore::class)); - expect($handler->toTableOptions($table)->getAllowUpdate())->toBeFalse(); -}); - -test('throughput reservations change determination', function () { - $handler = new SchemaHandler(Mockery::mock(Tablestore::class)); - expect($handler->hasReservedThroughputUpdate(new Blueprint))->toBeFalse(); - expect($handler->hasReservedThroughputUpdate((new Blueprint)->reserveRead(2)))->toBeTrue(); - expect($handler->hasReservedThroughputUpdate((new Blueprint)->reserveWrite(1)))->toBeTrue(); -}); - -test('table options modify determination', function () { - $handler = new SchemaHandler(Mockery::mock(Tablestore::class)); - expect($handler->hasTableOptionsUpdate(new Blueprint))->toBeFalse(); - expect($handler->hasTableOptionsUpdate((new Blueprint)->ttl(86400 * 30)))->toBeTrue(); - expect($handler->hasTableOptionsUpdate((new Blueprint)->maxVersions(10)))->toBeTrue(); - expect($handler->hasTableOptionsUpdate((new Blueprint)->versionOffsetIn(86400)))->toBeTrue(); - expect($handler->hasTableOptionsUpdate((new Blueprint)->allowUpdate(true)))->toBeTrue(); - expect($handler->hasTableOptionsUpdate((new Blueprint)->allowUpdate(false)))->toBeTrue(); -});