google-cloud-firestore 0.22.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +1 -0
- data/README.md +8 -8
- data/lib/google-cloud-firestore.rb +1 -1
- data/lib/google/cloud/firestore.rb +46 -0
- data/lib/google/cloud/firestore/batch.rb +1 -1
- data/lib/google/cloud/firestore/client.rb +18 -13
- data/lib/google/cloud/firestore/convert.rb +78 -35
- data/lib/google/cloud/firestore/credentials.rb +2 -12
- data/lib/google/cloud/firestore/document_change.rb +124 -0
- data/lib/google/cloud/firestore/document_listener.rb +125 -0
- data/lib/google/cloud/firestore/document_reference.rb +35 -0
- data/lib/google/cloud/firestore/document_snapshot.rb +91 -9
- data/lib/google/cloud/firestore/field_path.rb +23 -13
- data/lib/google/cloud/firestore/query.rb +513 -69
- data/lib/google/cloud/firestore/query_listener.rb +118 -0
- data/lib/google/cloud/firestore/query_snapshot.rb +121 -0
- data/lib/google/cloud/firestore/service.rb +8 -0
- data/lib/google/cloud/firestore/transaction.rb +2 -2
- data/lib/google/cloud/firestore/v1beta1.rb +62 -37
- data/lib/google/cloud/firestore/v1beta1/credentials.rb +41 -0
- data/lib/google/cloud/firestore/v1beta1/doc/google/firestore/v1beta1/common.rb +1 -1
- data/lib/google/cloud/firestore/v1beta1/doc/google/firestore/v1beta1/document.rb +5 -4
- data/lib/google/cloud/firestore/v1beta1/doc/google/firestore/v1beta1/firestore.rb +1 -12
- data/lib/google/cloud/firestore/v1beta1/doc/google/firestore/v1beta1/query.rb +4 -1
- data/lib/google/cloud/firestore/v1beta1/doc/google/firestore/v1beta1/write.rb +37 -8
- data/lib/google/cloud/firestore/v1beta1/doc/google/protobuf/any.rb +1 -1
- data/lib/google/cloud/firestore/v1beta1/doc/google/protobuf/empty.rb +28 -0
- data/lib/google/cloud/firestore/v1beta1/doc/google/protobuf/timestamp.rb +1 -1
- data/lib/google/cloud/firestore/v1beta1/doc/google/protobuf/wrappers.rb +1 -1
- data/lib/google/cloud/firestore/v1beta1/doc/google/rpc/status.rb +1 -1
- data/lib/google/cloud/firestore/v1beta1/firestore_client.rb +124 -56
- data/lib/google/cloud/firestore/v1beta1/firestore_client_config.json +2 -2
- data/lib/google/cloud/firestore/version.rb +1 -1
- data/lib/google/cloud/firestore/watch/enumerator_queue.rb +47 -0
- data/lib/google/cloud/firestore/watch/inventory.rb +280 -0
- data/lib/google/cloud/firestore/watch/listener.rb +298 -0
- data/lib/google/cloud/firestore/watch/order.rb +98 -0
- data/lib/google/firestore/v1beta1/firestore_services_pb.rb +2 -4
- data/lib/google/firestore/v1beta1/query_pb.rb +1 -0
- data/lib/google/firestore/v1beta1/write_pb.rb +2 -0
- metadata +40 -3
- data/lib/google/cloud/firestore/v1beta1/doc/overview.rb +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c249cbd2bcfd378c5ab77ce2b5e717f629e741ca8c30b259897cfcd87ca732a
|
4
|
+
data.tar.gz: 90d335ef83762a548eefdc4ed2a35ea5c5c830a1069bd7b969e67a704496cf3b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f8c8534c873bf3b86e8bccce74529c69ffebb5ba14e377ad60e0b32ae319ae22d8b96ff3eece237786952d169f49210168f3243a220e963b363d740c84aa54f
|
7
|
+
data.tar.gz: e0ae957a20ae64ae3c26cc6f379c12080fb8d71cf6b30bc0e4717787e7fadf785dcd5694a5d2422477639cb971da33715f21dae5f20613f490dd8a3ab5d9b1ba
|
data/.yardopts
CHANGED
data/README.md
CHANGED
@@ -50,14 +50,14 @@ end
|
|
50
50
|
|
51
51
|
## Supported Ruby Versions
|
52
52
|
|
53
|
-
This library is supported on Ruby 2.
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
53
|
+
This library is supported on Ruby 2.3+.
|
54
|
+
|
55
|
+
Google provides official support for Ruby versions that are actively supported
|
56
|
+
by Ruby Core—that is, Ruby versions that are either in normal maintenance or
|
57
|
+
in security maintenance, and not end of life. Currently, this means Ruby 2.3
|
58
|
+
and later. Older versions of Ruby _may_ still work, but are unsupported and not
|
59
|
+
recommended. See https://www.ruby-lang.org/en/downloads/branches/ for details
|
60
|
+
about the Ruby support schedule.
|
61
61
|
|
62
62
|
[Client Library Documentation]: https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-firestore/latest/google/firestore/v1beta1
|
63
63
|
[Product Documentation]: https://cloud.google.com/firestore
|
@@ -76,7 +76,7 @@ module Google
|
|
76
76
|
# present, the default project for the credentials is used.
|
77
77
|
# @param [String, Hash, Google::Auth::Credentials] credentials The path to
|
78
78
|
# the keyfile as a String, the contents of the keyfile as a Hash, or a
|
79
|
-
# Google::Auth::Credentials object. (See {
|
79
|
+
# Google::Auth::Credentials object. (See {Firestore::Credentials})
|
80
80
|
# @param [String, Array<String>] scope The OAuth 2.0 scopes controlling the
|
81
81
|
# set of resources and operations that the connection can access. See
|
82
82
|
# [Using OAuth 2.0 to Access Google
|
@@ -390,6 +390,52 @@ module Google
|
|
390
390
|
# user_ref.update({ nested_field_path => "Pasta" })
|
391
391
|
# ```
|
392
392
|
#
|
393
|
+
# ### Listening for changes
|
394
|
+
#
|
395
|
+
# You can listen to a document reference or a collection reference/query for
|
396
|
+
# changes. The current document snapshot or query results snapshot will be
|
397
|
+
# yielded first, and each time the contents change.
|
398
|
+
#
|
399
|
+
# You can use {Firestore::DocumentReference#listen} to be notified of
|
400
|
+
# changes to a single document:
|
401
|
+
#
|
402
|
+
# ```ruby
|
403
|
+
# require "google/cloud/firestore"
|
404
|
+
#
|
405
|
+
# firestore = Google::Cloud::Firestore.new
|
406
|
+
#
|
407
|
+
# # Get a document reference
|
408
|
+
# nyc_ref = firestore.doc "cities/NYC"
|
409
|
+
#
|
410
|
+
# listener = nyc_ref.listen do |snapshot|
|
411
|
+
# puts "The population of #{snapshot[:name]} "
|
412
|
+
# puts "is #{snapshot[:population]}."
|
413
|
+
# end
|
414
|
+
#
|
415
|
+
# # When ready, stop the listen operation and close the stream.
|
416
|
+
# listener.stop
|
417
|
+
# ```
|
418
|
+
#
|
419
|
+
# You can use {Firestore::Query#listen} to be notified of changes to any
|
420
|
+
# document contained in the query:
|
421
|
+
#
|
422
|
+
# ```ruby
|
423
|
+
# require "google/cloud/firestore"
|
424
|
+
#
|
425
|
+
# firestore = Google::Cloud::Firestore.new
|
426
|
+
#
|
427
|
+
# # Create a query
|
428
|
+
# query = firestore.col(:cities).order(:population, :desc)
|
429
|
+
#
|
430
|
+
# listener = query.listen do |snapshot|
|
431
|
+
# puts "The query snapshot has #{snapshot.docs.count} documents "
|
432
|
+
# puts "and has #{snapshot.changes.count} changes."
|
433
|
+
# end
|
434
|
+
#
|
435
|
+
# # When ready, stop the listen operation and close the stream.
|
436
|
+
# listener.stop
|
437
|
+
# ```
|
438
|
+
#
|
393
439
|
# ## Using transactions and batched writes
|
394
440
|
#
|
395
441
|
# Cloud Firestore supports atomic operations for reading and writing data.
|
@@ -30,7 +30,7 @@ module Google
|
|
30
30
|
# atomically at a single logical point in time in a database.
|
31
31
|
#
|
32
32
|
# All changes are accumulated in memory until the block passed to
|
33
|
-
# {
|
33
|
+
# {Client#batch} completes. Unlike transactions, batches don't lock on
|
34
34
|
# document reads, should only fail if users provide preconditions, and are
|
35
35
|
# not automatically retried.
|
36
36
|
#
|
@@ -212,7 +212,7 @@ module Google
|
|
212
212
|
##
|
213
213
|
# Creates a field path object representing the sentinel ID of a
|
214
214
|
# document. It can be used in queries to sort or filter by the document
|
215
|
-
# ID. See {
|
215
|
+
# ID. See {FieldPath#document_id}.
|
216
216
|
#
|
217
217
|
# @return [FieldPath] The field path object.
|
218
218
|
#
|
@@ -225,9 +225,8 @@ module Google
|
|
225
225
|
# cities_col = firestore.col "cities"
|
226
226
|
#
|
227
227
|
# # Create a query
|
228
|
-
# query = cities_col.
|
229
|
-
#
|
230
|
-
# )
|
228
|
+
# query = cities_col.order(firestore.document_id)
|
229
|
+
# .start_at("NYC")
|
231
230
|
#
|
232
231
|
# query.get do |city|
|
233
232
|
# puts "#{city.document_id} has #{city[:population]} residents."
|
@@ -383,31 +382,37 @@ module Google
|
|
383
382
|
#
|
384
383
|
def transaction max_retries: nil
|
385
384
|
max_retries = 5 unless max_retries.is_a? Integer
|
386
|
-
|
387
|
-
backoff = 1.0
|
385
|
+
backoff = { current: 0, delay: 1.0, max: max_retries, mod: 1.3 }
|
388
386
|
|
389
387
|
transaction = Transaction.from_client self
|
390
388
|
begin
|
391
389
|
yield transaction
|
392
390
|
transaction.commit
|
393
391
|
rescue Google::Cloud::UnavailableError => err
|
394
|
-
# Re-raise if
|
395
|
-
raise err if
|
396
|
-
|
397
|
-
|
392
|
+
# Re-raise if retried more than the max
|
393
|
+
raise err if backoff[:current] > backoff[:max]
|
394
|
+
|
395
|
+
# Sleep with incremental backoff before restarting
|
396
|
+
sleep backoff[:delay]
|
397
|
+
|
398
|
+
# Update increment backoff delay and retry counter
|
399
|
+
backoff[:delay] *= backoff[:mod]
|
400
|
+
backoff[:current] += 1
|
401
|
+
|
398
402
|
# Create new transaction and retry
|
399
403
|
transaction = Transaction.from_client \
|
400
404
|
self, previous_transaction: transaction.transaction_id
|
401
|
-
retries += 1
|
402
405
|
retry
|
403
406
|
rescue Google::Cloud::InvalidArgumentError => err
|
404
|
-
# Return if a previous call
|
405
|
-
return nil if
|
407
|
+
# Return if a previous call was retried but ultimately succeeded
|
408
|
+
return nil if backoff[:current] > 0
|
409
|
+
|
406
410
|
# Re-raise error.
|
407
411
|
raise err
|
408
412
|
rescue StandardError => err
|
409
413
|
# Rollback transaction when handling unexpected error
|
410
414
|
transaction.rollback rescue nil
|
415
|
+
|
411
416
|
# Re-raise error.
|
412
417
|
raise err
|
413
418
|
end
|
@@ -43,9 +43,9 @@ module Google
|
|
43
43
|
Time.at timestamp.seconds, Rational(timestamp.nanos, 1000)
|
44
44
|
end
|
45
45
|
|
46
|
-
def fields_to_hash fields,
|
46
|
+
def fields_to_hash fields, client
|
47
47
|
Hash[fields.map do |key, value|
|
48
|
-
[key.to_sym, value_to_raw(value,
|
48
|
+
[key.to_sym, value_to_raw(value, client)]
|
49
49
|
end]
|
50
50
|
end
|
51
51
|
|
@@ -55,7 +55,7 @@ module Google
|
|
55
55
|
end]
|
56
56
|
end
|
57
57
|
|
58
|
-
def value_to_raw value,
|
58
|
+
def value_to_raw value, client
|
59
59
|
case value.value_type
|
60
60
|
when :null_value
|
61
61
|
nil
|
@@ -73,13 +73,13 @@ module Google
|
|
73
73
|
StringIO.new value.bytes_value
|
74
74
|
when :reference_value
|
75
75
|
Google::Cloud::Firestore::DocumentReference.from_path \
|
76
|
-
value.reference_value,
|
76
|
+
value.reference_value, client
|
77
77
|
when :geo_point_value
|
78
78
|
value.geo_point_value.to_hash
|
79
79
|
when :array_value
|
80
|
-
value.array_value.values.map { |v| value_to_raw v,
|
80
|
+
value.array_value.values.map { |v| value_to_raw v, client }
|
81
81
|
when :map_value
|
82
|
-
fields_to_hash value.map_value.fields,
|
82
|
+
fields_to_hash value.map_value.fields, client
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
@@ -104,9 +104,12 @@ module Google
|
|
104
104
|
Google::Firestore::V1beta1::Value.new(array_value:
|
105
105
|
Google::Firestore::V1beta1::ArrayValue.new(values: values))
|
106
106
|
elsif Hash === obj
|
107
|
-
|
108
|
-
|
109
|
-
|
107
|
+
# keys have been changed to strings before the hash gets here
|
108
|
+
geo_pairs = hash_is_geo_point? obj
|
109
|
+
if geo_pairs
|
110
|
+
Google::Firestore::V1beta1::Value.new(
|
111
|
+
geo_point_value: hash_to_geo_point(obj, geo_pairs)
|
112
|
+
)
|
110
113
|
else
|
111
114
|
fields = hash_to_fields obj
|
112
115
|
Google::Firestore::V1beta1::Value.new(map_value:
|
@@ -118,10 +121,30 @@ module Google
|
|
118
121
|
Google::Firestore::V1beta1::Value.new bytes_value: content
|
119
122
|
else
|
120
123
|
raise ArgumentError,
|
121
|
-
|
124
|
+
"A value of type #{obj.class} is not supported."
|
122
125
|
end
|
123
126
|
end
|
124
127
|
|
128
|
+
def hash_is_geo_point? hash
|
129
|
+
return false unless hash.keys.count == 2
|
130
|
+
|
131
|
+
pairs = hash.map { |k, v| [String(k), v] }.sort
|
132
|
+
if pairs.map(&:first) == ["latitude".freeze, "longitude".freeze]
|
133
|
+
pairs
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def hash_to_geo_point hash, pairs = nil
|
138
|
+
pairs ||= hash_is_geo_point? hash
|
139
|
+
|
140
|
+
raise ArgumentError, "value is not a geo point" unless pairs
|
141
|
+
|
142
|
+
Google::Type::LatLng.new(
|
143
|
+
latitude: pairs.first.last,
|
144
|
+
longitude: pairs.last.last,
|
145
|
+
)
|
146
|
+
end
|
147
|
+
|
125
148
|
def writes_for_create doc_path, data
|
126
149
|
writes = []
|
127
150
|
|
@@ -164,13 +187,15 @@ module Google
|
|
164
187
|
if merge == true
|
165
188
|
# extract the leaf node field paths from data
|
166
189
|
field_paths = identify_leaf_nodes data
|
190
|
+
allow_empty = true
|
167
191
|
else
|
168
192
|
field_paths = Array(merge).map do |field_path|
|
169
193
|
field_path = FieldPath.parse field_path unless field_path.is_a? FieldPath
|
170
194
|
field_path
|
171
195
|
end
|
196
|
+
allow_empty = false
|
172
197
|
end
|
173
|
-
return writes_for_set_merge doc_path, data, field_paths
|
198
|
+
return writes_for_set_merge doc_path, data, field_paths, allow_empty
|
174
199
|
end
|
175
200
|
|
176
201
|
writes = []
|
@@ -195,9 +220,11 @@ module Google
|
|
195
220
|
writes
|
196
221
|
end
|
197
222
|
|
198
|
-
def writes_for_set_merge doc_path, data, field_paths
|
223
|
+
def writes_for_set_merge doc_path, data, field_paths, allow_empty
|
199
224
|
raise ArgumentError, "data is required" unless data.is_a? Hash
|
200
225
|
|
226
|
+
validate_field_paths! field_paths
|
227
|
+
|
201
228
|
writes = []
|
202
229
|
|
203
230
|
# Ensure provided field paths are valid.
|
@@ -231,22 +258,32 @@ module Google
|
|
231
258
|
delete_valid_check = delete_valid_check.include? false
|
232
259
|
raise ArgumentError, "deleted field not included in merge" if delete_valid_check
|
233
260
|
|
261
|
+
server_time_paths.select! do |server_time_path|
|
262
|
+
field_paths.any? do |field_path|
|
263
|
+
server_time_path.formatted_string.start_with? field_path.formatted_string
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
234
267
|
# Choose only the data there are field paths for
|
235
268
|
field_paths -= delete_paths
|
236
269
|
field_paths -= server_time_paths
|
237
270
|
data = select_by_field_paths data, field_paths
|
271
|
+
# Restore delete paths
|
272
|
+
field_paths += delete_paths
|
238
273
|
|
239
|
-
if data.empty?
|
240
|
-
if server_time_paths.empty?
|
274
|
+
if data.empty? && !allow_empty
|
275
|
+
if server_time_paths.empty? && delete_paths.empty?
|
241
276
|
raise ArgumentError, "data required for set with merge"
|
242
277
|
end
|
243
|
-
|
278
|
+
end
|
279
|
+
|
280
|
+
if data.any? || field_paths.any? || (allow_empty && server_time_paths.empty?)
|
244
281
|
writes << Google::Firestore::V1beta1::Write.new(
|
245
282
|
update: Google::Firestore::V1beta1::Document.new(
|
246
283
|
name: doc_path,
|
247
284
|
fields: hash_to_fields(data)),
|
248
285
|
update_mask: Google::Firestore::V1beta1::DocumentMask.new(
|
249
|
-
field_paths: field_paths.map(&:formatted_string))
|
286
|
+
field_paths: field_paths.map(&:formatted_string).sort)
|
250
287
|
)
|
251
288
|
end
|
252
289
|
|
@@ -269,18 +306,7 @@ module Google
|
|
269
306
|
end
|
270
307
|
|
271
308
|
# Duplicate field paths check
|
272
|
-
|
273
|
-
if dup_keys.size != dup_keys.uniq.size
|
274
|
-
raise ArgumentError, "duplicate field paths"
|
275
|
-
end
|
276
|
-
dup_keys.each do |field_path|
|
277
|
-
prefix_check = dup_keys.select do |this_path|
|
278
|
-
this_path.start_with? "#{field_path}."
|
279
|
-
end
|
280
|
-
if prefix_check.any?
|
281
|
-
raise ArgumentError, "one field cannot be a prefix of another"
|
282
|
-
end
|
283
|
-
end
|
309
|
+
validate_field_paths! new_data_pairs.map(&:first)
|
284
310
|
|
285
311
|
delete_paths, new_data_pairs = new_data_pairs.partition do |field_path, value|
|
286
312
|
value.is_a?(FieldValue) && value.type == :delete
|
@@ -301,10 +327,9 @@ module Google
|
|
301
327
|
|
302
328
|
data, nested_server_time_paths = remove_field_value_from data, :server_time
|
303
329
|
|
304
|
-
server_time_paths = root_server_time_paths + nested_server_time_paths
|
305
330
|
server_time_paths = root_server_time_paths + nested_server_time_paths
|
306
331
|
|
307
|
-
field_paths = (field_paths
|
332
|
+
field_paths = (field_paths + delete_paths).uniq
|
308
333
|
field_paths.each do |field_path|
|
309
334
|
raise ArgumentError, "empty paths not allowed" if field_path.fields.empty?
|
310
335
|
end
|
@@ -319,7 +344,7 @@ module Google
|
|
319
344
|
name: doc_path,
|
320
345
|
fields: hash_to_fields(data)),
|
321
346
|
update_mask: Google::Firestore::V1beta1::DocumentMask.new(
|
322
|
-
field_paths: field_paths.map(&:formatted_string)),
|
347
|
+
field_paths: (field_paths).map(&:formatted_string).sort),
|
323
348
|
current_document: Google::Firestore::V1beta1::Precondition.new(
|
324
349
|
exists: true)
|
325
350
|
)
|
@@ -464,13 +489,15 @@ module Google
|
|
464
489
|
tmp_hash = ret_hash
|
465
490
|
prev_hash = ret_hash
|
466
491
|
dup_hash = hash.dup
|
467
|
-
fields = field_path.fields
|
492
|
+
fields = field_path.fields.dup
|
468
493
|
last_field = nil
|
469
494
|
|
470
495
|
# squash fields until the key exists?
|
471
|
-
|
472
|
-
|
473
|
-
|
496
|
+
if fields.count > 1
|
497
|
+
until dup_hash.key? fields.first
|
498
|
+
fields.unshift "#{fields.shift}.#{fields.shift}"
|
499
|
+
break if fields.count <= 1
|
500
|
+
end
|
474
501
|
end
|
475
502
|
|
476
503
|
fields.each do |field|
|
@@ -482,9 +509,25 @@ module Google
|
|
482
509
|
dup_hash = dup_hash[field]
|
483
510
|
end
|
484
511
|
prev_hash[last_field] = dup_hash
|
512
|
+
prev_hash.delete_if { |_k, v| v.nil? }
|
485
513
|
ret_hash
|
486
514
|
end
|
487
515
|
|
516
|
+
def validate_field_paths! field_paths
|
517
|
+
field_paths_strings = field_paths.map(&:formatted_string)
|
518
|
+
if field_paths_strings.size != field_paths_strings.uniq.size
|
519
|
+
raise ArgumentError, "duplicate field paths"
|
520
|
+
end
|
521
|
+
field_paths_strings.each do |field_path|
|
522
|
+
prefix_check = field_paths_strings.select do |this_path|
|
523
|
+
this_path.start_with? "#{field_path}."
|
524
|
+
end
|
525
|
+
if prefix_check.any?
|
526
|
+
raise ArgumentError, "one field cannot be a prefix of another"
|
527
|
+
end
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
488
531
|
def deep_merge_hashes left_hash, right_hash
|
489
532
|
right_hash.each_pair do |key, right_value|
|
490
533
|
left_value = left_hash[key]
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
|
16
|
-
require "
|
16
|
+
require "google/cloud/firestore/v1beta1/credentials"
|
17
17
|
|
18
18
|
module Google
|
19
19
|
module Cloud
|
@@ -37,17 +37,7 @@ module Google
|
|
37
37
|
#
|
38
38
|
# firestore.project_id #=> "my-project"
|
39
39
|
#
|
40
|
-
class Credentials < Google::
|
41
|
-
SCOPE = ["https://www.googleapis.com/auth/datastore"].freeze
|
42
|
-
PATH_ENV_VARS = %w[FIRESTORE_CREDENTIALS FIRESTORE_KEYFILE
|
43
|
-
GOOGLE_CLOUD_CREDENTIALS GOOGLE_CLOUD_KEYFILE
|
44
|
-
GCLOUD_KEYFILE].freeze
|
45
|
-
JSON_ENV_VARS = %w[FIRESTORE_CREDENTIALS_JSON FIRESTORE_KEYFILE_JSON
|
46
|
-
GOOGLE_CLOUD_CREDENTIALS_JSON
|
47
|
-
GOOGLE_CLOUD_KEYFILE_JSON
|
48
|
-
GCLOUD_KEYFILE_JSON].freeze
|
49
|
-
DEFAULT_PATHS = \
|
50
|
-
["~/.config/gcloud/application_default_credentials.json"].freeze
|
40
|
+
class Credentials < Google::Cloud::Firestore::V1beta1::Credentials
|
51
41
|
end
|
52
42
|
end
|
53
43
|
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# Copyright 2018 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
|
16
|
+
module Google
|
17
|
+
module Cloud
|
18
|
+
module Firestore
|
19
|
+
##
|
20
|
+
# # DocumentChange
|
21
|
+
#
|
22
|
+
# A DocumentChange object represents a change to the document matching a
|
23
|
+
# query. It contains the document affected and the type of change that
|
24
|
+
# occurred (added, modifed, or removed).
|
25
|
+
#
|
26
|
+
# See {Query#listen} and {QuerySnapshot#changes}.
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# require "google/cloud/firestore"
|
30
|
+
#
|
31
|
+
# firestore = Google::Cloud::Firestore.new
|
32
|
+
#
|
33
|
+
# # Create a query
|
34
|
+
# query = firestore.col(:cities).order(:population, :desc)
|
35
|
+
#
|
36
|
+
# listener = query.listen do |snapshot|
|
37
|
+
# puts "The query snapshot has #{snapshot.docs.count} documents "
|
38
|
+
# puts "and has #{snapshot.changes.count} changes."
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# # When ready, stop the listen operation and close the stream.
|
42
|
+
# listener.stop
|
43
|
+
#
|
44
|
+
class DocumentChange
|
45
|
+
##
|
46
|
+
# The document snapshot object for the data.
|
47
|
+
#
|
48
|
+
# @return [DocumentSnapshot] document snapshot.
|
49
|
+
#
|
50
|
+
def doc
|
51
|
+
@doc
|
52
|
+
end
|
53
|
+
alias document doc
|
54
|
+
|
55
|
+
##
|
56
|
+
# The type of change (':added', ':modified', or ':removed').
|
57
|
+
#
|
58
|
+
# @return [Symbol] The type of change.
|
59
|
+
#
|
60
|
+
def type
|
61
|
+
return :removed if @new_index.nil?
|
62
|
+
return :added if @old_index.nil?
|
63
|
+
:modified
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Determines whether the document was added.
|
68
|
+
#
|
69
|
+
# @return [Boolean] Whether the document was added.
|
70
|
+
#
|
71
|
+
def added?
|
72
|
+
type == :added
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# Determines whether the document was modified.
|
77
|
+
#
|
78
|
+
# @return [Boolean] Whether the document was modified.
|
79
|
+
#
|
80
|
+
def modified?
|
81
|
+
type == :modified
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Determines whether the document was removed.
|
86
|
+
#
|
87
|
+
# @return [Boolean] Whether the document was removed.
|
88
|
+
#
|
89
|
+
def removed?
|
90
|
+
type == :removed
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# The index in the documents array prior to the change.
|
95
|
+
#
|
96
|
+
# @return [Integer, nil] The old index
|
97
|
+
#
|
98
|
+
def old_index
|
99
|
+
@old_index
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# The index in the documents array after the change.
|
104
|
+
#
|
105
|
+
# @return [Integer, nil] The new index
|
106
|
+
#
|
107
|
+
def new_index
|
108
|
+
@new_index
|
109
|
+
end
|
110
|
+
|
111
|
+
##
|
112
|
+
# @private New DocumentChange from a
|
113
|
+
# Google::Cloud::Firestore::DocumentSnapshot object.
|
114
|
+
def self.from_doc doc, old_index, new_index
|
115
|
+
new.tap do |s|
|
116
|
+
s.instance_variable_set :@doc, doc
|
117
|
+
s.instance_variable_set :@old_index, old_index
|
118
|
+
s.instance_variable_set :@new_index, new_index
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|