gcloud 0.8.2 → 0.9.0

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