google-cloud-datastore 1.4.2 → 1.4.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,57 @@
1
+ # Google Cloud Datastore Emulator
2
+
3
+ To develop and test your application locally, you can use the [Google Cloud
4
+ Datastore
5
+ Emulator](https://cloud.google.com/datastore/docs/tools/datastore-emulator),
6
+ which provides [local
7
+ emulation](https://cloud.google.com/sdk/gcloud/reference/beta/emulators/) of the
8
+ production Google Cloud Datastore environment. You can start the Google Cloud
9
+ Datastore emulator using the `gcloud` command-line tool.
10
+
11
+ When you run the Cloud Datastore emulator you will see a message similar to the
12
+ following printed:
13
+
14
+ ```
15
+ If you are using a library that supports the DATASTORE_EMULATOR_HOST
16
+ environment variable, run:
17
+
18
+ export DATASTORE_EMULATOR_HOST=localhost:8978
19
+ ```
20
+
21
+ Now you can connect to the emulator using the `DATASTORE_EMULATOR_HOST`
22
+ environment variable:
23
+
24
+ ```ruby
25
+ require "google/cloud/datastore"
26
+
27
+ # Make Datastore use the emulator
28
+ ENV["DATASTORE_EMULATOR_HOST"] = "localhost:8978"
29
+
30
+ datastore = Google::Cloud::Datastore.new project: "emulator-project-id"
31
+
32
+ task = datastore.entity "Task", "emulatorTask" do |t|
33
+ t["type"] = "Testing"
34
+ t["done"] = false
35
+ t["priority"] = 5
36
+ t["description"] = "Use Datastore Emulator"
37
+ end
38
+
39
+ datastore.save task
40
+ ```
41
+
42
+ Or by providing the `emulator_host` argument:
43
+
44
+ ```ruby
45
+ require "google/cloud/datastore"
46
+
47
+ datastore = Google::Cloud::Datastore.new emulator_host: "localhost:8978"
48
+
49
+ task = datastore.entity "Task", "emulatorTask" do |t|
50
+ t["type"] = "Testing"
51
+ t["done"] = false
52
+ t["priority"] = 5
53
+ t["description"] = "Use Datastore Emulator"
54
+ end
55
+
56
+ datastore.save task
57
+ ```
@@ -0,0 +1,32 @@
1
+ # Enabling gRPC Logging
2
+
3
+ To enable logging for this library, set the logger for the underlying
4
+ [gRPC](https://github.com/grpc/grpc/tree/master/src/ruby) library. The logger
5
+ that you set may be a Ruby stdlib
6
+ [`Logger`](https://ruby-doc.org/stdlib-2.5.0/libdoc/logger/rdoc/Logger.html) as
7
+ shown below, or a
8
+ [`Google::Cloud::Logging::Logger`](https://googlecloudplatform.github.io/google-cloud-ruby/docs/google-cloud-logging/latest/Google/Cloud/Logging/Logger)
9
+ that will write logs to [Stackdriver
10
+ Logging](https://cloud.google.com/logging/). See
11
+ [grpc/logconfig.rb](https://github.com/grpc/grpc/blob/master/src/ruby/lib/grpc/logconfig.rb)
12
+ and the gRPC
13
+ [spec_helper.rb](https://github.com/grpc/grpc/blob/master/src/ruby/spec/spec_helper.rb)
14
+ for additional information.
15
+
16
+ Configuring a Ruby stdlib logger:
17
+
18
+ ```ruby
19
+ require "logger"
20
+
21
+ module MyLogger
22
+ LOGGER = Logger.new $stderr, level: Logger::WARN
23
+ def logger
24
+ LOGGER
25
+ end
26
+ end
27
+
28
+ # Define a gRPC module-level logger method before grpc/logconfig.rb loads.
29
+ module GRPC
30
+ extend MyLogger
31
+ end
32
+ ```
@@ -0,0 +1,494 @@
1
+ # Google Cloud Datastore
2
+
3
+ Google Cloud Datastore is a fully managed, schemaless database for storing
4
+ non-relational data. You should feel at home if you are familiar with relational
5
+ databases, but there are some key differences to be aware of to make the most of
6
+ using Datastore.
7
+
8
+ The goal of google-cloud is to provide an API that is comfortable to Rubyists.
9
+ Your authentication credentials are detected automatically in Google Cloud
10
+ Platform environments such as Google Compute Engine, Google App Engine and
11
+ Google Kubernetes Engine. In other environments you can configure authentication
12
+ easily, either directly in your code or via environment variables. Read more
13
+ about the options for connecting in the {file:AUTHENTICATION.md Authentication
14
+ Guide}.
15
+
16
+ ```ruby
17
+ require "google/cloud/datastore"
18
+
19
+ datastore = Google::Cloud::Datastore.new(
20
+ project_id: "my-todo-project",
21
+ credentials: "/path/to/keyfile.json"
22
+ )
23
+
24
+ task = datastore.find "Task", "sampleTask"
25
+ task["priority"] = 5
26
+ datastore.save task
27
+ ```
28
+
29
+ To learn more about Datastore, read the
30
+ [Google Cloud Datastore Concepts Overview
31
+ ](https://cloud.google.com/datastore/docs/concepts/overview).
32
+
33
+ ## Retrieving records
34
+
35
+ Records, called "entities" in Datastore, are retrieved by using a key. The key
36
+ is more than a numeric identifier, it is a complex data structure that can be
37
+ used to model relationships. The simplest key has a string `kind` value and
38
+ either a numeric `id` value or a string `name` value. A single record can be
39
+ retrieved by calling {Google::Cloud::Datastore::Dataset#find} and passing the
40
+ parts of the key:
41
+
42
+ ```ruby
43
+ require "google/cloud/datastore"
44
+
45
+ datastore = Google::Cloud::Datastore.new
46
+
47
+ task = datastore.find "Task", "sampleTask"
48
+ ```
49
+
50
+ Optionally, {Google::Cloud::Datastore::Dataset#find} can be given a key object:
51
+
52
+ ```ruby
53
+ require "google/cloud/datastore"
54
+
55
+ datastore = Google::Cloud::Datastore.new
56
+
57
+ task_key = datastore.key "Task", 123456
58
+ task = datastore.find task_key
59
+ ```
60
+
61
+ See {Google::Cloud::Datastore::Dataset#find}
62
+
63
+ ## Querying records
64
+
65
+ Multiple records can be found that match criteria. (See
66
+ {Google::Cloud::Datastore::Query#where})
67
+
68
+ ```ruby
69
+ require "google/cloud/datastore"
70
+
71
+ datastore = Google::Cloud::Datastore.new
72
+
73
+ query = datastore.query("Task").
74
+ where("done", "=", false)
75
+
76
+ tasks = datastore.run query
77
+ ```
78
+
79
+ Records can also be ordered. (See {Google::Cloud::Datastore::Query#order})
80
+
81
+ ```ruby
82
+ require "google/cloud/datastore"
83
+
84
+ datastore = Google::Cloud::Datastore.new
85
+
86
+ query = datastore.query("Task").
87
+ order("created")
88
+
89
+ tasks = datastore.run query
90
+ ```
91
+
92
+ The number of records returned can be specified. (See
93
+ {Google::Cloud::Datastore::Query#limit})
94
+
95
+ ```ruby
96
+ require "google/cloud/datastore"
97
+
98
+ datastore = Google::Cloud::Datastore.new
99
+
100
+ query = datastore.query("Task").
101
+ limit(5)
102
+
103
+ tasks = datastore.run query
104
+ ```
105
+
106
+ When using Datastore in a multitenant application, a query may be run within a
107
+ namespace using the `namespace` option. (See
108
+ [Multitenancy](https://cloud.google.com/datastore/docs/concepts/multitenancy))
109
+
110
+ ```ruby
111
+ require "google/cloud/datastore"
112
+
113
+ datastore = Google::Cloud::Datastore.new
114
+
115
+ query = datastore.query("Task").
116
+ where("done", "=", false)
117
+
118
+ tasks = datastore.run query, namespace: "example-ns"
119
+ ```
120
+
121
+ Records' key structures can also be queried. (See
122
+ {Google::Cloud::Datastore::Query#ancestor})
123
+
124
+ ```ruby
125
+ require "google/cloud/datastore"
126
+
127
+ datastore = Google::Cloud::Datastore.new
128
+
129
+ task_list_key = datastore.key "TaskList", "default"
130
+
131
+ query = datastore.query("Task").
132
+ ancestor(task_list_key)
133
+
134
+ tasks = datastore.run query
135
+ ```
136
+
137
+ See {Google::Cloud::Datastore::Query} and
138
+ {Google::Cloud::Datastore::Dataset#run}
139
+
140
+ ### Paginating records
141
+
142
+ All records may not return at once, but multiple calls can be made to Datastore
143
+ to return them all.
144
+
145
+ ```ruby
146
+ require "google/cloud/datastore"
147
+
148
+ datastore = Google::Cloud::Datastore.new
149
+
150
+ query = datastore.query("Task")
151
+ tasks = datastore.run query
152
+ tasks.all do |t|
153
+ puts t["description"]
154
+ end
155
+ ```
156
+
157
+ See {Google::Cloud::Datastore::Dataset::LookupResults} and
158
+ {Google::Cloud::Datastore::Dataset::QueryResults}
159
+
160
+ ## Creating records
161
+
162
+ New entities can be created and persisted buy calling
163
+ {Google::Cloud::Datastore::Dataset#save}. The entity must have a key to be
164
+ saved. If the key is incomplete then it will be completed when saved.
165
+
166
+ ```ruby
167
+ require "google/cloud/datastore"
168
+
169
+ datastore = Google::Cloud::Datastore.new
170
+
171
+ task = datastore.entity "Task" do |t|
172
+ t["type"] = "Personal"
173
+ t["done"] = false
174
+ t["priority"] = 4
175
+ t["description"] = "Learn Cloud Datastore"
176
+ end
177
+ task.key.id #=> nil
178
+ datastore.save task
179
+ task.key.id #=> 123456
180
+ ```
181
+
182
+ Multiple new entities may be created in a batch.
183
+
184
+ ```ruby
185
+ require "google/cloud/datastore"
186
+
187
+ datastore = Google::Cloud::Datastore.new
188
+
189
+ task1 = datastore.entity "Task" do |t|
190
+ t["type"] = "Personal"
191
+ t["done"] = false
192
+ t["priority"] = 4
193
+ t["description"] = "Learn Cloud Datastore"
194
+ end
195
+
196
+ task2 = datastore.entity "Task" do |t|
197
+ t["type"] = "Personal"
198
+ t["done"] = false
199
+ t["priority"] = 5
200
+ t["description"] = "Integrate Cloud Datastore"
201
+ end
202
+
203
+ tasks = datastore.save(task1, task2)
204
+ task_key1 = tasks[0].key
205
+ task_key2 = tasks[1].key
206
+ ```
207
+
208
+ Entities in Datastore form a hierarchically structured space similar to the
209
+ directory structure of a file system. When you create an entity, you can
210
+ optionally designate another entity as its parent; the new entity is a child of
211
+ the parent entity.
212
+
213
+ ```ruby
214
+ require "google/cloud/datastore"
215
+
216
+ datastore = Google::Cloud::Datastore.new
217
+
218
+ task_key = datastore.key "Task", "sampleTask"
219
+ task_key.parent = datastore.key "TaskList", "default"
220
+
221
+ task = datastore.entity task_key do |t|
222
+ t["type"] = "Personal"
223
+ t["done"] = false
224
+ t["priority"] = 5
225
+ t["description"] = "Integrate Cloud Datastore"
226
+ end
227
+ ```
228
+
229
+ ## Setting properties
230
+
231
+ Entities hold properties. A property has a name that is a string or symbol, and
232
+ a value that is an object. Most value objects are supported, including `String`,
233
+ `Integer`, `Date`, `Time`, and even other entity or key objects. Changes to the
234
+ entity's properties are persisted by calling
235
+ {Google::Cloud::Datastore::Dataset#save}.
236
+
237
+ ```ruby
238
+ require "google/cloud/datastore"
239
+
240
+ datastore = Google::Cloud::Datastore.new
241
+
242
+ task = datastore.find "Task", "sampleTask"
243
+ # Read the priority property
244
+ task["priority"] #=> 4
245
+ # Write the priority property
246
+ task["priority"] = 5
247
+ # Persist the changes
248
+ datastore.save task
249
+ ```
250
+
251
+ Array properties can be used to store more than one value.
252
+
253
+ ```ruby
254
+ require "google/cloud/datastore"
255
+
256
+ datastore = Google::Cloud::Datastore.new
257
+
258
+ task = datastore.entity "Task", "sampleTask" do |t|
259
+ t["tags"] = ["fun", "programming"]
260
+ t["collaborators"] = ["alice", "bob"]
261
+ end
262
+ ```
263
+
264
+ ## Deleting records
265
+
266
+ Entities can be removed from Datastore by calling
267
+ {Google::Cloud::Datastore::Dataset#delete} and passing the entity object or the
268
+ entity's key object.
269
+
270
+ ```ruby
271
+ require "google/cloud/datastore"
272
+
273
+ datastore = Google::Cloud::Datastore.new
274
+
275
+ task = datastore.find "Task", "sampleTask"
276
+ datastore.delete task
277
+ ```
278
+
279
+ Multiple entities may be deleted in a batch.
280
+
281
+ ```ruby
282
+ require "google/cloud/datastore"
283
+
284
+ datastore = Google::Cloud::Datastore.new
285
+
286
+ task_key1 = datastore.key "Task", "sampleTask1"
287
+ task_key2 = datastore.key "Task", "sampleTask2"
288
+ datastore.delete task_key1, task_key2
289
+ ```
290
+
291
+ ## Transactions
292
+
293
+ Complex logic can be wrapped in a transaction. All queries and updates within
294
+ the {Google::Cloud::Datastore::Dataset#transaction} block are run within the
295
+ transaction scope, and will be automatically committed when the block completes.
296
+
297
+ ```ruby
298
+ require "google/cloud/datastore"
299
+
300
+ datastore = Google::Cloud::Datastore.new
301
+
302
+ task_key = datastore.key "Task", "sampleTask"
303
+
304
+ datastore.transaction do |tx|
305
+ if tx.find(task_key).nil?
306
+ task = datastore.entity task_key do |t|
307
+ t["type"] = "Personal"
308
+ t["done"] = false
309
+ t["priority"] = 4
310
+ t["description"] = "Learn Cloud Datastore"
311
+ end
312
+ tx.save task
313
+ end
314
+ end
315
+ ```
316
+
317
+ Alternatively, if no block is given the transaction object is returned allowing
318
+ you to commit or rollback manually.
319
+
320
+ ```ruby
321
+ require "google/cloud/datastore"
322
+
323
+ datastore = Google::Cloud::Datastore.new
324
+
325
+ task_key = datastore.key "Task", "sampleTask"
326
+
327
+ tx = datastore.transaction
328
+ begin
329
+ if tx.find(task_key).nil?
330
+ task = datastore.entity task_key do |t|
331
+ t["type"] = "Personal"
332
+ t["done"] = false
333
+ t["priority"] = 4
334
+ t["description"] = "Learn Cloud Datastore"
335
+ end
336
+ tx.save task
337
+ end
338
+ tx.commit
339
+ rescue
340
+ tx.rollback
341
+ end
342
+ ```
343
+
344
+ A read-only transaction cannot modify entities; in return they do not contend
345
+ with other read-write or read-only transactions. Using a read-only transaction
346
+ for transactions that only read data will potentially improve throughput.
347
+
348
+ ```ruby
349
+ require "google/cloud/datastore"
350
+
351
+ datastore = Google::Cloud::Datastore.new
352
+
353
+ task_list_key = datastore.key "TaskList", "default"
354
+ query = datastore.query("Task").
355
+ ancestor(task_list_key)
356
+
357
+ tasks = nil
358
+
359
+ datastore.transaction read_only: true do |tx|
360
+ task_list = tx.find task_list_key
361
+ if task_list
362
+ tasks = tx.run query
363
+ end
364
+ end
365
+ ```
366
+
367
+ See {Google::Cloud::Datastore::Transaction} and
368
+ {Google::Cloud::Datastore::Dataset#transaction}
369
+
370
+ ## Querying metadata
371
+
372
+ Datastore provides programmatic access to some of its metadata to support
373
+ meta-programming, implementing backend administrative functions, simplify
374
+ consistent caching, and similar purposes. The metadata available includes
375
+ information about the entity groups, namespaces, entity kinds, and properties
376
+ your application uses, as well as the property representations for each
377
+ property.
378
+
379
+ The special entity kind `__namespace__` can be used to find all the namespaces
380
+ used in your application entities.
381
+
382
+ ```ruby
383
+ require "google/cloud/datastore"
384
+
385
+ datastore = Google::Cloud::Datastore.new
386
+
387
+ query = datastore.query("__namespace__").
388
+ select("__key__").
389
+ where("__key__", ">=", datastore.key("__namespace__", "g")).
390
+ where("__key__", "<", datastore.key("__namespace__", "h"))
391
+
392
+ namespaces = datastore.run(query).map do |entity|
393
+ entity.key.name
394
+ end
395
+ ```
396
+
397
+ The special entity kind `__kind__` can be used to return all the kinds used in
398
+ your application.
399
+
400
+ ```ruby
401
+ require "google/cloud/datastore"
402
+
403
+ datastore = Google::Cloud::Datastore.new
404
+
405
+ query = datastore.query("__kind__").
406
+ select("__key__")
407
+
408
+ kinds = datastore.run(query).map do |entity|
409
+ entity.key.name
410
+ end
411
+ ```
412
+
413
+ Property queries return entities of kind `__property__` denoting the indexed
414
+ properties associated with an entity kind. (Unindexed properties are not
415
+ included.)
416
+
417
+ ```ruby
418
+ require "google/cloud/datastore"
419
+
420
+ datastore = Google::Cloud::Datastore.new
421
+
422
+ query = datastore.query("__property__").
423
+ select("__key__")
424
+
425
+ entities = datastore.run(query)
426
+ properties_by_kind = entities.each_with_object({}) do |entity, memo|
427
+ kind = entity.key.parent.name
428
+ prop = entity.key.name
429
+ memo[kind] ||= []
430
+ memo[kind] << prop
431
+ end
432
+ ```
433
+
434
+ Property queries support ancestor filtering on a `__kind__` or `__property__`
435
+ key, to limit the query results to a single kind or property. The
436
+ `property_representation` property in the entity representing property `p` of
437
+ kind `k` is an array containing all representations of `p`'s value in any entity
438
+ of kind `k`.
439
+
440
+ ```ruby
441
+ require "google/cloud/datastore"
442
+
443
+ datastore = Google::Cloud::Datastore.new
444
+
445
+ ancestor_key = datastore.key "__kind__", "Task"
446
+ query = datastore.query("__property__").
447
+ ancestor(ancestor_key)
448
+
449
+ entities = datastore.run(query)
450
+ representations = entities.each_with_object({}) do |entity, memo|
451
+ property_name = entity.key.name
452
+ property_types = entity["property_representation"]
453
+ memo[property_name] = property_types
454
+ end
455
+ ```
456
+
457
+ Property queries can also be filtered with a range over the pseudo-property
458
+ `__key__`, where the keys denote either `__kind__` or `__property__` entities.
459
+
460
+ ```ruby
461
+ require "google/cloud/datastore"
462
+
463
+ datastore = Google::Cloud::Datastore.new
464
+
465
+ start_key = datastore.key "__property__", "priority"
466
+ start_key.parent = datastore.key "__kind__", "Task"
467
+ query = datastore.query("__property__").
468
+ select("__key__").
469
+ where("__key__", ">=", start_key)
470
+
471
+ entities = datastore.run(query)
472
+ properties_by_kind = entities.each_with_object({}) do |entity, memo|
473
+ kind = entity.key.parent.name
474
+ prop = entity.key.name
475
+ memo[kind] ||= []
476
+ memo[kind] << prop
477
+ end
478
+ ```
479
+
480
+ ## Configuring timeout
481
+
482
+ You can configure the request `timeout` value in seconds.
483
+
484
+ ```ruby
485
+ require "google/cloud/datastore"
486
+
487
+ datastore = Google::Cloud::Datastore.new timeout: 120
488
+ ```
489
+
490
+ ## Additional information
491
+
492
+ Google Cloud Datastore can be configured to use an emulator or to enable gRPC's
493
+ logging. To learn more, see the {file:EMULATOR.md Emulator guide} and
494
+ {file:LOGGING.md Logging guide}.