google-cloud-firestore 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +8 -0
  3. data/LICENSE +201 -0
  4. data/README.md +30 -0
  5. data/lib/google-cloud-firestore.rb +106 -0
  6. data/lib/google/cloud/firestore.rb +514 -0
  7. data/lib/google/cloud/firestore/batch.rb +462 -0
  8. data/lib/google/cloud/firestore/client.rb +449 -0
  9. data/lib/google/cloud/firestore/collection_reference.rb +249 -0
  10. data/lib/google/cloud/firestore/commit_response.rb +145 -0
  11. data/lib/google/cloud/firestore/convert.rb +561 -0
  12. data/lib/google/cloud/firestore/credentials.rb +35 -0
  13. data/lib/google/cloud/firestore/document_reference.rb +468 -0
  14. data/lib/google/cloud/firestore/document_snapshot.rb +324 -0
  15. data/lib/google/cloud/firestore/field_path.rb +216 -0
  16. data/lib/google/cloud/firestore/field_value.rb +113 -0
  17. data/lib/google/cloud/firestore/generate.rb +35 -0
  18. data/lib/google/cloud/firestore/query.rb +651 -0
  19. data/lib/google/cloud/firestore/service.rb +176 -0
  20. data/lib/google/cloud/firestore/transaction.rb +726 -0
  21. data/lib/google/cloud/firestore/v1beta1.rb +121 -0
  22. data/lib/google/cloud/firestore/v1beta1/doc/google/firestore/v1beta1/common.rb +63 -0
  23. data/lib/google/cloud/firestore/v1beta1/doc/google/firestore/v1beta1/document.rb +134 -0
  24. data/lib/google/cloud/firestore/v1beta1/doc/google/firestore/v1beta1/firestore.rb +584 -0
  25. data/lib/google/cloud/firestore/v1beta1/doc/google/firestore/v1beta1/query.rb +215 -0
  26. data/lib/google/cloud/firestore/v1beta1/doc/google/firestore/v1beta1/write.rb +167 -0
  27. data/lib/google/cloud/firestore/v1beta1/doc/google/protobuf/any.rb +124 -0
  28. data/lib/google/cloud/firestore/v1beta1/doc/google/protobuf/timestamp.rb +106 -0
  29. data/lib/google/cloud/firestore/v1beta1/doc/google/protobuf/wrappers.rb +89 -0
  30. data/lib/google/cloud/firestore/v1beta1/doc/google/rpc/status.rb +83 -0
  31. data/lib/google/cloud/firestore/v1beta1/doc/overview.rb +53 -0
  32. data/lib/google/cloud/firestore/v1beta1/firestore_client.rb +974 -0
  33. data/lib/google/cloud/firestore/v1beta1/firestore_client_config.json +100 -0
  34. data/lib/google/cloud/firestore/version.rb +22 -0
  35. data/lib/google/firestore/v1beta1/common_pb.rb +44 -0
  36. data/lib/google/firestore/v1beta1/document_pb.rb +49 -0
  37. data/lib/google/firestore/v1beta1/firestore_pb.rb +219 -0
  38. data/lib/google/firestore/v1beta1/firestore_services_pb.rb +87 -0
  39. data/lib/google/firestore/v1beta1/query_pb.rb +103 -0
  40. data/lib/google/firestore/v1beta1/write_pb.rb +73 -0
  41. metadata +251 -0
@@ -0,0 +1,462 @@
1
+ # Copyright 2017 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
+ require "google/cloud/firestore/v1beta1"
17
+ require "google/cloud/firestore/collection_reference"
18
+ require "google/cloud/firestore/document_reference"
19
+ require "google/cloud/firestore/document_snapshot"
20
+ require "google/cloud/firestore/commit_response"
21
+ require "google/cloud/firestore/convert"
22
+
23
+ module Google
24
+ module Cloud
25
+ module Firestore
26
+ ##
27
+ # # Batch
28
+ #
29
+ # A batch in Cloud Firestore is a set of writes that execute
30
+ # atomically at a single logical point in time in a database.
31
+ #
32
+ # All changes are accumulated in memory until the block passed to
33
+ # {Database#batch} completes. Unlike transactions, batches don't lock on
34
+ # document reads, should only fail if users provide preconditions, and are
35
+ # not automatically retried.
36
+ #
37
+ # @see https://firebase.google.com/docs/firestore/manage-data/transactions
38
+ # Transactions and Batched Writes
39
+ #
40
+ # @example
41
+ # require "google/cloud/firestore"
42
+ #
43
+ # firestore = Google::Cloud::Firestore.new
44
+ #
45
+ # firestore.batch do |b|
46
+ # # Set the data for NYC
47
+ # b.set("cities/NYC", { name: "New York City" })
48
+ #
49
+ # # Update the population for SF
50
+ # b.update("cities/SF", { population: 1000000 })
51
+ #
52
+ # # Delete LA
53
+ # b.delete("cities/LA")
54
+ # end
55
+ #
56
+ class Batch
57
+ ##
58
+ # @private New Batch object.
59
+ def initialize
60
+ @writes = []
61
+ end
62
+
63
+ ##
64
+ # The client the Cloud Firestore batch belongs to.
65
+ #
66
+ # @return [Client] firestore client.
67
+ def firestore
68
+ @client
69
+ end
70
+ alias_method :client, :firestore
71
+
72
+ # @!group Modifications
73
+
74
+ ##
75
+ # Create a document with the provided data (fields and values).
76
+ #
77
+ # The batch will fail if the document already exists.
78
+ #
79
+ # @param [String, DocumentReference] doc A string representing the
80
+ # path of the document, or a document reference object.
81
+ # @param [Hash] data The document's fields and values.
82
+ #
83
+ # @example Create a document using a document path:
84
+ # require "google/cloud/firestore"
85
+ #
86
+ # firestore = Google::Cloud::Firestore.new
87
+ #
88
+ # firestore.batch do |b|
89
+ # b.create("cities/NYC", { name: "New York City" })
90
+ # end
91
+ #
92
+ # @example Create a document using a document reference:
93
+ # require "google/cloud/firestore"
94
+ #
95
+ # firestore = Google::Cloud::Firestore.new
96
+ #
97
+ # # Get a document reference
98
+ # nyc_ref = firestore.doc "cities/NYC"
99
+ #
100
+ # firestore.batch do |b|
101
+ # b.create(nyc_ref, { name: "New York City" })
102
+ # end
103
+ #
104
+ # @example Create a document and set a field to server_time:
105
+ # require "google/cloud/firestore"
106
+ #
107
+ # firestore = Google::Cloud::Firestore.new
108
+ #
109
+ # # Get a document reference
110
+ # nyc_ref = firestore.doc "cities/NYC"
111
+ #
112
+ # firestore.batch do |b|
113
+ # b.create(nyc_ref, { name: "New York City",
114
+ # updated_at: firestore.field_server_time })
115
+ # end
116
+ #
117
+ def create doc, data
118
+ ensure_not_closed!
119
+
120
+ doc_path = coalesce_doc_path_argument doc
121
+
122
+ @writes << Convert.writes_for_create(doc_path, data)
123
+
124
+ nil
125
+ end
126
+
127
+ ##
128
+ # Write the provided data (fields and values) to the provided document.
129
+ # If the document does not exist, it will be created. By default, the
130
+ # provided data overwrites existing data, but the provided data can be
131
+ # merged into the existing document using the `merge` argument.
132
+ #
133
+ # If you're not sure whether the document exists, use the `merge`
134
+ # argument to merge the new data with any existing document data to
135
+ # avoid overwriting entire documents.
136
+ #
137
+ # @param [String, DocumentReference] doc A string representing the
138
+ # path of the document, or a document reference object.
139
+ # @param [Hash] data The document's fields and values.
140
+ # @param [Boolean, FieldPath, String, Symbol] merge When
141
+ # `true`, all provided data is merged with the existing document data.
142
+ # When the argument is one or more field path, only the data for
143
+ # fields in this argument is merged with the existing document data.
144
+ # The default is to not merge, but to instead overwrite the existing
145
+ # document data.
146
+ #
147
+ # @example Set a document using a document path:
148
+ # require "google/cloud/firestore"
149
+ #
150
+ # firestore = Google::Cloud::Firestore.new
151
+ #
152
+ # firestore.batch do |b|
153
+ # b.set("cities/NYC", { name: "New York City" })
154
+ # end
155
+ #
156
+ # @example Create a document using a document reference:
157
+ # require "google/cloud/firestore"
158
+ #
159
+ # firestore = Google::Cloud::Firestore.new
160
+ #
161
+ # # Get a document reference
162
+ # nyc_ref = firestore.doc "cities/NYC"
163
+ #
164
+ # firestore.batch do |b|
165
+ # b.set(nyc_ref, { name: "New York City" })
166
+ # end
167
+ #
168
+ # @example Set a document and merge all data:
169
+ # require "google/cloud/firestore"
170
+ #
171
+ # firestore = Google::Cloud::Firestore.new
172
+ #
173
+ # firestore.batch do |b|
174
+ # b.set("cities/NYC", { name: "New York City" }, merge: true)
175
+ # end
176
+ #
177
+ # @example Set a document and merge only name:
178
+ # require "google/cloud/firestore"
179
+ #
180
+ # firestore = Google::Cloud::Firestore.new
181
+ #
182
+ # firestore.batch do |b|
183
+ # b.set("cities/NYC", { name: "New York City" }, merge: :name)
184
+ # end
185
+ #
186
+ # @example Set a document and deleting a field using merge:
187
+ # require "google/cloud/firestore"
188
+ #
189
+ # firestore = Google::Cloud::Firestore.new
190
+ #
191
+ # # Get a document reference
192
+ # nyc_ref = firestore.doc "cities/NYC"
193
+ #
194
+ # nyc_data = { name: "New York City",
195
+ # trash: firestore.field_delete }
196
+ #
197
+ # firestore.batch do |b|
198
+ # b.set(nyc_ref, nyc_data, merge: true)
199
+ # end
200
+ #
201
+ # @example Set a document and set a field to server_time:
202
+ # require "google/cloud/firestore"
203
+ #
204
+ # firestore = Google::Cloud::Firestore.new
205
+ #
206
+ # # Get a document reference
207
+ # nyc_ref = firestore.doc "cities/NYC"
208
+ #
209
+ # nyc_data = { name: "New York City",
210
+ # updated_at: firestore.field_server_time }
211
+ #
212
+ # firestore.batch do |b|
213
+ # b.set(nyc_ref, nyc_data, merge: true)
214
+ # end
215
+ #
216
+ def set doc, data, merge: nil
217
+ ensure_not_closed!
218
+
219
+ doc_path = coalesce_doc_path_argument doc
220
+
221
+ @writes << Convert.writes_for_set(doc_path, data, merge: merge)
222
+
223
+ nil
224
+ end
225
+
226
+ ##
227
+ # Update the document with the provided data (fields and values). The
228
+ # provided data is merged into the existing document data.
229
+ #
230
+ # The batch will fail if the document does not exist.
231
+ #
232
+ # @param [String, DocumentReference] doc A string representing the
233
+ # path of the document, or a document reference object.
234
+ # @param [Hash<FieldPath|String|Symbol, Object>] data The document's
235
+ # fields and values.
236
+ #
237
+ # The top-level keys in the data hash are considered field paths, and
238
+ # can either be a FieldPath object, or a string representing the
239
+ # nested fields. In other words the string represents individual
240
+ # fields joined by ".". Fields containing `~`, `*`, `/`, `[`, `]`, and
241
+ # `.` cannot be in a dotted string, and should provided using a
242
+ # {FieldPath} object instead.
243
+ # @param [Time] update_time When set, the document must have been last
244
+ # updated at that time. Optional.
245
+ #
246
+ # @example Update a document using a document path:
247
+ # require "google/cloud/firestore"
248
+ #
249
+ # firestore = Google::Cloud::Firestore.new
250
+ #
251
+ # firestore.batch do |b|
252
+ # b.update("cities/NYC", { name: "New York City" })
253
+ # end
254
+ #
255
+ # @example Directly update a deeply-nested field with a `FieldPath`:
256
+ # require "google/cloud/firestore"
257
+ #
258
+ # firestore = Google::Cloud::Firestore.new
259
+ #
260
+ # nested_field_path = Google::Cloud::Firestore::FieldPath.new(
261
+ # :favorites, :food
262
+ # )
263
+ #
264
+ # firestore.batch do |b|
265
+ # b.update("users/frank", { nested_field_path: "Pasta" })
266
+ # end
267
+ #
268
+ # @example Update a document using a document reference:
269
+ # require "google/cloud/firestore"
270
+ #
271
+ # firestore = Google::Cloud::Firestore.new
272
+ #
273
+ # # Get a document reference
274
+ # nyc_ref = firestore.doc "cities/NYC"
275
+ #
276
+ # firestore.batch do |b|
277
+ # b.update(nyc_ref, { name: "New York City" })
278
+ # end
279
+ #
280
+ # @example Update a document using the `update_time` precondition:
281
+ # require "google/cloud/firestore"
282
+ #
283
+ # firestore = Google::Cloud::Firestore.new
284
+ #
285
+ # last_updated_at = Time.now - 42 # 42 seconds ago
286
+ #
287
+ # firestore.batch do |b|
288
+ # b.update("cities/NYC", { name: "New York City" },
289
+ # update_time: last_updated_at)
290
+ # end
291
+ #
292
+ # @example Update a document and deleting a field:
293
+ # require "google/cloud/firestore"
294
+ #
295
+ # firestore = Google::Cloud::Firestore.new
296
+ #
297
+ # # Get a document reference
298
+ # nyc_ref = firestore.doc "cities/NYC"
299
+ #
300
+ # nyc_data = { name: "New York City",
301
+ # trash: firestore.field_delete }
302
+ #
303
+ # firestore.batch do |b|
304
+ # b.update(nyc_ref, nyc_data)
305
+ # end
306
+ #
307
+ # @example Update a document and set a field to server_time:
308
+ # require "google/cloud/firestore"
309
+ #
310
+ # firestore = Google::Cloud::Firestore.new
311
+ #
312
+ # # Get a document reference
313
+ # nyc_ref = firestore.doc "cities/NYC"
314
+ #
315
+ # nyc_data = { name: "New York City",
316
+ # updated_at: firestore.field_server_time }
317
+ #
318
+ # firestore.batch do |b|
319
+ # b.update(nyc_ref, nyc_data)
320
+ # end
321
+ #
322
+ def update doc, data, update_time: nil
323
+ ensure_not_closed!
324
+
325
+ doc_path = coalesce_doc_path_argument doc
326
+
327
+ @writes << Convert.writes_for_update(doc_path, data,
328
+ update_time: update_time)
329
+
330
+ nil
331
+ end
332
+
333
+ ##
334
+ # Deletes a document from the database.
335
+ #
336
+ # @param [String, DocumentReference] doc A string representing the
337
+ # path of the document, or a document reference object.
338
+ # @param [Boolean] exists Whether the document must exist. When `true`,
339
+ # the document must exist or an error is raised. Default is `false`.
340
+ # Optional.
341
+ # @param [Time] update_time When set, the document must have been last
342
+ # updated at that time. Optional.
343
+ #
344
+ # @example Delete a document using a document path:
345
+ # require "google/cloud/firestore"
346
+ #
347
+ # firestore = Google::Cloud::Firestore.new
348
+ #
349
+ # firestore.batch do |b|
350
+ # b.delete "cities/NYC"
351
+ # end
352
+ #
353
+ # @example Delete a document using a document reference:
354
+ # require "google/cloud/firestore"
355
+ #
356
+ # firestore = Google::Cloud::Firestore.new
357
+ #
358
+ # # Get a document reference
359
+ # nyc_ref = firestore.doc "cities/NYC"
360
+ #
361
+ # firestore.batch do |b|
362
+ # b.delete nyc_ref
363
+ # end
364
+ #
365
+ # @example Delete a document using `exists`:
366
+ # require "google/cloud/firestore"
367
+ #
368
+ # firestore = Google::Cloud::Firestore.new
369
+ #
370
+ # firestore.batch do |b|
371
+ # b.delete "cities/NYC", exists: true
372
+ # end
373
+ #
374
+ # @example Delete a document using the `update_time` precondition:
375
+ # require "google/cloud/firestore"
376
+ #
377
+ # firestore = Google::Cloud::Firestore.new
378
+ #
379
+ # last_updated_at = Time.now - 42 # 42 seconds ago
380
+ #
381
+ # firestore.batch do |b|
382
+ # b.delete "cities/NYC", update_time: last_updated_at
383
+ # end
384
+ #
385
+ def delete doc, exists: nil, update_time: nil
386
+ ensure_not_closed!
387
+
388
+ doc_path = coalesce_doc_path_argument doc
389
+
390
+ @writes << Convert.write_for_delete(
391
+ doc_path, exists: exists, update_time: update_time)
392
+
393
+ nil
394
+ end
395
+
396
+ # @!endgroup
397
+
398
+ ##
399
+ # @private commit the batch
400
+ def commit
401
+ ensure_not_closed!
402
+ @closed = true
403
+ return nil if @writes.empty?
404
+ resp = service.commit @writes.flatten
405
+ return nil if resp.nil?
406
+ CommitResponse.from_grpc resp, @writes
407
+ end
408
+
409
+ ##
410
+ # @private the batch is complete and closed
411
+ def closed?
412
+ @closed
413
+ end
414
+
415
+ ##
416
+ # @private New Batch reference object from a path.
417
+ def self.from_client client
418
+ new.tap do |b|
419
+ b.instance_variable_set :@client, client
420
+ end
421
+ end
422
+
423
+ ##
424
+ # @private The Service object.
425
+ def service
426
+ ensure_client!
427
+
428
+ firestore.service
429
+ end
430
+
431
+ protected
432
+
433
+ ##
434
+ # @private
435
+ def coalesce_doc_path_argument doc_path
436
+ return doc_path.path if doc_path.respond_to? :path
437
+
438
+ client.doc(doc_path).path
439
+ end
440
+
441
+ ##
442
+ # @private
443
+ def ensure_not_closed!
444
+ fail "batch is closed" if closed?
445
+ end
446
+
447
+ ##
448
+ # @private Raise an error unless an database available.
449
+ def ensure_client!
450
+ fail "Must have active connection to service" unless firestore
451
+ end
452
+
453
+ ##
454
+ # @private Raise an error unless an active connection to the service
455
+ # is available.
456
+ def ensure_service!
457
+ fail "Must have active connection to service" unless service
458
+ end
459
+ end
460
+ end
461
+ end
462
+ end