gcloud 0.5.0 → 0.6.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.
Files changed (52) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG.md +8 -0
  3. data/lib/gcloud.rb +48 -30
  4. data/lib/gcloud/bigquery.rb +4 -6
  5. data/lib/gcloud/bigquery/connection.rb +2 -14
  6. data/lib/gcloud/bigquery/dataset.rb +41 -42
  7. data/lib/gcloud/bigquery/project.rb +50 -46
  8. data/lib/gcloud/bigquery/query_job.rb +7 -8
  9. data/lib/gcloud/bigquery/table.rb +54 -55
  10. data/lib/gcloud/bigquery/table/schema.rb +30 -40
  11. data/lib/gcloud/bigquery/view.rb +10 -11
  12. data/lib/gcloud/credentials.rb +19 -25
  13. data/lib/gcloud/datastore.rb +4 -6
  14. data/lib/gcloud/datastore/dataset.rb +3 -5
  15. data/lib/gcloud/dns.rb +4 -6
  16. data/lib/gcloud/dns/connection.rb +17 -16
  17. data/lib/gcloud/dns/importer.rb +5 -11
  18. data/lib/gcloud/dns/project.rb +11 -12
  19. data/lib/gcloud/dns/zone.rb +52 -92
  20. data/lib/gcloud/dns/zone/transaction.rb +2 -2
  21. data/lib/gcloud/pubsub.rb +4 -6
  22. data/lib/gcloud/pubsub/connection.rb +1 -12
  23. data/lib/gcloud/pubsub/project.rb +30 -36
  24. data/lib/gcloud/pubsub/subscription.rb +18 -26
  25. data/lib/gcloud/pubsub/topic.rb +16 -26
  26. data/lib/gcloud/resource_manager.rb +5 -6
  27. data/lib/gcloud/resource_manager/connection.rb +4 -4
  28. data/lib/gcloud/resource_manager/manager.rb +10 -14
  29. data/lib/gcloud/resource_manager/project.rb +3 -5
  30. data/lib/gcloud/search.rb +295 -0
  31. data/lib/gcloud/search/api_client.rb +144 -0
  32. data/lib/gcloud/search/connection.rb +146 -0
  33. data/lib/gcloud/search/credentials.rb +30 -0
  34. data/lib/gcloud/search/document.rb +301 -0
  35. data/lib/gcloud/search/document/list.rb +85 -0
  36. data/lib/gcloud/search/errors.rb +67 -0
  37. data/lib/gcloud/search/field_value.rb +164 -0
  38. data/lib/gcloud/search/field_values.rb +263 -0
  39. data/lib/gcloud/search/fields.rb +267 -0
  40. data/lib/gcloud/search/index.rb +613 -0
  41. data/lib/gcloud/search/index/list.rb +90 -0
  42. data/lib/gcloud/search/project.rb +197 -0
  43. data/lib/gcloud/search/result.rb +169 -0
  44. data/lib/gcloud/search/result/list.rb +95 -0
  45. data/lib/gcloud/storage.rb +4 -6
  46. data/lib/gcloud/storage/bucket.rb +55 -43
  47. data/lib/gcloud/storage/bucket/cors.rb +5 -7
  48. data/lib/gcloud/storage/file.rb +35 -30
  49. data/lib/gcloud/storage/file/acl.rb +12 -16
  50. data/lib/gcloud/storage/project.rb +56 -22
  51. data/lib/gcloud/version.rb +1 -1
  52. metadata +20 -3
@@ -0,0 +1,144 @@
1
+ #--
2
+ # Copyright 2015 Google Inc. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require "gcloud/version"
17
+ require "google/api_client"
18
+
19
+ module Gcloud
20
+ module Search
21
+ ##
22
+ # Temporary substitute for Google::APIClient. Once the Search API is
23
+ # discoverable, initialization of this class in Connection should be
24
+ # replaced with the Google API Client.
25
+ class APIClient #:nodoc:
26
+ attr_accessor :authorization, :connection
27
+
28
+ ##
29
+ # Creates a new APIClient instance.
30
+ def initialize _options
31
+ @connection = Faraday.new request: {
32
+ params_encoder: Faraday::FlatParamsEncoder }
33
+ end
34
+
35
+ def discovered_api name, version
36
+ DiscoveredApi.new name, version
37
+ end
38
+
39
+ def execute options
40
+ api_method = options[:api_method]
41
+ uri = generate_search_uri api_method[:uri], options
42
+ run api_method[:method], uri, options
43
+ end
44
+
45
+ def inspect
46
+ "#{self.class}(#{@project})"
47
+ end
48
+
49
+ protected
50
+
51
+ ##
52
+ # Return type for APIClient#discovered_api
53
+ class DiscoveredApi #:nodoc:
54
+ def initialize name, version
55
+ @name = name
56
+ @version = version
57
+ end
58
+
59
+ def indexes
60
+ IndexResourcePath.new @name, @version, "indexes", "indexId"
61
+ end
62
+
63
+ def documents
64
+ ResourcePath.new @name,
65
+ @version,
66
+ "indexes/{indexId}/documents",
67
+ "docId"
68
+ end
69
+ end
70
+
71
+ ##
72
+ # Return type for DiscoveredApi http verb methods
73
+ class ResourcePath #:nodoc:
74
+ def initialize api_name, api_version, resource_root, resource_id_param
75
+ @root = "https://#{api_name}.googleapis.com/#{api_version}" \
76
+ "/projects/{projectId}/#{resource_root}"
77
+ @resource_id_param = resource_id_param
78
+ end
79
+
80
+ def create
81
+ api_method :post
82
+ end
83
+
84
+ def delete
85
+ api_method :delete, "/{docId}"
86
+ end
87
+
88
+ def get
89
+ api_method :get, "/{docId}"
90
+ end
91
+
92
+ def list
93
+ api_method :get
94
+ end
95
+
96
+ def api_method method, path = nil
97
+ { method: method, uri: "#{@root}#{path}" }
98
+ end
99
+ end
100
+
101
+ ##
102
+ # Special-case return type for DiscoveredApi http search verb method
103
+ class IndexResourcePath < ResourcePath #:nodoc:
104
+ def search
105
+ api_method :get, "/{indexId}/search"
106
+ end
107
+ end
108
+
109
+ def run method, uri, options = {}
110
+ fix_serialization! options
111
+ if authorization.nil?
112
+ @connection.send method do |req|
113
+ req.url uri
114
+ req.params = options[:parameters] if options[:parameters]
115
+ req.body = options[:body] if options[:body]
116
+ end
117
+ else
118
+ options[:method] = method
119
+ options[:uri] = uri
120
+ options[:connection] = @connection
121
+ authorization.fetch_protected_resource options
122
+ end
123
+ end
124
+
125
+ def generate_search_uri uri, options = {}
126
+ params = options.delete :parameters
127
+ [:projectId, :indexId, :docId].each do |param|
128
+ uri.gsub! "{#{param}}", params.delete(param) if params[param]
129
+ end
130
+ uri = URI uri
131
+ unless params.empty?
132
+ uri.query = Faraday::FlatParamsEncoder.encode params
133
+ end
134
+ uri.to_s
135
+ end
136
+
137
+ def fix_serialization! options
138
+ return unless options[:body_object]
139
+ options[:headers] = { "Content-Type" => "application/json" }
140
+ options[:body] = options.delete(:body_object).to_json
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,146 @@
1
+ #--
2
+ # Copyright 2015 Google Inc. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require "gcloud/version"
17
+ require "gcloud/search/api_client"
18
+
19
+ module Gcloud
20
+ module Search
21
+ ##
22
+ # Represents the connection to Search,
23
+ # as well as expose the API calls.
24
+ class Connection #:nodoc:
25
+ API_VERSION = "v1"
26
+
27
+ attr_accessor :project
28
+ attr_accessor :credentials #:nodoc:
29
+ attr_accessor :client #:nodoc:
30
+ attr_accessor :connection #:nodoc:
31
+
32
+ ##
33
+ # Creates a new Connection instance.
34
+ def initialize project, credentials #:nodoc:
35
+ @project = project
36
+ @credentials = credentials
37
+ client_config = {
38
+ application_name: "gcloud-ruby",
39
+ application_version: Gcloud::VERSION
40
+ }
41
+ @client = Gcloud::Search::APIClient.new client_config
42
+ @client.authorization = @credentials.client
43
+ @search = @client.discovered_api "cloudsearch", API_VERSION
44
+ end
45
+
46
+ def list_indexes options = {}
47
+ params = { projectId: @project,
48
+ indexNamePrefix: options[:prefix],
49
+ view: (options[:view] || "FULL"),
50
+ pageSize: options[:max],
51
+ pageToken: options[:token]
52
+ }.delete_if { |_, v| v.nil? }
53
+
54
+ @client.execute(
55
+ api_method: @search.indexes.list,
56
+ parameters: params
57
+ )
58
+ end
59
+
60
+ def delete_index index_id
61
+ @client.execute(
62
+ api_method: @search.indexes.delete,
63
+ parameters: { projectId: @project,
64
+ indexId: index_id }
65
+ )
66
+ end
67
+
68
+ def get_doc index_id, doc_id
69
+ @client.execute(
70
+ api_method: @search.documents.get,
71
+ parameters: { projectId: @project,
72
+ indexId: index_id,
73
+ docId: doc_id }
74
+ )
75
+ end
76
+
77
+ def list_docs index_id, options = {}
78
+ params = { projectId: @project,
79
+ indexId: index_id,
80
+ view: (options[:view] || "FULL"),
81
+ pageSize: options[:max],
82
+ pageToken: options[:token]
83
+ }.delete_if { |_, v| v.nil? }
84
+
85
+ @client.execute(
86
+ api_method: @search.documents.list,
87
+ parameters: params
88
+ )
89
+ end
90
+
91
+ def create_doc index_id, document_hash
92
+ @client.execute(
93
+ api_method: @search.documents.create,
94
+ parameters: { projectId: @project,
95
+ indexId: index_id },
96
+ body_object: document_hash
97
+ )
98
+ end
99
+
100
+ def delete_doc index_id, doc_id
101
+ @client.execute(
102
+ api_method: @search.documents.delete,
103
+ parameters: { projectId: @project,
104
+ indexId: index_id,
105
+ docId: doc_id }
106
+ )
107
+ end
108
+
109
+ def search index_id, query, options = {}
110
+ # Always encode expression hashes as JSON strings
111
+ if options[:expressions]
112
+ # Force to an array of hashes, this works with an array or a hash
113
+ tmp = [options[:expressions]].flatten.map { |ex| JSON.dump ex }
114
+ options[:expressions] = tmp
115
+ end
116
+
117
+ @client.execute(
118
+ api_method: @search.indexes.search,
119
+ parameters: search_request(index_id, query, options)
120
+ )
121
+ end
122
+
123
+ def inspect #:nodoc:
124
+ "#{self.class}(#{@project})"
125
+ end
126
+
127
+ protected
128
+
129
+ def search_request index_id, query, options = {}
130
+ { projectId: @project,
131
+ indexId: index_id,
132
+ query: query,
133
+ fieldExpressions: options[:expressions],
134
+ matchedCountAccuracy: options[:matched_count_accuracy],
135
+ offset: options[:offset],
136
+ orderBy: options[:order],
137
+ pageSize: options[:max],
138
+ pageToken: options[:token],
139
+ returnFields: options[:fields],
140
+ scorerSize: options[:scorer_size],
141
+ scorer: options[:scorer]
142
+ }.delete_if { |_, v| v.nil? }
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,30 @@
1
+ #--
2
+ # Copyright 2015 Google Inc. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require "gcloud/credentials"
17
+
18
+ module Gcloud
19
+ module Search
20
+ ##
21
+ # Represents the Oauth2 signing logic for Search.
22
+ class Credentials < Gcloud::Credentials #:nodoc:
23
+ SCOPE = ["https://www.googleapis.com/auth/cloudsearch",
24
+ "https://www.googleapis.com/auth/userinfo.email"]
25
+ PATH_ENV_VARS = %w(SEARCH_KEYFILE GCLOUD_KEYFILE GOOGLE_CLOUD_KEYFILE)
26
+ JSON_ENV_VARS = %w(SEARCH_KEYFILE_JSON GCLOUD_KEYFILE_JSON
27
+ GOOGLE_CLOUD_KEYFILE_JSON)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,301 @@
1
+ #--
2
+ # Copyright 2015 Google Inc. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require "gcloud/search/document/list"
17
+ require "gcloud/search/connection"
18
+ require "gcloud/search/fields"
19
+
20
+ module Gcloud
21
+ module Search
22
+ ##
23
+ # = Document
24
+ #
25
+ # A document is an object that stores data that can be searched. Each
26
+ # document has a #doc_id that is
27
+ # unique within its index, a #rank, and a list of #fields that contain typed
28
+ # data. Its field values can be accessed through hash-like methods such as
29
+ # #[] and #each.
30
+ #
31
+ # require "gcloud"
32
+ #
33
+ # gcloud = Gcloud.new
34
+ # search = gcloud.search
35
+ # index = search.index "products"
36
+ #
37
+ # document = index.document "product-sku-000001"
38
+ # document.add "price", 24.95
39
+ # index.save document
40
+ # document.rank #=> 1443648166
41
+ # document["price"] #=> 24.95
42
+ #
43
+ # For more information, see {Documents and
44
+ # Indexes}[https://cloud.google.com/search/documents_indexes].
45
+ #
46
+ class Document
47
+ ##
48
+ # Creates a new Document instance.
49
+ #
50
+ def initialize #:nodoc:
51
+ @fields = Fields.new
52
+ @raw = {}
53
+ end
54
+
55
+ ##
56
+ # The unique identifier for the document. Can be set explicitly when the
57
+ # document is saved. (See Index#document and #doc_id= .) If missing, it is
58
+ # automatically assigned to the document when saved.
59
+ def doc_id
60
+ @raw["docId"]
61
+ end
62
+
63
+ ##
64
+ # Sets the unique identifier for the document.
65
+ #
66
+ # Must contain only visible, printable ASCII characters (ASCII codes 33
67
+ # through 126 inclusive) and be no longer than 500 characters. It cannot
68
+ # begin with an exclamation point (<code>!</code>), and it cannot begin
69
+ # and end with double underscores (<code>__</code>).
70
+ def doc_id= new_doc_id
71
+ @raw["docId"] = new_doc_id
72
+ end
73
+
74
+ ##
75
+ # A positive integer which determines the default ordering of documents
76
+ # returned from a search. The rank can be set explicitly when the document
77
+ # is saved. (See Index#document and #rank= .) If missing, it is
78
+ # automatically assigned to the document when saved.
79
+ def rank
80
+ @raw["rank"]
81
+ end
82
+
83
+ ##
84
+ # Sets the rank of the document.
85
+ #
86
+ # The same rank should not be assigned to many documents, and should
87
+ # never be assigned to more than 10,000 documents. By default (when it is
88
+ # not specified or set to 0), it is set at the time the document is
89
+ # created to the number of seconds since January 1, 2011. The rank can be
90
+ # used in Index#search options +expressions+, +order+, and
91
+ # +fields+, where it is referenced as +rank+.
92
+ def rank= new_rank
93
+ @raw["rank"] = new_rank
94
+ end
95
+
96
+ ##
97
+ # Retrieve the field values associated to a field name.
98
+ #
99
+ # === Parameters
100
+ #
101
+ # +name+::
102
+ # The name of the field. New values will be configured with this name.
103
+ # (+String+)
104
+ #
105
+ # === Returns
106
+ #
107
+ # FieldValues
108
+ #
109
+ # === Example
110
+ #
111
+ # require "gcloud"
112
+ #
113
+ # gcloud = Gcloud.new
114
+ # search = gcloud.search
115
+ # index = search.index "products"
116
+ #
117
+ # document = index.document "product-sku-000001"
118
+ # puts "The document description is:"
119
+ # document["description"].each do |value|
120
+ # puts "* #{value} (#{value.type}) [#{value.lang}]"
121
+ # end
122
+ #
123
+ def [] name
124
+ @fields[name]
125
+ end
126
+
127
+ # rubocop:disable Style/TrivialAccessors
128
+ # Disable rubocop because we want .fields to be listed with the other
129
+ # methods on the class.
130
+
131
+ ##
132
+ # The fields in the document. Each field has a name (String) and a list of
133
+ # values (FieldValues). (See Fields)
134
+ def fields
135
+ @fields
136
+ end
137
+
138
+ # rubocop:enable Style/TrivialAccessors
139
+
140
+ # rubocop:disable Metrics/LineLength
141
+ # Disabled because there are links in the docs that are long.
142
+
143
+ ##
144
+ # Add a new value. If the field name does not exist it will be added. If
145
+ # the field value is a DateTime or Numeric, or the type is set to
146
+ # +:datetime+ or +:number+, then the added value will replace any existing
147
+ # values of the same type (since there can be only one). (See Fields#add)
148
+ #
149
+ # === Parameters
150
+ #
151
+ # +name+::
152
+ # The name of the field. (+String+)
153
+ # +value+::
154
+ # The value to add to the field. (+String+ or +Datetime+ or +Float+)
155
+ # +type+::
156
+ # The type of the field value. An attempt is made to set the correct
157
+ # type when this option is missing, although it must be provided for
158
+ # +:geo+ values. A field can have multiple values with same or different
159
+ # types; however, it cannot have multiple +:datetime+ or +:number+
160
+ # values. (+Symbol+)
161
+ #
162
+ # The following values are supported:
163
+ # * +:default+ - The value is a string. The format will be automatically
164
+ # detected. This is the default value for strings.
165
+ # * +:text+ - The value is a string with maximum length 1024**2
166
+ # characters.
167
+ # * +:html+ - The value is an HTML-formatted string with maximum length
168
+ # 1024**2 characters.
169
+ # * +:atom+ - The value is a string with maximum length 500 characters.
170
+ # * +:geo+ - The value is a point on earth described by latitude and
171
+ # longitude coordinates, represented in string with any of the listed
172
+ # {ways of writing
173
+ # coordinates}[http://en.wikipedia.org/wiki/Geographic_coordinate_conversion].
174
+ # * +:datetime+ - The value is a +DateTime+.
175
+ # * +:number+ - The value is a +Numeric+ between -2,147,483,647 and
176
+ # 2,147,483,647. The value will be stored as a double precision
177
+ # floating point value in Cloud Search.
178
+ # +lang+::
179
+ # The language of a string value. Must be a valid {ISO 639-1
180
+ # code}[https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes].
181
+ # (+String+)
182
+ #
183
+ # === Example
184
+ #
185
+ # require "gcloud"
186
+ #
187
+ # gcloud = Gcloud.new
188
+ # search = gcloud.search
189
+ # index = search.index "products"
190
+ #
191
+ # document = index.document "product-sku-000001"
192
+ # document.add "sku", "product-sku-000001", type: :atom
193
+ # document.add "description", "The best T-shirt ever.",
194
+ # type: :text, lang: "en"
195
+ # document.add "description", "<p>The best T-shirt ever.</p>",
196
+ # type: :html, lang: "en"
197
+ # document.add "price", 24.95
198
+ #
199
+ def add name, value, type: nil, lang: nil
200
+ @fields[name].add value, type: type, lang: lang
201
+ end
202
+
203
+ # rubocop:enable Metrics/LineLength
204
+
205
+ ##
206
+ # Deletes a field and all values. (See Fields#delete)
207
+ #
208
+ # === Parameters
209
+ #
210
+ # +name+::
211
+ # The name of the field. (+String+)
212
+ #
213
+ # === Example
214
+ #
215
+ # require "gcloud"
216
+ #
217
+ # gcloud = Gcloud.new
218
+ # search = gcloud.search
219
+ # index = search.index "products"
220
+ #
221
+ # document = index.document "product-sku-000001"
222
+ # document.delete "description"
223
+ #
224
+ def delete name, &block
225
+ @fields.delete name, &block
226
+ end
227
+
228
+ ##
229
+ # Calls block once for each field, passing the field name and values pair
230
+ # as parameters. If no block is given an enumerator is returned instead.
231
+ # (See Fields#each)
232
+ #
233
+ # === Example
234
+ #
235
+ # require "gcloud"
236
+ #
237
+ # gcloud = Gcloud.new
238
+ # search = gcloud.search
239
+ # index = search.index "products"
240
+ #
241
+ # document = index.document "product-sku-000001"
242
+ # puts "The document #{document.doc_id} has the following fields:"
243
+ # document.each do |name, values|
244
+ # puts "* #{name}:"
245
+ # values.each do |value|
246
+ # puts " * #{value} (#{value.type})"
247
+ # end
248
+ # end
249
+ #
250
+ def each &block
251
+ @fields.each(&block)
252
+ end
253
+
254
+ ##
255
+ # Returns a new array populated with all the field names.
256
+ # (See Fields#names)
257
+ #
258
+ # require "gcloud"
259
+ #
260
+ # gcloud = Gcloud.new
261
+ # search = gcloud.search
262
+ # index = search.index "products"
263
+ #
264
+ # document = index.document "product-sku-000001"
265
+ # puts "The document #{document.doc_id} has the following fields:"
266
+ # document.names.each do |name|
267
+ # puts "* #{name}:"
268
+ # end
269
+ #
270
+ def names
271
+ @fields.names
272
+ end
273
+
274
+ ##
275
+ # Override to keep working in interactive shells manageable.
276
+ def inspect #:nodoc:
277
+ insp_rank = ""
278
+ insp_rank = ", rank: #{rank}" if rank
279
+ insp_fields = ", fields: (#{fields.names.map(&:inspect).join ', '})"
280
+ "#{self.class}(doc_id: #{doc_id.inspect}#{insp_rank}#{insp_fields})"
281
+ end
282
+
283
+ ##
284
+ # New Document from a raw data object.
285
+ def self.from_hash hash #:nodoc:
286
+ doc = new
287
+ doc.instance_variable_set "@raw", hash
288
+ doc.instance_variable_set "@fields", Fields.from_raw(hash["fields"])
289
+ doc
290
+ end
291
+
292
+ ##
293
+ # Returns the Document data as a hash
294
+ def to_hash #:nodoc:
295
+ hash = @raw.dup
296
+ hash["fields"] = @fields.to_raw
297
+ hash
298
+ end
299
+ end
300
+ end
301
+ end