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,324 @@
|
|
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_reference"
|
18
|
+
require "google/cloud/firestore/collection_reference"
|
19
|
+
require "google/cloud/firestore/convert"
|
20
|
+
|
21
|
+
module Google
|
22
|
+
module Cloud
|
23
|
+
module Firestore
|
24
|
+
##
|
25
|
+
# # DocumentSnapshot
|
26
|
+
#
|
27
|
+
# A document snapshot object is an immutable representation for a
|
28
|
+
# document in a Cloud Firestore database.
|
29
|
+
#
|
30
|
+
# The snapshot can reference a non-existing document.
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# require "google/cloud/firestore"
|
34
|
+
#
|
35
|
+
# firestore = Google::Cloud::Firestore.new
|
36
|
+
#
|
37
|
+
# # Get a document snapshot
|
38
|
+
# nyc_snap = firestore.doc("cities/NYC").get
|
39
|
+
#
|
40
|
+
# # Get the document data
|
41
|
+
# nyc_snap[:population] #=> 1000000
|
42
|
+
#
|
43
|
+
class DocumentSnapshot
|
44
|
+
##
|
45
|
+
# @private The Google::Firestore::V1beta1::Document object.
|
46
|
+
attr_accessor :grpc
|
47
|
+
|
48
|
+
##
|
49
|
+
# The document identifier for the document snapshot.
|
50
|
+
#
|
51
|
+
# @return [String] document identifier.
|
52
|
+
def document_id
|
53
|
+
ref.document_id
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# A string representing the path of the document, relative to the
|
58
|
+
# document root of the database.
|
59
|
+
#
|
60
|
+
# @return [String] document path.
|
61
|
+
def document_path
|
62
|
+
ref.document_path
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# @private A string representing the full path of the document resource.
|
67
|
+
#
|
68
|
+
# @return [String] document resource path.
|
69
|
+
def path
|
70
|
+
ref.path
|
71
|
+
end
|
72
|
+
|
73
|
+
# @!group Access
|
74
|
+
|
75
|
+
##
|
76
|
+
# The document reference object for the data.
|
77
|
+
#
|
78
|
+
# @return [DocumentReference] document reference.
|
79
|
+
#
|
80
|
+
# @example
|
81
|
+
# require "google/cloud/firestore"
|
82
|
+
#
|
83
|
+
# firestore = Google::Cloud::Firestore.new
|
84
|
+
#
|
85
|
+
# # Get a document snapshot
|
86
|
+
# nyc_snap = firestore.doc("cities/NYC").get
|
87
|
+
#
|
88
|
+
# # Get the document reference
|
89
|
+
# nyc_ref = nyc_snap.ref
|
90
|
+
#
|
91
|
+
def ref
|
92
|
+
@ref
|
93
|
+
end
|
94
|
+
alias_method :reference, :ref
|
95
|
+
|
96
|
+
##
|
97
|
+
# The collection the document snapshot belongs to.
|
98
|
+
#
|
99
|
+
# @return [CollectionReference] parent collection.
|
100
|
+
#
|
101
|
+
# @example
|
102
|
+
# require "google/cloud/firestore"
|
103
|
+
#
|
104
|
+
# firestore = Google::Cloud::Firestore.new
|
105
|
+
#
|
106
|
+
# # Get a document snapshot
|
107
|
+
# nyc_snap = firestore.doc("cities/NYC").get
|
108
|
+
#
|
109
|
+
# # Get the document's parent collection
|
110
|
+
# cities_col = nyc_snap.parent
|
111
|
+
#
|
112
|
+
def parent
|
113
|
+
ref.parent
|
114
|
+
end
|
115
|
+
|
116
|
+
# @!endgroup
|
117
|
+
|
118
|
+
# @!group Data
|
119
|
+
|
120
|
+
##
|
121
|
+
# Retrieves the document data.
|
122
|
+
#
|
123
|
+
# @return [Hash] The document data.
|
124
|
+
#
|
125
|
+
# @example
|
126
|
+
# require "google/cloud/firestore"
|
127
|
+
#
|
128
|
+
# firestore = Google::Cloud::Firestore.new
|
129
|
+
#
|
130
|
+
# nyc_snap = firestore.doc("cities/NYC").get
|
131
|
+
#
|
132
|
+
# # Get the document data
|
133
|
+
# nyc_snap.data[:population] #=> 1000000
|
134
|
+
#
|
135
|
+
def data
|
136
|
+
return nil if missing?
|
137
|
+
Convert.fields_to_hash grpc.fields, ref.client
|
138
|
+
end
|
139
|
+
alias_method :fields, :data
|
140
|
+
|
141
|
+
##
|
142
|
+
# Retrieves the document data.
|
143
|
+
#
|
144
|
+
# @param [FieldPath, String, Symbol] field_path A field path
|
145
|
+
# representing the path of the data to select. A field path can
|
146
|
+
# represent as a string of individual fields joined by ".". Fields
|
147
|
+
# containing `~`, `*`, `/`, `[`, `]`, and `.` cannot be in a dotted
|
148
|
+
# string, and should provided using a {FieldPath} object instead.
|
149
|
+
#
|
150
|
+
# @return [Object] The data at the field path.
|
151
|
+
#
|
152
|
+
# @example
|
153
|
+
# require "google/cloud/firestore"
|
154
|
+
#
|
155
|
+
# firestore = Google::Cloud::Firestore.new
|
156
|
+
#
|
157
|
+
# nyc_snap = firestore.doc("cities/NYC").get
|
158
|
+
#
|
159
|
+
# nyc_snap.get(:population) #=> 1000000
|
160
|
+
#
|
161
|
+
# @example Accessing data using []:
|
162
|
+
# require "google/cloud/firestore"
|
163
|
+
#
|
164
|
+
# firestore = Google::Cloud::Firestore.new
|
165
|
+
#
|
166
|
+
# nyc_snap = firestore.doc("cities/NYC").get
|
167
|
+
#
|
168
|
+
# nyc_snap[:population] #=> 1000000
|
169
|
+
#
|
170
|
+
# @example Nested data can be accessing with field path:
|
171
|
+
# require "google/cloud/firestore"
|
172
|
+
#
|
173
|
+
# firestore = Google::Cloud::Firestore.new
|
174
|
+
#
|
175
|
+
# frank_snap = firestore.doc("users/frank").get
|
176
|
+
#
|
177
|
+
# frank_snap.get("favorites.food") #=> "Pizza"
|
178
|
+
#
|
179
|
+
# @example Nested data can be accessing with FieldPath object:
|
180
|
+
# require "google/cloud/firestore"
|
181
|
+
#
|
182
|
+
# firestore = Google::Cloud::Firestore.new
|
183
|
+
#
|
184
|
+
# user_snap = firestore.doc("users/frank").get
|
185
|
+
#
|
186
|
+
# nested_field_path = firestore.field_path :favorites, :food
|
187
|
+
# user_snap.get(nested_field_path) #=> "Pizza"
|
188
|
+
#
|
189
|
+
def get field_path
|
190
|
+
unless field_path.is_a? FieldPath
|
191
|
+
field_path = FieldPath.parse field_path
|
192
|
+
end
|
193
|
+
|
194
|
+
nodes = field_path.fields.map(&:to_sym)
|
195
|
+
selected_data = data
|
196
|
+
|
197
|
+
nodes.each do |node|
|
198
|
+
unless selected_data.is_a? Hash
|
199
|
+
fail ArgumentError,
|
200
|
+
"#{field_path.formatted_string} is not contained in the data"
|
201
|
+
end
|
202
|
+
selected_data = selected_data[node]
|
203
|
+
end
|
204
|
+
selected_data
|
205
|
+
end
|
206
|
+
alias_method :[], :get
|
207
|
+
|
208
|
+
# @!endgroup
|
209
|
+
|
210
|
+
##
|
211
|
+
# The time at which the document was created.
|
212
|
+
#
|
213
|
+
# This value increases when a document is deleted then recreated.
|
214
|
+
#
|
215
|
+
# @return [Time] The time the document was was created
|
216
|
+
#
|
217
|
+
def created_at
|
218
|
+
return nil if missing?
|
219
|
+
Convert.timestamp_to_time grpc.create_time
|
220
|
+
end
|
221
|
+
alias_method :create_time, :created_at
|
222
|
+
|
223
|
+
##
|
224
|
+
# The time at which the document was last changed.
|
225
|
+
#
|
226
|
+
# This value is initally set to the `created_at` on document creation,
|
227
|
+
# and increases each time the document is updated.
|
228
|
+
#
|
229
|
+
# @return [Time] The time the document was was last changed
|
230
|
+
#
|
231
|
+
def updated_at
|
232
|
+
return nil if missing?
|
233
|
+
Convert.timestamp_to_time grpc.update_time
|
234
|
+
end
|
235
|
+
alias_method :update_time, :updated_at
|
236
|
+
|
237
|
+
##
|
238
|
+
# The time at which the document was read.
|
239
|
+
#
|
240
|
+
# This value is set even if the document does not exist.
|
241
|
+
#
|
242
|
+
# @return [Time] The time the document was read
|
243
|
+
#
|
244
|
+
def read_at
|
245
|
+
@read_at
|
246
|
+
end
|
247
|
+
alias_method :read_time, :read_at
|
248
|
+
|
249
|
+
##
|
250
|
+
# Determines whether the document exists.
|
251
|
+
#
|
252
|
+
# @return [Boolean] Whether the document exists.
|
253
|
+
#
|
254
|
+
# @example
|
255
|
+
# require "google/cloud/firestore"
|
256
|
+
#
|
257
|
+
# firestore = Google::Cloud::Firestore.new
|
258
|
+
#
|
259
|
+
# nyc_snap = firestore.doc("cities/NYC").get
|
260
|
+
#
|
261
|
+
# # Does NYC exist?
|
262
|
+
# nyc_snap.exists? #=> true
|
263
|
+
#
|
264
|
+
def exists?
|
265
|
+
!missing?
|
266
|
+
end
|
267
|
+
|
268
|
+
##
|
269
|
+
# Determines whether the document is missing.
|
270
|
+
#
|
271
|
+
# @return [Boolean] Whether the document is missing.
|
272
|
+
#
|
273
|
+
# @example
|
274
|
+
# require "google/cloud/firestore"
|
275
|
+
#
|
276
|
+
# firestore = Google::Cloud::Firestore.new
|
277
|
+
#
|
278
|
+
# atlantis_snap = firestore.doc("cities/Atlantis").get
|
279
|
+
#
|
280
|
+
# # Does Atlantis exist?
|
281
|
+
# atlantis_snap.missing? #=> true
|
282
|
+
#
|
283
|
+
def missing?
|
284
|
+
grpc.nil?
|
285
|
+
end
|
286
|
+
|
287
|
+
##
|
288
|
+
# @private New DocumentSnapshot from a
|
289
|
+
# Google::Firestore::V1beta1::RunQueryResponse object.
|
290
|
+
def self.from_query_result result, context
|
291
|
+
ref = DocumentReference.from_path result.document.name, context
|
292
|
+
read_at = Convert.timestamp_to_time result.read_time
|
293
|
+
|
294
|
+
new.tap do |s|
|
295
|
+
s.grpc = result.document
|
296
|
+
s.instance_variable_set :@ref, ref
|
297
|
+
s.instance_variable_set :@read_at, read_at
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
##
|
302
|
+
# @private New DocumentSnapshot from a
|
303
|
+
# Google::Firestore::V1beta1::BatchGetDocumentsResponse object.
|
304
|
+
def self.from_batch_result result, context
|
305
|
+
ref = nil
|
306
|
+
grpc = nil
|
307
|
+
if result.result == :found
|
308
|
+
grpc = result.found
|
309
|
+
ref = DocumentReference.from_path grpc.name, context
|
310
|
+
else
|
311
|
+
ref = DocumentReference.from_path result.missing, context
|
312
|
+
end
|
313
|
+
read_at = Convert.timestamp_to_time result.read_time
|
314
|
+
|
315
|
+
new.tap do |s|
|
316
|
+
s.grpc = grpc
|
317
|
+
s.instance_variable_set :@ref, ref
|
318
|
+
s.instance_variable_set :@read_at, read_at
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
@@ -0,0 +1,216 @@
|
|
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/convert"
|
17
|
+
|
18
|
+
module Google
|
19
|
+
module Cloud
|
20
|
+
module Firestore
|
21
|
+
##
|
22
|
+
# # FieldPath
|
23
|
+
#
|
24
|
+
# Represents a field path to the Firestore API. See {Client#field_path}.
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# require "google/cloud/firestore"
|
28
|
+
#
|
29
|
+
# firestore = Google::Cloud::Firestore.new
|
30
|
+
#
|
31
|
+
# user_snap = firestore.doc("users/frank").get
|
32
|
+
#
|
33
|
+
# nested_field_path = Google::Cloud::Firestore::FieldPath.new(
|
34
|
+
# :favorites, :food
|
35
|
+
# )
|
36
|
+
# user_snap.get(nested_field_path) #=> "Pizza"
|
37
|
+
#
|
38
|
+
class FieldPath
|
39
|
+
include Comparable
|
40
|
+
|
41
|
+
##
|
42
|
+
# Creates a field path object representing a nested field for
|
43
|
+
# document data.
|
44
|
+
#
|
45
|
+
# @return [FieldPath] The field path object.
|
46
|
+
#
|
47
|
+
# @example
|
48
|
+
# require "google/cloud/firestore"
|
49
|
+
#
|
50
|
+
# firestore = Google::Cloud::Firestore.new
|
51
|
+
#
|
52
|
+
# user_snap = firestore.doc("users/frank").get
|
53
|
+
#
|
54
|
+
# nested_field_path = Google::Cloud::Firestore::FieldPath.new(
|
55
|
+
# :favorites, :food
|
56
|
+
# )
|
57
|
+
# user_snap.get(nested_field_path) #=> "Pizza"
|
58
|
+
#
|
59
|
+
def initialize *fields
|
60
|
+
@fields = fields.flatten.map(&:to_s)
|
61
|
+
@fields.each do |field|
|
62
|
+
fail ArgumentError, "empty paths not allowed" if field.empty?
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# @private The individual fields representing the nested field path for
|
68
|
+
# document data.
|
69
|
+
#
|
70
|
+
# @return [Array<String>] The fields.
|
71
|
+
#
|
72
|
+
# @example
|
73
|
+
# require "google/cloud/firestore"
|
74
|
+
#
|
75
|
+
# firestore = Google::Cloud::Firestore.new
|
76
|
+
#
|
77
|
+
# user_snap = firestore.doc("users/frank").get
|
78
|
+
#
|
79
|
+
# nested_field_path = Google::Cloud::Firestore::FieldPath.new(
|
80
|
+
# :favorites, :food
|
81
|
+
# )
|
82
|
+
# nested_field_path.fields #=> ["favorites", "food"]
|
83
|
+
#
|
84
|
+
def fields
|
85
|
+
@fields
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# @private A string representing the nested fields for document data as
|
90
|
+
# a string of individual fields joined by ".". Fields containing `~`,
|
91
|
+
# `*`, `/`, `[`, `]`, and `.` are escaped.
|
92
|
+
#
|
93
|
+
# @return [String] The formatted string.
|
94
|
+
#
|
95
|
+
# @example
|
96
|
+
# require "google/cloud/firestore"
|
97
|
+
#
|
98
|
+
# firestore = Google::Cloud::Firestore.new
|
99
|
+
#
|
100
|
+
# user_snap = firestore.doc("users/frank").get
|
101
|
+
#
|
102
|
+
# nested_field_path = Google::Cloud::Firestore::FieldPath.new(
|
103
|
+
# :favorites, :food
|
104
|
+
# )
|
105
|
+
# nested_field_path.formatted_string #=> "favorites.food"
|
106
|
+
#
|
107
|
+
def formatted_string
|
108
|
+
escaped_fields = @fields.map { |field| escape_field_for_path field }
|
109
|
+
escaped_fields.join(".")
|
110
|
+
end
|
111
|
+
|
112
|
+
##
|
113
|
+
# Creates a field path object representing the sentinel ID of a
|
114
|
+
# document. It can be used in queries to sort or filter by the document
|
115
|
+
# ID. See {Client#document_id}.
|
116
|
+
#
|
117
|
+
# @return [FieldPath] The field path object.
|
118
|
+
#
|
119
|
+
# @example
|
120
|
+
# require "google/cloud/firestore"
|
121
|
+
#
|
122
|
+
# firestore = Google::Cloud::Firestore.new
|
123
|
+
#
|
124
|
+
# # Get a collection reference
|
125
|
+
# cities_col = firestore.col "cities"
|
126
|
+
#
|
127
|
+
# # Create a query
|
128
|
+
# query = cities_col.start_at("NYC").order(
|
129
|
+
# Google::Cloud::Firestore::FieldPath.document_id
|
130
|
+
# )
|
131
|
+
#
|
132
|
+
# query.get do |city|
|
133
|
+
# puts "#{city.document_id} has #{city[:population]} residents."
|
134
|
+
# end
|
135
|
+
#
|
136
|
+
def self.document_id
|
137
|
+
new :__name__
|
138
|
+
end
|
139
|
+
|
140
|
+
##
|
141
|
+
# @private Creates a field path object representing the nested fields
|
142
|
+
# for document data.
|
143
|
+
#
|
144
|
+
# @param [String] dotted_string A string representing the path of the
|
145
|
+
# document data. The string can represent as a string of individual
|
146
|
+
# fields joined by ".". Fields containing `~`, `*`, `/`, `[`, `]`, and
|
147
|
+
# `.` cannot be in a dotted string, and should be created by passing
|
148
|
+
# individual field strings to {FieldPath.new} instead.
|
149
|
+
#
|
150
|
+
# @return [FieldPath] The field path object.
|
151
|
+
#
|
152
|
+
# @example
|
153
|
+
# require "google/cloud/firestore"
|
154
|
+
#
|
155
|
+
# firestore = Google::Cloud::Firestore.new
|
156
|
+
#
|
157
|
+
# user_snap = firestore.doc("users/frank").get
|
158
|
+
#
|
159
|
+
# field_path = Google::Cloud::Firestore::FieldPath.parse(
|
160
|
+
# "favorites.food"
|
161
|
+
# )
|
162
|
+
# field_path.fields #=> ["favorites", "food"]
|
163
|
+
#
|
164
|
+
def self.parse dotted_string
|
165
|
+
return new dotted_string if dotted_string.is_a? Array
|
166
|
+
|
167
|
+
fields = String(dotted_string).split(".")
|
168
|
+
fields.each do |field|
|
169
|
+
if INVALID_FIELD_PATH_CHARS.match field
|
170
|
+
fail ArgumentError, "invalid character, use FieldPath instead"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
new fields
|
174
|
+
end
|
175
|
+
|
176
|
+
##
|
177
|
+
# @private
|
178
|
+
def <=> other
|
179
|
+
return nil unless other.is_a? FieldPath
|
180
|
+
formatted_string <=> other.formatted_string
|
181
|
+
end
|
182
|
+
|
183
|
+
##
|
184
|
+
# @private
|
185
|
+
def eql? other
|
186
|
+
formatted_string.eql? other.formatted_string
|
187
|
+
end
|
188
|
+
|
189
|
+
##
|
190
|
+
# @private
|
191
|
+
def hash
|
192
|
+
formatted_string.hash
|
193
|
+
end
|
194
|
+
|
195
|
+
protected
|
196
|
+
|
197
|
+
START_FIELD_PATH_CHARS = /\A[a-zA-Z_]/
|
198
|
+
INVALID_FIELD_PATH_CHARS = %r{[\~\*\/\[\]]}
|
199
|
+
|
200
|
+
def escape_field_for_path field
|
201
|
+
field = String field
|
202
|
+
|
203
|
+
if INVALID_FIELD_PATH_CHARS.match(field) ||
|
204
|
+
field["."] || field["`"] || field["\\"]
|
205
|
+
escaped_field = field.gsub(/[\`\\]/, "`" => "\\\`", "\\" => "\\\\")
|
206
|
+
return "`#{escaped_field}`"
|
207
|
+
end
|
208
|
+
|
209
|
+
return field if START_FIELD_PATH_CHARS.match field
|
210
|
+
|
211
|
+
"`#{field}`"
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|