From 08b6f4993b4a8eff07da47b13123c1b223fa4395 Mon Sep 17 00:00:00 2001 From: andrewinc Date: Tue, 8 Oct 2019 18:10:42 +0300 Subject: [PATCH 1/5] Pre release --- .../firestore_snippets/SolutionCounters.php | 142 ++++++++++++++++++ firestore/test/SolutionCountersTest.php | 126 ++++++++++++++++ 2 files changed, 268 insertions(+) create mode 100644 firestore/src/firestore_snippets/SolutionCounters.php create mode 100644 firestore/test/SolutionCountersTest.php diff --git a/firestore/src/firestore_snippets/SolutionCounters.php b/firestore/src/firestore_snippets/SolutionCounters.php new file mode 100644 index 0000000000..c26d82e1d5 --- /dev/null +++ b/firestore/src/firestore_snippets/SolutionCounters.php @@ -0,0 +1,142 @@ +numShards = $numShards; + } + + public function getNumShards() + { + return $this->numShards; + } +} + + +/** + * Shard is a single counter, which is used in a group + * of other shards within Counter. + * */ +class Shard +{ + /** + * @var int + */ + private $count; + + public function __construct(int $count) + { + $this->count = $count; + } + + public function getCount() + { + return $this->count; + } + +} + +// [END fs_counter_classes] + + +class SolutionCounters { + + const SHARD_COLLECT_NAME='SHARDS'; + const SHARDS_COUNT=10; + + // [START fs_create_counter] + /** + * InitCounter creates a given number of shards as + * subcollection of specified document. + * + * @param DocumentReference $ref Firestore document + * @param int $numShards The number of counter fragments. (default 10) + */ + public static function initCounter(DocumentReference $ref, int $numShards=self::SHARDS_COUNT) + { + $counter = new Counter($numShards); + $colRef = $ref->collection(self::SHARD_COLLECT_NAME); + for ($i = 0; $i < $counter->getNumShards(); $i++) { + $doc = $colRef->document($i); + $doc->set([Counter::FIELD_NAME=>0]); + } + } + + // [END fs_create_counter] + + + // [START fs_increment_counter] + /** + * incrementCounter increments a randomly picked shard. + * + * Example: + * ``` + * SolutionCounters::incrementCounter($db->collection('MyCollection')->document('CounterDoc'), $counter->getNumShards()); + * ``` + * + * @param DocumentReference $ref Firestore document + * @param int $numShards The number of counter fragments. (default 10) + */ + public static function incrementCounter(DocumentReference $ref, int $numShards=self::SHARDS_COUNT) + { + $colRef = $ref->collection(self::SHARD_COLLECT_NAME); + $shardIdx = random_int(0, $numShards-1); + $doc = $colRef->document($shardIdx); + $doc->update([ + ['path' => Counter::FIELD_NAME, 'value' => FieldValue::increment(1)] + ]); + } + + // [END fs_increment_counter] + + // [START fs_get_count] + + /** + * getCount returns a total count across all shards. + * + * @param DocumentReference $ref Firestore document + * @return int + */ + public static function getCount(DocumentReference $ref) + { + $result = 0; + $docCollection = $ref->collection(self::SHARD_COLLECT_NAME)->documents(); + foreach ($docCollection as $doc) { + $result += $doc->data()[Counter::FIELD_NAME]; + } + return $result; + } + + // [END fs_get_count] +} diff --git a/firestore/test/SolutionCountersTest.php b/firestore/test/SolutionCountersTest.php new file mode 100644 index 0000000000..e464f6a0fc --- /dev/null +++ b/firestore/test/SolutionCountersTest.php @@ -0,0 +1,126 @@ + self::$firestoreProjectId + ]); + + self::$ref=$db->collection(self::COLLECTION_NAME)->document(self::SHARD_NAME); + } + + protected function setUp() + { + if (!extension_loaded('grpc')) { + self::markTestSkipped('Must enable grpc extension.'); + } + } + + + /** + * @covers Google\Cloud\Firestore\Counter::getNumShards + */ + public function testCounter() + { + $counter=new Counter(1000); + $this->assertEquals(1000, $counter->getNumShards()); + + $counter2=new Counter(1); + $this->assertEquals(1, $counter2->getNumShards()); + } + + /** + * @covers Google\Cloud\Firestore\Shard::getCount + */ + public function testShard() + { + $shard = new Shard(1000); + $this->assertEquals(1000, $shard->getCount()); + + $shard2 = new Shard(1); + $this->assertEquals(1, $shard2->getCount()); + } + + /** + * @covers Google\Cloud\Firestore\SolutionCounters::initCounter + * @covers Google\Cloud\Firestore\SolutionCounters::incrementCounter + * @covers Google\Cloud\Firestore\SolutionCounters::getCount + */ + public function testSolutionCounters() + { + $cnt=5; + SolutionCounters::initCounter(self::$ref, $cnt); + + $collect = self::$ref->collection(SolutionCounters::SHARD_COLLECT_NAME); + $docCollection = $collect->documents(); + $docIdList=[]; + + foreach ($docCollection as $docSnap) { + $docIdList[] = $docSnap->id(); + } + $this->assertEquals($cnt, count($docIdList)); + + $this->assertEquals(0, SolutionCounters::getCount(self::$ref)); + + SolutionCounters::incrementCounter(self::$ref, $cnt); + $this->assertEquals(1, SolutionCounters::getCount(self::$ref)); + + SolutionCounters::incrementCounter(self::$ref, $cnt); + $this->assertEquals(2, SolutionCounters::getCount(self::$ref)); + + SolutionCounters::incrementCounter(self::$ref, $cnt); + $this->assertEquals(3, SolutionCounters::getCount(self::$ref)); + + foreach ($docIdList as $docId){ + $collect->document($docId)->delete(); + } + } + + /** Remove SHARD_NAME document + */ + public static function tearDownAfterClass() + { + self::$ref->delete(); + } +} From 83f573f1de733681c468cb80e3caf09a5667ca45 Mon Sep 17 00:00:00 2001 From: andrewinc Date: Thu, 10 Oct 2019 12:35:08 +0300 Subject: [PATCH 2/5] last static --- .../firestore_snippets/SolutionCounters.php | 33 +++++-------------- firestore/test/SolutionCountersTest.php | 14 ++++---- 2 files changed, 15 insertions(+), 32 deletions(-) diff --git a/firestore/src/firestore_snippets/SolutionCounters.php b/firestore/src/firestore_snippets/SolutionCounters.php index c26d82e1d5..c261e75dfb 100644 --- a/firestore/src/firestore_snippets/SolutionCounters.php +++ b/firestore/src/firestore_snippets/SolutionCounters.php @@ -25,8 +25,6 @@ */ class Counter { - const FIELD_NAME='Cnt'; - /** * @var int */ @@ -64,17 +62,12 @@ public function getCount() { return $this->count; } - } // [END fs_counter_classes] class SolutionCounters { - - const SHARD_COLLECT_NAME='SHARDS'; - const SHARDS_COUNT=10; - // [START fs_create_counter] /** * InitCounter creates a given number of shards as @@ -83,45 +76,36 @@ class SolutionCounters { * @param DocumentReference $ref Firestore document * @param int $numShards The number of counter fragments. (default 10) */ - public static function initCounter(DocumentReference $ref, int $numShards=self::SHARDS_COUNT) + public static function initCounter(DocumentReference $ref, int $numShards = 10) { $counter = new Counter($numShards); - $colRef = $ref->collection(self::SHARD_COLLECT_NAME); + $colRef = $ref->collection('SHARDS'); for ($i = 0; $i < $counter->getNumShards(); $i++) { $doc = $colRef->document($i); - $doc->set([Counter::FIELD_NAME=>0]); + $doc->set(['Cnt' => 0]); } } - // [END fs_create_counter] - // [START fs_increment_counter] /** * incrementCounter increments a randomly picked shard. * - * Example: - * ``` - * SolutionCounters::incrementCounter($db->collection('MyCollection')->document('CounterDoc'), $counter->getNumShards()); - * ``` - * * @param DocumentReference $ref Firestore document * @param int $numShards The number of counter fragments. (default 10) */ - public static function incrementCounter(DocumentReference $ref, int $numShards=self::SHARDS_COUNT) + public static function incrementCounter(DocumentReference $ref, int $numShards = 10) { - $colRef = $ref->collection(self::SHARD_COLLECT_NAME); + $colRef = $ref->collection('SHARDS'); $shardIdx = random_int(0, $numShards-1); $doc = $colRef->document($shardIdx); $doc->update([ - ['path' => Counter::FIELD_NAME, 'value' => FieldValue::increment(1)] + ['path' => 'Cnt', 'value' => FieldValue::increment(1)] ]); } - // [END fs_increment_counter] // [START fs_get_count] - /** * getCount returns a total count across all shards. * @@ -131,12 +115,11 @@ public static function incrementCounter(DocumentReference $ref, int $numShards=s public static function getCount(DocumentReference $ref) { $result = 0; - $docCollection = $ref->collection(self::SHARD_COLLECT_NAME)->documents(); + $docCollection = $ref->collection('SHARDS')->documents(); foreach ($docCollection as $doc) { - $result += $doc->data()[Counter::FIELD_NAME]; + $result += $doc->data()['Cnt']; } return $result; } - // [END fs_get_count] } diff --git a/firestore/test/SolutionCountersTest.php b/firestore/test/SolutionCountersTest.php index e464f6a0fc..7393bdbf2a 100644 --- a/firestore/test/SolutionCountersTest.php +++ b/firestore/test/SolutionCountersTest.php @@ -63,8 +63,8 @@ protected function setUp() */ public function testCounter() { - $counter=new Counter(1000); - $this->assertEquals(1000, $counter->getNumShards()); + $counter=new Counter(5); + $this->assertEquals(5, $counter->getNumShards()); $counter2=new Counter(1); $this->assertEquals(1, $counter2->getNumShards()); @@ -75,11 +75,11 @@ public function testCounter() */ public function testShard() { - $shard = new Shard(1000); - $this->assertEquals(1000, $shard->getCount()); + $shard = new Shard(7); + $this->assertEquals(7, $shard->getCount()); - $shard2 = new Shard(1); - $this->assertEquals(1, $shard2->getCount()); + $shard2 = new Shard(2); + $this->assertEquals(2, $shard2->getCount()); } /** @@ -92,7 +92,7 @@ public function testSolutionCounters() $cnt=5; SolutionCounters::initCounter(self::$ref, $cnt); - $collect = self::$ref->collection(SolutionCounters::SHARD_COLLECT_NAME); + $collect = self::$ref->collection('SHARDS'); $docCollection = $collect->documents(); $docIdList=[]; From e55a42401a7907aea2c367a814f1a67f39110626 Mon Sep 17 00:00:00 2001 From: andrewinc Date: Thu, 10 Oct 2019 15:43:01 +0300 Subject: [PATCH 3/5] metods moved to class Counter --- .../src/firestore_snippets/{SolutionCounters.php => Counter.php} | 0 firestore/test/{SolutionCountersTest.php => CounterTest.php} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename firestore/src/firestore_snippets/{SolutionCounters.php => Counter.php} (100%) rename firestore/test/{SolutionCountersTest.php => CounterTest.php} (100%) diff --git a/firestore/src/firestore_snippets/SolutionCounters.php b/firestore/src/firestore_snippets/Counter.php similarity index 100% rename from firestore/src/firestore_snippets/SolutionCounters.php rename to firestore/src/firestore_snippets/Counter.php diff --git a/firestore/test/SolutionCountersTest.php b/firestore/test/CounterTest.php similarity index 100% rename from firestore/test/SolutionCountersTest.php rename to firestore/test/CounterTest.php From 5d143080c46f426fa5177f6f04b30e8755dd836c Mon Sep 17 00:00:00 2001 From: andrewinc Date: Fri, 11 Oct 2019 10:36:08 +0300 Subject: [PATCH 4/5] removed empty strings --- firestore/src/firestore_snippets/Counter.php | 64 +++++++----------- firestore/test/CounterTest.php | 69 ++++++++------------ 2 files changed, 51 insertions(+), 82 deletions(-) diff --git a/firestore/src/firestore_snippets/Counter.php b/firestore/src/firestore_snippets/Counter.php index c261e75dfb..fd166fc650 100644 --- a/firestore/src/firestore_snippets/Counter.php +++ b/firestore/src/firestore_snippets/Counter.php @@ -20,32 +20,10 @@ use Google\Cloud\Firestore\DocumentReference; // [START fs_counter_classes] -/** Counter is a collection of documents (shards) - * to realize counter with high frequency - */ -class Counter -{ - /** - * @var int - */ - private $numShards; - - public function __construct(int $numShards) - { - $this->numShards = $numShards; - } - - public function getNumShards() - { - return $this->numShards; - } -} - - -/** +/** * Shard is a single counter, which is used in a group * of other shards within Counter. - * */ + */ class Shard { /** @@ -64,11 +42,18 @@ public function getCount() } } +/** Counter is a collection of documents (shards) + * to realize counter with high frequency + */ +class Counter +{ + /** + * @var int + */ + private $numShards; // [END fs_counter_classes] - -class SolutionCounters { - // [START fs_create_counter] +// [START fs_create_counter] /** * InitCounter creates a given number of shards as * subcollection of specified document. @@ -76,43 +61,42 @@ class SolutionCounters { * @param DocumentReference $ref Firestore document * @param int $numShards The number of counter fragments. (default 10) */ - public static function initCounter(DocumentReference $ref, int $numShards = 10) + public function __construct(DocumentReference $ref, int $numShards) { - $counter = new Counter($numShards); + $this->numShards = $numShards; $colRef = $ref->collection('SHARDS'); - for ($i = 0; $i < $counter->getNumShards(); $i++) { + for ($i = 0; $i < $numShards; $i++) { $doc = $colRef->document($i); $doc->set(['Cnt' => 0]); } } - // [END fs_create_counter] +// [END fs_create_counter] - // [START fs_increment_counter] +// [START fs_increment_counter] /** * incrementCounter increments a randomly picked shard. * * @param DocumentReference $ref Firestore document - * @param int $numShards The number of counter fragments. (default 10) */ - public static function incrementCounter(DocumentReference $ref, int $numShards = 10) + public function incrementCounter(DocumentReference $ref) { $colRef = $ref->collection('SHARDS'); - $shardIdx = random_int(0, $numShards-1); + $shardIdx = random_int(0, $this->numShards-1); $doc = $colRef->document($shardIdx); $doc->update([ ['path' => 'Cnt', 'value' => FieldValue::increment(1)] ]); } - // [END fs_increment_counter] - - // [START fs_get_count] +// [END fs_increment_counter] + +// [START fs_get_count] /** * getCount returns a total count across all shards. * * @param DocumentReference $ref Firestore document * @return int */ - public static function getCount(DocumentReference $ref) + public function getCount(DocumentReference $ref) { $result = 0; $docCollection = $ref->collection('SHARDS')->documents(); @@ -121,5 +105,5 @@ public static function getCount(DocumentReference $ref) } return $result; } - // [END fs_get_count] +// [END fs_get_count] } diff --git a/firestore/test/CounterTest.php b/firestore/test/CounterTest.php index 7393bdbf2a..c009fac7c3 100644 --- a/firestore/test/CounterTest.php +++ b/firestore/test/CounterTest.php @@ -17,7 +17,6 @@ namespace Google\Cloud\Firestore; -use Google\Cloud\Firestore\SolutionCounters; use Google\Cloud\Firestore\Counter; use Google\Cloud\Firestore\Shard; use Google\Cloud\TestUtils\TestTrait; @@ -39,7 +38,7 @@ class SolutionCountersTest extends TestCase public static function setUpBeforeClass() { - require_once __DIR__."/../src/firestore_snippets/SolutionCounters.php"; + require_once __DIR__."/../src/firestore_snippets/Counter.php"; self::$firestoreProjectId = self::requireEnv('FIRESTORE_PROJECT_ID'); @@ -57,65 +56,51 @@ protected function setUp() } } - /** - * @covers Google\Cloud\Firestore\Counter::getNumShards + * @covers Google\Cloud\Firestore\Counter::__construct + * @covers Google\Cloud\Firestore\Counter::incrementCounter + * @covers Google\Cloud\Firestore\Counter::getCount */ public function testCounter() { - $counter=new Counter(5); - $this->assertEquals(5, $counter->getNumShards()); - - $counter2=new Counter(1); - $this->assertEquals(1, $counter2->getNumShards()); - } - - /** - * @covers Google\Cloud\Firestore\Shard::getCount - */ - public function testShard() - { - $shard = new Shard(7); - $this->assertEquals(7, $shard->getCount()); - - $shard2 = new Shard(2); - $this->assertEquals(2, $shard2->getCount()); - } - - /** - * @covers Google\Cloud\Firestore\SolutionCounters::initCounter - * @covers Google\Cloud\Firestore\SolutionCounters::incrementCounter - * @covers Google\Cloud\Firestore\SolutionCounters::getCount - */ - public function testSolutionCounters() - { - $cnt=5; - SolutionCounters::initCounter(self::$ref, $cnt); + $counter = new Counter(self::$ref, 5); $collect = self::$ref->collection('SHARDS'); $docCollection = $collect->documents(); - $docIdList=[]; + $docIdList=[]; foreach ($docCollection as $docSnap) { $docIdList[] = $docSnap->id(); } - $this->assertEquals($cnt, count($docIdList)); + $this->assertEquals(5, count($docIdList)); - $this->assertEquals(0, SolutionCounters::getCount(self::$ref)); + $this->assertEquals(0, $counter->getCount(self::$ref)); - SolutionCounters::incrementCounter(self::$ref, $cnt); - $this->assertEquals(1, SolutionCounters::getCount(self::$ref)); + $counter->incrementCounter(self::$ref); + $this->assertEquals(1, $counter->getCount(self::$ref)); - SolutionCounters::incrementCounter(self::$ref, $cnt); - $this->assertEquals(2, SolutionCounters::getCount(self::$ref)); + $counter->incrementCounter(self::$ref); + $this->assertEquals(2, $counter->getCount(self::$ref)); - SolutionCounters::incrementCounter(self::$ref, $cnt); - $this->assertEquals(3, SolutionCounters::getCount(self::$ref)); + $counter->incrementCounter(self::$ref); + $this->assertEquals(3, $counter->getCount(self::$ref)); - foreach ($docIdList as $docId){ + foreach ($docIdList as $docId) { $collect->document($docId)->delete(); } } + + /** + * @covers Google\Cloud\Firestore\Shard::getCount + */ + public function testShard() + { + $shard = new Shard(7); + $this->assertEquals(7, $shard->getCount()); + + $shard2 = new Shard(2); + $this->assertEquals(2, $shard2->getCount()); + } /** Remove SHARD_NAME document */ From a01a22e4a5ed017f3a800b8735983182e94d885c Mon Sep 17 00:00:00 2001 From: andrewinc Date: Tue, 22 Oct 2019 18:30:02 +0300 Subject: [PATCH 5/5] firestore distributed counters - ADD 3 file (command) and test method testDistributedCounter for them - remove folder firestore_snippets with file - remove test CounterTest.php an3 file and --- firestore/composer.json | 3 + firestore/firestore.php | 51 ++++++++ firestore/src/firestore_snippets/Counter.php | 109 ----------------- .../src/get_distributed_counter_value.php | 49 ++++++++ .../src/initialize_distributed_counter.php | 49 ++++++++ firestore/src/update_distributed_counter.php | 55 +++++++++ firestore/test/CounterTest.php | 111 ------------------ firestore/test/firestoreTest.php | 35 ++++++ 8 files changed, 242 insertions(+), 220 deletions(-) delete mode 100644 firestore/src/firestore_snippets/Counter.php create mode 100644 firestore/src/get_distributed_counter_value.php create mode 100644 firestore/src/initialize_distributed_counter.php create mode 100644 firestore/src/update_distributed_counter.php delete mode 100644 firestore/test/CounterTest.php diff --git a/firestore/composer.json b/firestore/composer.json index fc60256a3b..3d4eba7ce5 100644 --- a/firestore/composer.json +++ b/firestore/composer.json @@ -24,9 +24,11 @@ "src/end_at_field_query_cursor.php", "src/get_all.php", "src/get_all_docs.php", + "src/get_distributed_counter_value.php", "src/get_document.php", "src/get_multiple_docs.php", "src/initialize.php", + "src/initialize_distributed_counter.php", "src/initialize_project_id.php", "src/invalid_range_order_by_query.php", "src/invalid_range_query.php", @@ -49,6 +51,7 @@ "src/start_at_field_query_cursor.php", "src/start_at_snapshot_query_cursor.php", "src/subcollection_ref.php", + "src/update_distributed_counter.php", "src/update_doc.php", "src/update_doc_array.php", "src/update_nested_fields.php", diff --git a/firestore/firestore.php b/firestore/firestore.php index da3f9995fe..8b0fc5beb9 100644 --- a/firestore/firestore.php +++ b/firestore/firestore.php @@ -939,6 +939,57 @@ }) ); +//Create distributed counter +$application->add((new Command('initialize-distributed-counter')) + ->setDefinition($inputDefinition) + ->setDescription('Creates a subcollection from the specified multiple shards.') + ->setHelp(<<%command.name% command creates a distributed counter as a sub collection in Google Cloud Firestore, consisting of several empty shards. + + php %command.full_name% + +EOF + ) + ->setCode(function ($input, $output) { + $projectId = $input->getArgument('project'); + initialize_distributed_counter($projectId); + }) +); + +//Increment (distributed counter) +$application->add((new Command('update-distributed-counter')) + ->setDefinition($inputDefinition) + ->setDescription('Increments a randomly picked shard of a distributed counter.') + ->setHelp(<<%command.name% command increments the randomly selected shard of a distributed counter using the Google Cloud Firestore API. + + php %command.full_name% + +EOF + ) + ->setCode(function ($input, $output) { + $projectId = $input->getArgument('project'); + update_distributed_counter($projectId); + }) +); + +//get value (distributed counter) +$application->add((new Command('get-distributed-counter-value')) + ->setDefinition($inputDefinition) + ->setDescription('Returns the total count across all the shards of a distributed counter.') + ->setHelp(<<%command.name% command returns the total count across all the shards of a distributed counter, using the Google Cloud Firestore API. + + php %command.full_name% + +EOF + ) + ->setCode(function ($input, $output) { + $projectId = $input->getArgument('project'); + get_distributed_counter_value($projectId); + }) +); + // for testing if (getenv('PHPUNIT_TESTS') === '1') { return $application; diff --git a/firestore/src/firestore_snippets/Counter.php b/firestore/src/firestore_snippets/Counter.php deleted file mode 100644 index fd166fc650..0000000000 --- a/firestore/src/firestore_snippets/Counter.php +++ /dev/null @@ -1,109 +0,0 @@ -count = $count; - } - - public function getCount() - { - return $this->count; - } -} - -/** Counter is a collection of documents (shards) - * to realize counter with high frequency - */ -class Counter -{ - /** - * @var int - */ - private $numShards; -// [END fs_counter_classes] - -// [START fs_create_counter] - /** - * InitCounter creates a given number of shards as - * subcollection of specified document. - * - * @param DocumentReference $ref Firestore document - * @param int $numShards The number of counter fragments. (default 10) - */ - public function __construct(DocumentReference $ref, int $numShards) - { - $this->numShards = $numShards; - $colRef = $ref->collection('SHARDS'); - for ($i = 0; $i < $numShards; $i++) { - $doc = $colRef->document($i); - $doc->set(['Cnt' => 0]); - } - } -// [END fs_create_counter] - -// [START fs_increment_counter] - /** - * incrementCounter increments a randomly picked shard. - * - * @param DocumentReference $ref Firestore document - */ - public function incrementCounter(DocumentReference $ref) - { - $colRef = $ref->collection('SHARDS'); - $shardIdx = random_int(0, $this->numShards-1); - $doc = $colRef->document($shardIdx); - $doc->update([ - ['path' => 'Cnt', 'value' => FieldValue::increment(1)] - ]); - } -// [END fs_increment_counter] - -// [START fs_get_count] - /** - * getCount returns a total count across all shards. - * - * @param DocumentReference $ref Firestore document - * @return int - */ - public function getCount(DocumentReference $ref) - { - $result = 0; - $docCollection = $ref->collection('SHARDS')->documents(); - foreach ($docCollection as $doc) { - $result += $doc->data()['Cnt']; - } - return $result; - } -// [END fs_get_count] -} diff --git a/firestore/src/get_distributed_counter_value.php b/firestore/src/get_distributed_counter_value.php new file mode 100644 index 0000000000..b413f44ff2 --- /dev/null +++ b/firestore/src/get_distributed_counter_value.php @@ -0,0 +1,49 @@ + $projectId, + ]); + $ref = $db->collection('Shards_collection')->document('Distributed_counters'); + # [START fs_get_distributed_counter_value] + $result = 0; + $docCollection = $ref->collection('SHARDS')->documents(); + foreach ($docCollection as $doc) { + $result += $doc->data()['Cnt']; + } + # [END fs_get_distributed_counter_value] + printf('The current value of the distributed counter: %d' . PHP_EOL, $result); +} diff --git a/firestore/src/initialize_distributed_counter.php b/firestore/src/initialize_distributed_counter.php new file mode 100644 index 0000000000..56a3486849 --- /dev/null +++ b/firestore/src/initialize_distributed_counter.php @@ -0,0 +1,49 @@ + $projectId, + ]); + $ref = $db->collection('Shards_collection')->document('Distributed_counters'); + # [START fs_initialize_distributed_counter] + $numShards = 10; + $colRef = $ref->collection('SHARDS'); + for ($i = 0; $i < $numShards; $i++) { + $doc = $colRef->document($i); + $doc->set(['Cnt' => 0]); + } + # [END fs_initialize_distributed_counter] +} diff --git a/firestore/src/update_distributed_counter.php b/firestore/src/update_distributed_counter.php new file mode 100644 index 0000000000..f0cffc30cb --- /dev/null +++ b/firestore/src/update_distributed_counter.php @@ -0,0 +1,55 @@ + $projectId, + ]); + $ref = $db->collection('Shards_collection')->document('Distributed_counters'); + # [START fs_update_distributed_counter] + $colRef = $ref->collection('SHARDS'); + $numShards = 0; + $docCollection = $colRef->documents(); + foreach ($docCollection as $doc) { + $numShards++; + } + $shardIdx = random_int(0, $numShards-1); + $doc = $colRef->document($shardIdx); + $doc->update([ + ['path' => 'Cnt', 'value' => FieldValue::increment(1)] + ]); + # [END fs_update_distributed_counter] +} diff --git a/firestore/test/CounterTest.php b/firestore/test/CounterTest.php deleted file mode 100644 index c009fac7c3..0000000000 --- a/firestore/test/CounterTest.php +++ /dev/null @@ -1,111 +0,0 @@ - self::$firestoreProjectId - ]); - - self::$ref=$db->collection(self::COLLECTION_NAME)->document(self::SHARD_NAME); - } - - protected function setUp() - { - if (!extension_loaded('grpc')) { - self::markTestSkipped('Must enable grpc extension.'); - } - } - - /** - * @covers Google\Cloud\Firestore\Counter::__construct - * @covers Google\Cloud\Firestore\Counter::incrementCounter - * @covers Google\Cloud\Firestore\Counter::getCount - */ - public function testCounter() - { - $counter = new Counter(self::$ref, 5); - - $collect = self::$ref->collection('SHARDS'); - $docCollection = $collect->documents(); - - $docIdList=[]; - foreach ($docCollection as $docSnap) { - $docIdList[] = $docSnap->id(); - } - $this->assertEquals(5, count($docIdList)); - - $this->assertEquals(0, $counter->getCount(self::$ref)); - - $counter->incrementCounter(self::$ref); - $this->assertEquals(1, $counter->getCount(self::$ref)); - - $counter->incrementCounter(self::$ref); - $this->assertEquals(2, $counter->getCount(self::$ref)); - - $counter->incrementCounter(self::$ref); - $this->assertEquals(3, $counter->getCount(self::$ref)); - - foreach ($docIdList as $docId) { - $collect->document($docId)->delete(); - } - } - - /** - * @covers Google\Cloud\Firestore\Shard::getCount - */ - public function testShard() - { - $shard = new Shard(7); - $this->assertEquals(7, $shard->getCount()); - - $shard2 = new Shard(2); - $this->assertEquals(2, $shard2->getCount()); - } - - /** Remove SHARD_NAME document - */ - public static function tearDownAfterClass() - { - self::$ref->delete(); - } -} diff --git a/firestore/test/firestoreTest.php b/firestore/test/firestoreTest.php index 7a7d72b3b1..9074719007 100644 --- a/firestore/test/firestoreTest.php +++ b/firestore/test/firestoreTest.php @@ -17,6 +17,7 @@ namespace Google\Cloud\Samples\Firestore\Tests; +use Google\Cloud\Firestore\FirestoreClient; use Google\Cloud\TestUtils\TestTrait; use Google\Cloud\TestUtils\ExecuteCommandTrait; use PHPUnit\Framework\TestCase; @@ -507,4 +508,38 @@ private function runFirestoreCommand($commandName) 'project' => self::$firestoreProjectId ]); } + + public function testDistributedCounter() + { + $this->runFirestoreCommand('initialize-distributed-counter'); + $outputZero = $this->runFirestoreCommand('get-distributed-counter-value'); + $this->assertContains('0', $outputZero); + + //check count of shards + $db = new FirestoreClient([ + 'projectId' => self::$firestoreProjectId, + ]); + $ref = $db->collection('Shards_collection')->document('Distributed_counters'); + $collect = $ref->collection('SHARDS'); + $docCollection = $collect->documents(); + + $docIdList = []; + foreach ($docCollection as $docSnap) { + $docIdList[] = $docSnap->id(); + } + $this->assertEquals(10, count($docIdList)); + + //call thrice and check the value + $this->runFirestoreCommand('update-distributed-counter'); + $this->runFirestoreCommand('update-distributed-counter'); + $this->runFirestoreCommand('update-distributed-counter'); + + $output = $this->runFirestoreCommand('get-distributed-counter-value'); + $this->assertContains('3', $output); + + //remove temporary data + foreach ($docIdList as $docId) { + $collect->document($docId)->delete(); + } + } }