gcloud 0.3.0 → 0.3.1

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 (42) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG.md +21 -0
  3. data/lib/gcloud.rb +0 -5
  4. data/lib/gcloud/bigquery.rb +31 -62
  5. data/lib/gcloud/bigquery/connection.rb +58 -35
  6. data/lib/gcloud/bigquery/dataset.rb +147 -18
  7. data/lib/gcloud/bigquery/dataset/access.rb +477 -0
  8. data/lib/gcloud/bigquery/dataset/list.rb +1 -1
  9. data/lib/gcloud/bigquery/errors.rb +2 -0
  10. data/lib/gcloud/bigquery/job.rb +30 -6
  11. data/lib/gcloud/bigquery/job/list.rb +1 -1
  12. data/lib/gcloud/bigquery/project.rb +47 -8
  13. data/lib/gcloud/bigquery/query_job.rb +1 -5
  14. data/lib/gcloud/bigquery/table.rb +185 -47
  15. data/lib/gcloud/bigquery/table/list.rb +1 -1
  16. data/lib/gcloud/bigquery/table/schema.rb +252 -0
  17. data/lib/gcloud/bigquery/view.rb +25 -0
  18. data/lib/gcloud/datastore/connection.rb +4 -0
  19. data/lib/gcloud/datastore/dataset.rb +5 -2
  20. data/lib/gcloud/datastore/errors.rb +1 -1
  21. data/lib/gcloud/datastore/properties.rb +1 -0
  22. data/lib/gcloud/datastore/proto.rb +3 -0
  23. data/lib/gcloud/errors.rb +23 -0
  24. data/lib/gcloud/gce.rb +62 -0
  25. data/lib/gcloud/pubsub/connection.rb +4 -0
  26. data/lib/gcloud/pubsub/errors.rb +2 -0
  27. data/lib/gcloud/pubsub/project.rb +5 -3
  28. data/lib/gcloud/pubsub/subscription/list.rb +1 -1
  29. data/lib/gcloud/pubsub/topic.rb +1 -1
  30. data/lib/gcloud/pubsub/topic/list.rb +1 -1
  31. data/lib/gcloud/storage.rb +16 -0
  32. data/lib/gcloud/storage/bucket.rb +31 -1
  33. data/lib/gcloud/storage/bucket/acl.rb +12 -10
  34. data/lib/gcloud/storage/bucket/list.rb +1 -1
  35. data/lib/gcloud/storage/connection.rb +4 -0
  36. data/lib/gcloud/storage/errors.rb +2 -0
  37. data/lib/gcloud/storage/file.rb +13 -0
  38. data/lib/gcloud/storage/file/acl.rb +6 -5
  39. data/lib/gcloud/storage/file/list.rb +1 -1
  40. data/lib/gcloud/storage/project.rb +4 -2
  41. data/lib/gcloud/version.rb +1 -1
  42. metadata +6 -2
@@ -38,7 +38,7 @@ module Gcloud
38
38
 
39
39
  ##
40
40
  # New Table::List from a response object.
41
- def self.from_resp resp, conn #:nodoc:
41
+ def self.from_response resp, conn #:nodoc:
42
42
  tables = List.new(Array(resp.data["tables"]).map do |gapi_object|
43
43
  Table.from_gapi gapi_object, conn
44
44
  end)
@@ -0,0 +1,252 @@
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 Bigquery
18
+ class Table
19
+ ##
20
+ # = Table Schema
21
+ #
22
+ # A builder for BigQuery table schemas, passed to block arguments to
23
+ # Dataset#create_table and Table#schema. Supports nested and
24
+ # repeated fields via a nested block. For more information about BigQuery
25
+ # schema definitions, see {Preparing Data for BigQuery
26
+ # }[https://cloud.google.com/bigquery/preparing-data-for-bigquery].
27
+ #
28
+ # require "gcloud"
29
+ #
30
+ # gcloud = Gcloud.new
31
+ # bigquery = gcloud.bigquery
32
+ # dataset = bigquery.dataset "my_dataset"
33
+ # table = dataset.create_table "my_table"
34
+ #
35
+ # table.schema do |schema|
36
+ # schema.string "first_name", mode: :required
37
+ # schema.record "cities_lived", mode: :repeated do |cities_lived|
38
+ # cities_lived.string "place", mode: :required
39
+ # cities_lived.integer "number_of_years", mode: :required
40
+ # end
41
+ # end
42
+ #
43
+ class Schema
44
+ MODES = %w( NULLABLE REQUIRED REPEATED ) #:nodoc:
45
+ TYPES = %w( STRING INTEGER FLOAT BOOLEAN TIMESTAMP RECORD ) #:nodoc:
46
+
47
+ attr_reader :fields #:nodoc:
48
+
49
+ ##
50
+ # Initializes a new schema object with an existing schema.
51
+ def initialize schema = nil, nested = false #:nodoc:
52
+ fields = (schema && schema["fields"]) || []
53
+ @original_fields = fields.dup
54
+ @fields = fields.dup
55
+ @nested = nested
56
+ end
57
+
58
+ def changed? #:nodoc:
59
+ @original_fields != @fields
60
+ end
61
+
62
+ ##
63
+ # Returns the schema as hash containing the keys and values specified by
64
+ # the Google Cloud BigQuery {Rest API
65
+ # }[https://cloud.google.com/bigquery/docs/reference/v2/tables#resource]
66
+ # .
67
+ def schema #:nodoc:
68
+ {
69
+ "fields" => @fields
70
+ }
71
+ end
72
+
73
+ ##
74
+ # Adds a string field to the schema.
75
+ #
76
+ # === Parameters
77
+ #
78
+ # +name+::
79
+ # The field name. The name must contain only letters (a-z, A-Z),
80
+ # numbers (0-9), or underscores (_), and must start with a letter or
81
+ # underscore. The maximum length is 128 characters. (+String+)
82
+ # +options+::
83
+ # An optional Hash for controlling additional behavior. (+Hash+)
84
+ # <code>options[:description]</code>::
85
+ # A description of the field. (+String+)
86
+ # <code>options[:mode]</code>::
87
+ # The field's mode. The possible values are +:nullable+, +:required+,
88
+ # and +:repeated+. The default value is +:nullable+. (+Symbol+)
89
+ def string name, options = {}
90
+ add_field name, :string, nil, options
91
+ end
92
+
93
+ ##
94
+ # Adds an integer field to the schema.
95
+ #
96
+ # === Parameters
97
+ #
98
+ # +name+::
99
+ # The field name. The name must contain only letters (a-z, A-Z),
100
+ # numbers (0-9), or underscores (_), and must start with a letter or
101
+ # underscore. The maximum length is 128 characters. (+String+)
102
+ # +options+::
103
+ # An optional Hash for controlling additional behavior. (+Hash+)
104
+ # <code>options[:description]</code>::
105
+ # A description of the field. (+String+)
106
+ # <code>options[:mode]</code>::
107
+ # The field's mode. The possible values are +:nullable+, +:required+,
108
+ # and +:repeated+. The default value is +:nullable+. (+Symbol+)
109
+ def integer name, options = {}
110
+ add_field name, :integer, nil, options
111
+ end
112
+
113
+ ##
114
+ # Adds a floating-point number field to the schema.
115
+ #
116
+ # === Parameters
117
+ #
118
+ # +name+::
119
+ # The field name. The name must contain only letters (a-z, A-Z),
120
+ # numbers (0-9), or underscores (_), and must start with a letter or
121
+ # underscore. The maximum length is 128 characters. (+String+)
122
+ # +options+::
123
+ # An optional Hash for controlling additional behavior. (+Hash+)
124
+ # <code>options[:description]</code>::
125
+ # A description of the field. (+String+)
126
+ # <code>options[:mode]</code>::
127
+ # The field's mode. The possible values are +:nullable+, +:required+,
128
+ # and +:repeated+. The default value is +:nullable+. (+Symbol+)
129
+ def float name, options = {}
130
+ add_field name, :float, nil, options
131
+ end
132
+
133
+ ##
134
+ # Adds a boolean field to the schema.
135
+ #
136
+ # === Parameters
137
+ #
138
+ # +name+::
139
+ # The field name. The name must contain only letters (a-z, A-Z),
140
+ # numbers (0-9), or underscores (_), and must start with a letter or
141
+ # underscore. The maximum length is 128 characters. (+String+)
142
+ # +options+::
143
+ # An optional Hash for controlling additional behavior. (+Hash+)
144
+ # <code>options[:description]</code>::
145
+ # A description of the field. (+String+)
146
+ # <code>options[:mode]</code>::
147
+ # The field's mode. The possible values are +:nullable+, +:required+,
148
+ # and +:repeated+. The default value is +:nullable+. (+Symbol+)
149
+ def boolean name, options = {}
150
+ add_field name, :boolean, nil, options
151
+ end
152
+
153
+ ##
154
+ # Adds a timestamp field to the schema.
155
+ #
156
+ # === Parameters
157
+ #
158
+ # +name+::
159
+ # The field name. The name must contain only letters (a-z, A-Z),
160
+ # numbers (0-9), or underscores (_), and must start with a letter or
161
+ # underscore. The maximum length is 128 characters. (+String+)
162
+ # +options+::
163
+ # An optional Hash for controlling additional behavior. (+Hash+)
164
+ # <code>options[:description]</code>::
165
+ # A description of the field. (+String+)
166
+ # <code>options[:mode]</code>::
167
+ # The field's mode. The possible values are +:nullable+, +:required+,
168
+ # and +:repeated+. The default value is +:nullable+. (+Symbol+)
169
+ def timestamp name, options = {}
170
+ add_field name, :timestamp, nil, options
171
+ end
172
+
173
+ ##
174
+ # Adds a record field to the schema. A block must be passed describing
175
+ # the nested fields of the record. For more information about nested
176
+ # and repeated records, see {Preparing Data for BigQuery
177
+ # }[https://cloud.google.com/bigquery/preparing-data-for-bigquery].
178
+ #
179
+ # === Parameters
180
+ #
181
+ # +name+::
182
+ # The field name. The name must contain only letters (a-z, A-Z),
183
+ # numbers (0-9), or underscores (_), and must start with a letter or
184
+ # underscore. The maximum length is 128 characters. (+String+)
185
+ # +options+::
186
+ # An optional Hash for controlling additional behavior. (+Hash+)
187
+ # <code>options[:description]</code>::
188
+ # A description of the field. (+String+)
189
+ # <code>options[:mode]</code>::
190
+ # The field's mode. The possible values are +:nullable+, +:required+,
191
+ # and +:repeated+. The default value is +:nullable+. (+Symbol+)
192
+ #
193
+ # === Example
194
+ #
195
+ # require "gcloud"
196
+ #
197
+ # gcloud = Gcloud.new
198
+ # bigquery = gcloud.bigquery
199
+ # dataset = bigquery.dataset "my_dataset"
200
+ # table = dataset.create_table "my_table"
201
+ #
202
+ # table.schema do |schema|
203
+ # schema.string "first_name", mode: :required
204
+ # schema.record "cities_lived", mode: :repeated do |cities_lived|
205
+ # cities_lived.string "place", mode: :required
206
+ # cities_lived.integer "number_of_years", mode: :required
207
+ # end
208
+ # end
209
+ #
210
+ def record name, options = {}
211
+ fail ArgumentError, "nested RECORD type is not permitted" if @nested
212
+ fail ArgumentError, "a block is required" unless block_given?
213
+ nested_schema = self.class.new nil, true
214
+ yield nested_schema
215
+ add_field name, :record, nested_schema.fields, options
216
+ end
217
+
218
+ protected
219
+
220
+ def upcase_type type
221
+ upcase_type = type.to_s.upcase
222
+ unless TYPES.include? upcase_type
223
+ fail ArgumentError,
224
+ "Type '#{upcase_type}' not found in #{TYPES.inspect}"
225
+ end
226
+ upcase_type
227
+ end
228
+
229
+ def upcase_mode mode
230
+ upcase_mode = mode.to_s.upcase
231
+ unless MODES.include? upcase_mode
232
+ fail ArgumentError "Unable to determine mode for '#{mode}'"
233
+ end
234
+ upcase_mode
235
+ end
236
+
237
+ def add_field name, type, nested_fields, options
238
+ # Remove any existing field of this name
239
+ @fields.reject! { |h| h["name"] == name }
240
+ field = {
241
+ "name" => name,
242
+ "type" => upcase_type(type)
243
+ }
244
+ field["mode"] = upcase_mode(options[:mode]) if options[:mode]
245
+ field["description"] =options[:description] if options[:description]
246
+ field["fields"] = nested_fields if nested_fields
247
+ @fields << field
248
+ end
249
+ end
250
+ end
251
+ end
252
+ end
@@ -83,6 +83,15 @@ module Gcloud
83
83
  @gapi["tableReference"]["projectId"]
84
84
  end
85
85
 
86
+ ##
87
+ # The gapi fragment containing the Project ID, Dataset ID, and Table ID as
88
+ # a camel-cased hash.
89
+ def table_ref #:nodoc:
90
+ table_ref = @gapi["tableReference"]
91
+ table_ref = table_ref.to_hash if table_ref.respond_to? :to_hash
92
+ table_ref
93
+ end
94
+
86
95
  ##
87
96
  # The name of the table.
88
97
  #
@@ -367,6 +376,22 @@ module Gcloud
367
376
  end
368
377
  end
369
378
 
379
+ ##
380
+ # Reloads the table with current data from the BigQuery service.
381
+ #
382
+ # :category: Lifecycle
383
+ #
384
+ def reload!
385
+ ensure_connection!
386
+ resp = connection.get_table dataset_id, table_id
387
+ if resp.success?
388
+ @gapi = resp.data
389
+ else
390
+ fail ApiError.from_response(resp)
391
+ end
392
+ end
393
+ alias_method :refresh!, :reload!
394
+
370
395
  ##
371
396
  # New Table from a Google API Client object.
372
397
  def self.from_gapi gapi, conn #:nodoc:
@@ -144,6 +144,10 @@ module Gcloud
144
144
  @http_host = new_http_host
145
145
  end
146
146
 
147
+ def inspect #:nodoc:
148
+ "#{self.class}(#{@dataset_id})"
149
+ end
150
+
147
151
  protected
148
152
 
149
153
  ##
@@ -13,6 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ require "gcloud/gce"
16
17
  require "gcloud/datastore/connection"
17
18
  require "gcloud/datastore/credentials"
18
19
  require "gcloud/datastore/entity"
@@ -77,9 +78,11 @@ module Gcloud
77
78
  ##
78
79
  # Default project.
79
80
  def self.default_project #:nodoc:
80
- ENV["DATASTORE_PROJECT"] ||
81
+ ENV["DATASTORE_DATASET"] ||
82
+ ENV["DATASTORE_PROJECT"] ||
81
83
  ENV["GCLOUD_PROJECT"] ||
82
- ENV["GOOGLE_CLOUD_PROJECT"]
84
+ ENV["GOOGLE_CLOUD_PROJECT"] ||
85
+ Gcloud::GCE.project_id
83
86
  end
84
87
 
85
88
  ##
@@ -13,7 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require "gcloud"
16
+ require "gcloud/errors"
17
17
 
18
18
  module Gcloud
19
19
  module Datastore
@@ -89,6 +89,7 @@ module Gcloud
89
89
  if Time === value ||
90
90
  Gcloud::Datastore::Key === value ||
91
91
  Gcloud::Datastore::Entity === value ||
92
+ NilClass === value ||
92
93
  TrueClass === value ||
93
94
  FalseClass === value ||
94
95
  Float === value ||
@@ -14,6 +14,7 @@
14
14
  # limitations under the License.
15
15
 
16
16
  require "gcloud/proto/datastore_v1.pb"
17
+ require "gcloud/datastore/errors"
17
18
 
18
19
  module Gcloud
19
20
  module Datastore
@@ -63,6 +64,8 @@ module Gcloud
63
64
  v.key_value = value.to_proto
64
65
  elsif Gcloud::Datastore::Entity === value
65
66
  v.entity_value = value.to_proto
67
+ elsif NilClass === value
68
+ # The correct behavior is to not set a value property
66
69
  elsif TrueClass === value
67
70
  v.boolean_value = true
68
71
  elsif FalseClass === value
@@ -0,0 +1,23 @@
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
+ #--
17
+ # Google Cloud Errors
18
+ module Gcloud
19
+ ##
20
+ # Base Gcloud exception class.
21
+ class Error < StandardError
22
+ end
23
+ end
data/lib/gcloud/gce.rb ADDED
@@ -0,0 +1,62 @@
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 "faraday"
17
+
18
+ #--
19
+ # Google Cloud Compute Engine
20
+ module Gcloud
21
+ ##
22
+ # Represents the Google Compute Engine environment.
23
+ module GCE #:nodoc:
24
+ CHECK_URI = "http://169.254.169.254"
25
+ PROJECT_URI = "#{CHECK_URI}/computeMetadata/v1/project/project-id"
26
+
27
+ # rubocop:disable all
28
+ # Disabled rubocop because this is private and we don't need more methods.
29
+
30
+ def self.gce? options = {}
31
+ conn = options[:connection] || Faraday.default_connection
32
+ resp = conn.get CHECK_URI do |req|
33
+ req.options.timeout = 0.1
34
+ end
35
+ return false unless resp.status == 200
36
+ return false unless resp.headers.key? "Metadata-Flavor"
37
+ return resp.headers["Metadata-Flavor"] == "Google"
38
+ rescue Faraday::TimeoutError, Faraday::ConnectionFailed
39
+ return false
40
+ end
41
+
42
+ def self.project_id options = {}
43
+ @gce ||= {}
44
+ return @gce[:project_id] if @gce.key? :project_id
45
+ conn = options[:connection] || Faraday.default_connection
46
+ conn.headers = { "Metadata-Flavor" => "Google" }
47
+ resp = conn.get PROJECT_URI do |req|
48
+ req.options.timeout = 0.1
49
+ end
50
+ if resp.status == 200
51
+ @gce[:project_id] = resp.body
52
+ else
53
+ @gce[:project_id] = nil
54
+ end
55
+ rescue Faraday::TimeoutError, Faraday::ConnectionFailed
56
+ @gce ||= {}
57
+ @gce[:project_id] = nil
58
+ end
59
+
60
+ # rubocop:enable all
61
+ end
62
+ end