google-cloud-spanner 0.21.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 (68) hide show
  1. checksums.yaml +7 -0
  2. data/lib/google-cloud-spanner.rb +106 -0
  3. data/lib/google/cloud/spanner.rb +382 -0
  4. data/lib/google/cloud/spanner/admin/database/v1.rb +17 -0
  5. data/lib/google/cloud/spanner/admin/database/v1/database_admin_client.rb +703 -0
  6. data/lib/google/cloud/spanner/admin/database/v1/database_admin_client_config.json +73 -0
  7. data/lib/google/cloud/spanner/admin/database/v1/doc/google/iam/v1/policy.rb +139 -0
  8. data/lib/google/cloud/spanner/admin/database/v1/doc/google/protobuf/any.rb +114 -0
  9. data/lib/google/cloud/spanner/admin/database/v1/doc/google/rpc/status.rb +83 -0
  10. data/lib/google/cloud/spanner/admin/database/v1/doc/google/spanner/admin/database/v1/spanner_database_admin.rb +188 -0
  11. data/lib/google/cloud/spanner/admin/instance/v1.rb +17 -0
  12. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/iam/v1/policy.rb +139 -0
  13. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/protobuf/any.rb +114 -0
  14. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/protobuf/field_mask.rb +223 -0
  15. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/rpc/status.rb +83 -0
  16. data/lib/google/cloud/spanner/admin/instance/v1/doc/google/spanner/admin/instance/v1/spanner_instance_admin.rb +268 -0
  17. data/lib/google/cloud/spanner/admin/instance/v1/instance_admin_client.rb +868 -0
  18. data/lib/google/cloud/spanner/admin/instance/v1/instance_admin_client_config.json +78 -0
  19. data/lib/google/cloud/spanner/client.rb +1034 -0
  20. data/lib/google/cloud/spanner/commit.rb +351 -0
  21. data/lib/google/cloud/spanner/convert.rb +311 -0
  22. data/lib/google/cloud/spanner/credentials.rb +32 -0
  23. data/lib/google/cloud/spanner/data.rb +199 -0
  24. data/lib/google/cloud/spanner/database.rb +377 -0
  25. data/lib/google/cloud/spanner/database/job.rb +179 -0
  26. data/lib/google/cloud/spanner/database/list.rb +171 -0
  27. data/lib/google/cloud/spanner/errors.rb +73 -0
  28. data/lib/google/cloud/spanner/fields.rb +252 -0
  29. data/lib/google/cloud/spanner/instance.rb +472 -0
  30. data/lib/google/cloud/spanner/instance/config.rb +99 -0
  31. data/lib/google/cloud/spanner/instance/config/list.rb +171 -0
  32. data/lib/google/cloud/spanner/instance/job.rb +197 -0
  33. data/lib/google/cloud/spanner/instance/list.rb +167 -0
  34. data/lib/google/cloud/spanner/policy.rb +201 -0
  35. data/lib/google/cloud/spanner/pool.rb +279 -0
  36. data/lib/google/cloud/spanner/project.rb +480 -0
  37. data/lib/google/cloud/spanner/range.rb +99 -0
  38. data/lib/google/cloud/spanner/results.rb +280 -0
  39. data/lib/google/cloud/spanner/service.rb +458 -0
  40. data/lib/google/cloud/spanner/session.rb +565 -0
  41. data/lib/google/cloud/spanner/snapshot.rb +260 -0
  42. data/lib/google/cloud/spanner/transaction.rb +533 -0
  43. data/lib/google/cloud/spanner/v1.rb +17 -0
  44. data/lib/google/cloud/spanner/v1/doc/google/protobuf/duration.rb +77 -0
  45. data/lib/google/cloud/spanner/v1/doc/google/protobuf/struct.rb +73 -0
  46. data/lib/google/cloud/spanner/v1/doc/google/protobuf/timestamp.rb +81 -0
  47. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/keys.rb +148 -0
  48. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/mutation.rb +80 -0
  49. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/query_plan.rb +120 -0
  50. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/result_set.rb +175 -0
  51. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/spanner.rb +206 -0
  52. data/lib/google/cloud/spanner/v1/doc/google/spanner/v1/transaction.rb +351 -0
  53. data/lib/google/cloud/spanner/v1/spanner_client.rb +850 -0
  54. data/lib/google/cloud/spanner/v1/spanner_client_config.json +78 -0
  55. data/lib/google/cloud/spanner/version.rb +22 -0
  56. data/lib/google/spanner/admin/database/v1/spanner_database_admin_pb.rb +85 -0
  57. data/lib/google/spanner/admin/database/v1/spanner_database_admin_services_pb.rb +95 -0
  58. data/lib/google/spanner/admin/instance/v1/spanner_instance_admin_pb.rb +106 -0
  59. data/lib/google/spanner/admin/instance/v1/spanner_instance_admin_services_pb.rb +180 -0
  60. data/lib/google/spanner/v1/keys_pb.rb +33 -0
  61. data/lib/google/spanner/v1/mutation_pb.rb +38 -0
  62. data/lib/google/spanner/v1/query_plan_pb.rb +47 -0
  63. data/lib/google/spanner/v1/result_set_pb.rb +43 -0
  64. data/lib/google/spanner/v1/spanner_pb.rb +90 -0
  65. data/lib/google/spanner/v1/spanner_services_pb.rb +131 -0
  66. data/lib/google/spanner/v1/transaction_pb.rb +51 -0
  67. data/lib/google/spanner/v1/type_pb.rb +43 -0
  68. metadata +309 -0
@@ -0,0 +1,32 @@
1
+ # Copyright 2016 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "google/cloud/credentials"
17
+ require "google/cloud/spanner/v1"
18
+
19
+ module Google
20
+ module Cloud
21
+ module Spanner
22
+ ##
23
+ # @private Represents the OAuth 2.0 signing logic for Spanner.
24
+ class Credentials < Google::Cloud::Credentials
25
+ SCOPE = V1::SpannerClient::ALL_SCOPES
26
+ PATH_ENV_VARS = %w(SPANNER_KEYFILE GOOGLE_CLOUD_KEYFILE GCLOUD_KEYFILE)
27
+ JSON_ENV_VARS = %w(SPANNER_KEYFILE_JSON GOOGLE_CLOUD_KEYFILE_JSON
28
+ GCLOUD_KEYFILE_JSON)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,199 @@
1
+ # Copyright 2017 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "google/cloud/spanner/fields"
17
+ require "google/cloud/spanner/convert"
18
+
19
+ module Google
20
+ module Cloud
21
+ module Spanner
22
+ ##
23
+ # # Data
24
+ #
25
+ # Represents a row in a result from Cloud Spanner. Provides access to data
26
+ # in a hash-like structure. Values can be retrieved by name (String), or
27
+ # in cases in which values are unnamed, by zero-based index position
28
+ # (Integer).
29
+ #
30
+ # @example
31
+ # require "google/cloud/spanner"
32
+ #
33
+ # spanner = Google::Cloud::Spanner.new
34
+ #
35
+ # db = spanner.client "my-instance", "my-database"
36
+ #
37
+ # results = db.execute "SELECT * FROM users"
38
+ #
39
+ # results.rows.each do |row|
40
+ # puts "User #{row[:id]} is #{row[:name]}"
41
+ # end
42
+ #
43
+ class Data
44
+ ##
45
+ # Returns the names and values of the data as an array of field objects.
46
+ #
47
+ # @return [Array<Array>] An array containing name and value pairs.
48
+ #
49
+ def fields
50
+ @fields ||= Fields.from_grpc @grpc_fields
51
+ end
52
+
53
+ ##
54
+ # Returns the types of the data.
55
+ #
56
+ # See [Data
57
+ # types](https://cloud.google.com/spanner/docs/data-definition-language#data_types).
58
+ #
59
+ # @return [Array<Symbol>] An array containing the types of the values.
60
+ #
61
+ def types
62
+ fields.types
63
+ end
64
+
65
+ ##
66
+ # Returns the names of values, or in cases in which values are unnamed,
67
+ # the zero-based index position of values.
68
+ #
69
+ # @return [Array<(String,Integer)>] An array containing the names
70
+ # (String) or position (Integer) for the corresponding values of the
71
+ # data.
72
+ #
73
+ def keys
74
+ fields.keys
75
+ end
76
+
77
+ ##
78
+ # Returns the values of the data.
79
+ #
80
+ # @return [Array<Object>] An array containing the values.
81
+ #
82
+ def values
83
+ keys.count.times.map { |i| self[i] }
84
+ end
85
+
86
+ ##
87
+ # Returns the names or positions and their corresponding values as an
88
+ # array of arrays.
89
+ #
90
+ # @return [Array<Array>] An array containing name/position and value
91
+ # pairs.
92
+ #
93
+ def pairs
94
+ keys.zip values
95
+ end
96
+
97
+ ##
98
+ # Returns the value object for the provided name (String) or index
99
+ # (Integer). Do not pass a name to this method if the data has more than
100
+ # one member with the same name.
101
+ #
102
+ # @param [String, Integer] key The name (String) or zero-based index
103
+ # position (Integer) of the value.
104
+ #
105
+ # @raise [Google::Cloud::Spanner::DuplicateNameError] if the data
106
+ # contains duplicate names.
107
+ #
108
+ # @return [Object, nil] The value, or nil if no value is found.
109
+ #
110
+ def [] key
111
+ if key.is_a? Integer
112
+ return Convert.value_to_raw(@grpc_values[key],
113
+ @grpc_fields[key].type)
114
+ end
115
+ name_count = @grpc_fields.find_all { |f| f.name == String(key) }.count
116
+ return nil if name_count == 0
117
+ fail DuplicateNameError if name_count > 1
118
+ index = @grpc_fields.find_index { |f| f.name == String(key) }
119
+ Convert.value_to_raw(@grpc_values[index], @grpc_fields[index].type)
120
+ end
121
+
122
+ ##
123
+ # Returns the values as an array.
124
+ #
125
+ # @return [Array<Object>] An array containing the values of the data.
126
+ #
127
+ def to_a
128
+ values.map do |value|
129
+ if value.is_a? Data
130
+ value.to_h
131
+ elsif value.is_a? Array
132
+ value.map { |v| v.is_a?(Data) ? v.to_h : v }
133
+ else
134
+ value
135
+ end
136
+ end
137
+ end
138
+
139
+ ##
140
+ # Returns the names or indexes and corresponding values of the data as a
141
+ # hash. Do not use this method if the data has more than one member with
142
+ # the same name.
143
+ #
144
+ # @raise [Google::Cloud::Spanner::DuplicateNameError] if the data
145
+ # contains duplicate names.
146
+ #
147
+ # @return [Hash<(String,Integer)=>Object>] A hash containing the names
148
+ # or indexes and corresponding values.
149
+ #
150
+ def to_h
151
+ fail DuplicateNameError if fields.duplicate_names?
152
+ hashified_pairs = pairs.map do |key, value|
153
+ if value.is_a? Data
154
+ [key, value.to_h]
155
+ elsif value.is_a? Array
156
+ [key, value.map { |v| v.is_a?(Data) ? v.to_h : v }]
157
+ else
158
+ [key, value]
159
+ end
160
+ end
161
+ Hash[hashified_pairs]
162
+ end
163
+
164
+ # @private
165
+ def == other
166
+ return false unless other.is_a? Data
167
+ pairs == other.pairs
168
+ end
169
+
170
+ # @private
171
+ def to_s
172
+ named_values = pairs.map do |key, value|
173
+ if key.is_a? Integer
174
+ "#{value.inspect}"
175
+ else
176
+ "(#{key})#{value.inspect}"
177
+ end
178
+ end
179
+ "(#{named_values.join ', '})"
180
+ end
181
+
182
+ # @private
183
+ def inspect
184
+ "#<#{self.class.name} #{self}>"
185
+ end
186
+
187
+ ##
188
+ # @private Creates a new Data instance from
189
+ # Spanner values and fields.
190
+ def self.from_grpc grpc_values, grpc_fields
191
+ new.tap do |d|
192
+ d.instance_variable_set :@grpc_values, grpc_values
193
+ d.instance_variable_set :@grpc_fields, grpc_fields
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,377 @@
1
+ # Copyright 2016 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "google/cloud/spanner/database/job"
17
+ require "google/cloud/spanner/database/list"
18
+ require "google/cloud/spanner/policy"
19
+
20
+ module Google
21
+ module Cloud
22
+ module Spanner
23
+ ##
24
+ # # Database
25
+ #
26
+ # Represents a Cloud Spanner database. To use Cloud Spanner's read and
27
+ # write operations, you must first create a database. A database belongs
28
+ # to a {Instance} and contains tables and indexes. You may create multiple
29
+ # databases in an {Instance}.
30
+ #
31
+ # See {Google::Cloud::Spanner::Instance#databases},
32
+ # {Google::Cloud::Spanner::Instance#database}, and
33
+ # {Google::Cloud::Spanner::Instance#create_database}.
34
+ #
35
+ # To read and/or modify data in a Cloud Spanner database, use an instance
36
+ # of {Google::Cloud::Spanner::Client}. See
37
+ # {Google::Cloud::Spanner::Project#client}.
38
+ #
39
+ # @example
40
+ # require "google/cloud"
41
+ #
42
+ # spanner = Google::Cloud::Spanner.new
43
+ # instance = spanner.instance "my-instance"
44
+ #
45
+ # job = instance.create_database "my-new-database"
46
+ #
47
+ # job.done? #=> false
48
+ # job.reload! # API call
49
+ # job.done? #=> true
50
+ #
51
+ # database = instance.database "my-new-database"
52
+ #
53
+ class Database
54
+ ##
55
+ # @private The gRPC Service object.
56
+ attr_accessor :service
57
+
58
+ # @private Creates a new Database instance.
59
+ def initialize grpc, service
60
+ @grpc = grpc
61
+ @service = service
62
+ end
63
+
64
+ # The unique identifier for the project.
65
+ # @return [String]
66
+ def project_id
67
+ Admin::Database::V1::DatabaseAdminClient
68
+ .match_project_from_database_name @grpc.name
69
+ end
70
+
71
+ # The unique identifier for the instance.
72
+ # @return [String]
73
+ def instance_id
74
+ Admin::Database::V1::DatabaseAdminClient
75
+ .match_instance_from_database_name @grpc.name
76
+ end
77
+
78
+ # The unique identifier for the database.
79
+ # @return [String]
80
+ def database_id
81
+ Admin::Database::V1::DatabaseAdminClient
82
+ .match_database_from_database_name @grpc.name
83
+ end
84
+
85
+ # rubocop:disable LineLength
86
+
87
+ ##
88
+ # The full path for the database resource. Values are of the form
89
+ # `projects/<project_id>/instances/<instance_id>/databases/<database_id>`.
90
+ # @return [String]
91
+ def path
92
+ @grpc.name
93
+ end
94
+
95
+ # rubocop:enable LineLength
96
+
97
+ ##
98
+ # The current database state. Possible values are `:CREATING` and
99
+ # `:READY`.
100
+ # @return [Symbol]
101
+ def state
102
+ @grpc.state
103
+ end
104
+
105
+ ##
106
+ # The database is still being created. Operations on the database may
107
+ # fail with `FAILED_PRECONDITION` in this state.
108
+ # @return [Boolean]
109
+ def creating?
110
+ state == :CREATING
111
+ end
112
+
113
+ ##
114
+ # The database is fully created and ready for use.
115
+ # @return [Boolean]
116
+ def ready?
117
+ state == :READY
118
+ end
119
+
120
+ ##
121
+ # Retrieve the Data Definition Language (DDL) statements that define
122
+ # database structures. DDL statements are used to create, update,
123
+ # and delete tables and indexes.
124
+ #
125
+ # @see https://cloud.google.com/spanner/docs/data-definition-language
126
+ # Data Definition Language
127
+ #
128
+ # @param [Boolean] force Force the latest DDL statements to be retrieved
129
+ # from the Spanner service when `true`. Otherwise the DDL statements
130
+ # will be memoized to reduce the number of API calls made to the
131
+ # Spanner service. The default is `false`.
132
+ #
133
+ # @return [Array<String>] The DDL statements.
134
+ #
135
+ # @example statements are memoized to reduce the number of API calls:
136
+ # require "google/cloud/spanner"
137
+ #
138
+ # spanner = Google::Cloud::Spanner.new
139
+ # database = spanner.database "my-instance", "my-database"
140
+ #
141
+ # statements = database.ddl # API call
142
+ # statements_2 = database.ddl # No API call
143
+ #
144
+ # @example Use `force` to retrieve the statements from the service:
145
+ # require "google/cloud/spanner"
146
+ #
147
+ # spanner = Google::Cloud::Spanner.new
148
+ # database = spanner.database "my-instance", "my-database"
149
+ #
150
+ # statements = database.ddl force: true # API call
151
+ # statements_2 = database.ddl force: true # API call
152
+ #
153
+ def ddl force: nil
154
+ return @ddl if @ddl && !force
155
+ ensure_service!
156
+ ddl_grpc = service.get_database_ddl instance_id, database_id
157
+ @ddl = ddl_grpc.statements
158
+ end
159
+
160
+ ##
161
+ # Updates the database schema by adding Data Definition Language (DDL)
162
+ # statements to create, update, and delete tables and indexes.
163
+ #
164
+ # @see https://cloud.google.com/spanner/docs/data-definition-language
165
+ # Data Definition Language
166
+ #
167
+ # @param [Array<String>] statements The DDL statements to be applied to
168
+ # the database.
169
+ # @param [String, nil] operation_id The operation ID used to perform the
170
+ # update. When `nil`, the update request is assigned an
171
+ # automatically-generated operation ID. Specifying an explicit value
172
+ # simplifies determining whether the statements were executed in the
173
+ # event that the update is replayed, or the return value is otherwise
174
+ # lost. This value should be unique within the database, and must be a
175
+ # valid identifier: `[a-z][a-z0-9_]*`. Will raise
176
+ # {Google::Cloud::AlreadyExistsError} if the named operation already
177
+ # exists. Optional.
178
+ #
179
+ # @return [Database::Job] The job representing the long-running,
180
+ # asynchronous processing of a database schema update operation.
181
+ #
182
+ # @example
183
+ # require "google/cloud/spanner"
184
+ #
185
+ # spanner = Google::Cloud::Spanner.new
186
+ # database = spanner.database "my-instance", "my-database"
187
+ #
188
+ # add_users_table_sql = %q(
189
+ # CREATE TABLE users (
190
+ # id INT64 NOT NULL,
191
+ # username STRING(25) NOT NULL,
192
+ # name STRING(45) NOT NULL,
193
+ # email STRING(128),
194
+ # ) PRIMARY KEY(id)
195
+ # )
196
+ #
197
+ # database.update statements: [add_users_table_sql]
198
+ #
199
+ def update statements: [], operation_id: nil
200
+ ensure_service!
201
+ grpc = service.update_database_ddl instance_id, database_id,
202
+ statements: statements,
203
+ operation_id: operation_id
204
+ Database::Job.from_grpc grpc, service
205
+ end
206
+
207
+ ##
208
+ # Drops (deletes) the Cloud Spanner database.
209
+ #
210
+ # @return [Boolean] Returns `true` if the database was deleted.
211
+ #
212
+ # @example
213
+ # require "google/cloud/spanner"
214
+ #
215
+ # spanner = Google::Cloud::Spanner.new
216
+ # database = spanner.database "my-instance", "my-database"
217
+ #
218
+ # database.drop
219
+ #
220
+ def drop
221
+ ensure_service!
222
+ service.drop_database instance_id, database_id
223
+ true
224
+ end
225
+
226
+ ##
227
+ # Gets the [Cloud IAM](https://cloud.google.com/iam/) access control
228
+ # policy for this database.
229
+ #
230
+ # @see https://cloud.google.com/spanner/reference/rpc/google.iam.v1#google.iam.v1.Policy
231
+ # google.iam.v1.IAMPolicy
232
+ #
233
+ # @yield [policy] A block for updating the policy. The latest policy
234
+ # will be read from the Spanner service and passed to the block. After
235
+ # the block completes, the modified policy will be written to the
236
+ # service.
237
+ # @yieldparam [Policy] policy the current Cloud IAM Policy for this
238
+ # database
239
+ #
240
+ # @return [Policy] The current Cloud IAM Policy for this database.
241
+ #
242
+ # @example
243
+ # require "google/cloud/spanner"
244
+ #
245
+ # spanner = Google::Cloud::Spanner.new
246
+ # database = spanner.database "my-instance", "my-database"
247
+ #
248
+ # policy = database.policy
249
+ #
250
+ # @example Update the policy by passing a block:
251
+ # require "google/cloud/spanner"
252
+ #
253
+ # spanner = Google::Cloud::Spanner.new
254
+ # database = spanner.database "my-instance", "my-database"
255
+ #
256
+ # database.policy do |p|
257
+ # p.add "roles/owner", "user:owner@example.com"
258
+ # end # 2 API calls
259
+ #
260
+ def policy
261
+ ensure_service!
262
+ grpc = service.get_database_policy instance_id, database_id
263
+ policy = Policy.from_grpc grpc
264
+ return policy unless block_given?
265
+ yield policy
266
+ self.policy = policy
267
+ end
268
+
269
+ ##
270
+ # Updates the [Cloud IAM](https://cloud.google.com/iam/) access control
271
+ # policy for this database. The policy should be read from {#policy}.
272
+ # See {Google::Cloud::Spanner::Policy} for an explanation of the policy
273
+ # `etag` property and how to modify policies.
274
+ #
275
+ # You can also update the policy by passing a block to {#policy}, which
276
+ # will call this method internally after the block completes.
277
+ #
278
+ # @see https://cloud.google.com/spanner/reference/rpc/google.iam.v1#google.iam.v1.Policy
279
+ # google.iam.v1.IAMPolicy
280
+ #
281
+ # @param [Policy] new_policy a new or modified Cloud IAM Policy for this
282
+ # database
283
+ #
284
+ # @return [Policy] The policy returned by the API update operation.
285
+ #
286
+ # @example
287
+ # require "google/cloud/spanner"
288
+ #
289
+ # spanner = Google::Cloud::Spanner.new
290
+ # database = spanner.database "my-instance", "my-database"
291
+ #
292
+ # policy = database.policy # API call
293
+ #
294
+ # policy.add "roles/owner", "user:owner@example.com"
295
+ #
296
+ # database.policy = policy # API call
297
+ #
298
+ def policy= new_policy
299
+ ensure_service!
300
+ grpc = service.set_database_policy \
301
+ instance_id, database_id, new_policy.to_grpc
302
+ Policy.from_grpc grpc
303
+ end
304
+
305
+ ##
306
+ # Tests the specified permissions against the [Cloud
307
+ # IAM](https://cloud.google.com/iam/) access control policy.
308
+ #
309
+ # @see https://cloud.google.com/iam/docs/managing-policies Managing
310
+ # Policies
311
+ #
312
+ # @param [String, Array<String>] permissions The set of permissions to
313
+ # check access for. Permissions with wildcards (such as `*` or
314
+ # `storage.*`) are not allowed.
315
+ #
316
+ # The permissions that can be checked on a database are:
317
+ #
318
+ # * pubsub.databases.create
319
+ # * pubsub.databases.list
320
+ # * pubsub.databases.update
321
+ # * pubsub.databases.updateDdl
322
+ # * pubsub.databases.get
323
+ # * pubsub.databases.getDdl
324
+ # * pubsub.databases.getIamPolicy
325
+ # * pubsub.databases.setIamPolicy
326
+ # * pubsub.databases.beginReadOnlyTransaction
327
+ # * pubsub.databases.beginOrRollbackReadWriteTransaction
328
+ # * pubsub.databases.read
329
+ # * pubsub.databases.select
330
+ # * pubsub.databases.write
331
+ # * pubsub.databases.drop
332
+ #
333
+ # @return [Array<Strings>] The permissions that have access.
334
+ #
335
+ # @example
336
+ # require "google/cloud/spanner"
337
+ #
338
+ # spanner = Google::Cloud::Spanner.new
339
+ # database = spanner.database "my-instance", "my-database"
340
+ # perms = database.test_permissions "spanner.databases.get",
341
+ # "spanner.databases.update"
342
+ # perms.include? "spanner.databases.get" #=> true
343
+ # perms.include? "spanner.databases.update" #=> false
344
+ #
345
+ def test_permissions *permissions
346
+ permissions = Array(permissions).flatten
347
+ permissions = Array(permissions).flatten
348
+ ensure_service!
349
+ grpc = service.test_database_permissions \
350
+ instance_id, database_id, permissions
351
+ grpc.permissions
352
+ end
353
+
354
+ ##
355
+ # @private Creates a new Database instance from a
356
+ # Google::Spanner::Admin::Database::V1::Database.
357
+ def self.from_grpc grpc, service
358
+ new grpc, service
359
+ end
360
+
361
+ protected
362
+
363
+ ##
364
+ # @private Raise an error unless an active connection to the service is
365
+ # available.
366
+ def ensure_service!
367
+ fail "Must have active connection to service" unless service
368
+ end
369
+
370
+ def session_path instance_id, database_id, session_id
371
+ V1::SpannerClient.session_path(
372
+ project_id, instance_id, database_id, session_id)
373
+ end
374
+ end
375
+ end
376
+ end
377
+ end