gcloud 0.8.2 → 0.9.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 (55) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG.md +26 -0
  3. data/OVERVIEW.md +10 -8
  4. data/lib/gcloud.rb +12 -13
  5. data/lib/gcloud/bigquery/dataset/list.rb +2 -4
  6. data/lib/gcloud/bigquery/job/list.rb +3 -5
  7. data/lib/gcloud/bigquery/table/list.rb +3 -5
  8. data/lib/gcloud/datastore.rb +326 -97
  9. data/lib/gcloud/datastore/commit.rb +73 -56
  10. data/lib/gcloud/datastore/credentials.rb +1 -12
  11. data/lib/gcloud/datastore/cursor.rb +76 -0
  12. data/lib/gcloud/datastore/dataset.rb +337 -134
  13. data/lib/gcloud/datastore/dataset/lookup_results.rb +12 -12
  14. data/lib/gcloud/datastore/dataset/query_results.rb +117 -27
  15. data/lib/gcloud/datastore/entity.rb +159 -93
  16. data/lib/gcloud/datastore/errors.rb +0 -21
  17. data/lib/gcloud/datastore/gql_query.rb +211 -0
  18. data/lib/gcloud/datastore/grpc_utils.rb +131 -0
  19. data/lib/gcloud/datastore/key.rb +74 -65
  20. data/lib/gcloud/datastore/properties.rb +14 -1
  21. data/lib/gcloud/datastore/query.rb +188 -52
  22. data/lib/gcloud/datastore/service.rb +161 -0
  23. data/lib/gcloud/datastore/transaction.rb +175 -60
  24. data/lib/gcloud/dns/change/list.rb +2 -4
  25. data/lib/gcloud/dns/record/list.rb +2 -4
  26. data/lib/gcloud/dns/zone/list.rb +2 -4
  27. data/lib/gcloud/grpc_utils.rb +11 -0
  28. data/lib/gcloud/logging/entry.rb +6 -17
  29. data/lib/gcloud/logging/entry/list.rb +8 -9
  30. data/lib/gcloud/logging/metric/list.rb +4 -5
  31. data/lib/gcloud/logging/resource.rb +1 -12
  32. data/lib/gcloud/logging/resource_descriptor.rb +9 -12
  33. data/lib/gcloud/logging/resource_descriptor/list.rb +4 -5
  34. data/lib/gcloud/logging/sink/list.rb +4 -5
  35. data/lib/gcloud/pubsub/message.rb +1 -3
  36. data/lib/gcloud/pubsub/subscription.rb +5 -7
  37. data/lib/gcloud/pubsub/topic.rb +1 -3
  38. data/lib/gcloud/resource_manager/project/list.rb +2 -4
  39. data/lib/gcloud/translate/api.rb +5 -3
  40. data/lib/gcloud/translate/connection.rb +4 -4
  41. data/lib/gcloud/version.rb +1 -1
  42. metadata +9 -20
  43. data/lib/gcloud/datastore/connection.rb +0 -203
  44. data/lib/gcloud/datastore/proto.rb +0 -266
  45. data/lib/gcloud/proto/datastore_v1.pb.rb +0 -377
  46. data/lib/google/protobuf/any.rb +0 -17
  47. data/lib/google/protobuf/api.rb +0 -31
  48. data/lib/google/protobuf/duration.rb +0 -17
  49. data/lib/google/protobuf/empty.rb +0 -15
  50. data/lib/google/protobuf/field_mask.rb +0 -16
  51. data/lib/google/protobuf/source_context.rb +0 -16
  52. data/lib/google/protobuf/struct.rb +0 -35
  53. data/lib/google/protobuf/timestamp.rb +0 -17
  54. data/lib/google/protobuf/type.rb +0 -79
  55. data/lib/google/protobuf/wrappers.rb +0 -48
@@ -31,27 +31,6 @@ module Gcloud
31
31
  class KeyfileError < Gcloud::Datastore::Error
32
32
  end
33
33
 
34
- ##
35
- # # ApiError
36
- #
37
- # Raised when an API call is not successful.
38
- class ApiError < Gcloud::Datastore::Error
39
- ##
40
- # The API method of the failed HTTP request.
41
- attr_reader :method
42
-
43
- ##
44
- # The response object of the failed HTTP request.
45
- attr_reader :response
46
-
47
- # @private
48
- def initialize method, response = nil
49
- super("API call to #{method} was not successful")
50
- @method = method
51
- @response = response
52
- end
53
- end
54
-
55
34
  ##
56
35
  # # PropertyError
57
36
  #
@@ -0,0 +1,211 @@
1
+ # Copyright 2016 Google Inc. All rights reserved.
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
+ # http://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 "gcloud/datastore/entity"
17
+ require "gcloud/datastore/key"
18
+
19
+ module Gcloud
20
+ module Datastore
21
+ ##
22
+ # # GqlQuery
23
+ #
24
+ # Represents a GQL query.
25
+ #
26
+ # GQL is a SQL-like language for retrieving entities or keys from Datastore.
27
+ #
28
+ # @see https://cloud.google.com/datastore/docs/apis/gql/gql_reference GQL
29
+ # Reference
30
+ #
31
+ # @example
32
+ # gql_query = Gcloud::Datastore::GqlQuery.new
33
+ # gql_query.query_string = "SELECT * FROM Task ORDER BY created ASC"
34
+ # tasks = datastore.run gql_query
35
+ #
36
+ class GqlQuery
37
+ ##
38
+ # Returns a new GqlQuery instance.
39
+ #
40
+ # @example
41
+ # gql_query = Gcloud::Datastore::GqlQuery.new
42
+ #
43
+ def initialize
44
+ @grpc = Google::Datastore::V1beta3::GqlQuery.new
45
+ end
46
+
47
+ ##
48
+ # The GQL query string for the query. The string may contain named
49
+ # or positional argument binding sites that start with `@`. Corresponding
50
+ # binding values should be set with {#named_bindings=} or
51
+ # {#positional_bindings=}.
52
+ #
53
+ # @return [String] a GQL statement
54
+ #
55
+ def query_string
56
+ gql = @grpc.query_string.dup
57
+ gql.freeze
58
+ gql
59
+ end
60
+
61
+ ##
62
+ # Sets the GQL query string for the query. The string may contain named
63
+ # or positional argument binding sites that start with `@`. Corresponding
64
+ # binding values should be set with {#named_bindings=} or
65
+ # {#positional_bindings=}.
66
+ #
67
+ # See the [GQL
68
+ # Reference](https://cloud.google.com/datastore/docs/apis/gql/gql_reference).
69
+ #
70
+ # @param [String] new_query_string a valid GQL statement
71
+ #
72
+ # @example
73
+ # gql_query = Gcloud::Datastore::GqlQuery.new
74
+ # gql_query.query_string = "SELECT * FROM Task " \
75
+ # "WHERE done = @done AND priority = @priority"
76
+ # gql_query.named_bindings = {done: false, priority: 4}
77
+ #
78
+ def query_string= new_query_string
79
+ @grpc.query_string = new_query_string.to_s
80
+ end
81
+
82
+ ##
83
+ # Whether the query may contain literal values. When false, the query
84
+ # string must not contain any literals and instead must bind all values
85
+ # using {#named_bindings=} or {#positional_bindings=}.
86
+ #
87
+ # @return [Boolean] `true` if the query may contain literal values
88
+ #
89
+ def allow_literals
90
+ @grpc.allow_literals
91
+ end
92
+
93
+ ##
94
+ # Sets whether the query may contain literal values. When false, the query
95
+ # string must not contain any literals and instead must bind all values
96
+ # using {#named_bindings=} or {#positional_bindings=}.
97
+ #
98
+ # @param [Boolean] new_allow_literals `true` if the query may contain
99
+ # literal values
100
+ #
101
+ # @example
102
+ # gql_query = Gcloud::Datastore::GqlQuery.new
103
+ # gql_query.query_string = "SELECT * FROM Task " \
104
+ # "WHERE completed = false AND priority = 4"
105
+ # gql_query.allow_literals = true
106
+ #
107
+ def allow_literals= new_allow_literals
108
+ @grpc.allow_literals = new_allow_literals
109
+ end
110
+
111
+ ##
112
+ # The named binding values for a query that contains named argument
113
+ # binding sites that start with `@`.
114
+ #
115
+ # @return [Hash] a frozen hash that maps the binding site names in the
116
+ # query string to valid GQL arguments
117
+ #
118
+ def named_bindings
119
+ bindings = Hash[@grpc.named_bindings.map do |name, gql_query_param|
120
+ if gql_query_param.cursor
121
+ [name, Cursor.from_grpc(gql_query_param.cursor)]
122
+ else
123
+ [name, GRPCUtils.from_value(gql_query_param.value)]
124
+ end
125
+ end]
126
+ bindings.freeze
127
+ bindings
128
+ end
129
+
130
+ ##
131
+ # Sets named binding values for a query that contains named argument
132
+ # binding sites that start with `@`.
133
+ #
134
+ # @param [Hash] new_named_bindings a hash that maps the binding site names
135
+ # in the query string to valid GQL arguments
136
+ #
137
+ # @example
138
+ # gql_query = Gcloud::Datastore::GqlQuery.new
139
+ # gql_query.query_string = "SELECT * FROM Task " \
140
+ # "WHERE done = @done AND priority = @priority"
141
+ # gql_query.named_bindings = {done: false, priority: 4}
142
+ #
143
+ def named_bindings= new_named_bindings
144
+ @grpc.named_bindings.clear
145
+ new_named_bindings.map do |name, value|
146
+ if value.is_a? Gcloud::Datastore::Cursor
147
+ @grpc.named_bindings[name.to_s] = \
148
+ Google::Datastore::V1beta3::GqlQueryParameter.new(
149
+ cursor: value.to_grpc)
150
+ else
151
+ @grpc.named_bindings[name.to_s] = \
152
+ Google::Datastore::V1beta3::GqlQueryParameter.new(
153
+ value: GRPCUtils.to_value(value))
154
+ end
155
+ end
156
+ end
157
+
158
+ ##
159
+ # The binding values for a query that contains numbered argument binding
160
+ # sites that start with `@`.
161
+ #
162
+ # @return [Array] a frozen array containing the query arguments in the
163
+ # order of the numbered binding sites in the query string
164
+ #
165
+ def positional_bindings
166
+ bindings = @grpc.positional_bindings.map do |gql_query_param|
167
+ if gql_query_param.cursor
168
+ Cursor.from_grpc gql_query_param.cursor
169
+ else
170
+ GRPCUtils.from_value gql_query_param.value
171
+ end
172
+ end
173
+ bindings.freeze
174
+ bindings
175
+ end
176
+
177
+ ##
178
+ # Sets the binding values for a query that contains numbered argument
179
+ # binding sites that start with `@`.
180
+ #
181
+ # @param [Array] new_positional_bindings query arguments in the order
182
+ # of the numbered binding sites in the query string
183
+ #
184
+ # @example
185
+ # gql_query = Gcloud::Datastore::GqlQuery.new
186
+ # gql_query.query_string = "SELECT * FROM Task" \
187
+ # "WHERE completed = @1 AND priority = @2"
188
+ # gql_query.positional_bindings = [false, 4]
189
+ #
190
+ def positional_bindings= new_positional_bindings
191
+ @grpc.positional_bindings.clear
192
+ new_positional_bindings.map do |value|
193
+ if value.is_a? Gcloud::Datastore::Cursor
194
+ @grpc.positional_bindings << \
195
+ Google::Datastore::V1beta3::GqlQueryParameter.new(
196
+ cursor: value.to_grpc)
197
+ else
198
+ @grpc.positional_bindings << \
199
+ Google::Datastore::V1beta3::GqlQueryParameter.new(
200
+ value: GRPCUtils.to_value(value))
201
+ end
202
+ end
203
+ end
204
+
205
+ # @private
206
+ def to_grpc
207
+ @grpc
208
+ end
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,131 @@
1
+ # Copyright 2016 Google Inc. All rights reserved.
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
+ # http://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 "gcloud/grpc_utils"
17
+ require "gcloud/datastore/errors"
18
+ require "stringio"
19
+
20
+ module Gcloud
21
+ ##
22
+ # @private Conversion to/from Datastore GRPC objects.
23
+ # This file adds Datastore methods to GRPCUtils.
24
+ module GRPCUtils
25
+ # rubocop:disable all
26
+
27
+ PROP_FILTER_OPS = { "<" => :LESS_THAN,
28
+ "lt" => :LESS_THAN,
29
+ "<=" => :LESS_THAN_OR_EQUAL,
30
+ "lte" => :LESS_THAN_OR_EQUAL,
31
+ ">" => :GREATER_THAN,
32
+ "gt" => :GREATER_THAN,
33
+ ">=" => :GREATER_THAN_OR_EQUAL,
34
+ "gte" => :GREATER_THAN_OR_EQUAL,
35
+ "=" => :EQUAL,
36
+ "eq" => :EQUAL,
37
+ "eql" => :EQUAL,
38
+ "~" => :HAS_ANCESTOR,
39
+ "~>" => :HAS_ANCESTOR,
40
+ "ancestor" => :HAS_ANCESTOR,
41
+ "has_ancestor" => :HAS_ANCESTOR,
42
+ "has ancestor" => :HAS_ANCESTOR }
43
+
44
+ ##
45
+ # Get a property filter operator from op
46
+ def self.to_prop_filter_op op
47
+ PROP_FILTER_OPS[op.to_s.downcase] || :EQUAL
48
+ end
49
+
50
+ ##
51
+ # Gets an object from a Google::Datastore::V1beta3::Value.
52
+ def self.from_value grpc_value
53
+ if grpc_value.value_type == :null_value
54
+ return nil
55
+ elsif grpc_value.value_type == :key_value
56
+ return Gcloud::Datastore::Key.from_grpc(grpc_value.key_value)
57
+ elsif grpc_value.value_type == :entity_value
58
+ return Gcloud::Datastore::Entity.from_grpc(grpc_value.entity_value)
59
+ elsif grpc_value.value_type == :boolean_value
60
+ return grpc_value.boolean_value
61
+ elsif grpc_value.value_type == :double_value
62
+ return grpc_value.double_value
63
+ elsif grpc_value.value_type == :integer_value
64
+ return grpc_value.integer_value
65
+ elsif grpc_value.value_type == :string_value
66
+ return grpc_value.string_value
67
+ elsif grpc_value.value_type == :array_value
68
+ return Array(grpc_value.array_value.values).map { |v| from_value v }
69
+ elsif grpc_value.value_type == :timestamp_value
70
+ return Time.at grpc_value.timestamp_value.seconds,
71
+ grpc_value.timestamp_value.nanos/1000.0
72
+ elsif grpc_value.value_type == :geo_point_value
73
+ return grpc_value.geo_point_value.to_hash
74
+ elsif grpc_value.value_type == :blob_value
75
+ return StringIO.new(grpc_value.blob_value.force_encoding("ASCII-8BIT"))
76
+ else
77
+ nil
78
+ end
79
+ end
80
+
81
+ ##
82
+ # Stores an object into a Google::Datastore::V1beta3::Value.
83
+ def self.to_value value
84
+ v = Google::Datastore::V1beta3::Value.new
85
+ if NilClass === value
86
+ v.null_value = :NULL_VALUE
87
+ elsif TrueClass === value
88
+ v.boolean_value = true
89
+ elsif FalseClass === value
90
+ v.boolean_value = false
91
+ elsif Integer === value
92
+ v.integer_value = value
93
+ elsif Float === value
94
+ v.double_value = value
95
+ elsif defined?(BigDecimal) && BigDecimal === value
96
+ v.double_value = value
97
+ elsif Gcloud::Datastore::Key === value
98
+ v.key_value = value.to_grpc
99
+ elsif Gcloud::Datastore::Entity === value
100
+ v.entity_value = value.to_grpc
101
+ elsif String === value
102
+ v.string_value = value
103
+ elsif Array === value
104
+ v.array_value = Google::Datastore::V1beta3::ArrayValue.new(
105
+ values: value.map { |v| to_value v }
106
+ )
107
+ elsif value.respond_to? :to_time
108
+ v.timestamp_value = Google::Protobuf::Timestamp.new(
109
+ seconds: value.to_time.to_i, nanos: value.to_time.nsec)
110
+ elsif value.respond_to?(:to_hash) && value.keys.sort == [:latitude, :longitude]
111
+ v.geo_point_value = Google::Type::LatLng.new(value)
112
+ elsif value.respond_to?(:read) && value.respond_to?(:rewind)
113
+ value.rewind
114
+ v.blob_value = value.read.force_encoding("ASCII-8BIT")
115
+ else
116
+ fail Gcloud::Datastore::PropertyError,
117
+ "A property of type #{value.class} is not supported."
118
+ end
119
+ v
120
+ end
121
+
122
+ def self.encode_bytes bytes
123
+ Array(bytes.to_s).pack("m").chomp.encode("ASCII-8BIT")
124
+ end
125
+
126
+ def self.decode_bytes bytes
127
+ bytes.to_s.unpack("m").first.force_encoding Encoding::ASCII_8BIT
128
+ end
129
+ # rubocop:enable all
130
+ end
131
+ end
@@ -13,8 +13,6 @@
13
13
  # limitations under the License.
14
14
 
15
15
 
16
- require "gcloud/datastore/proto"
17
-
18
16
  module Gcloud
19
17
  module Datastore
20
18
  ##
@@ -26,7 +24,7 @@ module Gcloud
26
24
  # ID, assigned automatically by Datastore.
27
25
  #
28
26
  # @example
29
- # key = Gcloud::Datastore::Key.new "User", "heidi@example.com"
27
+ # task_key = Gcloud::Datastore::Key.new "Task", "sampleTask"
30
28
  #
31
29
  class Key
32
30
  ##
@@ -35,14 +33,14 @@ module Gcloud
35
33
  # @return [String]
36
34
  #
37
35
  # @example
38
- # key = Gcloud::Datastore::Key.new "User"
39
- # key.kind #=> "User"
36
+ # key = Gcloud::Datastore::Key.new "TaskList"
37
+ # key.kind #=> "TaskList"
40
38
  # key.kind = "Task"
41
39
  #
42
40
  attr_accessor :kind
43
41
 
44
42
  ##
45
- # The dataset_id of the Key.
43
+ # The project of the Key.
46
44
  #
47
45
  # @return [String]
48
46
  #
@@ -52,11 +50,13 @@ module Gcloud
52
50
  # gcloud = Gcloud.new "my-todo-project",
53
51
  # "/path/to/keyfile.json"
54
52
  #
55
- # dataset = gcloud.datastore
56
- # entity = dataset.find "User", "heidi@example.com"
57
- # entity.key.dataset_id #=> "my-todo-project"
53
+ # datastore = gcloud.datastore
54
+ # task = datastore.find "Task", "sampleTask"
55
+ # task.key.project #=> "my-todo-project"
58
56
  #
59
- attr_accessor :dataset_id
57
+ attr_accessor :project
58
+ alias_method :dataset_id, :project
59
+ alias_method :dataset_id=, :project=
60
60
 
61
61
  ##
62
62
  # The namespace of the Key.
@@ -69,9 +69,9 @@ module Gcloud
69
69
  # gcloud = Gcloud.new "my-todo-project",
70
70
  # "/path/to/keyfile.json"
71
71
  #
72
- # dataset = gcloud.datastore
73
- # entity = dataset.find "User", "heidi@example.com"
74
- # entity.key.namespace #=> "ns~todo-project"
72
+ # datastore = gcloud.datastore
73
+ # task = datastore.find "Task", "sampleTask"
74
+ # task.key.namespace #=> "ns~todo-project"
75
75
  #
76
76
  attr_accessor :namespace
77
77
 
@@ -85,7 +85,7 @@ module Gcloud
85
85
  # @return [Gcloud::Datastore::Dataset::Key]
86
86
  #
87
87
  # @example
88
- # key = Gcloud::Datastore::Key.new "User", "heidi@example.com"
88
+ # task_key = Gcloud::Datastore::Key.new "Task", "sampleTask"
89
89
  #
90
90
  def initialize kind = nil, id_or_name = nil
91
91
  @kind = kind
@@ -103,12 +103,12 @@ module Gcloud
103
103
  # @return [Integer, nil]
104
104
  #
105
105
  # @example
106
- # key = Gcloud::Datastore::Key.new "User", "heidi@example.com"
107
- # key.id #=> nil
108
- # key.name #=> "heidi@example.com"
109
- # key.id = 654321
110
- # key.id #=> 654321
111
- # key.name #=> nil
106
+ # task_key = Gcloud::Datastore::Key.new "Task", "sampleTask"
107
+ # task_key.id #=> nil
108
+ # task_key.name #=> "sampleTask"
109
+ # task_key.id = 654321
110
+ # task_key.id #=> 654321
111
+ # task_key.name #=> nil
112
112
  #
113
113
  def id= new_id
114
114
  @name = nil if new_id
@@ -121,8 +121,8 @@ module Gcloud
121
121
  # @return [Integer, nil]
122
122
  #
123
123
  # @example
124
- # key = Gcloud::Datastore::Key.new "User", 123456
125
- # key.id #=> 123456
124
+ # task_key = Gcloud::Datastore::Key.new "Task", 123456
125
+ # task_key.id #=> 123456
126
126
  #
127
127
  attr_reader :id
128
128
 
@@ -133,12 +133,12 @@ module Gcloud
133
133
  # @return [String, nil]
134
134
  #
135
135
  # @example
136
- # key = Gcloud::Datastore::Key.new "User", 123456
137
- # key.id #=> 123456
138
- # key.name #=> nil
139
- # key.name = "heidi@example.com"
140
- # key.id #=> nil
141
- # key.name #=> "heidi@example.com"
136
+ # task_key = Gcloud::Datastore::Key.new "Task", 123456
137
+ # task_key.id #=> 123456
138
+ # task_key.name #=> nil
139
+ # task_key.name = "sampleTask"
140
+ # task_key.id #=> nil
141
+ # task_key.name #=> "sampleTask"
142
142
  #
143
143
  def name= new_name
144
144
  @id = nil if new_name
@@ -151,19 +151,26 @@ module Gcloud
151
151
  # @return [String, nil]
152
152
  #
153
153
  # @example
154
- # key = Gcloud::Datastore::Key.new "User", "heidi@example.com"
155
- # key.name #=> "heidi@example.com"
154
+ # task_key = Gcloud::Datastore::Key.new "Task", "sampleTask"
155
+ # task_key.name #=> "sampleTask"
156
156
  #
157
157
  attr_reader :name
158
158
 
159
159
  ##
160
- # @private Set the parent of the Key.
160
+ # Set the parent of the Key.
161
161
  #
162
162
  # @return [Key, nil]
163
163
  #
164
164
  # @example
165
- # key = Gcloud::Datastore::Key.new "List", "todos"
166
- # key.parent = Gcloud::Datastore::Key.new "User", "heidi@example.com"
165
+ # task_key = Gcloud::Datastore::Key.new "Task", "sampleTask"
166
+ # task_key.parent = Gcloud::Datastore::Key.new "TaskList", "default"
167
+ #
168
+ # @example With multiple levels:
169
+ # user_key = Gcloud::Datastore::Key.new "User", "alice"
170
+ # task_list_key = Gcloud::Datastore::Key.new "TaskList", "default"
171
+ # task_key = Gcloud::Datastore::Key.new "Task", "sampleTask"
172
+ # task_list_key.parent = user_key
173
+ # task_key.parent = task_list_key
167
174
  #
168
175
  def parent= new_parent
169
176
  # store key if given an entity
@@ -180,13 +187,13 @@ module Gcloud
180
187
  # require "gcloud"
181
188
  #
182
189
  # gcloud = Gcloud.new
183
- # dataset = gcloud.datastore
190
+ # datastore = gcloud.datastore
184
191
  #
185
- # user = dataset.find "User", "heidi@example.com"
186
- # query = dataset.query("List").
187
- # ancestor(user.key)
188
- # lists = dataset.run query
189
- # lists.first.key.parent #=> Key("User", "heidi@example.com")
192
+ # task_list = datastore.find "TaskList", "default"
193
+ # query = datastore.query("Task").
194
+ # ancestor(task_list)
195
+ # lists = datastore.run query
196
+ # lists.first.key.parent #=> Key("TaskList", "default")
190
197
  #
191
198
  attr_reader :parent
192
199
 
@@ -198,9 +205,9 @@ module Gcloud
198
205
  # @return [Array<Array<(String, String)>>]
199
206
  #
200
207
  # @example
201
- # key = Gcloud::Datastore::Key.new "List", "todos"
202
- # key.parent = Gcloud::Datastore::Key.new "User", "heidi@example.com"
203
- # key.path #=> [["User", "heidi@example.com"], ["List", "todos"]]
208
+ # task_key = Gcloud::Datastore::Key.new "Task", "sampleTask"
209
+ # task_key.parent = Gcloud::Datastore::Key.new "TaskList", "default"
210
+ # task_key.path #=> [["TaskList", "default"], ["Task", "sampleTask"]]
204
211
  #
205
212
  def path
206
213
  new_path = parent ? parent.path : []
@@ -226,41 +233,43 @@ module Gcloud
226
233
  end
227
234
 
228
235
  ##
229
- # @private Convert the Key to a protocol buffer object.
230
- def to_proto
231
- Proto::Key.new.tap do |k|
232
- k.path_element = path.map do |pe_kind, pe_id_or_name|
233
- Proto.new_path_element pe_kind, pe_id_or_name
236
+ # @private Convert the Key to a Google::Datastore::V1beta3::Key object.
237
+ def to_grpc
238
+ grpc_path = path.map do |pe_kind, pe_id_or_name|
239
+ path_args = { kind: pe_kind }
240
+ if pe_id_or_name.is_a? Integer
241
+ path_args[:id] = pe_id_or_name
242
+ elsif pe_id_or_name.is_a? String
243
+ path_args[:name] = pe_id_or_name unless pe_id_or_name.empty?
234
244
  end
235
- k.partition_id = Proto.new_partition_id dataset_id, namespace
245
+ Google::Datastore::V1beta3::Key::PathElement.new(path_args)
246
+ end
247
+ grpc = Google::Datastore::V1beta3::Key.new(path: grpc_path)
248
+ if project || namespace
249
+ grpc.partition_id = Google::Datastore::V1beta3::PartitionId.new(
250
+ project_id: project.to_s, namespace_id: namespace.to_s)
236
251
  end
252
+ grpc
237
253
  end
238
254
 
239
- # rubocop:disable all
240
-
241
255
  ##
242
- # @private Create a new Key from a protocol buffer object.
243
- def self.from_proto proto
244
- # Disable rules because the complexity here is neccessary.
245
- key_proto = proto.dup
256
+ # @private Create a new Key from a Google::Datastore::V1beta3::Key object.
257
+ def self.from_grpc grpc
258
+ key_grpc = grpc.dup
246
259
  key = Key.new
247
- proto_path_element = Array(key_proto.path_element).pop
248
- if proto_path_element
249
- key = Key.new proto_path_element.kind,
250
- proto_path_element.id || proto_path_element.name
251
- end
252
- if key_proto.partition_id
253
- key.dataset_id = key_proto.partition_id.dataset_id
254
- key.namespace = key_proto.partition_id.namespace
260
+ path_grpc = key_grpc.path.pop
261
+ if path_grpc
262
+ key = Key.new path_grpc.kind, (path_grpc.id || path_grpc.name)
255
263
  end
256
- if Array(key_proto.path_element).count > 0
257
- key.parent = Key.from_proto(key_proto)
264
+ if key_grpc.partition_id
265
+ key.project = key_grpc.partition_id.project_id
266
+ key.namespace = key_grpc.partition_id.namespace_id
258
267
  end
268
+ key.parent = Key.from_grpc(key_grpc) if key_grpc.path.count > 0
259
269
  # Freeze the key to make it immutable.
260
270
  key.freeze
261
271
  key
262
272
  end
263
- # rubocop:enable all
264
273
  end
265
274
  end
266
275
  end