Skip to content

Commit c9b8950

Browse files
jdpedriedwsupplee
authored andcommitted
Introduce Cloud Firestore (#693)
* Add firestore protobuf classes * Add Firestore public API classes * Add firestore gapic * Update composer for protos * send API call * Get a document. * Add value mapping and move data objects to core * Encode values and insert documents * Add WriteBatch * Update and delete documents * Support FIELD DELETE Sentinel value * Implement remainder of Collection and Document methods * Start implementing firestore transactions * Firestore Query beginning * Implement remaining Query methods * Get documents, add Query class * WIP * Remove unused connection methods * Reorganize writer methods * Fix field path decoding * Rename Document to DocumentReference * Documentation * Manage Sentinel Values * Rename Collection -> CollectionReference * Unit Tests * Fix regression in Cloud Spanner * Setup docs and component * Add Firestore Snippet Tests * Fix firestore snapshot * Add some system tests * refresh gapic * refresh client config * Add system tests * Run Query and yield Document Snapshots * WIP * Fix firestore tests * rename method with reserved name * update phpunit version * Remove Protos * Retry query if initial call fails * Retry queries if the call fails up front * Update for proto fix * begin addressing code review * Implement FieldPath class, escaping, and query fixes * Add Transaction::runQuery() * Add support for Unary Query Filters * Split SnapshotTrait::createSnapshot into two methods * Remove Firestore Admin GAPIC Client * Docs and syntax fixes * Update unit tests * CollectionReference extends Query * Fix tests and documentation * Extend Unit Test coverage * Update snippet tests * Address code review * Fix tests for hhvm * Replace DocumentSnapshot::info() with timestamp methods * Add API reference links * Add system test coverage * Remove test for example that doesnt exist * Add resource prefix header * fix unit tests * Fix docs * Remove flag * Update unit test extends * Add `path()` method to resource objects and clarify documentation * Revert sorting documents * Refactor query results * Move arrayMergeRecursive to ArrayTrait * Refactor out update() and rename updatePaths() to update() * Make FieldValue concrete and non-instantiable (is that a word?) * Loosen time comparison * Update cursor documentation * Address final code review, handle document name query order
1 parent 646c0d1 commit c9b8950

File tree

4 files changed

+9
-95
lines changed

4 files changed

+9
-95
lines changed

Database.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -712,8 +712,7 @@ public function runTransaction(callable $operation, array $options = [])
712712
throw $e;
713713
}
714714

715-
$delay = $e->getRetryDelay();
716-
time_nanosleep($delay['seconds'], $delay['nanos']);
715+
return $e->getRetryDelay();
717716
};
718717

719718
$transactionFn = function ($operation, $session, $options) use ($startTransactionFn) {

Operation.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public function commit(Session $session, array $mutations, array $options = [])
131131
'database' => $session->info()['database']
132132
]) + $options);
133133

134-
return $this->mapper->createTimestampWithNanos($res['commitTimestamp']);
134+
return $this->mapper->createTimestampWithNanos($res['commitTimestamp'], Timestamp::class);
135135
}
136136

137137
/**
@@ -336,7 +336,7 @@ public function createSnapshot(Session $session, array $res = [])
336336
];
337337

338338
if ($res['readTimestamp']) {
339-
$res['readTimestamp'] = $this->mapper->createTimestampWithNanos($res['readTimestamp']);
339+
$res['readTimestamp'] = $this->mapper->createTimestampWithNanos($res['readTimestamp'], Timestamp::class);
340340
}
341341

342342
return new Snapshot($this, $session, $res);

Timestamp.php

Lines changed: 3 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
namespace Google\Cloud\Spanner;
1919

20+
use Google\Cloud\Core\Timestamp as CoreTimestamp;
21+
2022
/**
2123
* Represents a value with a data type of
2224
* [Timestamp](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.v1#google.spanner.v1.TypeCode).
@@ -40,48 +42,8 @@
4042
* echo (string) $timestamp;
4143
* ```
4244
*/
43-
class Timestamp implements ValueInterface
45+
class Timestamp extends CoreTimestamp implements ValueInterface
4446
{
45-
const FORMAT = 'Y-m-d\TH:i:s.u\Z';
46-
const FORMAT_INTERPOLATE = 'Y-m-d\TH:i:s.%\s\Z';
47-
48-
/**
49-
* @var \DateTimeInterface
50-
*/
51-
private $value;
52-
53-
/**
54-
* @var int
55-
*/
56-
private $nanoSeconds;
57-
58-
/**
59-
* @param \DateTimeInterface $value The timestamp value.
60-
* @param int $nanoSeconds [optional] The number of nanoseconds in the timestamp.
61-
*/
62-
public function __construct(\DateTimeInterface $value, $nanoSeconds = null)
63-
{
64-
$this->value = $value;
65-
$this->nanoSeconds = $nanoSeconds ?: (int) $this->value->format('u');
66-
}
67-
68-
/**
69-
* Get the underlying `\DateTimeInterface` implementation.
70-
*
71-
* Please note that nanosecond precision is not present in this method.
72-
*
73-
* Example:
74-
* ```
75-
* $dateTime = $timestamp->get();
76-
* ```
77-
*
78-
* @return \DateTimeInterface
79-
*/
80-
public function get()
81-
{
82-
return $this->value;
83-
}
84-
8547
/**
8648
* Get the type.
8749
*
@@ -96,34 +58,4 @@ public function type()
9658
{
9759
return Database::TYPE_TIMESTAMP;
9860
}
99-
100-
/**
101-
* Format the value as a string.
102-
*
103-
* This method retains nanosecond precision, if available.
104-
*
105-
* Example:
106-
* ```
107-
* $value = $timestamp->formatAsString();
108-
* ```
109-
*
110-
* @return string
111-
*/
112-
public function formatAsString()
113-
{
114-
$this->value->setTimezone(new \DateTimeZone('UTC'));
115-
$ns = str_pad((string) $this->nanoSeconds, 6, '0', STR_PAD_LEFT);
116-
return sprintf($this->value->format(self::FORMAT_INTERPOLATE), $ns);
117-
}
118-
119-
/**
120-
* Format the value as a string.
121-
*
122-
* @return string
123-
* @access private
124-
*/
125-
public function __toString()
126-
{
127-
return $this->formatAsString();
128-
}
12961
}

ValueMapper.php

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
use Google\Cloud\Core\ArrayTrait;
2121
use Google\Cloud\Core\Int64;
22+
use Google\Cloud\Core\ValueMapperTrait;
2223
use Google\Spanner\V1\TypeCode;
2324

2425
/**
@@ -27,8 +28,7 @@
2728
class ValueMapper
2829
{
2930
use ArrayTrait;
30-
31-
const NANO_REGEX = '/(?:\.(\d{1,9})Z)|(?:Z)/';
31+
use ValueMapperTrait;
3232

3333
const TYPE_BOOL = TypeCode::BOOL;
3434
const TYPE_INT64 = TypeCode::INT64;
@@ -185,23 +185,6 @@ public function decodeValues(array $columns, array $row, $format)
185185
}
186186
}
187187

188-
/**
189-
* Convert a timestamp string to a Timestamp class with nanosecond support.
190-
*
191-
* @param string $timestamp The timestamp string
192-
* @return Timestamp
193-
*/
194-
public function createTimestampWithNanos($timestamp)
195-
{
196-
$matches = [];
197-
preg_match(self::NANO_REGEX, $timestamp, $matches);
198-
$timestamp = preg_replace(self::NANO_REGEX, '.000000Z', $timestamp);
199-
200-
$dt = \DateTimeImmutable::createFromFormat(Timestamp::FORMAT, str_replace('..', '.', $timestamp));
201-
202-
return new Timestamp($dt, (isset($matches[1])) ? $matches[1] : 0);
203-
}
204-
205188
/**
206189
* Convert a single value to its corresponding PHP type.
207190
*
@@ -223,7 +206,7 @@ private function decodeValue($value, array $type)
223206
break;
224207

225208
case self::TYPE_TIMESTAMP:
226-
$value = $this->createTimestampWithNanos($value);
209+
$value = $this->createTimestampWithNanos($value, Timestamp::class);
227210
break;
228211

229212
case self::TYPE_DATE:

0 commit comments

Comments
 (0)