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,85 @@
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
+ module Gcloud
17
+ module Search
18
+ class Document
19
+ ##
20
+ # Document::List is a special case Array with additional values.
21
+ class List < DelegateClass(::Array)
22
+ ##
23
+ # If not empty, indicates that there are more records that match
24
+ # the request and this value should be passed to continue.
25
+ attr_accessor :token
26
+
27
+ ##
28
+ # Create a new Document::List with an array of Document instances.
29
+ def initialize arr = []
30
+ super arr
31
+ end
32
+
33
+ ##
34
+ # Whether there a next page of documents.
35
+ def next?
36
+ !token.nil?
37
+ end
38
+
39
+ ##
40
+ # Retrieve the next page of documents.
41
+ def next
42
+ return nil unless next?
43
+ ensure_index!
44
+ @index.documents token: token
45
+ end
46
+
47
+ ##
48
+ # Retrieves all documents by repeatedly loading pages until #next?
49
+ # returns false. Returns the list instance for method chaining.
50
+ def all
51
+ while next?
52
+ next_documents = self.next
53
+ push(*next_documents)
54
+ self.token = next_documents.token
55
+ end
56
+ self
57
+ end
58
+
59
+ ##
60
+ # New Documents::List from a response object.
61
+ def self.from_response resp, index #:nodoc:
62
+ data = JSON.parse resp.body
63
+ documents = new(Array(data["documents"]).map do |doc_hash|
64
+ Document.from_hash doc_hash
65
+ end)
66
+ documents.instance_eval do
67
+ @token = data["nextPageToken"]
68
+ @index = index
69
+ end
70
+ documents
71
+ rescue JSON::ParserError
72
+ raise ApiError.from_response(resp)
73
+ end
74
+
75
+ protected
76
+
77
+ ##
78
+ # Raise an error unless an active connection is available.
79
+ def ensure_index!
80
+ fail "Must have active connection" unless @index
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,67 @@
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/errors"
17
+
18
+ module Gcloud
19
+ module Search
20
+ ##
21
+ # Base Search exception class.
22
+ class Error < Gcloud::Error
23
+ end
24
+
25
+ ##
26
+ # Raised when an API call is not successful.
27
+ class ApiError < Error
28
+ ##
29
+ # The code of the error.
30
+ attr_reader :code
31
+
32
+ ##
33
+ # The errors encountered.
34
+ attr_reader :errors
35
+
36
+ def initialize message, code, errors = [] #:nodoc:
37
+ super message
38
+ @code = code
39
+ @errors = errors
40
+ end
41
+
42
+ def self.from_response resp #:nodoc:
43
+ data = JSON.parse resp.body
44
+ if data["error"]
45
+ from_response_data data["error"]
46
+ else
47
+ from_response_status resp
48
+ end
49
+ rescue JSON::ParserError
50
+ from_response_status resp
51
+ end
52
+
53
+ def self.from_response_data error #:nodoc:
54
+ new error["message"], error["code"], error["errors"]
55
+ end
56
+
57
+ def self.from_response_status resp #:nodoc:
58
+ if resp.status == 404
59
+ new "#{resp.body}: #{resp.request.uri.request_uri}",
60
+ resp.status
61
+ else
62
+ new resp.body, resp.status
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,164 @@
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
+ module Gcloud
17
+ module Search
18
+ ##
19
+ # = FieldValue
20
+ #
21
+ # FieldValue is used to represent a value that belongs to a field. (See
22
+ # Fields and FieldValues)
23
+ #
24
+ # A field value must have a type. A value that is a Numeric will default to
25
+ # `:number`, while a DateTime will default to `:datetime`. If a type is not
26
+ # provided it will be determined by looking at the value.
27
+ #
28
+ # String values (text, html, atom) can also specify a lang value, which is
29
+ # an {ISO 639-1
30
+ # code}[https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes].
31
+ #
32
+ # require "gcloud"
33
+ #
34
+ # gcloud = Gcloud.new
35
+ # search = gcloud.search
36
+ # index = search.index "products"
37
+ #
38
+ # document = index.document "product-sku-000001"
39
+ # puts "The document description is:"
40
+ # document["description"].each do |value|
41
+ # puts "* #{value} (#{value.type}) [#{value.lang}]"
42
+ # end
43
+ #
44
+ # For more information see {Documents and
45
+ # fields}[https://cloud.google.com/search/documents_indexes].
46
+ #
47
+ class FieldValue < DelegateClass(::Object)
48
+ attr_reader :type, :lang, :name
49
+
50
+ # rubocop:disable Metrics/LineLength
51
+ # Disabled because there are links in the docs that are long.
52
+
53
+ ##
54
+ # Create a new FieldValue object.
55
+ #
56
+ # === Parameters
57
+ #
58
+ # +value+::
59
+ # The value to add to the field. (+String+ or +Datetime+ or +Float+)
60
+ # +type+::
61
+ # The type of the field value. A field can have multiple values with
62
+ # same or different types; however, it cannot have multiple Timestamp or
63
+ # number values. (+Symbol+)
64
+ #
65
+ # The following values are supported:
66
+ # * +:text+ - The value is a string with maximum length 1024**2
67
+ # characters.
68
+ # * +:html+ - The value is an HTML-formatted string with maximum length
69
+ # 1024**2 characters.
70
+ # * +:atom+ - The value is a string with maximum length 500 characters.
71
+ # * +:geo+ - The value is a point on earth described by latitude and
72
+ # longitude coordinates, represented in string with any of the listed
73
+ # {ways of writing
74
+ # coordinates}[http://en.wikipedia.org/wiki/Geographic_coordinate_conversion].
75
+ # * +:datetime+ - The value is a +DateTime+.
76
+ # * +:number+ - The value is a +Numeric+ between -2,147,483,647 and
77
+ # 2,147,483,647. The value will be stored as a double precision
78
+ # floating point value in Cloud Search.
79
+ # +lang+::
80
+ # The language of a string value. Must be a valid {ISO 639-1
81
+ # code}[https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes].
82
+ # (+String+)
83
+ # +name+::
84
+ # The name of the field. New values will be configured with this name.
85
+ # (+String+)
86
+ #
87
+ def initialize value, type: nil, lang: nil, name: nil #:nodoc:
88
+ super value
89
+ if type
90
+ @type = type.to_s.downcase.to_sym
91
+ else
92
+ @type = infer_type
93
+ end
94
+ @lang = lang if string_type?
95
+ @name = name
96
+ end
97
+
98
+ # rubocop:enable Metrics/LineLength
99
+
100
+ ##
101
+ # Determines if the value a string type. The value is text or html or atom
102
+ # (or default).
103
+ def string_type?
104
+ [:atom, :default, :html, :text].include? type
105
+ end
106
+
107
+ ##
108
+ # Get the original value object.
109
+ def value #:nodoc:
110
+ __getobj__
111
+ end
112
+
113
+ ##
114
+ # Create a new FieldValue instance from a value Hash.
115
+ def self.from_raw field_value, name = nil #:nodoc:
116
+ value = field_value["stringValue"]
117
+ type = field_value["stringFormat"]
118
+ if field_value["timestampValue"]
119
+ value = DateTime.parse(field_value["timestampValue"])
120
+ type = :datetime
121
+ elsif field_value["geoValue"]
122
+ value = field_value["geoValue"]
123
+ type = :geo
124
+ elsif field_value["numberValue"]
125
+ value = Float(field_value["numberValue"])
126
+ type = :number
127
+ end
128
+ fail "No value found in #{raw_field.inspect}" if value.nil?
129
+ new value, type: type, lang: field_value["lang"], name: name
130
+ end
131
+
132
+ ##
133
+ # Create a raw Hash object containing the field value.
134
+ def to_raw #:nodoc:
135
+ case type
136
+ when :atom, :default, :html, :text
137
+ {
138
+ "stringFormat" => type.to_s.upcase,
139
+ "lang" => lang,
140
+ "stringValue" => to_s
141
+ }.delete_if { |_, v| v.nil? }
142
+ when :geo
143
+ { "geoValue" => to_s }
144
+ when :number
145
+ { "numberValue" => to_f }
146
+ when :datetime
147
+ { "timestampValue" => rfc3339 }
148
+ end
149
+ end
150
+
151
+ protected
152
+
153
+ def infer_type #:nodoc:
154
+ if respond_to? :rfc3339
155
+ :datetime
156
+ elsif value.is_a? Numeric # must call on original object...
157
+ :number
158
+ else
159
+ :default
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,263 @@
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/field_value"
17
+
18
+ module Gcloud
19
+ module Search
20
+ ##
21
+ # = FieldValues
22
+ #
23
+ # The list of values for a field.
24
+ #
25
+ # Each field has a name (String) and a list of values. Each field name
26
+ # consists of only ASCII characters, must be unique within the document and
27
+ # is case sensitive. A field name must start with a letter and can contain
28
+ # letters, digits, or underscore, with a maximum of 500 characters.
29
+ #
30
+ # Each field on a document can have multiple values. FieldValues is the
31
+ # object that manages the multiple values. Values can be the same or
32
+ # different types; however, it cannot have multiple datetime (DateTime) or
33
+ # number (Float) values. (See FieldValue)
34
+ #
35
+ # require "gcloud"
36
+ #
37
+ # gcloud = Gcloud.new
38
+ # search = gcloud.search
39
+ # index = search.index "products"
40
+ #
41
+ # document = index.document "product-sku-000001"
42
+ # puts "The document description is:"
43
+ # document["description"].each do |value|
44
+ # puts "* #{value} (#{value.type}) [#{value.lang}]"
45
+ # end
46
+ #
47
+ # For more information see {Documents and
48
+ # fields}[https://cloud.google.com/search/documents_indexes].
49
+ #
50
+ class FieldValues
51
+ include Enumerable
52
+
53
+ ##
54
+ # Create a new FieldValues object.
55
+ #
56
+ # === Parameters
57
+ #
58
+ # +name+::
59
+ # The name of the field. New values will be configured with this name.
60
+ # (+String+)
61
+ # +values+::
62
+ # A list of values to add to the field. (+Array+ of +FieldValue+
63
+ # objects)
64
+ #
65
+ def initialize name, values = [] # :nodoc:
66
+ @name = name
67
+ @values = values
68
+ end
69
+
70
+ ##
71
+ # Returns the element at index, or returns a subarray starting at the
72
+ # start index and continuing for length elements, or returns a subarray
73
+ # specified by range of indices.
74
+ #
75
+ # Negative indices count backward from the end of the array (-1 is the
76
+ # last element). For start and range cases the starting index is just
77
+ # before an element. Additionally, an empty array is returned when the
78
+ # starting index for an element range is at the end of the array.
79
+ #
80
+ # Returns nil if the index (or starting index) are out of range.
81
+ def [] index
82
+ @values[index]
83
+ end
84
+
85
+ # rubocop:disable Metrics/LineLength
86
+ # Disabled because there are links in the docs that are long.
87
+
88
+ ##
89
+ # Add a new value. The field name will be added to the value object. If
90
+ # the field value is a DateTime or Numeric, or the type is set to
91
+ # +:datetime+ or +:number+, then the added value will replace any existing
92
+ # values of the same type (since there can be only one).
93
+ #
94
+ # === Parameters
95
+ #
96
+ # +value+::
97
+ # The value to add to the field. (+String+ or +Datetime+ or +Float+)
98
+ # +type+::
99
+ # The type of the field value. An attempt is made to set the correct
100
+ # type when this option is missing, although it must be provided for
101
+ # +:geo+ values. A field can have multiple values with same or different
102
+ # types; however, it cannot have multiple +:datetime+ or +:number+
103
+ # values. (+Symbol+)
104
+ #
105
+ # The following values are supported:
106
+ # * +:default+ - The value is a string. The format will be automatically
107
+ # detected. This is the default value for strings.
108
+ # * +:text+ - The value is a string with maximum length 1024**2
109
+ # characters.
110
+ # * +:html+ - The value is an HTML-formatted string with maximum length
111
+ # 1024**2 characters.
112
+ # * +:atom+ - The value is a string with maximum length 500 characters.
113
+ # * +:geo+ - The value is a point on earth described by latitude and
114
+ # longitude coordinates, represented in string with any of the listed
115
+ # {ways of writing
116
+ # coordinates}[http://en.wikipedia.org/wiki/Geographic_coordinate_conversion].
117
+ # * +:datetime+ - The value is a +DateTime+.
118
+ # * +:number+ - The value is a +Numeric+ between -2,147,483,647 and
119
+ # 2,147,483,647. The value will be stored as a double precision
120
+ # floating point value in Cloud Search.
121
+ # +lang+::
122
+ # The language of a string value. Must be a valid {ISO 639-1
123
+ # code}[https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes].
124
+ # (+String+)
125
+ #
126
+ # === Returns
127
+ #
128
+ # FieldValue
129
+ #
130
+ # === Example
131
+ #
132
+ # require "gcloud"
133
+ #
134
+ # gcloud = Gcloud.new
135
+ # search = gcloud.search
136
+ # index = search.index "products"
137
+ #
138
+ # document = index.document "product-sku-000001"
139
+ # document["sku"].add "product-sku-000001", type: :atom
140
+ # document["description"].add "The best T-shirt ever.",
141
+ # type: :text, lang: "en"
142
+ # document["description"].add "<p>The best T-shirt ever.</p>",
143
+ # type: :html, lang: "en"
144
+ # document["price"].add 24.95
145
+ #
146
+ def add value, type: nil, lang: nil
147
+ new_field = FieldValue.new value, type: type, lang: lang, name: @name
148
+ if [:datetime, :number].include? new_field.type
149
+ @values.delete_if { |v| v.type == new_field.type }
150
+ end
151
+ @values << new_field
152
+ end
153
+
154
+ # rubocop:enable Metrics/LineLength
155
+
156
+ ##
157
+ # Deletes all values that are equal to value.
158
+ #
159
+ # === Parameters
160
+ #
161
+ # +value+::
162
+ # The value to remove from the list of values.
163
+ #
164
+ # === Returns
165
+ #
166
+ # The last deleted +FieldValue+, or +nil+ if no matching value is found.
167
+ #
168
+ # === Example
169
+ #
170
+ # require "gcloud"
171
+ #
172
+ # gcloud = Gcloud.new
173
+ # search = gcloud.search
174
+ # index = search.index "products"
175
+ #
176
+ # document = index.document "product-sku-000001"
177
+ # document["description"].count #=> 2
178
+ # document["description"].delete "The best T-shirt ever."
179
+ # document["description"].count #=> 1
180
+ #
181
+ def delete value, &block
182
+ fv = @values.detect { |v| v == value }
183
+ @values.delete fv, &block
184
+ end
185
+
186
+ ##
187
+ # Deletes the value at the specified index, returning that FieldValue, or
188
+ # +nil+ if the index is out of range.
189
+ ##
190
+ # Deletes all values that are equal to value.
191
+ #
192
+ # === Parameters
193
+ #
194
+ # +index+::
195
+ # The index of the value to be removed from the list of values.
196
+ #
197
+ # === Returns
198
+ #
199
+ # The deleted +FieldValue+ found at the specified index, or # +nil+ if the
200
+ # index is out of range.
201
+ #
202
+ # === Example
203
+ #
204
+ # require "gcloud"
205
+ #
206
+ # gcloud = Gcloud.new
207
+ # search = gcloud.search
208
+ # index = search.index "products"
209
+ #
210
+ # document = index.document "product-sku-000001"
211
+ # document["description"].count #=> 2
212
+ # document["description"].delete_at 0
213
+ # document["description"].count #=> 1
214
+ #
215
+ def delete_at index
216
+ @values.delete_at index
217
+ end
218
+
219
+ ##
220
+ # Calls the given block once for each field value, passing the field value
221
+ # as a parameter.
222
+ #
223
+ # An Enumerator is returned if no block is given.
224
+ #
225
+ # === Example
226
+ #
227
+ # require "gcloud"
228
+ #
229
+ # gcloud = Gcloud.new
230
+ # search = gcloud.search
231
+ # index = search.index "products"
232
+ #
233
+ # document = index.document "product-sku-000001"
234
+ # puts "The document description is:"
235
+ # document["description"].each do |value|
236
+ # puts "* #{value} (#{value.type}) [#{value.lang}]"
237
+ # end
238
+ #
239
+ def each &block
240
+ @values.each(&block)
241
+ end
242
+
243
+ ##
244
+ # Returns +true+ if there are no values.
245
+ def empty?
246
+ @values.empty?
247
+ end
248
+
249
+ ##
250
+ # Create a new FieldValues instance from a name and values Hash.
251
+ def self.from_raw name, values #:nodoc:
252
+ field_values = values.map { |value| FieldValue.from_raw value, name }
253
+ FieldValues.new name, field_values
254
+ end
255
+
256
+ ##
257
+ # Create a raw Hash object containing all the field values.
258
+ def to_raw #:nodoc:
259
+ { "values" => @values.map(&:to_raw) }
260
+ end
261
+ end
262
+ end
263
+ end