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
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZjM3ZTdhZGU0OWE0NTcxY2M0ZDAxNTY4NDAwNmI4MzNiNjlhZjBjZg==
4
+ OGM0OTdkYTJmYjlhOTU0NWFjYjEzZmI2ZGJmZDBhMGQ5NzJhODY1OQ==
5
5
  data.tar.gz: !binary |-
6
- NTU2MWEwNzk1MjhlOWU1Mzc4MzUxNDdhZjEzNmYzZmI5NDViZjBkZA==
6
+ NDgxNGI1OTM3MTMwZGY5ZmQ4NzcxZWZkMjg4YTM2MTg1ZDMyMWRjMw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- Y2JlMDZiZGFiZmZkNTQ3N2QxOTRlZjlkOTdjNDk2ZWEwNTQ5NjA1MjUxMTVk
10
- NjBhNDcxZjMyOWM1ZjEzMTFjYzQzMzU1YTA2ZmQ1ZGYwMTQ3OTg3OGRhMzhm
11
- YTMyNjQzODhlYTVhMThmMjkwY2Q0MjhmMmZhZGIwOTcyODU1Mjc=
9
+ YTFmYTY4YmRhOWJiMjJmMWU5OWM2YmZmODE1ZGQ0NmQ0MTgyNmExOTdhN2E1
10
+ NGU4OTAyODg3NTUwOWM1YzVmYjQwNThmMDdmNmQzYjU0YTA3NGVhOGQ5ZmFk
11
+ ZjE1OGFiMDcxZjFmZGFhNzkzMjhmMGIxZGNhYjhmMWQ0YzRlOTU=
12
12
  data.tar.gz: !binary |-
13
- NjNmMDkzZDhjNWZjYjFlMGVkOWM4MTliOGU4ZjRlN2E4MjAxYjgzNzBiNTgx
14
- ZjdiOWY2NmY1YTY0OGE4OWQ5ZTg1MDEzMDE2ZGYwNjg0M2M2ZjNhMmI3YmY2
15
- MGE4MDBlNWY4YTU2NGM3Mzc1MThlZDAyMjA0YTkzZGE2NDAxMGI=
13
+ NDQxZmMxNTk5NjAwODA3ZDg5NGM5NjVkZDBmY2Q1OWIxYWM3OGIwNzQ2OTE0
14
+ ZDA5MjNlNzgxODMyY2MyNWM3NmJmZGZjZjdhZGJlYTNlZWQ4MmRkNzA2NTk1
15
+ OGYxNTVlNjk4ZWUzN2M0YTFkNDY2Yjk3MDY4MTUzNDM1MWVlOTI=
data/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Release History
2
2
 
3
+ ### 0.9.0 / 2016-05-11
4
+
5
+ #### Major Changes
6
+
7
+ * Datastore
8
+ * Upgrade Datastore to v1beta3 using gRPC
9
+ * Add GQL query support
10
+ * Breaking Changes:
11
+ * `QueryResults#more_results` is now a symbol, was a string
12
+ * `ApiError` is removed, top-level Gcloud errors returned now
13
+ * `DATASTORE_HOST` environment variable removed, use
14
+ `DATASTORE_EMULATOR_HOST` now
15
+
16
+ #### Minor Changes
17
+
18
+ * Datastore
19
+ * Add insert and update methods to specify persistence behavior
20
+ * Allow different updates (upsert/insert/update/delete) in a
21
+ single commit outside of a transaction
22
+ * Entity can now have Location property values
23
+ * `QueryResults#more_after_cursor?` was added
24
+ * `QueryResults#next?`, `#next`, `#all` were added
25
+ * Allow array of objects as well as splat arguments
26
+ * Translate
27
+ * Allow array of strings as well as splat arguments
28
+
3
29
  ### 0.8.2 / 2016-05-04
4
30
 
5
31
  #### Changes
data/OVERVIEW.md CHANGED
@@ -50,21 +50,23 @@ See the {Gcloud::Bigquery gcloud-ruby Datastore API documentation} to learn how
50
50
  require "gcloud"
51
51
 
52
52
  gcloud = Gcloud.new
53
- dataset = gcloud.datastore
53
+ datastore = gcloud.datastore
54
54
 
55
55
  # Create a new task to demo datastore
56
- demo_task = dataset.entity "Task", "datastore-demo" do |t|
57
- t["description"] = "Demonstrate Datastore functionality"
58
- t["completed"] = false
56
+ task = datastore.entity "Task", "sampleTask" do |t|
57
+ t["type"] = "Personal"
58
+ t["done"] = false
59
+ t["priority"] = 4
60
+ t["description"] = "Learn Cloud Datastore"
59
61
  end
60
62
 
61
63
  # Save the new task
62
- dataset.save demo_task
64
+ datastore.save task
63
65
 
64
66
  # Run a query for all completed tasks
65
- query = dataset.query("Task").
66
- where("completed", "=", true)
67
- completed_tasks = dataset.run query
67
+ query = datastore.query("Task").
68
+ where("done", "=", false)
69
+ tasks = datastore.run query
68
70
  ```
69
71
 
70
72
  # DNS
data/lib/gcloud.rb CHANGED
@@ -48,16 +48,14 @@ module Gcloud
48
48
  # require "gcloud"
49
49
  #
50
50
  # gcloud = Gcloud.new
51
- # dataset = gcloud.datastore
51
+ # datastore = gcloud.datastore
52
52
  # pubsub = gcloud.pubsub
53
53
  # storage = gcloud.storage
54
54
  #
55
55
  def self.new project = nil, keyfile = nil
56
56
  gcloud = Object.new
57
- gcloud.instance_eval do
58
- @project = project
59
- @keyfile = keyfile
60
- end
57
+ gcloud.instance_variable_set "@project", project
58
+ gcloud.instance_variable_set "@keyfile", keyfile
61
59
  gcloud.extend Gcloud
62
60
  gcloud
63
61
  end
@@ -74,10 +72,9 @@ module Gcloud
74
72
  # OAuth 2.0 to Access Google
75
73
  # APIs](https://developers.google.com/identity/protocols/OAuth2).
76
74
  #
77
- # The default scopes are:
75
+ # The default scope is:
78
76
  #
79
77
  # * `https://www.googleapis.com/auth/datastore`
80
- # * `https://www.googleapis.com/auth/userinfo.email`
81
78
  #
82
79
  # @return [Gcloud::Datastore::Dataset]
83
80
  #
@@ -85,21 +82,23 @@ module Gcloud
85
82
  # require "gcloud"
86
83
  #
87
84
  # gcloud = Gcloud.new
88
- # dataset = gcloud.datastore
85
+ # datastore = gcloud.datastore
89
86
  #
90
- # entity = dataset.entity "Task" do |t|
91
- # t["description"] = "Get started with Google Cloud"
92
- # t["completed"] = false
87
+ # task = datastore.entity "Task" do |t|
88
+ # t["type"] = "Personal"
89
+ # t["done"] = false
90
+ # t["priority"] = 4
91
+ # t["description"] = "Learn Cloud Datastore"
93
92
  # end
94
93
  #
95
- # dataset.save entity
94
+ # datastore.save task
96
95
  #
97
96
  # @example You shouldn't need to override the default scope, but you can:
98
97
  # require "gcloud"
99
98
  #
100
99
  # gcloud = Gcloud.new
101
100
  # platform_scope = "https://www.googleapis.com/auth/cloud-platform"
102
- # dataset = gcloud.datastore scope: platform_scope
101
+ # datastore = gcloud.datastore scope: platform_scope
103
102
  #
104
103
  def datastore scope: nil
105
104
  require "gcloud/datastore"
@@ -41,10 +41,8 @@ module Gcloud
41
41
  datasets = List.new(Array(resp.data["datasets"]).map do |gapi_object|
42
42
  Dataset.from_gapi gapi_object, conn
43
43
  end)
44
- datasets.instance_eval do
45
- @token = resp.data["nextPageToken"]
46
- @etag = resp.data["etag"]
47
- end
44
+ datasets.instance_variable_set "@token", resp.data["nextPageToken"]
45
+ datasets.instance_variable_set "@etag", resp.data["etag"]
48
46
  datasets
49
47
  end
50
48
  end
@@ -44,11 +44,9 @@ module Gcloud
44
44
  jobs = List.new(Array(resp.data["jobs"]).map do |gapi_object|
45
45
  Job.from_gapi gapi_object, conn
46
46
  end)
47
- jobs.instance_eval do
48
- @token = resp.data["nextPageToken"]
49
- @etag = resp.data["etag"]
50
- @total = resp.data["totalItems"]
51
- end
47
+ jobs.instance_variable_set "@token", resp.data["nextPageToken"]
48
+ jobs.instance_variable_set "@etag", resp.data["etag"]
49
+ jobs.instance_variable_set "@total", resp.data["totalItems"]
52
50
  jobs
53
51
  end
54
52
  end
@@ -44,11 +44,9 @@ module Gcloud
44
44
  tables = List.new(Array(resp.data["tables"]).map do |gapi_object|
45
45
  Table.from_gapi gapi_object, conn
46
46
  end)
47
- tables.instance_eval do
48
- @token = resp.data["nextPageToken"]
49
- @etag = resp.data["etag"]
50
- @total = resp.data["totalItems"]
51
- end
47
+ tables.instance_variable_set "@token", resp.data["nextPageToken"]
48
+ tables.instance_variable_set "@etag", resp.data["etag"]
49
+ tables.instance_variable_set "@total", resp.data["totalItems"]
52
50
  tables
53
51
  end
54
52
  end
@@ -36,28 +36,34 @@ module Gcloud
36
36
  # OAuth 2.0 to Access Google
37
37
  # APIs](https://developers.google.com/identity/protocols/OAuth2).
38
38
  #
39
- # The default scopes are:
39
+ # The default scope is:
40
40
  #
41
41
  # * `https://www.googleapis.com/auth/datastore`
42
- # * `https://www.googleapis.com/auth/userinfo.email`
43
42
  #
44
43
  # @return [Gcloud::Datastore::Dataset]
45
44
  #
46
45
  # @example
47
46
  # require "gcloud/datastore"
48
47
  #
49
- # dataset = Gcloud.datastore "my-todo-project",
48
+ # datastore = Gcloud.datastore "my-todo-project",
50
49
  # "/path/to/keyfile.json"
51
50
  #
52
- # entity = dataset.entity "Task" do |t|
53
- # t["description"] = "Get started with Google Cloud"
54
- # t["completed"] = false
51
+ # task = datastore.entity "Task", "sampleTask" do |t|
52
+ # t["type"] = "Personal"
53
+ # t["done"] = false
54
+ # t["priority"] = 4
55
+ # t["description"] = "Learn Cloud Datastore"
55
56
  # end
56
57
  #
57
- # dataset.save entity
58
+ # datastore.save task
58
59
  #
59
60
  def self.datastore project = nil, keyfile = nil, scope: nil
60
61
  project ||= Gcloud::Datastore::Dataset.default_project
62
+ if ENV["DATASTORE_EMULATOR_HOST"]
63
+ ds = Gcloud::Datastore::Dataset.new project, :this_channel_is_insecure
64
+ ds.service.host = ENV["DATASTORE_EMULATOR_HOST"]
65
+ return ds
66
+ end
61
67
  if keyfile.nil?
62
68
  credentials = Gcloud::Datastore::Credentials.default scope: scope
63
69
  else
@@ -85,10 +91,11 @@ module Gcloud
85
91
  #
86
92
  # gcloud = Gcloud.new "my-todo-project",
87
93
  # "/path/to/keyfile.json"
88
- # dataset = gcloud.datastore
89
- # entity = dataset.find "Task", "start"
90
- # entity["completed"] = true
91
- # dataset.save entity
94
+ # datastore = gcloud.datastore
95
+ #
96
+ # task = datastore.find "Task", "sampleTask"
97
+ # task["priority"] = 5
98
+ # datastore.save task
92
99
  # ```
93
100
  #
94
101
  # You can learn more about various options for connection on the
@@ -99,11 +106,11 @@ module Gcloud
99
106
  # [Google Cloud Datastore Concepts Overview
100
107
  # ](https://cloud.google.com/datastore/docs/concepts/overview).
101
108
  #
102
- # ## Retrieving Records
109
+ # ## Retrieving records
103
110
  #
104
- # Records, called "entities" in Datastore, are retrieved by using a Key.
105
- # The Key is more than a numeric identifier, it is a complex data structure
106
- # that can be used to model relationships. The simplest Key has a string
111
+ # Records, called "entities" in Datastore, are retrieved by using a key.
112
+ # The key is more than a numeric identifier, it is a complex data structure
113
+ # that can be used to model relationships. The simplest key has a string
107
114
  # <tt>kind</tt> value, and either a numeric <tt>id</tt> value, or a string
108
115
  # <tt>name</tt> value. A single record can be retrieved by calling
109
116
  # {Gcloud::Datastore::Dataset#find} and passing the parts of the key:
@@ -112,24 +119,26 @@ module Gcloud
112
119
  # require "gcloud"
113
120
  #
114
121
  # gcloud = Gcloud.new
115
- # dataset = gcloud.datastore
116
- # entity = dataset.find "Task", "start"
122
+ # datastore = gcloud.datastore
123
+ #
124
+ # task = datastore.find "Task", "sampleTask"
117
125
  # ```
118
126
  #
119
- # Optionally, {Gcloud::Datastore::Dataset#find} can be given a Key object:
127
+ # Optionally, {Gcloud::Datastore::Dataset#find} can be given a key object:
120
128
  #
121
129
  # ```ruby
122
130
  # require "gcloud"
123
131
  #
124
132
  # gcloud = Gcloud.new
125
- # dataset = gcloud.datastore
126
- # key = dataset.key "Task", 12345
127
- # entity = dataset.find key
133
+ # datastore = gcloud.datastore
134
+ #
135
+ # task_key = datastore.key "Task", 123456
136
+ # task = datastore.find task_key
128
137
  # ```
129
138
  #
130
139
  # See {Gcloud::Datastore::Dataset#find}
131
140
  #
132
- # ## Querying Records
141
+ # ## Querying records
133
142
  #
134
143
  # Multiple records can be found that match criteria.
135
144
  # (See {Gcloud::Datastore::Query#where})
@@ -138,10 +147,12 @@ module Gcloud
138
147
  # require "gcloud"
139
148
  #
140
149
  # gcloud = Gcloud.new
141
- # dataset = gcloud.datastore
142
- # query = dataset.query("List").
143
- # where("active", "=", true)
144
- # active_lists = dataset.run query
150
+ # datastore = gcloud.datastore
151
+ #
152
+ # query = datastore.query("Task").
153
+ # where("done", "=", false)
154
+ #
155
+ # tasks = datastore.run query
145
156
  # ```
146
157
  #
147
158
  # Records can also be ordered. (See {Gcloud::Datastore::Query#order})
@@ -150,11 +161,12 @@ module Gcloud
150
161
  # require "gcloud"
151
162
  #
152
163
  # gcloud = Gcloud.new
153
- # dataset = gcloud.datastore
154
- # query = dataset.query("List").
155
- # where("active", "=", true).
156
- # order("name")
157
- # active_lists = dataset.run query
164
+ # datastore = gcloud.datastore
165
+ #
166
+ # query = datastore.query("Task").
167
+ # order("created")
168
+ #
169
+ # tasks = datastore.run query
158
170
  # ```
159
171
  #
160
172
  # The number of records returned can be specified.
@@ -164,34 +176,36 @@ module Gcloud
164
176
  # require "gcloud"
165
177
  #
166
178
  # gcloud = Gcloud.new
167
- # dataset = gcloud.datastore
168
- # query = dataset.query("List").
169
- # where("active", "=", true).
170
- # order("name").
179
+ # datastore = gcloud.datastore
180
+ #
181
+ # query = datastore.query("Task").
171
182
  # limit(5)
172
- # active_lists = dataset.run query
183
+ #
184
+ # tasks = datastore.run query
173
185
  # ```
174
186
  #
175
- # Records' Key structures can also be queried.
187
+ # Records' key structures can also be queried.
176
188
  # (See {Gcloud::Datastore::Query#ancestor})
177
189
  #
178
190
  # ```ruby
179
191
  # require "gcloud"
180
192
  #
181
193
  # gcloud = Gcloud.new
182
- # dataset = gcloud.datastore
194
+ # datastore = gcloud.datastore
183
195
  #
184
- # list = dataset.find "List", "todos"
185
- # query = dataset.query("Task").
186
- # ancestor(list.key)
187
- # items = dataset.run query
196
+ # task_list_key = datastore.key "TaskList", "default"
197
+ #
198
+ # query = datastore.query("Task").
199
+ # ancestor(task_list_key)
200
+ #
201
+ # tasks = datastore.run query
188
202
  # ```
189
203
  #
190
204
  # See {Gcloud::Datastore::Query} and {Gcloud::Datastore::Dataset#run}
191
205
  #
192
- # ## Paginating Records
206
+ # ### Paginating records
193
207
  #
194
- # All Records may not return at once, requiring multiple calls to Datastore
208
+ # All records may not return at once, requiring multiple calls to Datastore
195
209
  # to return them all. The returned records will have a <tt>cursor</tt> if
196
210
  # there are more available.
197
211
  #
@@ -199,13 +213,14 @@ module Gcloud
199
213
  # require "gcloud"
200
214
  #
201
215
  # gcloud = Gcloud.new
202
- # dataset = gcloud.datastore
216
+ # datastore = gcloud.datastore
217
+ #
218
+ # task_list_key = datastore.key "TaskList", "default"
203
219
  #
204
- # list = dataset.find "List", "todos"
205
- # query = dataset.query("Task").
206
- # ancestor(list.key)
220
+ # query = datastore.query("Task").
221
+ # ancestor(task_list_key)
207
222
  # all_tasks = []
208
- # tmp_tasks = dataset.run query
223
+ # tmp_tasks = datastore.run query
209
224
  # while tmp_tasks.any? do
210
225
  # tmp_tasks.each do |task|
211
226
  # all_tasks << task
@@ -215,67 +230,144 @@ module Gcloud
215
230
  # # set cursor on the query
216
231
  # query = query.cursor tmp_tasks.cursor
217
232
  # # query for more records
218
- # tmp_tasks = dataset.run query
233
+ # tmp_tasks = datastore.run query
219
234
  # end
220
235
  # ```
221
236
  #
222
237
  # See {Gcloud::Datastore::Dataset::LookupResults} and
223
238
  # {Gcloud::Datastore::Dataset::QueryResults}
224
239
  #
225
- # ## Creating Records
240
+ # ## Creating records
226
241
  #
227
242
  # New entities can be created and persisted buy calling
228
- # {Gcloud::Datastore::Dataset#save}. The entity must have a Key to be saved.
229
- # If the Key is incomplete then it will be completed when saved.
243
+ # {Gcloud::Datastore::Dataset#save}. The entity must have a key to be saved.
244
+ # If the key is incomplete then it will be completed when saved.
230
245
  #
231
246
  # ```ruby
232
247
  # require "gcloud"
233
248
  #
234
249
  # gcloud = Gcloud.new
235
- # dataset = gcloud.datastore
236
- # entity = dataset.entity "User" do |e|
237
- # e["name"] = "Heidi Henderson"
250
+ # datastore = gcloud.datastore
251
+ #
252
+ # task = datastore.entity "Task" do |t|
253
+ # t["type"] = "Personal"
254
+ # t["done"] = false
255
+ # t["priority"] = 4
256
+ # t["description"] = "Learn Cloud Datastore"
257
+ # end
258
+ # task.key.id #=> nil
259
+ # datastore.save task
260
+ # task.key.id #=> 123456
261
+ # ```
262
+ #
263
+ # Multiple new entities may be created in a batch.
264
+ #
265
+ # ```ruby
266
+ # require "gcloud"
267
+ #
268
+ # gcloud = Gcloud.new
269
+ # datastore = gcloud.datastore
270
+ #
271
+ # task1 = datastore.entity "Task" do |t|
272
+ # t["type"] = "Personal"
273
+ # t["done"] = false
274
+ # t["priority"] = 4
275
+ # t["description"] = "Learn Cloud Datastore"
276
+ # end
277
+ #
278
+ # task2 = datastore.entity "Task" do |t|
279
+ # t["type"] = "Personal"
280
+ # t["done"] = false
281
+ # t["priority"] = 5
282
+ # t["description"] = "Integrate Cloud Datastore"
283
+ # end
284
+ #
285
+ # tasks = datastore.save(task1, task2)
286
+ # task_key1 = tasks[0].key
287
+ # task_key2 = tasks[1].key
288
+ # ```
289
+ #
290
+ # Entities in Datastore form a hierarchically structured space similar to the
291
+ # directory structure of a file system. When you create an entity, you can
292
+ # optionally designate another entity as its parent; the new entity is a child
293
+ # of the parent entity.
294
+ #
295
+ # ```ruby
296
+ # task_key = datastore.key "Task", "sampleTask"
297
+ # task_key.parent = datastore.key "TaskList", "default"
298
+ #
299
+ # task = datastore.entity task_key do |t|
300
+ # t["type"] = "Personal"
301
+ # t["done"] = false
302
+ # t["priority"] = 5
303
+ # t["description"] = "Integrate Cloud Datastore"
238
304
  # end
239
- # entity.key.id #=> nil
240
- # dataset.save entity
241
- # entity.key.id #=> 123456789
242
305
  # ```
243
306
  #
244
- # ## Updating Records
307
+ # ## Setting properties
245
308
  #
246
309
  # Entities hold properties. A property has a name that is a string or symbol,
247
310
  # and a value that is an object. Most value objects are supported, including
248
- # String, Integer, Date, Time, and even other Entity or Key objects. Changes
249
- # to the Entity's properties are persisted by calling
311
+ # String, Integer, Date, Time, and even other entity or key objects. Changes
312
+ # to the entity's properties are persisted by calling
250
313
  # {Gcloud::Datastore::Dataset#save}.
251
314
  #
252
315
  # ```ruby
253
316
  # require "gcloud"
254
317
  #
255
318
  # gcloud = Gcloud.new
256
- # dataset = gcloud.datastore
257
- # entity = dataset.find "User", "heidi"
258
- # # Read the status property
259
- # entity["status"] #=> "inactive"
260
- # # Write the status property
261
- # entity["status"] = "active"
319
+ # datastore = gcloud.datastore
320
+ #
321
+ # task = datastore.find "Task", "sampleTask"
322
+ # # Read the priority property
323
+ # task["priority"] #=> 4
324
+ # # Write the priority property
325
+ # task["priority"] = 5
262
326
  # # Persist the changes
263
- # dataset.save entity
327
+ # datastore.save task
328
+ # ```
329
+ #
330
+ # Array properties can be used to store more than one value.
331
+ #
332
+ # ```ruby
333
+ # require "gcloud"
334
+ #
335
+ # gcloud = Gcloud.new
336
+ # datastore = gcloud.datastore
337
+ #
338
+ # task = datastore.entity "Task", "sampleTask" do |t|
339
+ # t["tags"] = ["fun", "programming"]
340
+ # t["collaborators"] = ["alice", "bob"]
341
+ # end
264
342
  # ```
265
343
  #
266
- # ## Deleting Records
344
+ # ## Deleting records
267
345
  #
268
346
  # Entities can be removed from Datastore by calling
269
- # {Gcloud::Datastore::Dataset#delete} and passing the Entity object or the
270
- # entity's Key object.
347
+ # {Gcloud::Datastore::Dataset#delete} and passing the entity object or the
348
+ # entity's key object.
271
349
  #
272
350
  # ```ruby
273
351
  # require "gcloud"
274
352
  #
275
353
  # gcloud = Gcloud.new
276
- # dataset = gcloud.datastore
277
- # entity = dataset.find "User", "heidi"
278
- # dataset.delete entity
354
+ # datastore = gcloud.datastore
355
+ #
356
+ # task = datastore.find "Task", "sampleTask"
357
+ # datastore.delete task
358
+ # ```
359
+ #
360
+ # Multiple entities may be deleted in a batch.
361
+ #
362
+ # ```ruby
363
+ # require "gcloud"
364
+ #
365
+ # gcloud = Gcloud.new
366
+ # datastore = gcloud.datastore
367
+ #
368
+ # task_key1 = datastore.key "Task", "sampleTask1"
369
+ # task_key2 = datastore.key "Task", "sampleTask2"
370
+ # datastore.delete task_key1, task_key2
279
371
  # ```
280
372
  #
281
373
  # ## Transactions
@@ -289,18 +381,19 @@ module Gcloud
289
381
  # require "gcloud"
290
382
  #
291
383
  # gcloud = Gcloud.new
292
- # dataset = gcloud.datastore
293
- #
294
- # key = dataset.key "User", "heidi"
295
- #
296
- # user = dataset.entity key do |u|
297
- # u["name"] = "Heidi Henderson"
298
- # u["email"] = "heidi@example.net"
299
- # end
300
- #
301
- # dataset.transaction do |tx|
302
- # if tx.find(user.key).nil?
303
- # tx.save user
384
+ # datastore = gcloud.datastore
385
+ #
386
+ # task_key = datastore.key "Task", "sampleTask"
387
+ #
388
+ # datastore.transaction do |tx|
389
+ # if tx.find(task_key).nil?
390
+ # task = datastore.entity task_key do |t|
391
+ # t["type"] = "Personal"
392
+ # t["done"] = false
393
+ # t["priority"] = 4
394
+ # t["description"] = "Learn Cloud Datastore"
395
+ # end
396
+ # tx.save task
304
397
  # end
305
398
  # end
306
399
  # ```
@@ -312,19 +405,20 @@ module Gcloud
312
405
  # require "gcloud"
313
406
  #
314
407
  # gcloud = Gcloud.new
315
- # dataset = gcloud.datastore
408
+ # datastore = gcloud.datastore
316
409
  #
317
- # key = dataset.key "User", "heidi"
318
- #
319
- # user = dataset.entity key do |u|
320
- # u["name"] = "Heidi Henderson"
321
- # u["email"] = "heidi@example.net"
322
- # end
410
+ # task_key = datastore.key "Task", "sampleTask"
323
411
  #
324
- # tx = dataset.transaction
412
+ # tx = datastore.transaction
325
413
  # begin
326
- # if tx.find(user.key).nil?
327
- # tx.save user
414
+ # if tx.find(task_key).nil?
415
+ # task = datastore.entity task_key do |t|
416
+ # t["type"] = "Personal"
417
+ # t["done"] = false
418
+ # t["priority"] = 4
419
+ # t["description"] = "Learn Cloud Datastore"
420
+ # end
421
+ # tx.save task
328
422
  # end
329
423
  # tx.commit
330
424
  # rescue
@@ -334,6 +428,141 @@ module Gcloud
334
428
  #
335
429
  # See {Gcloud::Datastore::Transaction} and
336
430
  # {Gcloud::Datastore::Dataset#transaction}
431
+ #
432
+ # ## Querying metadata
433
+ #
434
+ # Datastore provides programmatic access to some of its metadata to support
435
+ # meta-programming, implementing backend administrative functions, simplify
436
+ # consistent caching, and similar purposes. The metadata available includes
437
+ # information about the entity groups, namespaces, entity kinds, and
438
+ # properties your application uses, as well as the property representations
439
+ # for each property.
440
+ #
441
+ # The special entity kind `__namespace__` can be used to find all the
442
+ # namespaces used in your application entities.
443
+ #
444
+ # ```ruby
445
+ # query = datastore.query("__namespace__").
446
+ # select("__key__").
447
+ # where("__key__", ">=", datastore.key("__namespace__", "g")).
448
+ # where("__key__", "<", datastore.key("__namespace__", "h"))
449
+ #
450
+ # namespaces = datastore.run(query).map do |entity|
451
+ # entity.key.name
452
+ # end
453
+ # ```
454
+ #
455
+ # The special entity kind `__kind__` can be used to return all the
456
+ # kinds used in your application.
457
+ #
458
+ # ```ruby
459
+ # query = datastore.query("__kind__").
460
+ # select("__key__")
461
+ #
462
+ # kinds = datastore.run(query).map do |entity|
463
+ # entity.key.name
464
+ # end
465
+ # ```
466
+ #
467
+ # Property queries return entities of kind `__property__` denoting the indexed
468
+ # properties associated with an entity kind. (Unindexed properties are not
469
+ # included.)
470
+ #
471
+ # ```ruby
472
+ # query = datastore.query("__property__").
473
+ # select("__key__")
474
+ #
475
+ # entities = datastore.run(query)
476
+ # properties_by_kind = entities.each_with_object({}) do |entity, memo|
477
+ # kind = entity.key.parent.name
478
+ # prop = entity.key.name
479
+ # memo[kind] ||= []
480
+ # memo[kind] << prop
481
+ # end
482
+ # ```
483
+ #
484
+ # Property queries support ancestor filtering on a `__kind__` or
485
+ # `__property__` key, to limit the query results to a single kind or property.
486
+ # The `property_representation` property in the entity representing property
487
+ # `p` of kind `k` is an array containing all representations of `p`'s value in
488
+ # any entity of kind `k`.
489
+ #
490
+ # ```ruby
491
+ # ancestor_key = datastore.key "__kind__", "Task"
492
+ # query = datastore.query("__property__").
493
+ # ancestor(ancestor_key)
494
+ #
495
+ # entities = datastore.run(query)
496
+ # representations = entities.each_with_object({}) do |entity, memo|
497
+ # property_name = entity.key.name
498
+ # property_types = entity["property_representation"]
499
+ # memo[property_name] = property_types
500
+ # end
501
+ # ```
502
+ #
503
+ # Property queries can also be filtered with a range over the pseudo-property
504
+ # `__key__`, where the keys denote either `__kind__` or `__property__`
505
+ # entities.
506
+ #
507
+ # ```ruby
508
+ # start_key = datastore.key "__property__", "priority"
509
+ # start_key.parent = datastore.key "__kind__", "Task"
510
+ # query = datastore.query("__property__").
511
+ # select("__key__").
512
+ # where("__key__", ">=", start_key)
513
+ #
514
+ # entities = datastore.run(query)
515
+ # properties_by_kind = entities.each_with_object({}) do |entity, memo|
516
+ # kind = entity.key.parent.name
517
+ # prop = entity.key.name
518
+ # memo[kind] ||= []
519
+ # memo[kind] << prop
520
+ # end
521
+ # ```
522
+ #
523
+ # ## The Datastore Emulator
524
+ #
525
+ # As of this release, the Datastore emulator that is part of the gcloud SDK is
526
+ # no longer compatible with gcloud-ruby. This is because the gcloud SDK's
527
+ # Datastore emulator does not yet support gRPC as a transport layer.
528
+ #
529
+ # A gRPC-compatible emulator is available until the gcloud SDK Datastore
530
+ # emulator supports gRPC. To use it you must [download the gRPC
531
+ # emulator](https://storage.googleapis.com/gcd/tools/gcd-grpc-1.0.0.zip) and
532
+ # use the `gcd.sh` script.
533
+ #
534
+ # When you run the gRPC emulator you will see a message similar to the
535
+ # following printed:
536
+ #
537
+ # ```
538
+ # If you are using a library that supports the DATASTORE_EMULATOR_HOST
539
+ # environment variable, run:
540
+ #
541
+ # export DATASTORE_EMULATOR_HOST=localhost:8978
542
+ # ```
543
+ #
544
+ # Now you can connect to the emulator using the `DATASTORE_EMULATOR_HOST`
545
+ # environment variable:
546
+ #
547
+ # ```ruby
548
+ # require "gcloud"
549
+ #
550
+ # # Make Datastore use the emulator
551
+ # ENV["DATASTORE_EMULATOR_HOST"] = "localhost:8978"
552
+ #
553
+ # gcloud = Gcloud.new "emulator-project-id"
554
+ # datastore = gcloud.datastore
555
+ #
556
+ # task = datastore.entity "Task", "emulatorTask" do |t|
557
+ # t["type"] = "Testing"
558
+ # t["done"] = false
559
+ # t["priority"] = 5
560
+ # t["description"] = "Use Datastore Emulator"
561
+ # end
562
+ #
563
+ # datastore.save task
564
+ # ```
565
+ #
337
566
  module Datastore
338
567
  end
339
568
  end