Skip to content

Commit fa4a1e2

Browse files
feat(Spanner): Added samples for PG JSONB (GoogleCloudPlatform#1687)
* Spanner: Add samples for PG.JSONB
1 parent 9144c25 commit fa4a1e2

File tree

4 files changed

+272
-6
lines changed

4 files changed

+272
-6
lines changed

spanner/src/pg_add_jsonb_column.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
2+
/**
3+
* Copyright 2022 Google Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/**
19+
* For instructions on how to run the full sample:
20+
*
21+
* @see https://github.com/GoogleCloudPlatform/php-docs-samples/tree/master/spanner/README.md
22+
*/
23+
24+
namespace Google\Cloud\Samples\Spanner;
25+
26+
// [START spanner_postgresql_jsonb_add_column]
27+
use Google\Cloud\Spanner\SpannerClient;
28+
29+
/**
30+
* Add a JSONB column to a table present in a PG Spanner database.
31+
*
32+
* @param string $instanceId The Spanner instance ID.
33+
* @param string $databaseId The Spanner database ID.
34+
* @param string $tableName The table in which the column needs to be added.
35+
*/
36+
function pg_add_jsonb_column(
37+
string $instanceId,
38+
string $databaseId,
39+
string $tableName = 'Venues'
40+
): void {
41+
$spanner = new SpannerClient();
42+
$instance = $spanner->instance($instanceId);
43+
$database = $instance->database($databaseId);
44+
45+
$operation = $database->updateDdl(
46+
sprintf('ALTER TABLE %s ADD COLUMN VenueDetails JSONB', $tableName)
47+
);
48+
49+
print('Waiting for operation to complete...' . PHP_EOL);
50+
$operation->pollUntilComplete();
51+
52+
print(sprintf('Added column VenueDetails on table %s.', $tableName) . PHP_EOL);
53+
}
54+
// [END spanner_postgresql_jsonb_add_column]
55+
56+
// The following 2 lines are only needed to run the samples
57+
require_once __DIR__ . '/../../testing/sample_helpers.php';
58+
\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv);
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
2+
/**
3+
* Copyright 2022 Google Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/**
19+
* For instructions on how to run the full sample:
20+
*
21+
* @see https://github.com/GoogleCloudPlatform/php-docs-samples/tree/master/spanner/README.md
22+
*/
23+
24+
namespace Google\Cloud\Samples\Spanner;
25+
26+
// [START spanner_postgresql_jsonb_query_parameter]
27+
28+
use Google\Cloud\Spanner\Database;
29+
use Google\Cloud\Spanner\SpannerClient;
30+
31+
/**
32+
* Query data to a jsonb column in a PostgreSQL table.
33+
*
34+
* @param string $instanceId The Spanner instance ID.
35+
* @param string $databaseId The Spanner database ID.
36+
* @param string $tableName The table from which the data needs to be queried.
37+
*/
38+
function pg_jsonb_query_parameter(
39+
string $instanceId,
40+
string $databaseId,
41+
string $tableName = 'Venues'
42+
): void {
43+
$spanner = new SpannerClient();
44+
$instance = $spanner->instance($instanceId);
45+
$database = $instance->database($databaseId);
46+
47+
$results = $database->execute(
48+
sprintf('SELECT venueid, venuedetails FROM %s', $tableName) .
49+
" WHERE CAST(venuedetails ->> 'rating' AS INTEGER) > $1",
50+
[
51+
'parameters' => [
52+
'p1' => 2
53+
],
54+
'types' => [
55+
'p1' => Database::TYPE_INT64
56+
]
57+
]);
58+
59+
foreach ($results as $row) {
60+
printf('VenueId: %s, VenueDetails: %s' . PHP_EOL, $row['venueid'], $row['venuedetails']);
61+
}
62+
}
63+
// [END spanner_postgresql_jsonb_query_parameter]
64+
65+
// The following 2 lines are only needed to run the samples
66+
require_once __DIR__ . '/../../testing/sample_helpers.php';
67+
\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv);

spanner/src/pg_jsonb_update_data.php

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
2+
/**
3+
* Copyright 2022 Google Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/**
19+
* For instructions on how to run the full sample:
20+
*
21+
* @see https://github.com/GoogleCloudPlatform/php-docs-samples/tree/master/spanner/README.md
22+
*/
23+
24+
namespace Google\Cloud\Samples\Spanner;
25+
26+
// [START spanner_postgresql_jsonb_update_data]
27+
use Google\Cloud\Spanner\SpannerClient;
28+
29+
/**
30+
* Insert/update data in a JSONB column in a Postgres table.
31+
*
32+
* @param string $instanceId The Spanner instance ID.
33+
* @param string $databaseId The Spanner database ID.
34+
* @param string $tableName The table in which the data needs to be updated.
35+
*/
36+
function pg_jsonb_update_data(
37+
string $instanceId,
38+
string $databaseId,
39+
string $tableName = 'Venues'
40+
): void {
41+
$spanner = new SpannerClient();
42+
$instance = $spanner->instance($instanceId);
43+
$database = $instance->database($databaseId);
44+
45+
$database->insertOrUpdateBatch($tableName, [
46+
[
47+
'VenueId' => 1,
48+
'VenueDetails' => '{"rating": 9, "open": true}'
49+
],
50+
[
51+
'VenueId' => 4,
52+
'VenueDetails' => '[
53+
{
54+
"name": null,
55+
"available": true
56+
},' .
57+
// PG JSONB sorts first by key length and then lexicographically with
58+
// equivalent key length and takes the last value in the case of duplicate keys
59+
'{
60+
"name": "room 2",
61+
"available": false,
62+
"name": "room 3"
63+
},
64+
{
65+
"main hall": {
66+
"description": "this is the biggest space",
67+
"size": 200
68+
}
69+
}
70+
]'
71+
],
72+
[
73+
'VenueId' => 42,
74+
'VenueDetails' => $spanner->pgJsonb([
75+
'name' => null,
76+
'open' => [
77+
'Monday' => true,
78+
'Tuesday' => false
79+
],
80+
'tags' => ['large', 'airy'],
81+
])
82+
]
83+
]);
84+
85+
print(sprintf('Inserted/updated 3 rows in table %s', $tableName) . PHP_EOL);
86+
}
87+
// [END spanner_postgresql_jsonb_update_data]
88+
89+
// The following 2 lines are only needed to run the samples
90+
require_once __DIR__ . '/../../testing/sample_helpers.php';
91+
\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv);

spanner/test/spannerPgTest.php

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,15 @@
2222
use Google\Cloud\Spanner\Transaction;
2323
use Google\Cloud\TestUtils\EventuallyConsistentTestTrait;
2424
use Google\Cloud\TestUtils\TestTrait;
25-
use PHPUnitRetry\RetryTrait;
2625
use PHPUnit\Framework\TestCase;
2726

28-
/**
29-
* @retryAttempts 3
30-
* @retryDelayMethod exponentialBackoff
31-
*/
3227
class spannerPgTest extends TestCase
3328
{
3429
use TestTrait {
3530
TestTrait::runFunctionSnippet as traitRunFunctionSnippet;
3631
}
3732

38-
use RetryTrait, EventuallyConsistentTestTrait;
33+
use EventuallyConsistentTestTrait;
3934

4035
/** @var string instanceId */
4136
protected static $instanceId;
@@ -49,6 +44,9 @@ class spannerPgTest extends TestCase
4944
/** @var $lastUpdateData int */
5045
protected static $lastUpdateDataTimestamp;
5146

47+
/** @var $jsonbTable string */
48+
protected static $jsonbTable;
49+
5250
public static function setUpBeforeClass(): void
5351
{
5452
self::checkProjectEnvVars();
@@ -245,6 +243,58 @@ public function testNumericDataType()
245243
$this->assertStringContainsString('Inserted 1 venue(s) with NaN revenue.', $output);
246244
}
247245

246+
/**
247+
* @depends testCreateDatabase
248+
*/
249+
public function testJsonbAddColumn()
250+
{
251+
self::$jsonbTable = 'Venues' . time() . rand();
252+
253+
// Create the table for our JSONB tests.
254+
$database = self::$instance->database(self::$databaseId);
255+
$op = $database->updateDdl(
256+
sprintf('CREATE TABLE %s (
257+
VenueId bigint NOT NULL PRIMARY KEY
258+
)', self::$jsonbTable)
259+
);
260+
261+
$op->pollUntilComplete();
262+
263+
// Now run the test
264+
$output = $this->runFunctionSnippet('pg_add_jsonb_column', [
265+
self::$instanceId, self::$databaseId, self::$jsonbTable
266+
]);
267+
self::$lastUpdateDataTimestamp = time();
268+
269+
$this->assertStringContainsString(sprintf('Added column VenueDetails on table %s.', self::$jsonbTable), $output);
270+
}
271+
272+
/**
273+
* @depends testJsonbAddColumn
274+
*/
275+
public function testJsonbUpdateData()
276+
{
277+
$output = $this->runFunctionSnippet('pg_jsonb_update_data', [
278+
self::$instanceId, self::$databaseId, self::$jsonbTable
279+
]);
280+
self::$lastUpdateDataTimestamp = time();
281+
282+
$this->assertStringContainsString(sprintf('Inserted/updated 3 rows in table %s', self::$jsonbTable), $output);
283+
}
284+
285+
/**
286+
* @depends testJsonbUpdateData
287+
*/
288+
public function testJsonbQueryParam()
289+
{
290+
$output = $this->runFunctionSnippet('pg_jsonb_query_parameter', [
291+
self::$instanceId, self::$databaseId, self::$jsonbTable
292+
]);
293+
self::$lastUpdateDataTimestamp = time();
294+
295+
$this->assertEquals('VenueId: 1, VenueDetails: {"open": true, "rating": 9}' . PHP_EOL, $output);
296+
}
297+
248298
/**
249299
* @depends testCreateDatabase
250300
*/

0 commit comments

Comments
 (0)