google-cloud-firestore 2.5.1 → 2.6.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8d0f9ea11dcd132795aca2ffe91250ca03fce477e6fdcb3aafc7e9d01560b172
4
- data.tar.gz: 3701797b2412e82cdf227fe9d162291e53e2aaf4a1c3cc8d37d18ea0a9795f1c
3
+ metadata.gz: 43a875c5288189790070d70828e54d6a4d094979c0f2443c557a6e4fd3de1915
4
+ data.tar.gz: 982a614359a38a6227d8498a5d36f8fe49f2a198c7c9b3561b8e2d24bec07476
5
5
  SHA512:
6
- metadata.gz: e8ce0745147c89e081b94f08a3753bc0a234f1a2e9a5eb9eb15cfc798abbb01e5970fb354db0ff6b71096353dabe2a023e8cba7d5d4c909f20793f953473044d
7
- data.tar.gz: 489e87876e77584f429472f12c157b0c1412d336190b3a8a88e706e262c3d0409b4b00c55207ebd6cab15f0a6ae7b1ad45177c8dfcc87408cd96384db1a11038
6
+ metadata.gz: bb4b447824f289da585555d5210a4672872b7b8e99ca5c5c4a02577637b7d74565da923adb1ae2776d888645c2836e785a70f6080acdc0541c35482fd1dfbd08
7
+ data.tar.gz: 4a0641708dee2f1b923aeb3bf2aeca4b7517bd45fca9762376c2b1b16bf3cb1c8cd7b96956498c9031ec52c15662d1b9ea88e4f828cbb5f907a17ad7d54be41e
data/AUTHENTICATION.md CHANGED
@@ -95,7 +95,8 @@ client = Google::Cloud::Firestore.new
95
95
 
96
96
  ### Configuration
97
97
 
98
- The **Project ID** and **Credentials JSON** can be configured instead of placing them in environment variables or providing them as arguments.
98
+ The **Project ID** and the path to the **Credentials JSON** file can be configured
99
+ instead of placing them in environment variables or providing them as arguments.
99
100
 
100
101
  ```ruby
101
102
  require "google/cloud/firestore"
data/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Release History
2
2
 
3
+ ### 2.6.3 / 2021-08-24
4
+
5
+ #### Bug Fixes
6
+
7
+ * Fix transaction retry behavior
8
+
9
+ ### 2.6.2 / 2021-07-26
10
+
11
+ #### Bug Fixes
12
+
13
+ * Update FieldPath#formatted_string to correctly escape non-simple characters
14
+
15
+ ### 2.6.1 / 2021-07-08
16
+
17
+ #### Documentation
18
+
19
+ * Update AUTHENTICATION.md in handwritten packages
20
+
21
+ ### 2.6.0 / 2021-06-15
22
+
23
+ #### Features
24
+
25
+ * Add support for Query Partitions
26
+ * Add CollectionGroup
27
+ * Update Client#col_group to return CollectionGroup (subclass of Query)
28
+ * Add QueryPartition
29
+ * Add QueryPartition::List
30
+ * Add Query#to_json and Query.from_json
31
+
3
32
  ### 2.5.1 / 2021-04-19
4
33
 
5
34
  #### Bug Fixes
@@ -20,6 +20,7 @@ require "google/cloud/firestore/field_value"
20
20
  require "google/cloud/firestore/collection_reference"
21
21
  require "google/cloud/firestore/document_reference"
22
22
  require "google/cloud/firestore/document_snapshot"
23
+ require "google/cloud/firestore/collection_group"
23
24
  require "google/cloud/firestore/batch"
24
25
  require "google/cloud/firestore/transaction"
25
26
 
@@ -139,7 +140,7 @@ module Google
139
140
  alias collection col
140
141
 
141
142
  ##
142
- # Creates and returns a new Query that includes all documents in the
143
+ # Creates and returns a new collection group that includes all documents in the
143
144
  # database that are contained in a collection or subcollection with the
144
145
  # given collection_id.
145
146
  #
@@ -147,7 +148,7 @@ module Google
147
148
  # over. Every collection or subcollection with this ID as the last
148
149
  # segment of its path will be included. Cannot contain a slash (`/`).
149
150
  #
150
- # @return [Query] The created Query.
151
+ # @return [CollectionGroup] The created collection group.
151
152
  #
152
153
  # @example
153
154
  # require "google/cloud/firestore"
@@ -155,9 +156,9 @@ module Google
155
156
  # firestore = Google::Cloud::Firestore.new
156
157
  #
157
158
  # # Get the cities collection group query
158
- # query = firestore.col_group "cities"
159
+ # col_group = firestore.col_group "cities"
159
160
  #
160
- # query.get do |city|
161
+ # col_group.get do |city|
161
162
  # puts "#{city.document_id} has #{city[:population]} residents."
162
163
  # end
163
164
  #
@@ -166,15 +167,8 @@ module Google
166
167
  raise ArgumentError, "Invalid collection_id: '#{collection_id}', " \
167
168
  "must not contain '/'."
168
169
  end
169
- query = Google::Cloud::Firestore::V1::StructuredQuery.new(
170
- from: [
171
- Google::Cloud::Firestore::V1::StructuredQuery::CollectionSelector.new(
172
- collection_id: collection_id, all_descendants: true
173
- )
174
- ]
175
- )
176
-
177
- Query.start query, service.documents_path, self
170
+
171
+ CollectionGroup.from_collection_id service.documents_path, collection_id, self
178
172
  end
179
173
  alias collection_group col_group
180
174
 
@@ -634,7 +628,24 @@ module Google
634
628
  commit_return = transaction.commit
635
629
  # Conditional return value, depending on truthy commit_response
636
630
  commit_response ? commit_return : transaction_return
637
- rescue Google::Cloud::UnavailableError => e
631
+ rescue Google::Cloud::AbortedError,
632
+ Google::Cloud::CanceledError,
633
+ Google::Cloud::UnknownError,
634
+ Google::Cloud::DeadlineExceededError,
635
+ Google::Cloud::InternalError,
636
+ Google::Cloud::UnauthenticatedError,
637
+ Google::Cloud::ResourceExhaustedError,
638
+ Google::Cloud::UnavailableError,
639
+ Google::Cloud::InvalidArgumentError => e
640
+
641
+ if e.instance_of? Google::Cloud::InvalidArgumentError
642
+ # Return if a previous call was retried but ultimately succeeded
643
+ return nil if backoff[:current].positive?
644
+ # The Firestore backend uses "INVALID_ARGUMENT" for transaction IDs that have expired.
645
+ # While INVALID_ARGUMENT is generally not retryable, we retry this specific case.
646
+ raise e unless e.message =~ /transaction has expired/
647
+ end
648
+
638
649
  # Re-raise if retried more than the max
639
650
  raise e if backoff[:current] > backoff[:max]
640
651
 
@@ -649,12 +660,6 @@ module Google
649
660
  transaction = Transaction.from_client \
650
661
  self, previous_transaction: transaction.transaction_id
651
662
  retry
652
- rescue Google::Cloud::InvalidArgumentError => e
653
- # Return if a previous call was retried but ultimately succeeded
654
- return nil if backoff[:current].positive?
655
-
656
- # Re-raise error.
657
- raise e
658
663
  rescue StandardError => e
659
664
  # Rollback transaction when handling unexpected error
660
665
  transaction.rollback rescue nil
@@ -0,0 +1,136 @@
1
+ # Copyright 2021 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/v1"
17
+ require "google/cloud/firestore/query"
18
+ require "google/cloud/firestore/query_partition"
19
+
20
+ module Google
21
+ module Cloud
22
+ module Firestore
23
+ ##
24
+ # # CollectionGroup
25
+ #
26
+ # A collection group object is used for adding documents, getting
27
+ # document references, and querying for documents, including with partitions.
28
+ #
29
+ # See {Client#col_group} and {Query}.
30
+ #
31
+ # @example
32
+ # require "google/cloud/firestore"
33
+ #
34
+ # firestore = Google::Cloud::Firestore.new
35
+ #
36
+ # # Get a collection group
37
+ # col_group = firestore.col_group "cities"
38
+ #
39
+ # # Get and print all city documents
40
+ # col_group.get do |city|
41
+ # puts "#{city.document_id} has #{city[:population]} residents."
42
+ # end
43
+ #
44
+ class CollectionGroup < Query
45
+ ##
46
+ # Partitions a query by returning partition cursors that can be used to run the query in parallel. The returned
47
+ # partition cursors are split points that can be used as starting/end points for the query results.
48
+ #
49
+ # @param [Integer] partition_count The desired maximum number of partition points. The number must be strictly
50
+ # positive. The actual number of partitions returned may be fewer.
51
+ #
52
+ # @return [Array<QueryPartition>] An ordered array of query partitions.
53
+ #
54
+ # @example
55
+ # require "google/cloud/firestore"
56
+ #
57
+ # firestore = Google::Cloud::Firestore.new
58
+ #
59
+ # col_group = firestore.col_group "cities"
60
+ #
61
+ # partitions = col_group.partitions 3
62
+ #
63
+ # queries = partitions.map(&:to_query)
64
+ #
65
+ def partitions partition_count
66
+ ensure_service!
67
+
68
+ raise ArgumentError, "partition_count must be > 0" unless partition_count.positive?
69
+
70
+ # Partition queries require explicit ordering by __name__.
71
+ query_with_default_order = order "__name__"
72
+ # Since we are always returning an extra partition (with en empty endBefore cursor), we reduce the desired
73
+ # partition count by one.
74
+ partition_count -= 1
75
+
76
+ grpc_partitions = if partition_count.positive?
77
+ # Retrieve all pages, since cursor order is not guaranteed and they must be sorted.
78
+ list_all partition_count, query_with_default_order
79
+ else
80
+ [] # Ensure that a single, empty QueryPartition is returned.
81
+ end
82
+ cursor_values = grpc_partitions.map do |cursor|
83
+ # Convert each cursor to a (single-element) array of Google::Cloud::Firestore::DocumentReference.
84
+ cursor.values.map do |value|
85
+ Convert.value_to_raw value, client
86
+ end
87
+ end
88
+ # Sort the values of the returned cursor, which right now should only contain a single reference value (which
89
+ # needs to be sorted one component at a time).
90
+ cursor_values.sort! do |a, b|
91
+ a.first <=> b.first
92
+ end
93
+
94
+ start_at = nil
95
+ results = cursor_values.map do |end_before|
96
+ partition = QueryPartition.new query_with_default_order, start_at, end_before
97
+ start_at = end_before
98
+ partition
99
+ end
100
+ # Always add a final QueryPartition with an empty end_before value.
101
+ results << QueryPartition.new(query_with_default_order, start_at, nil)
102
+ results
103
+ end
104
+
105
+ ##
106
+ # @private New Collection group object from a path.
107
+ def self.from_collection_id parent_path, collection_id, client
108
+ query = Google::Cloud::Firestore::V1::StructuredQuery.new(
109
+ from: [
110
+ Google::Cloud::Firestore::V1::StructuredQuery::CollectionSelector.new(
111
+ collection_id: collection_id,
112
+ all_descendants: true
113
+ )
114
+ ]
115
+ )
116
+ CollectionGroup.new query, parent_path, client
117
+ end
118
+
119
+ protected
120
+
121
+ def list_all partition_count, query_with_default_order
122
+ grpc_partitions = []
123
+ token = nil
124
+ loop do
125
+ grpc = service.partition_query parent_path, query_with_default_order.query, partition_count, token: token
126
+ grpc_partitions += Array(grpc.partitions)
127
+ token = grpc.next_page_token
128
+ token = nil if token == ""
129
+ break unless token
130
+ end
131
+ grpc_partitions
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -14,9 +14,9 @@
14
14
 
15
15
 
16
16
  require "google/cloud/firestore/v1"
17
+ require "google/cloud/firestore/query"
17
18
  require "google/cloud/firestore/document_reference"
18
19
  require "google/cloud/firestore/document_snapshot"
19
- require "google/cloud/firestore/query"
20
20
  require "google/cloud/firestore/generate"
21
21
  require "google/cloud/firestore/collection_reference_list"
22
22
 
@@ -47,6 +47,13 @@ module Google
47
47
  # @private The firestore client object.
48
48
  attr_accessor :client
49
49
 
50
+ ##
51
+ # @private Creates a new CollectionReference.
52
+ def initialize query, path, client
53
+ super query, nil, client # Pass nil parent_path arg since this class implements #parent_path
54
+ @path = path
55
+ end
56
+
50
57
  ##
51
58
  # The collection identifier for the collection resource.
52
59
  #
@@ -257,11 +264,7 @@ module Google
257
264
  ]
258
265
  )
259
266
 
260
- new.tap do |c|
261
- c.client = client
262
- c.instance_variable_set :@path, path
263
- c.instance_variable_set :@query, query
264
- end
267
+ CollectionReference.new query, path, client
265
268
  end
266
269
 
267
270
  protected
@@ -109,7 +109,7 @@ module Google
109
109
  #
110
110
  # @return [Enumerator]
111
111
  #
112
- # @example Iterating each document reference by passing a block:
112
+ # @example Iterating each document reference by passing a block or proc:
113
113
  # require "google/cloud/firestore"
114
114
  #
115
115
  # firestore = Google::Cloud::Firestore.new
@@ -18,6 +18,7 @@ require "google/cloud/firestore/document_snapshot"
18
18
  require "google/cloud/firestore/collection_reference"
19
19
  require "google/cloud/firestore/document_listener"
20
20
  require "google/cloud/firestore/document_reference/list"
21
+ require "google/cloud/firestore/resource_path"
21
22
 
22
23
  module Google
23
24
  module Cloud
@@ -459,6 +460,12 @@ module Google
459
460
 
460
461
  # @!endgroup
461
462
 
463
+ # @private
464
+ def <=> other
465
+ return nil unless other.is_a? self.class
466
+ ResourcePath.from_path(path) <=> ResourcePath.from_path(other.path)
467
+ end
468
+
462
469
  ##
463
470
  # @private New DocumentReference object from a path.
464
471
  def self.from_path path, client
@@ -209,19 +209,15 @@ module Google
209
209
 
210
210
  protected
211
211
 
212
- START_FIELD_PATH_CHARS = /\A[a-zA-Z_]/.freeze
213
212
  INVALID_FIELD_PATH_CHARS = %r{[~*/\[\]]}.freeze
213
+ SIMPLE_FIELD_PATH_CHARS = /\A[_a-zA-Z][_a-zA-Z0-9]*\Z/.freeze
214
214
 
215
215
  def escape_field_for_path field
216
216
  field = String field
217
217
 
218
- if INVALID_FIELD_PATH_CHARS.match(field) ||
219
- field["."] || field["`"] || field["\\"]
220
- escaped_field = field.gsub(/[`\\]/, "`" => "\\\`", "\\" => "\\\\")
221
- return "`#{escaped_field}`"
222
- end
218
+ return field if SIMPLE_FIELD_PATH_CHARS.match field
223
219
 
224
- return field if START_FIELD_PATH_CHARS.match field
220
+ field = field.gsub(/[`\\]/, "`" => "\\`", "\\" => "\\\\")
225
221
 
226
222
  "`#{field}`"
227
223
  end
@@ -27,9 +27,14 @@ module Google
27
27
  #
28
28
  # firestore = Google::Cloud::Firestore.new
29
29
  #
30
- # user_snap = firestore.doc("users/frank").get
30
+ # # Get a document reference
31
+ # nyc_ref = firestore.doc "cities/NYC"
31
32
  #
32
- # # TODO
33
+ # # Set the population to increment by 1.
34
+ # increment_value = Google::Cloud::Firestore::FieldValue.increment 1
35
+ #
36
+ # nyc_ref.update({ name: "New York City",
37
+ # population: increment_value })
33
38
  #
34
39
  class FieldValue
35
40
  ##
@@ -17,6 +17,7 @@ require "google/cloud/firestore/v1"
17
17
  require "google/cloud/firestore/document_snapshot"
18
18
  require "google/cloud/firestore/query_listener"
19
19
  require "google/cloud/firestore/convert"
20
+ require "json"
20
21
 
21
22
  module Google
22
23
  module Cloud
@@ -74,6 +75,16 @@ module Google
74
75
  # @private The firestore client object.
75
76
  attr_accessor :client
76
77
 
78
+ ##
79
+ # @private Creates a new Query.
80
+ def initialize query, parent_path, client, limit_type: nil
81
+ query ||= StructuredQuery.new
82
+ @query = query
83
+ @parent_path = parent_path
84
+ @limit_type = limit_type
85
+ @client = client
86
+ end
87
+
77
88
  ##
78
89
  # Restricts documents matching the query to return only data for the
79
90
  # provided fields.
@@ -962,16 +973,71 @@ module Google
962
973
  end
963
974
  alias on_snapshot listen
964
975
 
976
+ ##
977
+ # Serializes the instance to a JSON text string. See also {Query.from_json}.
978
+ #
979
+ # @return [String] A JSON text string.
980
+ #
981
+ # @example
982
+ # require "google/cloud/firestore"
983
+ #
984
+ # firestore = Google::Cloud::Firestore.new
985
+ # query = firestore.col(:cities).select(:population)
986
+ #
987
+ # json = query.to_json
988
+ #
989
+ # new_query = Google::Cloud::Firestore::Query.from_json json, firestore
990
+ #
991
+ # new_query.get do |city|
992
+ # puts "#{city.document_id} has #{city[:population]} residents."
993
+ # end
994
+ #
995
+ def to_json options = nil
996
+ query_json = Google::Cloud::Firestore::V1::StructuredQuery.encode_json query
997
+ {
998
+ "query" => JSON.parse(query_json),
999
+ "parent_path" => parent_path,
1000
+ "limit_type" => limit_type
1001
+ }.to_json options
1002
+ end
1003
+
1004
+ ##
1005
+ # Deserializes a JSON text string serialized from this class and returns it as a new instance. See also
1006
+ # {#to_json}.
1007
+ #
1008
+ # @param [String] json A JSON text string serialized using {#to_json}.
1009
+ # @param [Google::Cloud::Firestore::Client] client A connected client instance.
1010
+ #
1011
+ # @return [Query] A new query equal to the original query used to create the JSON text string.
1012
+ #
1013
+ # @example
1014
+ # require "google/cloud/firestore"
1015
+ #
1016
+ # firestore = Google::Cloud::Firestore.new
1017
+ # query = firestore.col(:cities).select(:population)
1018
+ #
1019
+ # json = query.to_json
1020
+ #
1021
+ # new_query = Google::Cloud::Firestore::Query.from_json json, firestore
1022
+ #
1023
+ # new_query.get do |city|
1024
+ # puts "#{city.document_id} has #{city[:population]} residents."
1025
+ # end
1026
+ #
1027
+ def self.from_json json, client
1028
+ raise ArgumentError, "client is required" unless client
1029
+
1030
+ json = JSON.parse json
1031
+ query_json = json["query"]
1032
+ raise ArgumentError, "Field 'query' is required" unless query_json
1033
+ query = Google::Cloud::Firestore::V1::StructuredQuery.decode_json query_json.to_json
1034
+ start query, json["parent_path"], client, limit_type: json["limit_type"]&.to_sym
1035
+ end
1036
+
965
1037
  ##
966
1038
  # @private Start a new Query.
967
1039
  def self.start query, parent_path, client, limit_type: nil
968
- query ||= StructuredQuery.new
969
- Query.new.tap do |q|
970
- q.instance_variable_set :@query, query
971
- q.instance_variable_set :@parent_path, parent_path
972
- q.instance_variable_set :@limit_type, limit_type
973
- q.instance_variable_set :@client, client
974
- end
1040
+ new query, parent_path, client, limit_type: limit_type
975
1041
  end
976
1042
 
977
1043
  protected
@@ -1094,11 +1160,14 @@ module Google
1094
1160
  return snapshot_to_cursor values.first, query
1095
1161
  end
1096
1162
 
1163
+ # The *values param in start_at, start_after, etc. will wrap an array argument in an array, so unwrap it here.
1164
+ values = values.first if values.count == 1 && values.first.is_a?(Array)
1165
+
1097
1166
  # pair values with their field_paths to ensure correct formatting
1098
1167
  order_field_paths = order_by_field_paths query
1099
1168
  if values.count > order_field_paths.count
1100
1169
  # raise if too many values provided for the cursor
1101
- raise ArgumentError, "too many values"
1170
+ raise ArgumentError, "There cannot be more cursor values than order by fields"
1102
1171
  end
1103
1172
 
1104
1173
  values = values.zip(order_field_paths).map do |value, field_path|
@@ -1130,7 +1199,6 @@ module Google
1130
1199
  snapshot[field_path]
1131
1200
  end
1132
1201
  end
1133
-
1134
1202
  values_to_cursor values, query
1135
1203
  end
1136
1204
 
@@ -0,0 +1,80 @@
1
+ # Copyright 2021 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
+ # # QueryPartition
21
+ #
22
+ # Represents a split point that can be used in a query as a starting and/or end point for the query results.
23
+ #
24
+ # The cursors returned by {#start_at} and {#end_before} can only be used in a query that matches the constraint of
25
+ # the query that produced this partition.
26
+ #
27
+ # See {CollectionGroup#partitions} and {Query}.
28
+ #
29
+ # @!attribute [r] start_at
30
+ # The cursor values that define the first result for this partition, or `nil` if this is the first partition.
31
+ # Returns an array of values that represent a position, in the order they appear in the order by clause of the
32
+ # query. Can contain fewer values than specified in the order by clause. Will be used in the query returned by
33
+ # {#to_query}.
34
+ # @return [Array<Object>, nil] Typically, the values are {DocumentReference} objects.
35
+ # @!attribute [r] end_before
36
+ # The cursor values that define the first result after this partition, or `nil` if this is the last partition.
37
+ # Returns an array of values that represent a position, in the order they appear in the order by clause of the
38
+ # query. Can contain fewer values than specified in the order by clause. Will be used in the query returned by
39
+ # {#to_query}.
40
+ # @return [Array<Object>, nil] Typically, the values are {DocumentReference} objects.
41
+ #
42
+ # @example
43
+ # require "google/cloud/firestore"
44
+ #
45
+ # firestore = Google::Cloud::Firestore.new
46
+ #
47
+ # col_group = firestore.col_group "cities"
48
+ #
49
+ # partitions = col_group.partitions 3
50
+ #
51
+ # queries = partitions.map(&:to_query)
52
+ #
53
+ class QueryPartition
54
+ attr_reader :start_at
55
+ attr_reader :end_before
56
+
57
+ ##
58
+ # @private New QueryPartition from query and Cursor
59
+ def initialize query, start_at, end_before
60
+ @query = query
61
+ @start_at = start_at
62
+ @end_before = end_before
63
+ end
64
+
65
+ ##
66
+ # Creates a new query that only returns the documents for this partition, using the cursor values from
67
+ # {#start_at} and {#end_before}.
68
+ #
69
+ # @return [Query] The query for the partition.
70
+ #
71
+ def to_query
72
+ base_query = @query
73
+ base_query = base_query.start_at start_at if start_at
74
+ base_query = base_query.end_before end_before if end_before
75
+ base_query
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,58 @@
1
+ # Copyright 2021 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
+ # @private
21
+ #
22
+ # Represents a resource path to the Firestore API.
23
+ #
24
+ class ResourcePath
25
+ include Comparable
26
+
27
+ RESOURCE_PATH_RE = %r{^projects/([^/]*)/databases/([^/]*)(?:/documents/)?([\s\S]*)$}.freeze
28
+
29
+ attr_reader :project_id
30
+ attr_reader :database_id
31
+ attr_reader :segments
32
+
33
+ ##
34
+ # Creates a resource path object.
35
+ #
36
+ # @param [Array<String>] segments One or more strings representing the resource path.
37
+ #
38
+ # @return [ResourcePath] The resource path object.
39
+ #
40
+ def initialize project_id, database_id, segments
41
+ @project_id = project_id
42
+ @database_id = database_id
43
+ @segments = segments.split "/"
44
+ end
45
+
46
+ def <=> other
47
+ return nil unless other.is_a? ResourcePath
48
+ [project_id, database_id, segments] <=> [other.project_id, other.database_id, other.segments]
49
+ end
50
+
51
+ def self.from_path path
52
+ data = RESOURCE_PATH_RE.match path
53
+ new data[1], data[2], data[3]
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -96,6 +96,20 @@ module Google
96
96
  )
97
97
  end
98
98
 
99
+ ##
100
+ # Returns Google::Cloud::Firestore::V1::PartitionQueryResponse
101
+ def partition_query parent, query_grpc, partition_count, token: nil, max: nil
102
+ request = Google::Cloud::Firestore::V1::PartitionQueryRequest.new(
103
+ parent: parent,
104
+ structured_query: query_grpc,
105
+ partition_count: partition_count,
106
+ page_token: token,
107
+ page_size: max
108
+ )
109
+ paged_enum = firestore.partition_query request
110
+ paged_enum.response
111
+ end
112
+
99
113
  def run_query path, query_grpc, transaction: nil
100
114
  run_query_req = {
101
115
  parent: path,
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Firestore
19
- VERSION = "2.5.1".freeze
19
+ VERSION = "2.6.3".freeze
20
20
  end
21
21
  end
22
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-cloud-firestore
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.1
4
+ version: 2.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Google Inc
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-19 00:00:00.000000000 Z
11
+ date: 2021-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-cloud-core
@@ -227,6 +227,7 @@ files:
227
227
  - lib/google/cloud/firestore.rb
228
228
  - lib/google/cloud/firestore/batch.rb
229
229
  - lib/google/cloud/firestore/client.rb
230
+ - lib/google/cloud/firestore/collection_group.rb
230
231
  - lib/google/cloud/firestore/collection_reference.rb
231
232
  - lib/google/cloud/firestore/collection_reference_list.rb
232
233
  - lib/google/cloud/firestore/commit_response.rb
@@ -242,7 +243,9 @@ files:
242
243
  - lib/google/cloud/firestore/generate.rb
243
244
  - lib/google/cloud/firestore/query.rb
244
245
  - lib/google/cloud/firestore/query_listener.rb
246
+ - lib/google/cloud/firestore/query_partition.rb
245
247
  - lib/google/cloud/firestore/query_snapshot.rb
248
+ - lib/google/cloud/firestore/resource_path.rb
246
249
  - lib/google/cloud/firestore/service.rb
247
250
  - lib/google/cloud/firestore/transaction.rb
248
251
  - lib/google/cloud/firestore/version.rb
@@ -269,7 +272,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
269
272
  - !ruby/object:Gem::Version
270
273
  version: '0'
271
274
  requirements: []
272
- rubygems_version: 3.2.13
275
+ rubygems_version: 3.2.17
273
276
  signing_key:
274
277
  specification_version: 4
275
278
  summary: API Client library for Google Cloud Firestore API