google-cloud-bigtable 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +19 -0
  3. data/AUTHENTICATION.md +177 -0
  4. data/CHANGELOG.md +223 -0
  5. data/CODE_OF_CONDUCT.md +40 -0
  6. data/CONTRIBUTING.md +188 -0
  7. data/EMULATOR.md +30 -0
  8. data/LICENSE +201 -0
  9. data/LOGGING.md +32 -0
  10. data/OVERVIEW.md +400 -0
  11. data/TROUBLESHOOTING.md +31 -0
  12. data/lib/google-cloud-bigtable.rb +171 -0
  13. data/lib/google/bigtable/admin/v2/bigtable_instance_admin_pb.rb +145 -0
  14. data/lib/google/bigtable/admin/v2/bigtable_instance_admin_services_pb.rb +90 -0
  15. data/lib/google/bigtable/admin/v2/bigtable_table_admin_pb.rb +208 -0
  16. data/lib/google/bigtable/admin/v2/bigtable_table_admin_services_pb.rb +154 -0
  17. data/lib/google/bigtable/admin/v2/common_pb.rb +30 -0
  18. data/lib/google/bigtable/admin/v2/instance_pb.rb +74 -0
  19. data/lib/google/bigtable/admin/v2/table_pb.rb +127 -0
  20. data/lib/google/bigtable/v2/bigtable_pb.rb +113 -0
  21. data/lib/google/bigtable/v2/bigtable_services_pb.rb +68 -0
  22. data/lib/google/bigtable/v2/data_pb.rb +156 -0
  23. data/lib/google/cloud/bigtable.rb +184 -0
  24. data/lib/google/cloud/bigtable/admin.rb +202 -0
  25. data/lib/google/cloud/bigtable/admin/credentials.rb +27 -0
  26. data/lib/google/cloud/bigtable/admin/v2.rb +223 -0
  27. data/lib/google/cloud/bigtable/admin/v2/bigtable_instance_admin_client.rb +1451 -0
  28. data/lib/google/cloud/bigtable/admin/v2/bigtable_instance_admin_client_config.json +139 -0
  29. data/lib/google/cloud/bigtable/admin/v2/bigtable_table_admin_client.rb +1734 -0
  30. data/lib/google/cloud/bigtable/admin/v2/bigtable_table_admin_client_config.json +163 -0
  31. data/lib/google/cloud/bigtable/admin/v2/credentials.rb +51 -0
  32. data/lib/google/cloud/bigtable/admin/v2/doc/google/bigtable/admin/v2/bigtable_instance_admin.rb +297 -0
  33. data/lib/google/cloud/bigtable/admin/v2/doc/google/bigtable/admin/v2/bigtable_table_admin.rb +587 -0
  34. data/lib/google/cloud/bigtable/admin/v2/doc/google/bigtable/admin/v2/instance.rb +193 -0
  35. data/lib/google/cloud/bigtable/admin/v2/doc/google/bigtable/admin/v2/table.rb +303 -0
  36. data/lib/google/cloud/bigtable/admin/v2/doc/google/iam/v1/iam_policy.rb +64 -0
  37. data/lib/google/cloud/bigtable/admin/v2/doc/google/iam/v1/options.rb +33 -0
  38. data/lib/google/cloud/bigtable/admin/v2/doc/google/iam/v1/policy.rb +151 -0
  39. data/lib/google/cloud/bigtable/admin/v2/doc/google/longrunning/operations.rb +51 -0
  40. data/lib/google/cloud/bigtable/admin/v2/doc/google/protobuf/any.rb +131 -0
  41. data/lib/google/cloud/bigtable/admin/v2/doc/google/protobuf/duration.rb +91 -0
  42. data/lib/google/cloud/bigtable/admin/v2/doc/google/protobuf/empty.rb +29 -0
  43. data/lib/google/cloud/bigtable/admin/v2/doc/google/protobuf/field_mask.rb +222 -0
  44. data/lib/google/cloud/bigtable/admin/v2/doc/google/protobuf/timestamp.rb +113 -0
  45. data/lib/google/cloud/bigtable/admin/v2/doc/google/rpc/status.rb +39 -0
  46. data/lib/google/cloud/bigtable/admin/v2/doc/google/type/expr.rb +45 -0
  47. data/lib/google/cloud/bigtable/app_profile.rb +439 -0
  48. data/lib/google/cloud/bigtable/app_profile/job.rb +99 -0
  49. data/lib/google/cloud/bigtable/app_profile/list.rb +165 -0
  50. data/lib/google/cloud/bigtable/backup.rb +324 -0
  51. data/lib/google/cloud/bigtable/backup/job.rb +87 -0
  52. data/lib/google/cloud/bigtable/backup/list.rb +167 -0
  53. data/lib/google/cloud/bigtable/chunk_processor.rb +241 -0
  54. data/lib/google/cloud/bigtable/cluster.rb +390 -0
  55. data/lib/google/cloud/bigtable/cluster/job.rb +88 -0
  56. data/lib/google/cloud/bigtable/cluster/list.rb +171 -0
  57. data/lib/google/cloud/bigtable/column_family.rb +73 -0
  58. data/lib/google/cloud/bigtable/column_family_map.rb +426 -0
  59. data/lib/google/cloud/bigtable/column_range.rb +194 -0
  60. data/lib/google/cloud/bigtable/convert.rb +83 -0
  61. data/lib/google/cloud/bigtable/credentials.rb +25 -0
  62. data/lib/google/cloud/bigtable/errors.rb +38 -0
  63. data/lib/google/cloud/bigtable/gc_rule.rb +334 -0
  64. data/lib/google/cloud/bigtable/instance.rb +935 -0
  65. data/lib/google/cloud/bigtable/instance/cluster_map.rb +74 -0
  66. data/lib/google/cloud/bigtable/instance/job.rb +98 -0
  67. data/lib/google/cloud/bigtable/instance/list.rb +164 -0
  68. data/lib/google/cloud/bigtable/longrunning_job.rb +122 -0
  69. data/lib/google/cloud/bigtable/mutation_entry.rb +256 -0
  70. data/lib/google/cloud/bigtable/mutation_operations.rb +357 -0
  71. data/lib/google/cloud/bigtable/policy.rb +167 -0
  72. data/lib/google/cloud/bigtable/project.rb +471 -0
  73. data/lib/google/cloud/bigtable/read_modify_write_rule.rb +134 -0
  74. data/lib/google/cloud/bigtable/read_operations.rb +328 -0
  75. data/lib/google/cloud/bigtable/routing_policy.rb +172 -0
  76. data/lib/google/cloud/bigtable/row.rb +136 -0
  77. data/lib/google/cloud/bigtable/row_filter.rb +639 -0
  78. data/lib/google/cloud/bigtable/row_filter/chain_filter.rb +590 -0
  79. data/lib/google/cloud/bigtable/row_filter/condition_filter.rb +114 -0
  80. data/lib/google/cloud/bigtable/row_filter/interleave_filter.rb +621 -0
  81. data/lib/google/cloud/bigtable/row_filter/simple_filter.rb +287 -0
  82. data/lib/google/cloud/bigtable/row_range.rb +179 -0
  83. data/lib/google/cloud/bigtable/rows_mutator.rb +113 -0
  84. data/lib/google/cloud/bigtable/rows_reader.rb +200 -0
  85. data/lib/google/cloud/bigtable/sample_row_key.rb +85 -0
  86. data/lib/google/cloud/bigtable/service.rb +913 -0
  87. data/lib/google/cloud/bigtable/status.rb +76 -0
  88. data/lib/google/cloud/bigtable/table.rb +686 -0
  89. data/lib/google/cloud/bigtable/table/cluster_state.rb +125 -0
  90. data/lib/google/cloud/bigtable/table/list.rb +154 -0
  91. data/lib/google/cloud/bigtable/table/restore_job.rb +117 -0
  92. data/lib/google/cloud/bigtable/v2.rb +146 -0
  93. data/lib/google/cloud/bigtable/v2/bigtable_client.rb +591 -0
  94. data/lib/google/cloud/bigtable/v2/bigtable_client_config.json +83 -0
  95. data/lib/google/cloud/bigtable/v2/credentials.rb +46 -0
  96. data/lib/google/cloud/bigtable/v2/doc/google/bigtable/v2/bigtable.rb +290 -0
  97. data/lib/google/cloud/bigtable/v2/doc/google/bigtable/v2/data.rb +493 -0
  98. data/lib/google/cloud/bigtable/v2/doc/google/protobuf/any.rb +131 -0
  99. data/lib/google/cloud/bigtable/v2/doc/google/protobuf/wrappers.rb +34 -0
  100. data/lib/google/cloud/bigtable/v2/doc/google/rpc/status.rb +39 -0
  101. data/lib/google/cloud/bigtable/value_range.rb +181 -0
  102. data/lib/google/cloud/bigtable/version.rb +22 -0
  103. metadata +337 -0
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2020 Google LLC
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+
18
+ module Google
19
+ module Cloud
20
+ module Bigtable
21
+ class Backup
22
+ ##
23
+ # # Job
24
+ #
25
+ # A resource representing the long-running, asynchronous processing of an backup create operation. The job can
26
+ # be refreshed to retrieve the backup object once the operation has been completed.
27
+ #
28
+ # See {Cluster#create_backup}.
29
+ #
30
+ # @see https://cloud.google.com/bigtable/docs/reference/admin/rpc/google.longrunning#google.longrunning.Operation
31
+ # Long-running Operation
32
+ #
33
+ # @example
34
+ # require "google/cloud/bigtable"
35
+ #
36
+ # bigtable = Google::Cloud::Bigtable.new
37
+ # instance = bigtable.instance("my-instance")
38
+ # cluster = instance.cluster("my-cluster")
39
+ # table = instance.table("my-table")
40
+ #
41
+ # expire_time = Time.now + 60 * 60 * 7
42
+ # job = cluster.create_backup(table, "my-backup", expire_time)
43
+ #
44
+ # job.wait_until_done!
45
+ # job.done? #=> true
46
+ #
47
+ # if job.error?
48
+ # status = job.error
49
+ # else
50
+ # backup = job.backup
51
+ # end
52
+ #
53
+ class Job < LongrunningJob
54
+ ##
55
+ # Get the backup object from operation results.
56
+ #
57
+ # @return [Google::Cloud::Bigtable::Backup, nil] The backup instance, or `nil` if the operation is not
58
+ # complete.
59
+ #
60
+ # @example
61
+ # require "google/cloud/bigtable"
62
+ #
63
+ # bigtable = Google::Cloud::Bigtable.new
64
+ # instance = bigtable.instance("my-instance")
65
+ # cluster = instance.cluster("my-cluster")
66
+ # table = instance.table("my-table")
67
+ #
68
+ # expire_time = Time.now + 60 * 60 * 7
69
+ # job = cluster.create_backup(table, "my-backup", expire_time)
70
+ #
71
+ # job.wait_until_done!
72
+ # job.done? #=> true
73
+ #
74
+ # if job.error?
75
+ # status = job.error
76
+ # else
77
+ # backup = job.backup
78
+ # end
79
+ #
80
+ def backup
81
+ Backup.from_grpc results, service if results
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,167 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2020 Google LLC
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+
18
+ module Google
19
+ module Cloud
20
+ module Bigtable
21
+ class Backup
22
+ ##
23
+ # Backup::List is a special-case array with additional values.
24
+ class List < DelegateClass(::Array)
25
+ # @private
26
+ # The gRPC Service object.
27
+ attr_accessor :service
28
+
29
+ # @private
30
+ # The gRPC page enumerable object.
31
+ attr_accessor :grpc
32
+
33
+ # @private
34
+ # Creates a new Backup::List with an array of backups.
35
+ def initialize arr = []
36
+ super arr
37
+ end
38
+
39
+ ##
40
+ # Whether there is a next page of backups.
41
+ #
42
+ # @return [Boolean]
43
+ #
44
+ # @example
45
+ # require "google/cloud/bigtable"
46
+ #
47
+ # bigtable = Google::Cloud::Bigtable.new
48
+ #
49
+ # instance = bigtable.instance("my-instance")
50
+ # cluster = instance.cluster("my-cluster")
51
+ #
52
+ # backups = cluster.backups
53
+ #
54
+ # if backups.next?
55
+ # next_backups = backups.next
56
+ # end
57
+ #
58
+ def next?
59
+ grpc.next_page?
60
+ end
61
+
62
+ ##
63
+ # Retrieves the next page of backups.
64
+ #
65
+ # @return [Backup::List] The list of backups.
66
+ #
67
+ # @example
68
+ # require "google/cloud/bigtable"
69
+ #
70
+ # bigtable = Google::Cloud::Bigtable.new
71
+ #
72
+ # instance = bigtable.instance("my-instance")
73
+ # cluster = instance.cluster("my-cluster")
74
+ #
75
+ # backups = cluster.backups
76
+ #
77
+ # if backups.next?
78
+ # next_backups = backups.next
79
+ # end
80
+ #
81
+ def next
82
+ ensure_grpc!
83
+
84
+ return nil unless next?
85
+ grpc.next_page
86
+ self.class.from_grpc grpc, service
87
+ end
88
+
89
+ ##
90
+ # Retrieves remaining results by repeatedly invoking {#next} until {#next?} returns `false`. Calls the given
91
+ # block once for each result, which is passed as the argument to the block.
92
+ #
93
+ # An enumerator is returned if no block is given.
94
+ #
95
+ # This method will make repeated API calls until all remaining results are retrieved (unlike `#each`, for
96
+ # example, which merely iterates over the results returned by a single API call). Use with caution.
97
+ #
98
+ # @yield [backup] The block for accessing each backup.
99
+ # @yieldparam [Backup] backup The backup object.
100
+ #
101
+ # @return [Enumerator,nil] An enumerator is returned if no block is given, otherwise `nil`.
102
+ #
103
+ # @example Iterating each backup by passing a block:
104
+ # require "google/cloud/bigtable"
105
+ #
106
+ # bigtable = Google::Cloud::Bigtable.new
107
+ #
108
+ # instance = bigtable.instance("my-instance")
109
+ # cluster = instance.cluster("my-cluster")
110
+ #
111
+ # cluster.backups.all do |backup|
112
+ # puts backup.backup_id
113
+ # end
114
+ #
115
+ # @example Using the enumerator by not passing a block:
116
+ # require "google/cloud/bigtable"
117
+ #
118
+ # bigtable = Google::Cloud::Bigtable.new
119
+ #
120
+ # instance = bigtable.instance("my-instance")
121
+ # cluster = instance.cluster("my-cluster")
122
+ #
123
+ # all_backup_ids = cluster.backups.all.map do |backup|
124
+ # backup.backup_id
125
+ # end
126
+ #
127
+ def all
128
+ return enum_for :all unless block_given?
129
+
130
+ results = self
131
+ loop do
132
+ results.each { |r| yield r }
133
+ break unless next?
134
+ grpc.next_page
135
+ results = self.class.from_grpc grpc, service
136
+ end
137
+ end
138
+
139
+ # @private
140
+ # New Snapshot::List from a Google::Gax::PagedEnumerable<Google::Bigtable::Admin::V2::Backup> object.
141
+ # @param grpc [Google::Gax::PagedEnumerable<Google::Bigtable::Admin::V2::Backup> ]
142
+ # @param service [Google::Cloud::Bigtable::Service]
143
+ # @return [Array<Google::Cloud::Bigtable::Backup>]
144
+ def self.from_grpc grpc, service
145
+ backups = List.new(
146
+ Array(grpc.response.backups).map do |backup|
147
+ Backup.from_grpc backup, service
148
+ end
149
+ )
150
+ backups.grpc = grpc
151
+ backups.service = service
152
+ backups
153
+ end
154
+
155
+ protected
156
+
157
+ # @private
158
+ #
159
+ # Raises an error if an active gRPC call is not available.
160
+ def ensure_grpc!
161
+ raise "Must have active gRPC call" unless grpc
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,241 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2018 Google LLC
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+
18
+ module Google
19
+ module Cloud
20
+ module Bigtable
21
+ # @private
22
+ # # ChunkProcessor
23
+ #
24
+ # Read a chunk of data and merge it based on states and build rows and cells
25
+ #
26
+ class ChunkProcessor
27
+ # Row states
28
+ NEW_ROW = 1
29
+ ROW_IN_PROGRESS = 2
30
+ CELL_IN_PROGRESS = 3
31
+
32
+ # Current state
33
+ attr_accessor :state, :last_key
34
+
35
+ # Current cached row data
36
+ attr_accessor :chunk, :row
37
+
38
+ # Current cell values
39
+ attr_accessor :cur_family, :cur_qaul, :cur_ts, :cur_val, :cur_labels
40
+
41
+ # @private
42
+ #
43
+ # Create chunk reader object and set row state to new
44
+ #
45
+ def initialize
46
+ reset_to_new_row
47
+ end
48
+
49
+ ##
50
+ # Process chunk and build full row with cells
51
+ #
52
+ # @param chunk [Google::Bigtable::V2::ReadRowsResponse::CellChunk]
53
+ #
54
+ def process chunk
55
+ self.chunk = chunk
56
+
57
+
58
+ raise_if chunk.value_size.positive?, "Commit rows cannot have a non-zero value_size." if chunk.commit_row
59
+
60
+ if state == NEW_ROW
61
+ process_new_row
62
+ elsif state == CELL_IN_PROGRESS
63
+ process_cell_in_progress
64
+ elsif state == ROW_IN_PROGRESS
65
+ process_row_in_progress
66
+ end
67
+ end
68
+
69
+ ##
70
+ # Validate row status commit or reset
71
+ #
72
+ # @raise [Google::Cloud::Bigtable::InvalidRowStateError]
73
+ # if chunk has data on reset row state
74
+ #
75
+ def validate_reset_row
76
+ return unless chunk.reset_row
77
+
78
+ value = (!chunk.row_key.empty? ||
79
+ chunk.family_name ||
80
+ chunk.qualifier ||
81
+ !chunk.value.empty? ||
82
+ chunk.timestamp_micros.positive?)
83
+
84
+ raise_if value, "A reset should have no data"
85
+ end
86
+
87
+ ##
88
+ # Validate chunk has new row state
89
+ #
90
+ # @raise [Google::Cloud::Bigtable::InvalidRowStateError]
91
+ # If row already has a set key, chunk has an empty row key, chunk
92
+ # state is reset, new row key is the same as the last-read key,
93
+ # or if family name or column qualifier are empty
94
+ #
95
+ def validate_new_row
96
+ raise_if row.key, "A new row cannot have existing state"
97
+ raise_if chunk.row_key.empty?, "A row key must be set"
98
+ raise_if chunk.reset_row, "A new row cannot be reset"
99
+ raise_if last_key == chunk.row_key, "A commit happened but the same key followed"
100
+ raise_if chunk.family_name.nil?, "A family must be set"
101
+ raise_if chunk.qualifier.nil?, "A column qualifier must be set"
102
+ end
103
+
104
+ ##
105
+ # Validate chunk merge is in progress to build new row
106
+ #
107
+ # @raise [Google::Cloud::Bigtable::InvalidRowStateError]
108
+ # If row and chunk row key are not same or chunk row key is empty.
109
+ #
110
+ def validate_row_in_progress
111
+ raise_if !chunk.row_key.empty? && chunk.row_key != row.key, "A commit is required between row keys"
112
+
113
+ raise_if chunk.family_name && chunk.qualifier.nil?, "A qualifier must be specified"
114
+
115
+ validate_reset_row
116
+ end
117
+
118
+ ##
119
+ # Process new row by setting values from current chunk.
120
+ #
121
+ # @return [Google::Cloud::Bigtable::Row]
122
+ #
123
+ def process_new_row
124
+ validate_new_row
125
+
126
+ return if chunk.family_name.nil? || chunk.qualifier.nil?
127
+
128
+ row.key = chunk.row_key
129
+ self.cur_family = chunk.family_name.value
130
+ self.cur_qaul = chunk.qualifier.value
131
+ self.cur_ts = chunk.timestamp_micros
132
+ self.cur_labels = chunk.labels
133
+
134
+ next_state!
135
+ end
136
+
137
+ ##
138
+ # Process chunk if row state is in progress
139
+ #
140
+ # @return [Google::Cloud::Bigtable::Row]
141
+ #
142
+ def process_row_in_progress
143
+ validate_row_in_progress
144
+
145
+ return reset_to_new_row if chunk.reset_row
146
+
147
+ self.cur_family = chunk.family_name.value if chunk.family_name
148
+ self.cur_qaul = chunk.qualifier.value if chunk.qualifier
149
+ self.cur_ts = chunk.timestamp_micros
150
+ self.cur_labels = chunk.labels if chunk.labels
151
+ next_state!
152
+ end
153
+
154
+ ##
155
+ # Process chunk if row cell state is in progress
156
+ #
157
+ # @return [Google::Cloud::Bigtable::Row]
158
+ #
159
+ def process_cell_in_progress
160
+ validate_reset_row
161
+
162
+ return reset_to_new_row if chunk.reset_row
163
+
164
+ next_state!
165
+ end
166
+
167
+ ##
168
+ # Set next state of row.
169
+ #
170
+ # @return [Google::Cloud::Bigtable::Row]
171
+ #
172
+ def next_state!
173
+ if cur_val
174
+ self.cur_val += chunk.value
175
+ else
176
+ self.cur_val = chunk.value
177
+ end
178
+
179
+ if chunk.value_size.zero?
180
+ persist_cell
181
+ self.state = ROW_IN_PROGRESS
182
+ else
183
+ self.state = CELL_IN_PROGRESS
184
+ end
185
+
186
+ return unless chunk.commit_row
187
+
188
+ self.last_key = row.key
189
+ completed_row = row
190
+ reset_to_new_row
191
+ completed_row
192
+ end
193
+
194
+ # Build cell and append to row.
195
+ def persist_cell
196
+ cell = Row::Cell.new cur_family, cur_qaul, cur_ts, cur_val, cur_labels
197
+ row.cells[cur_family] << cell
198
+
199
+ # Clear cached cell values
200
+ self.cur_val = nil
201
+ self.cur_ts = nil
202
+ self.cur_labels = nil
203
+ end
204
+
205
+ # Reset read state and cached data
206
+ def reset_to_new_row
207
+ self.row = Row.new
208
+ self.state = NEW_ROW
209
+ self.cur_family = nil
210
+ self.cur_qaul = nil
211
+ self.cur_ts = nil
212
+ self.cur_val = nil
213
+ self.cur_labels = nil
214
+ end
215
+
216
+ ##
217
+ # Validate last row is completed
218
+ #
219
+ # @raise [Google::Cloud::Bigtable::InvalidRowStateError]
220
+ # If read rows response end without last row completed
221
+ #
222
+ def validate_last_row_complete
223
+ return if row.key.nil?
224
+
225
+ raise_if !chunk.commit_row, "Response ended with pending row without commit"
226
+ end
227
+
228
+ private
229
+
230
+ ##
231
+ # Raise error on condition failure
232
+ #
233
+ # @raise [Google::Cloud::Bigtable::InvalidRowStateError]
234
+ #
235
+ def raise_if condition, message
236
+ raise InvalidRowStateError.new(message, chunk.to_h) if condition
237
+ end
238
+ end
239
+ end
240
+ end
241
+ end