google-cloud-firestore 0.20.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 +7 -0
- data/.yardopts +8 -0
- data/LICENSE +201 -0
- data/README.md +30 -0
- data/lib/google-cloud-firestore.rb +106 -0
- data/lib/google/cloud/firestore.rb +514 -0
- data/lib/google/cloud/firestore/batch.rb +462 -0
- data/lib/google/cloud/firestore/client.rb +449 -0
- data/lib/google/cloud/firestore/collection_reference.rb +249 -0
- data/lib/google/cloud/firestore/commit_response.rb +145 -0
- data/lib/google/cloud/firestore/convert.rb +561 -0
- data/lib/google/cloud/firestore/credentials.rb +35 -0
- data/lib/google/cloud/firestore/document_reference.rb +468 -0
- data/lib/google/cloud/firestore/document_snapshot.rb +324 -0
- data/lib/google/cloud/firestore/field_path.rb +216 -0
- data/lib/google/cloud/firestore/field_value.rb +113 -0
- data/lib/google/cloud/firestore/generate.rb +35 -0
- data/lib/google/cloud/firestore/query.rb +651 -0
- data/lib/google/cloud/firestore/service.rb +176 -0
- data/lib/google/cloud/firestore/transaction.rb +726 -0
- data/lib/google/cloud/firestore/v1beta1.rb +121 -0
- data/lib/google/cloud/firestore/v1beta1/doc/google/firestore/v1beta1/common.rb +63 -0
- data/lib/google/cloud/firestore/v1beta1/doc/google/firestore/v1beta1/document.rb +134 -0
- data/lib/google/cloud/firestore/v1beta1/doc/google/firestore/v1beta1/firestore.rb +584 -0
- data/lib/google/cloud/firestore/v1beta1/doc/google/firestore/v1beta1/query.rb +215 -0
- data/lib/google/cloud/firestore/v1beta1/doc/google/firestore/v1beta1/write.rb +167 -0
- data/lib/google/cloud/firestore/v1beta1/doc/google/protobuf/any.rb +124 -0
- data/lib/google/cloud/firestore/v1beta1/doc/google/protobuf/timestamp.rb +106 -0
- data/lib/google/cloud/firestore/v1beta1/doc/google/protobuf/wrappers.rb +89 -0
- data/lib/google/cloud/firestore/v1beta1/doc/google/rpc/status.rb +83 -0
- data/lib/google/cloud/firestore/v1beta1/doc/overview.rb +53 -0
- data/lib/google/cloud/firestore/v1beta1/firestore_client.rb +974 -0
- data/lib/google/cloud/firestore/v1beta1/firestore_client_config.json +100 -0
- data/lib/google/cloud/firestore/version.rb +22 -0
- data/lib/google/firestore/v1beta1/common_pb.rb +44 -0
- data/lib/google/firestore/v1beta1/document_pb.rb +49 -0
- data/lib/google/firestore/v1beta1/firestore_pb.rb +219 -0
- data/lib/google/firestore/v1beta1/firestore_services_pb.rb +87 -0
- data/lib/google/firestore/v1beta1/query_pb.rb +103 -0
- data/lib/google/firestore/v1beta1/write_pb.rb +73 -0
- metadata +251 -0
@@ -0,0 +1,113 @@
|
|
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
|
+
module Google
|
17
|
+
module Cloud
|
18
|
+
module Firestore
|
19
|
+
##
|
20
|
+
# # FieldValue
|
21
|
+
#
|
22
|
+
# Represents a change to be made to fields in document data in the
|
23
|
+
# Firestore API.
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# require "google/cloud/firestore"
|
27
|
+
#
|
28
|
+
# firestore = Google::Cloud::Firestore.new
|
29
|
+
#
|
30
|
+
# user_snap = firestore.doc("users/frank").get
|
31
|
+
#
|
32
|
+
# # TODO
|
33
|
+
#
|
34
|
+
class FieldValue
|
35
|
+
##
|
36
|
+
# @private Creates a field value object representing changes made to
|
37
|
+
# fields in document data.
|
38
|
+
def initialize type
|
39
|
+
@type = type
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# The type of change to make to an individual field in document data.
|
44
|
+
#
|
45
|
+
# @return [Symbol] The type.
|
46
|
+
#
|
47
|
+
# @example
|
48
|
+
# require "google/cloud/firestore"
|
49
|
+
#
|
50
|
+
# firestore = Google::Cloud::Firestore.new
|
51
|
+
#
|
52
|
+
# # Get a document reference
|
53
|
+
# nyc_ref = firestore.doc "cities/NYC"
|
54
|
+
#
|
55
|
+
# field_delete = Google::Cloud::Firestore::FieldValue.delete
|
56
|
+
# field_delete.type #=> :delete
|
57
|
+
#
|
58
|
+
# nyc_ref.update({ name: "New York City",
|
59
|
+
# trash: field_delete })
|
60
|
+
#
|
61
|
+
def type
|
62
|
+
@type
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# Creates a field value object representing the deletion of a field in
|
67
|
+
# document data.
|
68
|
+
#
|
69
|
+
# @return [FieldValue] The delete field value object.
|
70
|
+
#
|
71
|
+
# @example
|
72
|
+
# require "google/cloud/firestore"
|
73
|
+
#
|
74
|
+
# firestore = Google::Cloud::Firestore.new
|
75
|
+
#
|
76
|
+
# # Get a document reference
|
77
|
+
# nyc_ref = firestore.doc "cities/NYC"
|
78
|
+
#
|
79
|
+
# field_delete = Google::Cloud::Firestore::FieldValue.delete
|
80
|
+
#
|
81
|
+
# nyc_ref.update({ name: "New York City",
|
82
|
+
# trash: field_delete })
|
83
|
+
#
|
84
|
+
def self.delete
|
85
|
+
new :delete
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# Creates a field value object representing set a field's value to
|
90
|
+
# the server timestamp when accessing the document data.
|
91
|
+
#
|
92
|
+
# @return [FieldValue] The server time field value object.
|
93
|
+
#
|
94
|
+
# @example
|
95
|
+
# require "google/cloud/firestore"
|
96
|
+
#
|
97
|
+
# firestore = Google::Cloud::Firestore.new
|
98
|
+
#
|
99
|
+
# # Get a document reference
|
100
|
+
# nyc_ref = firestore.doc "cities/NYC"
|
101
|
+
#
|
102
|
+
# field_server_time = Google::Cloud::Firestore::FieldValue.server_time
|
103
|
+
#
|
104
|
+
# nyc_ref.update({ name: "New York City",
|
105
|
+
# updated_at: field_server_time })
|
106
|
+
#
|
107
|
+
def self.server_time
|
108
|
+
new :server_time
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,35 @@
|
|
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 "securerandom"
|
17
|
+
|
18
|
+
module Google
|
19
|
+
module Cloud
|
20
|
+
module Firestore
|
21
|
+
##
|
22
|
+
# @private Helper module for generating random values
|
23
|
+
module Generate
|
24
|
+
CHARS = [*"a".."z", *"A".."Z", *"0".."9"]
|
25
|
+
|
26
|
+
def self.unique_id length: 20, chars: CHARS
|
27
|
+
size = chars.size
|
28
|
+
length.times.map do
|
29
|
+
chars[SecureRandom.random_number(size)]
|
30
|
+
end.join
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,651 @@
|
|
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/document_snapshot"
|
18
|
+
require "google/cloud/firestore/convert"
|
19
|
+
|
20
|
+
module Google
|
21
|
+
module Cloud
|
22
|
+
module Firestore
|
23
|
+
##
|
24
|
+
# # Query
|
25
|
+
#
|
26
|
+
# Represents a query to the Firestore API.
|
27
|
+
#
|
28
|
+
# Instances of this class are immutable. All methods that refine the query
|
29
|
+
# return new instances.
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# require "google/cloud/firestore"
|
33
|
+
#
|
34
|
+
# firestore = Google::Cloud::Firestore.new
|
35
|
+
#
|
36
|
+
# # Create a query
|
37
|
+
# query = firestore.col(:cities).select(:population)
|
38
|
+
#
|
39
|
+
# query.get do |city|
|
40
|
+
# puts "#{city.document_id} has #{city[:population]} residents."
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
class Query
|
44
|
+
##
|
45
|
+
# @private The parent path for the query.
|
46
|
+
attr_accessor :parent_path
|
47
|
+
|
48
|
+
##
|
49
|
+
# @private The Google::Firestore::V1beta1::Query object.
|
50
|
+
attr_accessor :query
|
51
|
+
|
52
|
+
##
|
53
|
+
# @private The firestore client object.
|
54
|
+
attr_accessor :client
|
55
|
+
|
56
|
+
##
|
57
|
+
# Restricts documents matching the query to return only data for the
|
58
|
+
# provided fields.
|
59
|
+
#
|
60
|
+
# @param [FieldPath, String, Symbol] fields A field path to
|
61
|
+
# filter results with and return only the specified fields. One or
|
62
|
+
# more field paths can be specified.
|
63
|
+
#
|
64
|
+
# If a {FieldPath} object is not provided then the field will be
|
65
|
+
# treated as a dotted string, meaning the string represents individual
|
66
|
+
# fields joined by ".". Fields containing `~`, `*`, `/`, `[`, `]`, and
|
67
|
+
# `.` cannot be in a dotted string, and should provided using a
|
68
|
+
# {FieldPath} object instead.
|
69
|
+
#
|
70
|
+
# @return [Query] New query with `select` called on it.
|
71
|
+
#
|
72
|
+
# @example
|
73
|
+
# require "google/cloud/firestore"
|
74
|
+
#
|
75
|
+
# firestore = Google::Cloud::Firestore.new
|
76
|
+
#
|
77
|
+
# # Get a collection reference
|
78
|
+
# cities_col = firestore.col "cities"
|
79
|
+
#
|
80
|
+
# # Create a query
|
81
|
+
# query = cities_col.select(:population)
|
82
|
+
#
|
83
|
+
# query.get do |city|
|
84
|
+
# puts "#{city.document_id} has #{city[:population]} residents."
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
def select *fields
|
88
|
+
new_query = @query.dup
|
89
|
+
new_query ||= StructuredQuery.new
|
90
|
+
|
91
|
+
field_refs = fields.flatten.compact.map do |field|
|
92
|
+
field = FieldPath.parse field unless field.is_a? FieldPath
|
93
|
+
StructuredQuery::FieldReference.new \
|
94
|
+
field_path: field.formatted_string
|
95
|
+
end
|
96
|
+
|
97
|
+
new_query.select ||= StructuredQuery::Projection.new
|
98
|
+
field_refs.each do |field_ref|
|
99
|
+
new_query.select.fields << field_ref
|
100
|
+
end
|
101
|
+
|
102
|
+
Query.start new_query, parent_path, client
|
103
|
+
end
|
104
|
+
|
105
|
+
##
|
106
|
+
# @private This is marked private and can't be removed.
|
107
|
+
#
|
108
|
+
# Selects documents from all collections, immediate children and nested,
|
109
|
+
# of where the query was created from.
|
110
|
+
#
|
111
|
+
# @return [Query] New query with `all_descendants` called on it.
|
112
|
+
#
|
113
|
+
# @example
|
114
|
+
# require "google/cloud/firestore"
|
115
|
+
#
|
116
|
+
# firestore = Google::Cloud::Firestore.new
|
117
|
+
#
|
118
|
+
# # Get a collection reference
|
119
|
+
# cities_col = firestore.col "cities"
|
120
|
+
#
|
121
|
+
# # Create a query
|
122
|
+
# query = cities_col.all_descendants
|
123
|
+
#
|
124
|
+
# query.get do |city|
|
125
|
+
# puts "#{city.document_id} has #{city[:population]} residents."
|
126
|
+
# end
|
127
|
+
#
|
128
|
+
def all_descendants
|
129
|
+
new_query = @query.dup
|
130
|
+
new_query ||= StructuredQuery.new
|
131
|
+
|
132
|
+
if new_query.from.empty?
|
133
|
+
fail "missing collection_id to specify descendants."
|
134
|
+
end
|
135
|
+
|
136
|
+
new_query.from.last.all_descendants = true
|
137
|
+
|
138
|
+
Query.start new_query, parent_path, client
|
139
|
+
end
|
140
|
+
|
141
|
+
##
|
142
|
+
# @private This is marked private and can't be removed.
|
143
|
+
#
|
144
|
+
# Selects only documents from collections that are immediate children of
|
145
|
+
# where the query was created from.
|
146
|
+
#
|
147
|
+
# @return [Query] New query with `direct_descendants` called on it.
|
148
|
+
#
|
149
|
+
# @example
|
150
|
+
# require "google/cloud/firestore"
|
151
|
+
#
|
152
|
+
# firestore = Google::Cloud::Firestore.new
|
153
|
+
#
|
154
|
+
# # Get a collection reference
|
155
|
+
# cities_col = firestore.col "cities"
|
156
|
+
#
|
157
|
+
# # Create a query
|
158
|
+
# query = cities_col.direct_descendants
|
159
|
+
#
|
160
|
+
# query.get do |city|
|
161
|
+
# puts "#{city.document_id} has #{city[:population]} residents."
|
162
|
+
# end
|
163
|
+
#
|
164
|
+
def direct_descendants
|
165
|
+
new_query = @query.dup
|
166
|
+
new_query ||= StructuredQuery.new
|
167
|
+
|
168
|
+
if new_query.from.empty?
|
169
|
+
fail "missing collection_id to specify descendants."
|
170
|
+
end
|
171
|
+
|
172
|
+
new_query.from.last.all_descendants = false
|
173
|
+
|
174
|
+
Query.start new_query, parent_path, client
|
175
|
+
end
|
176
|
+
|
177
|
+
##
|
178
|
+
# Filters the query on a field.
|
179
|
+
#
|
180
|
+
# @param [FieldPath, String, Symbol] field A field path to filter
|
181
|
+
# results with.
|
182
|
+
#
|
183
|
+
# If a {FieldPath} object is not provided then the field will be
|
184
|
+
# treated as a dotted string, meaning the string represents individual
|
185
|
+
# fields joined by ".". Fields containing `~`, `*`, `/`, `[`, `]`, and
|
186
|
+
# `.` cannot be in a dotted string, and should provided using a
|
187
|
+
# {FieldPath} object instead.
|
188
|
+
# @param [String, Symbol] operator The operation to compare the field
|
189
|
+
# to. Acceptable values include:
|
190
|
+
#
|
191
|
+
# * less than: `<`, `lt`
|
192
|
+
# * less than or equal: `<=`, `lte`
|
193
|
+
# * greater than: `>`, `gt`
|
194
|
+
# * greater than or equal: `>=`, `gte`
|
195
|
+
# * equal: `=`, `==`, `eq`, `eql`, `is`
|
196
|
+
# @param [Object] value A value the field is compared to.
|
197
|
+
#
|
198
|
+
# @return [Query] New query with `where` called on it.
|
199
|
+
#
|
200
|
+
# @example
|
201
|
+
# require "google/cloud/firestore"
|
202
|
+
#
|
203
|
+
# firestore = Google::Cloud::Firestore.new
|
204
|
+
#
|
205
|
+
# # Get a collection reference
|
206
|
+
# cities_col = firestore.col "cities"
|
207
|
+
#
|
208
|
+
# # Create a query
|
209
|
+
# query = cities_col.where(:population, :>=, 1000000)
|
210
|
+
#
|
211
|
+
# query.get do |city|
|
212
|
+
# puts "#{city.document_id} has #{city[:population]} residents."
|
213
|
+
# end
|
214
|
+
#
|
215
|
+
def where field, operator, value
|
216
|
+
new_query = @query.dup
|
217
|
+
new_query ||= StructuredQuery.new
|
218
|
+
|
219
|
+
field = FieldPath.parse field unless field.is_a? FieldPath
|
220
|
+
|
221
|
+
new_query.where ||= default_filter
|
222
|
+
new_query.where.composite_filter.filters << \
|
223
|
+
filter(field.formatted_string, operator, value)
|
224
|
+
|
225
|
+
Query.start new_query, parent_path, client
|
226
|
+
end
|
227
|
+
|
228
|
+
##
|
229
|
+
# Specifies an "order by" clause on a field.
|
230
|
+
#
|
231
|
+
# @param [FieldPath, String, Symbol] field A field path to order results
|
232
|
+
# with.
|
233
|
+
#
|
234
|
+
# If a {FieldPath} object is not provided then the field will be
|
235
|
+
# treated as a dotted string, meaning the string represents individual
|
236
|
+
# fields joined by ".". Fields containing `~`, `*`, `/`, `[`, `]`, and
|
237
|
+
# `.` cannot be in a dotted string, and should provided using a
|
238
|
+
# {FieldPath} object instead.
|
239
|
+
# @param [String, Symbol] direction The direction to order the results
|
240
|
+
# by. Values that start with "a" are considered `ascending`. Values
|
241
|
+
# that start with "d" are considered `descending`. Default is
|
242
|
+
# `ascending`. Optional.
|
243
|
+
#
|
244
|
+
# @return [Query] New query with `order` called on it.
|
245
|
+
#
|
246
|
+
# @example
|
247
|
+
# require "google/cloud/firestore"
|
248
|
+
#
|
249
|
+
# firestore = Google::Cloud::Firestore.new
|
250
|
+
#
|
251
|
+
# # Get a collection reference
|
252
|
+
# cities_col = firestore.col "cities"
|
253
|
+
#
|
254
|
+
# # Create a query
|
255
|
+
# query = cities_col.order(:name)
|
256
|
+
#
|
257
|
+
# query.get do |city|
|
258
|
+
# puts "#{city.document_id} has #{city[:population]} residents."
|
259
|
+
# end
|
260
|
+
#
|
261
|
+
# @example Order by name descending:
|
262
|
+
# require "google/cloud/firestore"
|
263
|
+
#
|
264
|
+
# firestore = Google::Cloud::Firestore.new
|
265
|
+
#
|
266
|
+
# # Get a collection reference
|
267
|
+
# cities_col = firestore.col "cities"
|
268
|
+
#
|
269
|
+
# # Create a query
|
270
|
+
# query = cities_col.order(:name, :desc)
|
271
|
+
#
|
272
|
+
# query.get do |city|
|
273
|
+
# puts "#{city.document_id} has #{city[:population]} residents."
|
274
|
+
# end
|
275
|
+
#
|
276
|
+
def order field, direction = :asc
|
277
|
+
new_query = @query.dup
|
278
|
+
new_query ||= StructuredQuery.new
|
279
|
+
|
280
|
+
field = FieldPath.parse field unless field.is_a? FieldPath
|
281
|
+
|
282
|
+
new_query.order_by << StructuredQuery::Order.new(
|
283
|
+
field: StructuredQuery::FieldReference.new(
|
284
|
+
field_path: field.formatted_string
|
285
|
+
),
|
286
|
+
direction: order_direction(direction))
|
287
|
+
|
288
|
+
Query.start new_query, parent_path, client
|
289
|
+
end
|
290
|
+
alias_method :order_by, :order
|
291
|
+
|
292
|
+
##
|
293
|
+
# Skips to an offset in a query. If the current query already has
|
294
|
+
# specified an offset, this will overwrite it.
|
295
|
+
#
|
296
|
+
# @param [Integer] num The number of results to skip.
|
297
|
+
#
|
298
|
+
# @return [Query] New query with `offset` called on it.
|
299
|
+
#
|
300
|
+
# @example
|
301
|
+
# require "google/cloud/firestore"
|
302
|
+
#
|
303
|
+
# firestore = Google::Cloud::Firestore.new
|
304
|
+
#
|
305
|
+
# # Get a collection reference
|
306
|
+
# cities_col = firestore.col "cities"
|
307
|
+
#
|
308
|
+
# # Create a query
|
309
|
+
# query = cities_col.limit(5).offset(10)
|
310
|
+
#
|
311
|
+
# query.get do |city|
|
312
|
+
# puts "#{city.document_id} has #{city[:population]} residents."
|
313
|
+
# end
|
314
|
+
#
|
315
|
+
def offset num
|
316
|
+
new_query = @query.dup
|
317
|
+
new_query ||= StructuredQuery.new
|
318
|
+
|
319
|
+
new_query.offset = num
|
320
|
+
|
321
|
+
Query.start new_query, parent_path, client
|
322
|
+
end
|
323
|
+
|
324
|
+
##
|
325
|
+
# Limits a query to return a fixed number of results. If the current
|
326
|
+
# query already has a limit set, this will overwrite it.
|
327
|
+
#
|
328
|
+
# @param [Integer] num The maximum number of results to return.
|
329
|
+
#
|
330
|
+
# @return [Query] New query with `limit` called on it.
|
331
|
+
#
|
332
|
+
# @example
|
333
|
+
# require "google/cloud/firestore"
|
334
|
+
#
|
335
|
+
# firestore = Google::Cloud::Firestore.new
|
336
|
+
#
|
337
|
+
# # Get a collection reference
|
338
|
+
# cities_col = firestore.col "cities"
|
339
|
+
#
|
340
|
+
# # Create a query
|
341
|
+
# query = cities_col.offset(10).limit(5)
|
342
|
+
#
|
343
|
+
# query.get do |city|
|
344
|
+
# puts "#{city.document_id} has #{city[:population]} residents."
|
345
|
+
# end
|
346
|
+
#
|
347
|
+
def limit num
|
348
|
+
new_query = @query.dup
|
349
|
+
new_query ||= StructuredQuery.new
|
350
|
+
|
351
|
+
new_query.limit = Google::Protobuf::Int32Value.new(value: num)
|
352
|
+
|
353
|
+
Query.start new_query, parent_path, client
|
354
|
+
end
|
355
|
+
|
356
|
+
##
|
357
|
+
# Starts query results at a set of field values. The result set will
|
358
|
+
# include the document specified by `values`.
|
359
|
+
#
|
360
|
+
# If the current query already has specified `start_at` or
|
361
|
+
# `start_after`, this will overwrite it.
|
362
|
+
#
|
363
|
+
# The values provided here are for the field paths provides to `order`.
|
364
|
+
# Values provided to `start_at` without an associated field path
|
365
|
+
# provided to `order` will result in an error.
|
366
|
+
#
|
367
|
+
# @param [Object] values The field value to start the query at.
|
368
|
+
#
|
369
|
+
# @return [Query] New query with `start_at` called on it.
|
370
|
+
#
|
371
|
+
# @example
|
372
|
+
# require "google/cloud/firestore"
|
373
|
+
#
|
374
|
+
# firestore = Google::Cloud::Firestore.new
|
375
|
+
#
|
376
|
+
# # Get a collection reference
|
377
|
+
# cities_col = firestore.col "cities"
|
378
|
+
#
|
379
|
+
# # Create a query
|
380
|
+
# query = cities_col.start_at("NYC").order(firestore.document_id)
|
381
|
+
#
|
382
|
+
# query.get do |city|
|
383
|
+
# puts "#{city.document_id} has #{city[:population]} residents."
|
384
|
+
# end
|
385
|
+
#
|
386
|
+
def start_at *values
|
387
|
+
new_query = @query.dup
|
388
|
+
new_query ||= StructuredQuery.new
|
389
|
+
|
390
|
+
values = values.flatten.map { |value| Convert.raw_to_value value }
|
391
|
+
new_query.start_at = Google::Firestore::V1beta1::Cursor.new(
|
392
|
+
values: values, before: true)
|
393
|
+
|
394
|
+
Query.start new_query, parent_path, client
|
395
|
+
end
|
396
|
+
|
397
|
+
|
398
|
+
##
|
399
|
+
# Starts query results after a set of field values. The result set will
|
400
|
+
# not include the document specified by `values`.
|
401
|
+
#
|
402
|
+
# If the current query already has specified `start_at` or
|
403
|
+
# `start_after`, this will overwrite it.
|
404
|
+
#
|
405
|
+
# The values provided here are for the field paths provides to `order`.
|
406
|
+
# Values provided to `start_after` without an associated field path
|
407
|
+
# provided to `order` will result in an error.
|
408
|
+
#
|
409
|
+
# @param [Object] values The field value to start the query after.
|
410
|
+
#
|
411
|
+
# @return [Query] New query with `start_after` called on it.
|
412
|
+
#
|
413
|
+
# @example
|
414
|
+
# require "google/cloud/firestore"
|
415
|
+
#
|
416
|
+
# firestore = Google::Cloud::Firestore.new
|
417
|
+
#
|
418
|
+
# # Get a collection reference
|
419
|
+
# cities_col = firestore.col "cities"
|
420
|
+
#
|
421
|
+
# # Create a query
|
422
|
+
# query = cities_col.start_after("NYC").order(firestore.document_id)
|
423
|
+
#
|
424
|
+
# query.get do |city|
|
425
|
+
# puts "#{city.document_id} has #{city[:population]} residents."
|
426
|
+
# end
|
427
|
+
#
|
428
|
+
def start_after *values
|
429
|
+
new_query = @query.dup
|
430
|
+
new_query ||= StructuredQuery.new
|
431
|
+
|
432
|
+
values = values.flatten.map { |value| Convert.raw_to_value value }
|
433
|
+
new_query.start_at = Google::Firestore::V1beta1::Cursor.new(
|
434
|
+
values: values, before: false)
|
435
|
+
|
436
|
+
Query.start new_query, parent_path, client
|
437
|
+
end
|
438
|
+
|
439
|
+
##
|
440
|
+
# Ends query results before a set of field values. The result set will
|
441
|
+
# not include the document specified by `values`.
|
442
|
+
#
|
443
|
+
# If the current query already has specified `end_before` or
|
444
|
+
# `end_at`, this will overwrite it.
|
445
|
+
#
|
446
|
+
# The values provided here are for the field paths provides to `order`.
|
447
|
+
# Values provided to `end_before` without an associated field path
|
448
|
+
# provided to `order` will result in an error.
|
449
|
+
#
|
450
|
+
# @param [Object] values The field value to end the query before.
|
451
|
+
#
|
452
|
+
# @return [Query] New query with `end_before` called on it.
|
453
|
+
#
|
454
|
+
# @example
|
455
|
+
# require "google/cloud/firestore"
|
456
|
+
#
|
457
|
+
# firestore = Google::Cloud::Firestore.new
|
458
|
+
#
|
459
|
+
# # Get a collection reference
|
460
|
+
# cities_col = firestore.col "cities"
|
461
|
+
#
|
462
|
+
# # Create a query
|
463
|
+
# query = cities_col.end_before("NYC").order(firestore.document_id)
|
464
|
+
#
|
465
|
+
# query.get do |city|
|
466
|
+
# puts "#{city.document_id} has #{city[:population]} residents."
|
467
|
+
# end
|
468
|
+
#
|
469
|
+
def end_before *values
|
470
|
+
new_query = @query.dup
|
471
|
+
new_query ||= StructuredQuery.new
|
472
|
+
|
473
|
+
values = values.flatten.map { |value| Convert.raw_to_value value }
|
474
|
+
new_query.end_at = Google::Firestore::V1beta1::Cursor.new(
|
475
|
+
values: values, before: true)
|
476
|
+
|
477
|
+
Query.start new_query, parent_path, client
|
478
|
+
end
|
479
|
+
|
480
|
+
##
|
481
|
+
# Ends query results at a set of field values. The result set will
|
482
|
+
# include the document specified by `values`.
|
483
|
+
#
|
484
|
+
# If the current query already has specified `end_before` or
|
485
|
+
# `end_at`, this will overwrite it.
|
486
|
+
#
|
487
|
+
# The values provided here are for the field paths provides to `order`.
|
488
|
+
# Values provided to `end_at` without an associated field path provided
|
489
|
+
# to `order` will result in an error.
|
490
|
+
#
|
491
|
+
# @param [Object] values The field value to end the query at.
|
492
|
+
#
|
493
|
+
# @return [Query] New query with `end_at` called on it.
|
494
|
+
#
|
495
|
+
# @example
|
496
|
+
# require "google/cloud/firestore"
|
497
|
+
#
|
498
|
+
# firestore = Google::Cloud::Firestore.new
|
499
|
+
#
|
500
|
+
# # Get a collection reference
|
501
|
+
# cities_col = firestore.col "cities"
|
502
|
+
#
|
503
|
+
# # Create a query
|
504
|
+
# query = cities_col.end_at("NYC").order(firestore.document_id)
|
505
|
+
#
|
506
|
+
# query.get do |city|
|
507
|
+
# puts "#{city.document_id} has #{city[:population]} residents."
|
508
|
+
# end
|
509
|
+
#
|
510
|
+
def end_at *values
|
511
|
+
new_query = @query.dup
|
512
|
+
new_query ||= StructuredQuery.new
|
513
|
+
|
514
|
+
values = values.flatten.map { |value| Convert.raw_to_value value }
|
515
|
+
new_query.end_at = Google::Firestore::V1beta1::Cursor.new(
|
516
|
+
values: values, before: false)
|
517
|
+
|
518
|
+
Query.start new_query, parent_path, client
|
519
|
+
end
|
520
|
+
|
521
|
+
##
|
522
|
+
# Retrieves document snapshots for the query.
|
523
|
+
#
|
524
|
+
# @yield [documents] The block for accessing the document snapshots.
|
525
|
+
# @yieldparam [DocumentReference] document A document snapshot.
|
526
|
+
#
|
527
|
+
# @return [Enumerator<DocumentReference>] A list of document snapshots.
|
528
|
+
#
|
529
|
+
# @example
|
530
|
+
# require "google/cloud/firestore"
|
531
|
+
#
|
532
|
+
# firestore = Google::Cloud::Firestore.new
|
533
|
+
#
|
534
|
+
# # Get a collection reference
|
535
|
+
# cities_col = firestore.col "cities"
|
536
|
+
#
|
537
|
+
# # Create a query
|
538
|
+
# query = cities_col.select(:population)
|
539
|
+
#
|
540
|
+
# query.get do |city|
|
541
|
+
# puts "#{city.document_id} has #{city[:population]} residents."
|
542
|
+
# end
|
543
|
+
#
|
544
|
+
def get
|
545
|
+
ensure_service!
|
546
|
+
|
547
|
+
return enum_for(:run) unless block_given?
|
548
|
+
|
549
|
+
results = service.run_query parent_path, @query
|
550
|
+
results.each do |result|
|
551
|
+
next if result.document.nil?
|
552
|
+
yield DocumentSnapshot.from_query_result(result, self)
|
553
|
+
end
|
554
|
+
end
|
555
|
+
alias_method :run, :get
|
556
|
+
|
557
|
+
##
|
558
|
+
# @private Start a new Query.
|
559
|
+
def self.start query, parent_path, client
|
560
|
+
query ||= StructuredQuery.new
|
561
|
+
Query.new.tap do |q|
|
562
|
+
q.instance_variable_set :@query, query
|
563
|
+
q.instance_variable_set :@parent_path, parent_path
|
564
|
+
q.instance_variable_set :@client, client
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
protected
|
569
|
+
|
570
|
+
StructuredQuery = Google::Firestore::V1beta1::StructuredQuery
|
571
|
+
|
572
|
+
FILTER_OPS = {
|
573
|
+
"<" => :LESS_THAN,
|
574
|
+
"lt" => :LESS_THAN,
|
575
|
+
"<=" => :LESS_THAN_OR_EQUAL,
|
576
|
+
"lte" => :LESS_THAN_OR_EQUAL,
|
577
|
+
">" => :GREATER_THAN,
|
578
|
+
"gt" => :GREATER_THAN,
|
579
|
+
">=" => :GREATER_THAN_OR_EQUAL,
|
580
|
+
"gte" => :GREATER_THAN_OR_EQUAL,
|
581
|
+
"=" => :EQUAL,
|
582
|
+
"==" => :EQUAL,
|
583
|
+
"eq" => :EQUAL,
|
584
|
+
"eql" => :EQUAL,
|
585
|
+
"is" => :EQUAL }
|
586
|
+
UNARY_NIL_VALUES = [nil, :null, :nil]
|
587
|
+
UNARY_NAN_VALUES = [:nan, Float::NAN]
|
588
|
+
UNARY_VALUES = UNARY_NIL_VALUES + UNARY_NAN_VALUES
|
589
|
+
|
590
|
+
def filter name, op, value
|
591
|
+
field = StructuredQuery::FieldReference.new field_path: name.to_s
|
592
|
+
op = FILTER_OPS[op.to_s.downcase] || :EQUAL
|
593
|
+
|
594
|
+
is_value_nan = value.respond_to?(:nan?) && value.nan?
|
595
|
+
if UNARY_VALUES.include?(value) || is_value_nan
|
596
|
+
if op != :EQUAL
|
597
|
+
fail ArgumentError, "can only check equality for #{value} values."
|
598
|
+
end
|
599
|
+
|
600
|
+
op = :IS_NULL
|
601
|
+
op = :IS_NAN if UNARY_NAN_VALUES.include?(value) || is_value_nan
|
602
|
+
|
603
|
+
return StructuredQuery::Filter.new(unary_filter:
|
604
|
+
StructuredQuery::UnaryFilter.new(field: field, op: op))
|
605
|
+
end
|
606
|
+
|
607
|
+
value = Convert.raw_to_value value
|
608
|
+
StructuredQuery::Filter.new(field_filter:
|
609
|
+
StructuredQuery::FieldFilter.new(field: field, op: op,
|
610
|
+
value: value))
|
611
|
+
end
|
612
|
+
|
613
|
+
def default_filter
|
614
|
+
StructuredQuery::Filter.new(composite_filter:
|
615
|
+
StructuredQuery::CompositeFilter.new(op: :AND))
|
616
|
+
end
|
617
|
+
|
618
|
+
def order_direction direction
|
619
|
+
if direction.to_s.downcase.start_with? "a"
|
620
|
+
:ASCENDING
|
621
|
+
elsif direction.to_s.downcase.start_with? "d"
|
622
|
+
:DESCENDING
|
623
|
+
else
|
624
|
+
:DIRECTION_UNSPECIFIED
|
625
|
+
end
|
626
|
+
end
|
627
|
+
|
628
|
+
##
|
629
|
+
# @private Raise an error unless an database available.
|
630
|
+
def ensure_client!
|
631
|
+
fail "Must have active connection to service" unless client
|
632
|
+
end
|
633
|
+
|
634
|
+
##
|
635
|
+
# @private The Service object.
|
636
|
+
def service
|
637
|
+
ensure_client!
|
638
|
+
|
639
|
+
client.service
|
640
|
+
end
|
641
|
+
|
642
|
+
##
|
643
|
+
# @private Raise an error unless an active connection to the service
|
644
|
+
# is available.
|
645
|
+
def ensure_service!
|
646
|
+
fail "Must have active connection to service" unless service
|
647
|
+
end
|
648
|
+
end
|
649
|
+
end
|
650
|
+
end
|
651
|
+
end
|