google-cloud-firestore 0.22.0 → 0.23.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|