gcloud 0.8.2 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|