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.
- checksums.yaml +8 -8
- data/CHANGELOG.md +26 -0
- data/OVERVIEW.md +10 -8
- data/lib/gcloud.rb +12 -13
- data/lib/gcloud/bigquery/dataset/list.rb +2 -4
- data/lib/gcloud/bigquery/job/list.rb +3 -5
- data/lib/gcloud/bigquery/table/list.rb +3 -5
- data/lib/gcloud/datastore.rb +326 -97
- data/lib/gcloud/datastore/commit.rb +73 -56
- data/lib/gcloud/datastore/credentials.rb +1 -12
- data/lib/gcloud/datastore/cursor.rb +76 -0
- data/lib/gcloud/datastore/dataset.rb +337 -134
- data/lib/gcloud/datastore/dataset/lookup_results.rb +12 -12
- data/lib/gcloud/datastore/dataset/query_results.rb +117 -27
- data/lib/gcloud/datastore/entity.rb +159 -93
- data/lib/gcloud/datastore/errors.rb +0 -21
- data/lib/gcloud/datastore/gql_query.rb +211 -0
- data/lib/gcloud/datastore/grpc_utils.rb +131 -0
- data/lib/gcloud/datastore/key.rb +74 -65
- data/lib/gcloud/datastore/properties.rb +14 -1
- data/lib/gcloud/datastore/query.rb +188 -52
- data/lib/gcloud/datastore/service.rb +161 -0
- data/lib/gcloud/datastore/transaction.rb +175 -60
- data/lib/gcloud/dns/change/list.rb +2 -4
- data/lib/gcloud/dns/record/list.rb +2 -4
- data/lib/gcloud/dns/zone/list.rb +2 -4
- data/lib/gcloud/grpc_utils.rb +11 -0
- data/lib/gcloud/logging/entry.rb +6 -17
- data/lib/gcloud/logging/entry/list.rb +8 -9
- data/lib/gcloud/logging/metric/list.rb +4 -5
- data/lib/gcloud/logging/resource.rb +1 -12
- data/lib/gcloud/logging/resource_descriptor.rb +9 -12
- data/lib/gcloud/logging/resource_descriptor/list.rb +4 -5
- data/lib/gcloud/logging/sink/list.rb +4 -5
- data/lib/gcloud/pubsub/message.rb +1 -3
- data/lib/gcloud/pubsub/subscription.rb +5 -7
- data/lib/gcloud/pubsub/topic.rb +1 -3
- data/lib/gcloud/resource_manager/project/list.rb +2 -4
- data/lib/gcloud/translate/api.rb +5 -3
- data/lib/gcloud/translate/connection.rb +4 -4
- data/lib/gcloud/version.rb +1 -1
- metadata +9 -20
- data/lib/gcloud/datastore/connection.rb +0 -203
- data/lib/gcloud/datastore/proto.rb +0 -266
- data/lib/gcloud/proto/datastore_v1.pb.rb +0 -377
- data/lib/google/protobuf/any.rb +0 -17
- data/lib/google/protobuf/api.rb +0 -31
- data/lib/google/protobuf/duration.rb +0 -17
- data/lib/google/protobuf/empty.rb +0 -15
- data/lib/google/protobuf/field_mask.rb +0 -16
- data/lib/google/protobuf/source_context.rb +0 -16
- data/lib/google/protobuf/struct.rb +0 -35
- data/lib/google/protobuf/timestamp.rb +0 -17
- data/lib/google/protobuf/type.rb +0 -79
- data/lib/google/protobuf/wrappers.rb +0 -48
@@ -28,20 +28,20 @@ module Gcloud
|
|
28
28
|
# Many common Array methods will return a new Array instance.
|
29
29
|
#
|
30
30
|
# @example
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
31
|
+
# tasks = datastore.find_all task_key1, task_key2, task_key3
|
32
|
+
# tasks.size #=> 3
|
33
|
+
# tasks.deferred #=> []
|
34
|
+
# tasks.missing #=> []
|
35
35
|
#
|
36
36
|
# @example Caution, many Array methods will return a new Array instance:
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
37
|
+
# tasks = datastore.find_all task_key1, task_key2, task_key3
|
38
|
+
# tasks.size #=> 3
|
39
|
+
# tasks.deferred #=> []
|
40
|
+
# tasks.missing #=> []
|
41
|
+
# descriptions = tasks.map { |task| task["description"] }
|
42
|
+
# descriptions.size #=> 3
|
43
|
+
# descriptions.deferred #=> NoMethodError
|
44
|
+
# descriptions.missing #=> NoMethodError
|
45
45
|
#
|
46
46
|
class LookupResults < DelegateClass(::Array)
|
47
47
|
##
|
@@ -28,21 +28,23 @@ module Gcloud
|
|
28
28
|
# Many common Array methods will return a new Array instance.
|
29
29
|
#
|
30
30
|
# @example
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
31
|
+
# tasks = datastore.run query
|
32
|
+
# tasks.size #=> 3
|
33
|
+
# tasks.cursor #=> Gcloud::Datastore::Cursor(c3VwZXJhd2Vzb21lIQ)
|
34
34
|
#
|
35
35
|
# @example Caution, many Array methods will return a new Array instance:
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
36
|
+
# tasks = datastore.run query
|
37
|
+
# tasks.size #=> 3
|
38
|
+
# tasks.end_cursor #=> Gcloud::Datastore::Cursor(c3VwZXJhd2Vzb21lIQ)
|
39
|
+
# descriptions = tasks.map { |task| task["description"] }
|
40
|
+
# descriptions.size #=> 3
|
41
|
+
# descriptions.cursor #=> NoMethodError
|
42
42
|
#
|
43
43
|
class QueryResults < DelegateClass(::Array)
|
44
44
|
##
|
45
45
|
# The end_cursor of the QueryResults.
|
46
|
+
#
|
47
|
+
# @return [Gcloud::Datastore::Cursor]
|
46
48
|
attr_reader :end_cursor
|
47
49
|
alias_method :cursor, :end_cursor
|
48
50
|
|
@@ -51,41 +53,129 @@ module Gcloud
|
|
51
53
|
#
|
52
54
|
# Expected values are:
|
53
55
|
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
56
|
+
# * `:NOT_FINISHED`
|
57
|
+
# * `:MORE_RESULTS_AFTER_LIMIT`
|
58
|
+
# * `:MORE_RESULTS_AFTER_CURSOR`
|
59
|
+
# * `:NO_MORE_RESULTS`
|
57
60
|
attr_reader :more_results
|
58
61
|
|
59
62
|
##
|
60
|
-
#
|
61
|
-
|
63
|
+
# @private
|
64
|
+
attr_accessor :service, :namespace, :query
|
65
|
+
|
66
|
+
##
|
67
|
+
# @private
|
68
|
+
attr_writer :end_cursor, :more_results
|
69
|
+
|
70
|
+
##
|
71
|
+
# Convenience method for determining if the `more_results` value
|
72
|
+
# is `:NOT_FINISHED`
|
62
73
|
def not_finished?
|
63
|
-
more_results ==
|
64
|
-
Proto::QueryResultBatch::MoreResultsType::NOT_FINISHED)
|
74
|
+
more_results == :NOT_FINISHED
|
65
75
|
end
|
66
76
|
|
67
77
|
##
|
68
|
-
# Convenience method for determining
|
69
|
-
# is
|
78
|
+
# Convenience method for determining if the `more_results` value
|
79
|
+
# is `:MORE_RESULTS_AFTER_LIMIT`
|
70
80
|
def more_after_limit?
|
71
|
-
more_results ==
|
72
|
-
|
81
|
+
more_results == :MORE_RESULTS_AFTER_LIMIT
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Convenience method for determining if the `more_results` value
|
86
|
+
# is `:MORE_RESULTS_AFTER_CURSOR`
|
87
|
+
def more_after_cursor?
|
88
|
+
more_results == :MORE_RESULTS_AFTER_CURSOR
|
73
89
|
end
|
74
90
|
|
75
91
|
##
|
76
|
-
# Convenience method for determining
|
77
|
-
# is
|
92
|
+
# Convenience method for determining if the `more_results` value
|
93
|
+
# is `:NO_MORE_RESULTS`
|
78
94
|
def no_more?
|
79
|
-
more_results ==
|
80
|
-
Proto::QueryResultBatch::MoreResultsType::NO_MORE_RESULTS)
|
95
|
+
more_results == :NO_MORE_RESULTS
|
81
96
|
end
|
82
97
|
|
83
98
|
##
|
84
99
|
# Create a new QueryResults with an array of values.
|
85
|
-
def initialize arr = []
|
100
|
+
def initialize arr = []
|
86
101
|
super arr
|
87
|
-
|
88
|
-
|
102
|
+
end
|
103
|
+
|
104
|
+
##
|
105
|
+
# Whether there are more results available.
|
106
|
+
def next?
|
107
|
+
!no_more?
|
108
|
+
end
|
109
|
+
|
110
|
+
##
|
111
|
+
# Retrieve the next page of results.
|
112
|
+
def next
|
113
|
+
return nil unless next?
|
114
|
+
return nil if end_cursor.nil?
|
115
|
+
ensure_service!
|
116
|
+
query.start_cursor = cursor.to_grpc # should always be a Cursor...
|
117
|
+
query_res = service.run_query query, namespace
|
118
|
+
self.class.from_grpc query_res, service, namespace, query
|
119
|
+
rescue GRPC::BadStatus => e
|
120
|
+
raise Gcloud::Error.from_error(e)
|
121
|
+
end
|
122
|
+
|
123
|
+
##
|
124
|
+
# Retrieves all log entries by repeatedly loading {#next} until
|
125
|
+
# {#next?} returns `false`. Returns the list instance for method
|
126
|
+
# chaining.
|
127
|
+
#
|
128
|
+
# This method may make several API calls until all log entries are
|
129
|
+
# retrieved. Be sure to use as narrow a search criteria as possible.
|
130
|
+
# Please use with caution.
|
131
|
+
#
|
132
|
+
# @example
|
133
|
+
# require "gcloud"
|
134
|
+
#
|
135
|
+
# gcloud = Gcloud.new
|
136
|
+
# logging = gcloud.logging
|
137
|
+
# hour_ago = (Time.now - 60*60).utc.strftime('%FT%TZ')
|
138
|
+
# recent_errors = "timestamp >= \"#{hour_ago}\" severity >= ERROR"
|
139
|
+
# entries = logging.entries(filter: recent_errors).all
|
140
|
+
#
|
141
|
+
def all
|
142
|
+
while next?
|
143
|
+
next_records = self.next
|
144
|
+
push(*next_records)
|
145
|
+
self.end_cursor = next_records.end_cursor
|
146
|
+
self.more_results = next_records.more_results
|
147
|
+
self.service = next_records.service
|
148
|
+
self.namespace = next_records.namespace
|
149
|
+
self.query = next_records.query
|
150
|
+
end
|
151
|
+
self
|
152
|
+
end
|
153
|
+
|
154
|
+
##
|
155
|
+
# @private New Dataset::QueryResults from a
|
156
|
+
# Google::Dataset::V1beta3::RunQueryResponse object.
|
157
|
+
def self.from_grpc query_res, service, namespace, query
|
158
|
+
entities = Array(query_res.batch.entity_results).map do |result|
|
159
|
+
# TODO: Make this return an EntityResult with cursor...
|
160
|
+
Entity.from_grpc result.entity
|
161
|
+
end
|
162
|
+
new(entities).tap do |qr|
|
163
|
+
qr.end_cursor = Cursor.from_grpc query_res.batch.end_cursor
|
164
|
+
qr.more_results = query_res.batch.more_results
|
165
|
+
qr.service = service
|
166
|
+
qr.namespace = namespace
|
167
|
+
qr.query = query_res.query || query
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
protected
|
172
|
+
|
173
|
+
##
|
174
|
+
# @private Raise an error unless an active connection to the service is
|
175
|
+
# available.
|
176
|
+
def ensure_service!
|
177
|
+
msg = "Must have active connection to datastore service to get next"
|
178
|
+
fail msg if @service.nil? || @query.nil?
|
89
179
|
end
|
90
180
|
end
|
91
181
|
end
|
@@ -15,7 +15,6 @@
|
|
15
15
|
|
16
16
|
require "gcloud/datastore/key"
|
17
17
|
require "gcloud/datastore/properties"
|
18
|
-
require "gcloud/datastore/proto"
|
19
18
|
|
20
19
|
module Gcloud
|
21
20
|
module Datastore
|
@@ -25,10 +24,35 @@ module Gcloud
|
|
25
24
|
# Entity represents a Datastore record.
|
26
25
|
# Every Entity has a {Key}, and a list of properties.
|
27
26
|
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
27
|
+
# Entities in Datastore form a hierarchically structured space similar to
|
28
|
+
# the directory structure of a file system. When you create an entity, you
|
29
|
+
# can optionally designate another entity as its parent; the new entity is a
|
30
|
+
# child of the parent entity.
|
31
|
+
#
|
32
|
+
# @see https://cloud.google.com/datastore/docs/concepts/entities Entities,
|
33
|
+
# Properties, and Keys
|
34
|
+
#
|
35
|
+
# @example Create a new entity using a block:
|
36
|
+
# task = datastore.entity "Task", "sampleTask" do |t|
|
37
|
+
# t["type"] = "Personal"
|
38
|
+
# t["created"] = Time.now
|
39
|
+
# t["done"] = false
|
40
|
+
# t["priority"] = 4
|
41
|
+
# t["percent_complete"] = 10.0
|
42
|
+
# t["description"] = "Learn Cloud Datastore"
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# @example Create a new entity belonging to an existing parent entity:
|
46
|
+
# task_key = datastore.key "Task", "sampleTask"
|
47
|
+
# task_key.parent = datastore.key "TaskList", "default"
|
48
|
+
#
|
49
|
+
# task = Gcloud::Datastore::Entity.new
|
50
|
+
# task.key = task_key
|
51
|
+
#
|
52
|
+
# task["type"] = "Personal"
|
53
|
+
# task["done"] = false
|
54
|
+
# task["priority"] = 4
|
55
|
+
# task["description"] = "Learn Cloud Datastore"
|
32
56
|
#
|
33
57
|
class Entity
|
34
58
|
##
|
@@ -48,6 +72,8 @@ module Gcloud
|
|
48
72
|
#
|
49
73
|
# Property values are converted from the Datastore value type
|
50
74
|
# automatically. Blob properties are returned as StringIO objects.
|
75
|
+
# Location properties are returned as a Hash with `:longitude` and
|
76
|
+
# `:latitude` keys.
|
51
77
|
#
|
52
78
|
# @param [String, Symbol] prop_name The name of the property.
|
53
79
|
#
|
@@ -57,28 +83,45 @@ module Gcloud
|
|
57
83
|
# require "gcloud"
|
58
84
|
#
|
59
85
|
# gcloud = Gcloud.new
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
86
|
+
# datastore = gcloud.datastore
|
87
|
+
# task = datastore.find "Task", "sampleTask"
|
88
|
+
# task["description"] #=> "Learn Cloud Datastore"
|
63
89
|
#
|
64
90
|
# @example Or with a symbol name:
|
65
91
|
# require "gcloud"
|
66
92
|
#
|
67
93
|
# gcloud = Gcloud.new
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
94
|
+
# datastore = gcloud.datastore
|
95
|
+
# task = datastore.find "Task", "sampleTask"
|
96
|
+
# task[:description] #=> "Learn Cloud Datastore"
|
97
|
+
#
|
98
|
+
# @example Getting a blob value returns a StringIO object:
|
99
|
+
# require "gcloud"
|
100
|
+
#
|
101
|
+
# gcloud = Gcloud.new
|
102
|
+
# datastore = gcloud.datastore
|
103
|
+
# user = datastore.find "User", "alice"
|
104
|
+
# user["avatar"] #=> StringIO("\x89PNG\r\n\x1A...")
|
105
|
+
#
|
106
|
+
# @example Getting a geo point value returns a Hash:
|
107
|
+
# require "gcloud"
|
108
|
+
#
|
109
|
+
# gcloud = Gcloud.new
|
110
|
+
# datastore = gcloud.datastore
|
111
|
+
# user = datastore.find "User", "alice"
|
112
|
+
# user["location"] #=> { longitude: -122.0862462,
|
113
|
+
# # latitude: 37.4220041 }
|
71
114
|
#
|
72
115
|
# @example Getting a blob value returns a StringIO object:
|
73
116
|
# require "gcloud"
|
74
117
|
#
|
75
118
|
# gcloud = Gcloud.new
|
76
|
-
#
|
77
|
-
# user =
|
119
|
+
# datastore = gcloud.datastore
|
120
|
+
# user = datastore.find "User", "alice"
|
78
121
|
# user["avatar"] #=> StringIO("\x89PNG\r\n\x1A...")
|
79
122
|
#
|
80
123
|
def [] prop_name
|
81
|
-
|
124
|
+
properties[prop_name]
|
82
125
|
end
|
83
126
|
|
84
127
|
##
|
@@ -88,7 +131,8 @@ module Gcloud
|
|
88
131
|
# automatically. Use an IO-compatible object (File, StringIO, Tempfile) to
|
89
132
|
# indicate the property value should be stored as a Datastore `blob`.
|
90
133
|
# IO-compatible objects are converted to StringIO objects when they are
|
91
|
-
# set.
|
134
|
+
# set. Use a Hash with `:longitude` and `:latitude` keys to indicate the
|
135
|
+
# property value should be stored as a Geo Point/LatLng.
|
92
136
|
#
|
93
137
|
# @param [String, Symbol] prop_name The name of the property.
|
94
138
|
# @param [Object] prop_value The value of the property.
|
@@ -97,29 +141,48 @@ module Gcloud
|
|
97
141
|
# require "gcloud"
|
98
142
|
#
|
99
143
|
# gcloud = Gcloud.new
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
144
|
+
# datastore = gcloud.datastore
|
145
|
+
# task = datastore.find "Task", "sampleTask"
|
146
|
+
# task["description"] = "Learn Cloud Datastore"
|
147
|
+
# task["tags"] = ["fun", "programming"]
|
103
148
|
#
|
104
149
|
# @example Or with a symbol name:
|
105
150
|
# require "gcloud"
|
106
151
|
#
|
107
152
|
# gcloud = Gcloud.new
|
108
|
-
#
|
109
|
-
#
|
110
|
-
#
|
153
|
+
# datastore = gcloud.datastore
|
154
|
+
# task = datastore.find "Task", "sampleTask"
|
155
|
+
# task[:description] = "Learn Cloud Datastore"
|
156
|
+
# task[:tags] = ["fun", "programming"]
|
111
157
|
#
|
112
158
|
# @example Setting a blob value using an IO:
|
113
159
|
# require "gcloud"
|
114
160
|
#
|
115
161
|
# gcloud = Gcloud.new
|
116
|
-
#
|
117
|
-
# user =
|
118
|
-
# user["avatar"] = File.open "/avatars/
|
162
|
+
# datastore = gcloud.datastore
|
163
|
+
# user = datastore.find "User", "alice"
|
164
|
+
# user["avatar"] = File.open "/avatars/alice.png"
|
165
|
+
# user["avatar"] #=> StringIO("\x89PNG\r\n\x1A...")
|
166
|
+
#
|
167
|
+
# @example Setting a geo point value using a Hash:
|
168
|
+
# require "gcloud"
|
169
|
+
#
|
170
|
+
# gcloud = Gcloud.new
|
171
|
+
# datastore = gcloud.datastore
|
172
|
+
# user = datastore.find "User", "alice"
|
173
|
+
# user["location"] = { longitude: -122.0862462, latitude: 37.4220041 }
|
174
|
+
#
|
175
|
+
# @example Setting a blob value using an IO:
|
176
|
+
# require "gcloud"
|
177
|
+
#
|
178
|
+
# gcloud = Gcloud.new
|
179
|
+
# datastore = gcloud.datastore
|
180
|
+
# user = datastore.find "User", "alice"
|
181
|
+
# user["avatar"] = File.open "/avatars/alice.png"
|
119
182
|
# user["avatar"] #=> StringIO("\x89PNG\r\n\x1A...")
|
120
183
|
#
|
121
184
|
def []= prop_name, prop_value
|
122
|
-
|
185
|
+
properties[prop_name] = prop_value
|
123
186
|
end
|
124
187
|
|
125
188
|
##
|
@@ -129,52 +192,52 @@ module Gcloud
|
|
129
192
|
# @return [Gcloud::Datastore::Properties]
|
130
193
|
#
|
131
194
|
# @example
|
132
|
-
#
|
133
|
-
#
|
195
|
+
# task.properties[:description] = "Learn Cloud Datastore"
|
196
|
+
# task.properties["description"] #=> "Learn Cloud Datastore"
|
134
197
|
#
|
135
|
-
#
|
198
|
+
# task.properties.each do |name, value|
|
136
199
|
# puts "property #{name} has a value of #{value}"
|
137
200
|
# end
|
138
201
|
#
|
139
202
|
# @example A property's existence can be determined by calling `exist?`:
|
140
|
-
#
|
141
|
-
#
|
142
|
-
#
|
203
|
+
# task.properties.exist? :description #=> true
|
204
|
+
# task.properties.exist? "description" #=> true
|
205
|
+
# task.properties.exist? :expiration #=> false
|
143
206
|
#
|
144
207
|
# @example A property can be removed from the entity:
|
145
|
-
#
|
146
|
-
#
|
208
|
+
# task.properties.delete :description
|
209
|
+
# task.save
|
147
210
|
#
|
148
211
|
# @example The properties can be converted to a hash:
|
149
|
-
# prop_hash =
|
212
|
+
# prop_hash = task.properties.to_h
|
150
213
|
#
|
151
214
|
attr_reader :properties
|
152
215
|
|
153
216
|
##
|
154
|
-
# Sets the Key that identifies the entity.
|
217
|
+
# Sets the {Gcloud::Datastore::Key} that identifies the entity.
|
155
218
|
#
|
156
219
|
# Once the entity is saved, the key is frozen and immutable. Trying to set
|
157
220
|
# a key when immutable will raise a `RuntimeError`.
|
158
221
|
#
|
159
|
-
# @example The
|
222
|
+
# @example The key can be set before the entity is saved:
|
160
223
|
# require "gcloud"
|
161
224
|
#
|
162
225
|
# gcloud = Gcloud.new
|
163
|
-
#
|
164
|
-
#
|
165
|
-
#
|
166
|
-
#
|
226
|
+
# datastore = gcloud.datastore
|
227
|
+
# task = Gcloud::Datastore::Entity.new
|
228
|
+
# task.key = datastore.key "Task"
|
229
|
+
# datastore.save task
|
167
230
|
#
|
168
231
|
# @example Once the entity is saved, the key is frozen and immutable:
|
169
232
|
# require "gcloud"
|
170
233
|
#
|
171
234
|
# gcloud = Gcloud.new
|
172
|
-
#
|
173
|
-
#
|
174
|
-
#
|
175
|
-
#
|
176
|
-
#
|
177
|
-
#
|
235
|
+
# datastore = gcloud.datastore
|
236
|
+
# task = datastore.find "Task", "sampleTask"
|
237
|
+
# task.persisted? #=> true
|
238
|
+
# task.key = datastore.key "Task" #=> RuntimeError
|
239
|
+
# task.key.frozen? #=> true
|
240
|
+
# task.key.id = 9876543221 #=> RuntimeError
|
178
241
|
#
|
179
242
|
def key= new_key
|
180
243
|
fail "This entity's key is immutable." if persisted?
|
@@ -188,13 +251,13 @@ module Gcloud
|
|
188
251
|
# require "gcloud"
|
189
252
|
#
|
190
253
|
# gcloud = Gcloud.new
|
191
|
-
#
|
254
|
+
# datastore = gcloud.datastore
|
192
255
|
#
|
193
|
-
#
|
194
|
-
#
|
256
|
+
# task = Gcloud::Datastore::Entity.new
|
257
|
+
# task.persisted? #=> false
|
195
258
|
#
|
196
|
-
#
|
197
|
-
#
|
259
|
+
# task = datastore.find "Task", "sampleTask"
|
260
|
+
# task.persisted? #=> true
|
198
261
|
#
|
199
262
|
def persisted?
|
200
263
|
@key && @key.frozen?
|
@@ -217,14 +280,14 @@ module Gcloud
|
|
217
280
|
# Unindexed properties
|
218
281
|
#
|
219
282
|
# @example Single property values will return a single flag setting:
|
220
|
-
#
|
221
|
-
#
|
283
|
+
# task["priority"] = 4
|
284
|
+
# task.exclude_from_indexes? "priority" #=> false
|
222
285
|
#
|
223
286
|
# @example A multi-valued property will return an array of flag settings:
|
224
|
-
#
|
225
|
-
#
|
287
|
+
# task["tags"] = ["fun", "programming"]
|
288
|
+
# task.exclude_from_indexes! "tags", [true, false]
|
226
289
|
#
|
227
|
-
#
|
290
|
+
# task.exclude_from_indexes? "tags" #=> [true, false]
|
228
291
|
#
|
229
292
|
def exclude_from_indexes? name
|
230
293
|
value = self[name]
|
@@ -260,21 +323,21 @@ module Gcloud
|
|
260
323
|
# Unindexed properties
|
261
324
|
#
|
262
325
|
# @example
|
263
|
-
# entity["
|
264
|
-
# entity.exclude_from_indexes! "
|
326
|
+
# entity["priority"] = 4
|
327
|
+
# entity.exclude_from_indexes! "priority", true
|
265
328
|
#
|
266
329
|
# @example Multi-valued properties can be given multiple exclude flags:
|
267
|
-
# entity["tags"] = ["
|
330
|
+
# entity["tags"] = ["fun", "programming"]
|
268
331
|
# entity.exclude_from_indexes! "tags", [true, false]
|
269
332
|
#
|
270
333
|
# @example Or, a single flag can be applied to all values in a property:
|
271
|
-
# entity["tags"] = ["
|
334
|
+
# entity["tags"] = ["fun", "programming"]
|
272
335
|
# entity.exclude_from_indexes! "tags", true
|
273
336
|
#
|
274
337
|
# @example Flags can also be set with a block:
|
275
|
-
# entity["
|
276
|
-
# entity.exclude_from_indexes! "
|
277
|
-
#
|
338
|
+
# entity["priority"] = 4
|
339
|
+
# entity.exclude_from_indexes! "priority" do |priority|
|
340
|
+
# priority > 4
|
278
341
|
# end
|
279
342
|
#
|
280
343
|
def exclude_from_indexes! name, flag = nil, &block
|
@@ -288,30 +351,34 @@ module Gcloud
|
|
288
351
|
end
|
289
352
|
|
290
353
|
##
|
291
|
-
# @private Convert the Entity to a
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
354
|
+
# @private Convert the Entity to a Google::Datastore::V1beta3::Entity
|
355
|
+
# object.
|
356
|
+
def to_grpc
|
357
|
+
grpc = Google::Datastore::V1beta3::Entity.new(
|
358
|
+
key: @key.to_grpc,
|
359
|
+
properties: @properties.to_grpc
|
360
|
+
)
|
361
|
+
update_properties_indexed! grpc.properties
|
362
|
+
grpc
|
299
363
|
end
|
300
364
|
|
301
365
|
##
|
302
|
-
# @private Create a new Entity from a
|
303
|
-
|
366
|
+
# @private Create a new Entity from a Google::Datastore::V1beta3::Key
|
367
|
+
# object.
|
368
|
+
def self.from_grpc grpc
|
304
369
|
entity = Entity.new
|
305
|
-
entity.key = Key.
|
306
|
-
|
307
|
-
|
308
|
-
end
|
309
|
-
entity.send :update_exclude_indexes!, proto
|
370
|
+
entity.key = Key.from_grpc grpc.key
|
371
|
+
entity.send :properties=, Properties.from_grpc(grpc.properties)
|
372
|
+
entity.send :update_exclude_indexes!, grpc.properties
|
310
373
|
entity
|
311
374
|
end
|
312
375
|
|
313
376
|
protected
|
314
377
|
|
378
|
+
##
|
379
|
+
# @private Allow friendly objects to set Properties object.
|
380
|
+
attr_writer :properties
|
381
|
+
|
315
382
|
# rubocop:disable all
|
316
383
|
# Disabled rubocop because this is intentionally complex.
|
317
384
|
|
@@ -342,31 +409,30 @@ module Gcloud
|
|
342
409
|
|
343
410
|
##
|
344
411
|
# @private Update the exclude data after a new object is created.
|
345
|
-
def update_exclude_indexes!
|
412
|
+
def update_exclude_indexes! grpc_map
|
346
413
|
@_exclude_indexes = {}
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
414
|
+
grpc_map.each do |name, value|
|
415
|
+
next if value.nil?
|
416
|
+
@_exclude_indexes[name] = value.exclude_from_indexes
|
417
|
+
unless value.array_value.nil?
|
418
|
+
exclude = value.array_value.values.map &:exclude_from_indexes
|
419
|
+
@_exclude_indexes[name] = exclude
|
352
420
|
end
|
353
421
|
end
|
354
422
|
end
|
355
423
|
|
356
424
|
##
|
357
425
|
# @private Update the indexed values before the object is saved.
|
358
|
-
def update_properties_indexed!
|
359
|
-
|
360
|
-
|
426
|
+
def update_properties_indexed! grpc_map
|
427
|
+
grpc_map.each do |name, value|
|
428
|
+
next if value.nil?
|
429
|
+
excluded = exclude_from_indexes? name
|
361
430
|
if excluded.is_a? Array
|
362
|
-
|
363
|
-
|
364
|
-
property.value.indexed = nil
|
365
|
-
property.value.list_value.each_with_index do |value, index|
|
366
|
-
value.indexed = !excluded[index]
|
431
|
+
value.array_value.values.each_with_index do |v, i|
|
432
|
+
v.exclude_from_indexes = excluded[i]
|
367
433
|
end
|
368
434
|
else
|
369
|
-
|
435
|
+
value.exclude_from_indexes = excluded
|
370
436
|
end
|
371
437
|
end
|
372
438
|
end
|