google-cloud-datastore 1.4.2 → 1.4.3

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.
@@ -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}.