cassandra-driver 3.0.0.beta.1-java → 3.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +106 -39
  3. data/lib/cassandra.rb +396 -148
  4. data/lib/cassandra/address_resolution.rb +1 -1
  5. data/lib/cassandra/address_resolution/policies/ec2_multi_region.rb +1 -1
  6. data/lib/cassandra/address_resolution/policies/none.rb +1 -1
  7. data/lib/cassandra/aggregate.rb +21 -7
  8. data/lib/cassandra/argument.rb +2 -2
  9. data/lib/cassandra/attr_boolean.rb +33 -0
  10. data/lib/cassandra/auth.rb +6 -5
  11. data/lib/cassandra/auth/providers.rb +1 -1
  12. data/lib/cassandra/auth/providers/password.rb +5 -13
  13. data/lib/cassandra/cassandra_logger.rb +80 -0
  14. data/lib/cassandra/cluster.rb +49 -9
  15. data/lib/cassandra/cluster/client.rb +835 -209
  16. data/lib/cassandra/cluster/connection_pool.rb +2 -2
  17. data/lib/cassandra/cluster/connector.rb +86 -27
  18. data/lib/cassandra/cluster/control_connection.rb +222 -95
  19. data/lib/cassandra/cluster/failed_connection.rb +1 -1
  20. data/lib/cassandra/cluster/metadata.rb +14 -8
  21. data/lib/cassandra/cluster/options.rb +68 -22
  22. data/lib/cassandra/cluster/registry.rb +81 -17
  23. data/lib/cassandra/cluster/schema.rb +70 -8
  24. data/lib/cassandra/cluster/schema/cql_type_parser.rb +15 -10
  25. data/lib/cassandra/cluster/schema/fetchers.rb +601 -241
  26. data/lib/cassandra/cluster/schema/fqcn_type_parser.rb +39 -38
  27. data/lib/cassandra/cluster/schema/partitioners.rb +1 -1
  28. data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +6 -8
  29. data/lib/cassandra/cluster/schema/partitioners/ordered.rb +1 -1
  30. data/lib/cassandra/cluster/schema/partitioners/random.rb +1 -1
  31. data/lib/cassandra/cluster/schema/replication_strategies.rb +1 -1
  32. data/lib/cassandra/cluster/schema/replication_strategies/network_topology.rb +19 -18
  33. data/lib/cassandra/cluster/schema/replication_strategies/none.rb +1 -1
  34. data/lib/cassandra/cluster/schema/replication_strategies/simple.rb +1 -1
  35. data/lib/cassandra/column.rb +4 -23
  36. data/lib/cassandra/column_container.rb +322 -0
  37. data/lib/cassandra/compression.rb +1 -1
  38. data/lib/cassandra/compression/compressors/lz4.rb +7 -8
  39. data/lib/cassandra/compression/compressors/snappy.rb +4 -3
  40. data/lib/cassandra/driver.rb +107 -46
  41. data/lib/cassandra/errors.rb +303 -52
  42. data/lib/cassandra/execution/info.rb +16 -5
  43. data/lib/cassandra/execution/options.rb +102 -55
  44. data/lib/cassandra/execution/trace.rb +16 -9
  45. data/lib/cassandra/executors.rb +1 -1
  46. data/lib/cassandra/function.rb +19 -13
  47. data/lib/cassandra/function_collection.rb +85 -0
  48. data/lib/cassandra/future.rb +101 -49
  49. data/lib/cassandra/host.rb +25 -5
  50. data/lib/cassandra/index.rb +118 -0
  51. data/lib/cassandra/keyspace.rb +169 -33
  52. data/lib/cassandra/listener.rb +1 -1
  53. data/lib/cassandra/load_balancing.rb +2 -2
  54. data/lib/cassandra/load_balancing/policies.rb +1 -1
  55. data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +39 -25
  56. data/lib/cassandra/load_balancing/policies/round_robin.rb +8 -1
  57. data/lib/cassandra/load_balancing/policies/token_aware.rb +22 -13
  58. data/lib/cassandra/load_balancing/policies/white_list.rb +18 -5
  59. data/lib/cassandra/materialized_view.rb +90 -0
  60. data/lib/cassandra/null_logger.rb +27 -6
  61. data/lib/cassandra/protocol.rb +1 -1
  62. data/lib/cassandra/protocol/coder.rb +81 -42
  63. data/lib/cassandra/protocol/cql_byte_buffer.rb +58 -44
  64. data/lib/cassandra/protocol/cql_protocol_handler.rb +57 -54
  65. data/lib/cassandra/protocol/request.rb +6 -7
  66. data/lib/cassandra/protocol/requests/auth_response_request.rb +3 -3
  67. data/lib/cassandra/protocol/requests/batch_request.rb +17 -8
  68. data/lib/cassandra/protocol/requests/credentials_request.rb +3 -3
  69. data/lib/cassandra/protocol/requests/execute_request.rb +39 -20
  70. data/lib/cassandra/protocol/requests/options_request.rb +1 -1
  71. data/lib/cassandra/protocol/requests/prepare_request.rb +5 -5
  72. data/lib/cassandra/protocol/requests/query_request.rb +28 -23
  73. data/lib/cassandra/protocol/requests/register_request.rb +2 -2
  74. data/lib/cassandra/protocol/requests/startup_request.rb +8 -8
  75. data/lib/cassandra/protocol/requests/void_query_request.rb +1 -1
  76. data/lib/cassandra/protocol/response.rb +3 -4
  77. data/lib/cassandra/protocol/responses/already_exists_error_response.rb +12 -2
  78. data/lib/cassandra/protocol/responses/auth_challenge_response.rb +4 -5
  79. data/lib/cassandra/protocol/responses/auth_success_response.rb +4 -5
  80. data/lib/cassandra/protocol/responses/authenticate_response.rb +4 -5
  81. data/lib/cassandra/protocol/responses/error_response.rb +104 -17
  82. data/lib/cassandra/protocol/responses/event_response.rb +3 -4
  83. data/lib/cassandra/protocol/responses/function_failure_error_response.rb +13 -2
  84. data/lib/cassandra/protocol/responses/prepared_result_response.rb +14 -9
  85. data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +14 -9
  86. data/lib/cassandra/protocol/responses/read_failure_error_response.rb +26 -4
  87. data/lib/cassandra/protocol/responses/read_timeout_error_response.rb +22 -3
  88. data/lib/cassandra/protocol/responses/ready_response.rb +6 -7
  89. data/lib/cassandra/protocol/responses/result_response.rb +11 -10
  90. data/lib/cassandra/protocol/responses/rows_result_response.rb +8 -7
  91. data/lib/cassandra/protocol/responses/schema_change_event_response.rb +8 -8
  92. data/lib/cassandra/protocol/responses/schema_change_result_response.rb +19 -13
  93. data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +5 -6
  94. data/lib/cassandra/protocol/responses/status_change_event_response.rb +5 -6
  95. data/lib/cassandra/protocol/responses/supported_response.rb +4 -5
  96. data/lib/cassandra/protocol/responses/topology_change_event_response.rb +4 -5
  97. data/lib/cassandra/protocol/responses/unavailable_error_response.rb +20 -3
  98. data/lib/cassandra/protocol/responses/unprepared_error_response.rb +11 -2
  99. data/lib/cassandra/protocol/responses/void_result_response.rb +4 -5
  100. data/lib/cassandra/protocol/responses/write_failure_error_response.rb +26 -4
  101. data/lib/cassandra/protocol/responses/write_timeout_error_response.rb +22 -3
  102. data/lib/cassandra/protocol/v1.rb +98 -37
  103. data/lib/cassandra/protocol/v3.rb +121 -50
  104. data/lib/cassandra/protocol/v4.rb +172 -68
  105. data/lib/cassandra/reconnection.rb +1 -1
  106. data/lib/cassandra/reconnection/policies.rb +1 -1
  107. data/lib/cassandra/reconnection/policies/constant.rb +2 -4
  108. data/lib/cassandra/reconnection/policies/exponential.rb +6 -6
  109. data/lib/cassandra/result.rb +55 -20
  110. data/lib/cassandra/retry.rb +8 -8
  111. data/lib/cassandra/retry/policies.rb +1 -1
  112. data/lib/cassandra/retry/policies/default.rb +1 -1
  113. data/lib/cassandra/retry/policies/downgrading_consistency.rb +4 -2
  114. data/lib/cassandra/retry/policies/fallthrough.rb +1 -1
  115. data/lib/cassandra/session.rb +24 -16
  116. data/lib/cassandra/statement.rb +1 -1
  117. data/lib/cassandra/statements.rb +1 -1
  118. data/lib/cassandra/statements/batch.rb +16 -10
  119. data/lib/cassandra/statements/bound.rb +10 -3
  120. data/lib/cassandra/statements/prepared.rb +62 -18
  121. data/lib/cassandra/statements/simple.rb +23 -10
  122. data/lib/cassandra/statements/void.rb +1 -1
  123. data/lib/cassandra/table.rb +53 -185
  124. data/lib/cassandra/time.rb +11 -6
  125. data/lib/cassandra/time_uuid.rb +12 -14
  126. data/lib/cassandra/timestamp_generator.rb +37 -0
  127. data/lib/cassandra/timestamp_generator/simple.rb +38 -0
  128. data/lib/cassandra/timestamp_generator/ticking_on_duplicate.rb +58 -0
  129. data/lib/cassandra/tuple.rb +4 -4
  130. data/lib/cassandra/types.rb +109 -71
  131. data/lib/cassandra/udt.rb +66 -50
  132. data/lib/cassandra/util.rb +155 -15
  133. data/lib/cassandra/uuid.rb +20 -21
  134. data/lib/cassandra/uuid/generator.rb +7 -5
  135. data/lib/cassandra/version.rb +2 -2
  136. data/lib/cassandra_murmur3.jar +0 -0
  137. data/lib/datastax/cassandra.rb +1 -1
  138. metadata +27 -16
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  #--
4
- # Copyright 2013-2015 DataStax, Inc.
4
+ # Copyright 2013-2016 DataStax, Inc.
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
@@ -40,9 +40,7 @@ module Cassandra
40
40
  private
41
41
 
42
42
  def lookup_type(node, types)
43
- if node.name == 'frozen'
44
- return lookup_type(node.children.first, types)
45
- end
43
+ return lookup_type(node.children.first, types) if node.name == 'frozen'
46
44
 
47
45
  case node.name
48
46
  when 'text' then Cassandra::Types.text
@@ -64,13 +62,20 @@ module Cassandra
64
62
  when 'smallint' then Cassandra::Types.smallint
65
63
  when 'time' then Cassandra::Types.time
66
64
  when 'tinyint' then Cassandra::Types.tinyint
67
- when 'map' then Cassandra::Types.map(*node.children.map { |t| lookup_type(t, types)})
68
- when 'set' then Cassandra::Types.set(lookup_type(node.children.first, types))
69
- when 'list' then Cassandra::Types.list(lookup_type(node.children.first, types))
70
- when 'tuple' then Cassandra::Types.tuple(*node.children.map { |t| lookup_type(t, types)})
71
- when 'empty' then Cassandra::Types.custom('org.apache.cassandra.db.marshal.EmptyType')
65
+ when 'map' then
66
+ Cassandra::Types.map(*node.children.map { |t| lookup_type(t, types)})
67
+ when 'set' then
68
+ Cassandra::Types.set(lookup_type(node.children.first, types))
69
+ when 'list' then
70
+ Cassandra::Types.list(lookup_type(node.children.first, types))
71
+ when 'tuple' then
72
+ Cassandra::Types.tuple(*node.children.map { |t| lookup_type(t, types)})
73
+ when 'empty' then
74
+ Cassandra::Types.custom('org.apache.cassandra.db.marshal.EmptyType')
72
75
  else
73
- types.fetch(node.name) { raise IncompleteTypeError, "unable to lookup type #{node.name.inspect}" }
76
+ types.fetch(node.name) do
77
+ raise IncompleteTypeError, "unable to lookup type #{node.name.inspect}"
78
+ end
74
79
  end
75
80
  end
76
81
 
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  #--
4
- # Copyright 2013-2015 DataStax, Inc.
4
+ # Copyright 2013-2016 DataStax, Inc.
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
@@ -26,20 +26,23 @@ module Cassandra
26
26
  COMPRESSION_PACKAGE_PREFIX = 'org.apache.cassandra.io.compress.'.freeze
27
27
 
28
28
  def fetch(connection)
29
+ # rubocop:disable Metrics/LineLength
29
30
  Ione::Future.all(select_keyspaces(connection),
30
31
  select_tables(connection),
31
32
  select_columns(connection),
32
33
  select_types(connection),
33
34
  select_functions(connection),
34
- select_aggregates(connection))
35
- .map do |(rows_keyspaces, rows_tables, rows_columns,
36
- rows_types, rows_functions, rows_aggregates)|
37
-
35
+ select_aggregates(connection),
36
+ select_materialized_views(connection),
37
+ select_indexes(connection))
38
+ .map do |rows_keyspaces, rows_tables, rows_columns, rows_types, rows_functions, rows_aggregates, rows_views, rows_indexes|
38
39
  lookup_tables = map_rows_by(rows_tables, 'keyspace_name')
39
40
  lookup_columns = map_rows_by(rows_columns, 'keyspace_name')
40
41
  lookup_types = map_rows_by(rows_types, 'keyspace_name')
41
42
  lookup_functions = map_rows_by(rows_functions, 'keyspace_name')
42
43
  lookup_aggregates = map_rows_by(rows_aggregates, 'keyspace_name')
44
+ lookup_views = map_rows_by(rows_views, 'keyspace_name')
45
+ lookup_indexes = map_rows_by(rows_indexes, 'keyspace_name')
43
46
 
44
47
  rows_keyspaces.map do |keyspace_data|
45
48
  name = keyspace_data['keyspace_name']
@@ -49,7 +52,9 @@ module Cassandra
49
52
  lookup_columns[name],
50
53
  lookup_types[name],
51
54
  lookup_functions[name],
52
- lookup_aggregates[name])
55
+ lookup_aggregates[name],
56
+ lookup_views[name],
57
+ lookup_indexes[name])
53
58
  end
54
59
  end
55
60
  end
@@ -60,9 +65,10 @@ module Cassandra
60
65
  select_keyspace_columns(connection, keyspace_name),
61
66
  select_keyspace_types(connection, keyspace_name),
62
67
  select_keyspace_functions(connection, keyspace_name),
63
- select_keyspace_aggregates(connection, keyspace_name))
64
- .map do |(rows_keyspaces, rows_tables, rows_columns,
65
- rows_types, rows_functions, rows_aggregates)|
68
+ select_keyspace_aggregates(connection, keyspace_name),
69
+ select_keyspace_materialized_views(connection, keyspace_name),
70
+ select_keyspace_indexes(connection, keyspace_name))
71
+ .map do |rows_keyspaces, rows_tables, rows_columns, rows_types, rows_functions, rows_aggregates, rows_views, rows_indexes|
66
72
  if rows_keyspaces.empty?
67
73
  nil
68
74
  else
@@ -71,20 +77,40 @@ module Cassandra
71
77
  rows_columns,
72
78
  rows_types,
73
79
  rows_functions,
74
- rows_aggregates)
80
+ rows_aggregates,
81
+ rows_views,
82
+ rows_indexes)
75
83
  end
76
84
  end
77
85
  end
78
86
 
79
87
  def fetch_table(connection, keyspace_name, table_name)
80
88
  Ione::Future.all(select_table(connection, keyspace_name, table_name),
81
- select_table_columns(connection, keyspace_name, table_name))
82
- .map do |(rows_tables, rows_columns)|
89
+ select_table_columns(connection, keyspace_name, table_name),
90
+ select_table_indexes(connection, keyspace_name, table_name))
91
+ .map do |(rows_tables, rows_columns, rows_indexes)|
83
92
  if rows_tables.empty?
84
93
  nil
85
94
  else
86
95
  create_table(rows_tables.first,
87
- rows_columns)
96
+ rows_columns,
97
+ rows_indexes)
98
+ end
99
+ end
100
+ end
101
+
102
+ def fetch_materialized_view(connection, keyspace_name, view_name)
103
+ Ione::Future.all(select_materialized_view(connection, keyspace_name, view_name),
104
+ select_table_columns(connection, keyspace_name, view_name))
105
+ .map do |rows_views, rows_columns|
106
+ if rows_views.empty?
107
+ nil
108
+ else
109
+ view_row = rows_views.first
110
+ base_table = @schema.keyspace(keyspace_name).table(view_row['base_table_name'])
111
+ create_materialized_view(view_row,
112
+ rows_columns,
113
+ base_table)
88
114
  end
89
115
  end
90
116
  end
@@ -100,7 +126,8 @@ module Cassandra
100
126
  end
101
127
 
102
128
  def fetch_function(connection, keyspace_name, function_name, function_args)
103
- select_function(connection, keyspace_name, function_name, function_args).map do |rows_functions|
129
+ select_function(connection, keyspace_name, function_name, function_args)
130
+ .map do |rows_functions|
104
131
  if rows_functions.empty?
105
132
  nil
106
133
  else
@@ -110,11 +137,13 @@ module Cassandra
110
137
  end
111
138
 
112
139
  def fetch_aggregate(connection, keyspace_name, aggregate_name, aggregate_args)
113
- select_aggregate(connection, keyspace_name, aggregate_name, aggregate_args).map do |rows_aggregates|
140
+ select_aggregate(connection, keyspace_name, aggregate_name, aggregate_args)
141
+ .map do |rows_aggregates|
114
142
  if rows_aggregates.empty?
115
143
  nil
116
144
  else
117
- create_aggregate(rows_aggregates.first, @schema.keyspace(keyspace_name).send(:raw_functions))
145
+ create_aggregate(rows_aggregates.first, @schema.keyspace(keyspace_name)
146
+ .send(:raw_functions))
118
147
  end
119
148
  end
120
149
  end
@@ -129,10 +158,18 @@ module Cassandra
129
158
  FUTURE_EMPTY_LIST
130
159
  end
131
160
 
161
+ def select_materialized_views(connection)
162
+ FUTURE_EMPTY_LIST
163
+ end
164
+
132
165
  def select_columns(connection)
133
166
  FUTURE_EMPTY_LIST
134
167
  end
135
168
 
169
+ def select_indexes(connection)
170
+ FUTURE_EMPTY_LIST
171
+ end
172
+
136
173
  def select_types(connection)
137
174
  FUTURE_EMPTY_LIST
138
175
  end
@@ -153,10 +190,18 @@ module Cassandra
153
190
  FUTURE_EMPTY_LIST
154
191
  end
155
192
 
193
+ def select_keyspace_materialized_views(connection, keyspace_name)
194
+ FUTURE_EMPTY_LIST
195
+ end
196
+
156
197
  def select_keyspace_columns(connection, keyspace_name)
157
198
  FUTURE_EMPTY_LIST
158
199
  end
159
200
 
201
+ def select_keyspace_indexes(connection, keyspace_name)
202
+ FUTURE_EMPTY_LIST
203
+ end
204
+
160
205
  def select_keyspace_types(connection, keyspace_name)
161
206
  FUTURE_EMPTY_LIST
162
207
  end
@@ -173,10 +218,18 @@ module Cassandra
173
218
  FUTURE_EMPTY_LIST
174
219
  end
175
220
 
221
+ def select_materialized_view(connection, keyspace_name, view_name)
222
+ FUTURE_EMPTY_LIST
223
+ end
224
+
176
225
  def select_table_columns(connection, keyspace_name, table_name)
177
226
  FUTURE_EMPTY_LIST
178
227
  end
179
228
 
229
+ def select_table_indexes(connection, keyspace_name, table_name)
230
+ FUTURE_EMPTY_LIST
231
+ end
232
+
180
233
  def select_type(connection, keyspace_name, type_name)
181
234
  FUTURE_EMPTY_LIST
182
235
  end
@@ -191,7 +244,8 @@ module Cassandra
191
244
 
192
245
  def send_select_request(connection, cql, params = EMPTY_LIST, types = EMPTY_LIST)
193
246
  backtrace = caller
194
- connection.send_request(Protocol::QueryRequest.new(cql, params, types, :one)).map do |r|
247
+ connection.send_request(
248
+ Protocol::QueryRequest.new(cql, params, types, :one)).map do |r|
195
249
  case r
196
250
  when Protocol::RowsResultResponse
197
251
  r.rows
@@ -208,30 +262,44 @@ module Cassandra
208
262
  def map_rows_by(rows, key_name, &block)
209
263
  rows.each_with_object(::Hash.new { EMPTY_LIST }) do |row, map|
210
264
  key = row[key_name]
211
- map[key] = [] unless map.has_key?(key)
265
+ map[key] = [] unless map.key?(key)
212
266
 
213
- if block
214
- map[key] << yield(row)
215
- else
216
- map[key] << row
217
- end
267
+ map[key] << if block
268
+ yield(row)
269
+ else
270
+ row
271
+ end
218
272
  end
219
273
  end
220
274
  end
221
275
 
222
276
  # @private
223
277
  module Fetchers
278
+ # rubocop:disable Style/ClassAndModuleCamelCase
224
279
  class V1_2_x
225
280
  SELECT_KEYSPACES = 'SELECT * FROM system.schema_keyspaces'.freeze
226
281
  SELECT_TABLES = 'SELECT * FROM system.schema_columnfamilies'.freeze
227
282
  SELECT_COLUMNS = 'SELECT * FROM system.schema_columns'.freeze
228
- SELECT_KEYSPACE = 'SELECT * FROM system.schema_keyspaces WHERE keyspace_name = \'%s\''.freeze
229
- SELECT_KEYSPACE_TABLES = 'SELECT * FROM system.schema_columnfamilies WHERE keyspace_name = \'%s\''.freeze
230
- SELECT_KEYSPACE_COLUMNS = 'SELECT * FROM system.schema_columns WHERE keyspace_name = \'%s\''.freeze
231
- SELECT_TABLE = 'SELECT * FROM system.schema_columnfamilies WHERE keyspace_name = \'%s\' AND columnfamily_name = \'%s\''.freeze
232
- SELECT_TABLE_COLUMNS = 'SELECT * FROM system.schema_columns WHERE keyspace_name = \'%s\' AND columnfamily_name = \'%s\''.freeze
233
-
234
- include Fetcher
283
+ SELECT_KEYSPACE =
284
+ 'SELECT * ' \
285
+ 'FROM system.schema_keyspaces ' \
286
+ 'WHERE keyspace_name = \'%s\''.freeze
287
+ SELECT_KEYSPACE_TABLES =
288
+ 'SELECT * ' \
289
+ 'FROM system.schema_columnfamilies ' \
290
+ 'WHERE keyspace_name = \'%s\''.freeze
291
+ SELECT_KEYSPACE_COLUMNS =
292
+ 'SELECT * FROM system.schema_columns WHERE keyspace_name = \'%s\''.freeze
293
+ SELECT_TABLE =
294
+ 'SELECT * ' \
295
+ 'FROM system.schema_columnfamilies ' \
296
+ 'WHERE keyspace_name = \'%s\' AND columnfamily_name = \'%s\''.freeze
297
+ SELECT_TABLE_COLUMNS =
298
+ 'SELECT * ' \
299
+ 'FROM system.schema_columns ' \
300
+ 'WHERE keyspace_name = \'%s\' AND columnfamily_name = \'%s\''.freeze
301
+
302
+ include Cassandra::Cluster::Schema::Fetcher
235
303
 
236
304
  def initialize(type_parser, schema)
237
305
  @type_parser = type_parser
@@ -257,19 +325,20 @@ module Cassandra
257
325
  end
258
326
 
259
327
  def select_keyspace_tables(connection, keyspace_name)
260
- send_select_request(connection, SELECT_KEYSPACE_TABLES % keyspace_name)
328
+ send_select_request(connection, format(SELECT_KEYSPACE_TABLES, keyspace_name))
261
329
  end
262
330
 
263
331
  def select_keyspace_columns(connection, keyspace_name)
264
- send_select_request(connection, SELECT_KEYSPACE_COLUMNS % keyspace_name)
332
+ send_select_request(connection, format(SELECT_KEYSPACE_COLUMNS, keyspace_name))
265
333
  end
266
334
 
267
335
  def select_table(connection, keyspace_name, table_name)
268
- send_select_request(connection, SELECT_TABLE % [keyspace_name, table_name])
336
+ send_select_request(connection, format(SELECT_TABLE, keyspace_name, table_name))
269
337
  end
270
338
 
271
339
  def select_table_columns(connection, keyspace_name, table_name)
272
- send_select_request(connection, SELECT_TABLE_COLUMNS % [keyspace_name, table_name])
340
+ send_select_request(connection,
341
+ format(SELECT_TABLE_COLUMNS, keyspace_name, table_name))
273
342
  end
274
343
 
275
344
  def create_replication(keyspace_data)
@@ -280,50 +349,66 @@ module Cassandra
280
349
  end
281
350
 
282
351
  def create_keyspace(keyspace_data, rows_tables, rows_columns,
283
- rows_types, rows_functions, rows_aggregates)
352
+ rows_types, rows_functions, rows_aggregates,
353
+ rows_views, rows_indexes)
284
354
  keyspace_name = keyspace_data['keyspace_name']
285
355
  replication = create_replication(keyspace_data)
286
- types = rows_types.each_with_object({}) do |row, types|
287
- types[row['type_name']] = create_type(row)
288
- end
289
-
290
- # We want the functions hash to be keyed on [name, arg-types-list].
291
- # Similarly for the aggregates hash.
356
+ types = rows_types.each_with_object({}) do |row, h|
357
+ h[row['type_name']] = create_type(row)
358
+ end
292
359
 
293
- functions = rows_functions.each_with_object({}) do |row, collector|
294
- func = create_function(row)
295
- collector[[func.name, func.argument_types]] = func
360
+ # Create a FunctionCollection for the functions and aggregates.
361
+ functions = Cassandra::FunctionCollection.new
362
+ rows_functions.each do |row|
363
+ functions.add_or_update(create_function(row))
296
364
  end
297
365
 
298
- aggregates = rows_aggregates.each_with_object({}) do |row, collector|
299
- agg = create_aggregate(row, functions)
300
- collector[[agg.name, agg.argument_types]] = agg
301
- end
366
+ aggregates = Cassandra::FunctionCollection.new
367
+ rows_aggregates.each do |row|
368
+ aggregates.add_or_update(create_aggregate(row, functions))
369
+ end
302
370
 
303
371
  lookup_columns = map_rows_by(rows_columns, 'columnfamily_name')
304
- tables = rows_tables.each_with_object({}) do |row, tables|
372
+ tables = rows_tables.each_with_object({}) do |row, h|
305
373
  table_name = row['columnfamily_name']
306
- tables[table_name] = create_table(row, lookup_columns[table_name])
374
+ # rows_indexes is nil for C* < 3.0.
375
+ h[table_name] = create_table(row, lookup_columns[table_name], nil)
307
376
  end
308
377
 
309
- Keyspace.new(keyspace_name, keyspace_data['durable_writes'],
310
- replication, tables, types, functions, aggregates)
378
+ Keyspace.new(keyspace_name,
379
+ keyspace_data['durable_writes'],
380
+ replication,
381
+ tables,
382
+ types,
383
+ functions,
384
+ aggregates,
385
+ {})
311
386
  end
312
387
 
313
- def create_table(table_data, rows_columns)
388
+ def create_table(table_data, rows_columns, rows_indexes)
314
389
  keyspace_name = table_data['keyspace_name']
315
390
  table_name = table_data['columnfamily_name']
316
391
  key_validator = @type_parser.parse(table_data['key_validator'])
317
392
  comparator = @type_parser.parse(table_data['comparator'])
318
393
  column_aliases = ::JSON.load(table_data['column_aliases'])
319
394
 
320
- if !comparator.collections.nil?
395
+ if comparator.collections.nil?
396
+ is_compact = true
397
+ if !column_aliases.empty? || rows_columns.empty?
398
+ has_value = true
399
+ clustering_size = comparator.results.size
400
+ else
401
+ has_value = false
402
+ clustering_size = 0
403
+ end
404
+ else
321
405
  size = comparator.results.size
322
406
  if !comparator.collections.empty?
323
407
  is_compact = false
324
408
  has_value = false
325
409
  clustering_size = size - 2
326
- elsif column_aliases.size == size - 1 && comparator.results.last.first == Cassandra::Types.varchar
410
+ elsif column_aliases.size == size - 1 &&
411
+ comparator.results.last.first == Cassandra::Types.varchar
327
412
  is_compact = false
328
413
  has_value = false
329
414
  clustering_size = size - 1
@@ -332,39 +417,32 @@ module Cassandra
332
417
  has_value = (!column_aliases.empty? || rows_columns.empty?)
333
418
  clustering_size = size
334
419
  end
335
- else
336
- is_compact = true
337
- if (!column_aliases.empty? || rows_columns.empty?)
338
- has_value = true
339
- clustering_size = comparator.results.size
340
- else
341
- has_value = false
342
- clustering_size = 0
343
- end
344
420
  end
345
421
 
422
+ # Separate out the partition-key, clustering-columns, and other-columns
346
423
  partition_key = []
347
424
  clustering_columns = []
348
425
  clustering_order = []
426
+ other_columns = []
349
427
 
350
428
  compaction_strategy = create_compaction_strategy(table_data)
351
- table_options = create_table_options(table_data, compaction_strategy, is_compact)
352
- table_columns = {}
353
- other_columns = []
429
+ table_options =
430
+ create_table_options(table_data, compaction_strategy, is_compact)
354
431
 
355
432
  key_aliases = ::JSON.load(table_data['key_aliases'])
356
433
 
357
434
  key_validator.results.each_with_index do |(type, order, is_frozen), i|
358
- key_alias = key_aliases.fetch(i) { i.zero? ? "key" : "key#{i + 1}" }
435
+ key_alias = key_aliases.fetch(i) { i.zero? ? 'key' : "key#{i + 1}" }
359
436
 
360
- partition_key[i] = Column.new(key_alias, type, order, nil, false, is_frozen)
437
+ partition_key[i] = Column.new(key_alias, type, order, false, is_frozen)
361
438
  end
362
439
 
363
440
  clustering_size.times do |i|
364
441
  column_alias = column_aliases.fetch(i) { "column#{i + 1}" }
365
442
  type, order, is_frozen = comparator.results.fetch(i)
366
443
 
367
- clustering_columns[i] = Column.new(column_alias, type, order, nil, false, is_frozen)
444
+ clustering_columns[i] =
445
+ Column.new(column_alias, type, order, false, is_frozen)
368
446
  clustering_order[i] = order
369
447
  end
370
448
 
@@ -373,59 +451,87 @@ module Cassandra
373
451
  value_alias ||= 'value'
374
452
 
375
453
  unless value_alias.empty?
376
- type, order, is_frozen = @type_parser.parse(table_data['default_validator']).results.first
377
- other_columns << Column.new(value_alias, type, order, nil, false, is_frozen)
454
+ type, order, is_frozen =
455
+ @type_parser.parse(table_data['default_validator']).results.first
456
+ other_columns <<
457
+ Column.new(value_alias, type, order, false, is_frozen)
378
458
  end
379
459
  end
380
460
 
461
+ index_rows = []
381
462
  rows_columns.each do |row|
382
- other_columns << create_column(row)
383
- end
463
+ column = create_column(row)
464
+ other_columns << column
384
465
 
385
- partition_key.each do |column|
386
- table_columns[column.name] = column
466
+ # In C* 1.2.x, index info is in the column metadata; rows_indexes is nil.
467
+ index_rows << [column, row] unless row['index_type'].nil?
387
468
  end
388
469
 
389
- clustering_columns.each do |column|
390
- table_columns[column.name] = column
470
+ table = Cassandra::Table.new(@schema.keyspace(keyspace_name),
471
+ table_name,
472
+ partition_key,
473
+ clustering_columns,
474
+ other_columns,
475
+ table_options,
476
+ clustering_order,
477
+ table_data['id'])
478
+
479
+ # Create Index objects and add them to the table.
480
+ index_rows.each do |column, row|
481
+ create_index(table, column, row)
391
482
  end
483
+ table
484
+ end
392
485
 
393
- other_columns.each do |column|
394
- table_columns[column.name] = column
486
+ def create_index(table, column, row_column)
487
+ # Most of this logic was taken from the Java driver.
488
+ options = {}
489
+ # For some versions of C*, this field could have a literal string 'null' value.
490
+ if !row_column['index_options'].nil? && row_column['index_options'] != 'null' && !row_column['index_options'].empty?
491
+ options = ::JSON.load(row_column['index_options'])
395
492
  end
396
-
397
- Table.new(keyspace_name, table_name, partition_key, clustering_columns,
398
- table_columns, table_options, clustering_order)
493
+ column_name = Util.escape_name(column.name)
494
+ target = if options.key?('index_keys')
495
+ "keys(#{column_name})"
496
+ elsif options.key?('index_keys_and_values')
497
+ "entries(#{column_name})"
498
+ elsif column.frozen? && (column.type == Cassandra::Types::Set ||
499
+ column.type == Cassandra::Types::List ||
500
+ column.type == Cassandra::Types::Map)
501
+ "full(#{column_name})"
502
+ else
503
+ column_name
504
+ end
505
+
506
+ table.add_index(Cassandra::Index.new(table,
507
+ row_column['index_name'],
508
+ row_column['index_type'].downcase.to_sym,
509
+ target,
510
+ options))
399
511
  end
400
512
 
401
513
  def create_column(column_data)
402
514
  name = column_data['column_name']
403
515
  is_static = (column_data['type'] == 'STATIC')
404
- type, order, is_frozen = @type_parser.parse(column_data['validator']).results.first
405
-
406
- if column_data['index_type'].nil?
407
- index = nil
408
- elsif column_data['index_type'].to_s.upcase == 'CUSTOM' || !column_data['index_options']
409
- index = Column::Index.new(column_data['index_name'])
410
- else
411
- options = ::JSON.load(column_data['index_options'])
412
- index = Column::Index.new(column_data['index_name'], options && options['class_name'])
413
- end
414
-
415
- Column.new(name, type, order, index, is_static, is_frozen)
516
+ type, order, is_frozen =
517
+ @type_parser.parse(column_data['validator']).results.first
518
+ Column.new(name, type, order, is_static, is_frozen)
416
519
  end
417
520
 
418
521
  def create_compaction_strategy(table_data)
419
522
  klass = table_data['compaction_strategy_class']
420
523
  klass.slice!('org.apache.cassandra.db.compaction.')
421
524
  options = ::JSON.load(table_data['compaction_strategy_options'])
422
- Table::Compaction.new(klass, options)
525
+ ColumnContainer::Compaction.new(klass, options)
423
526
  end
424
527
 
425
528
  def create_table_options(table_data, compaction_strategy, is_compact)
426
529
  compression_parameters = ::JSON.load(table_data['compression_parameters'])
427
- compression_parameters['sstable_compression'].slice!(COMPRESSION_PACKAGE_PREFIX) if compression_parameters['sstable_compression']
428
- Table::Options.new(
530
+ if compression_parameters['sstable_compression']
531
+ compression_parameters['sstable_compression']
532
+ .slice!(COMPRESSION_PACKAGE_PREFIX)
533
+ end
534
+ Cassandra::ColumnContainer::Options.new(
429
535
  table_data['comment'],
430
536
  table_data['read_repair_chance'],
431
537
  table_data['local_read_repair_chance'],
@@ -442,72 +548,87 @@ module Cassandra
442
548
  nil,
443
549
  compaction_strategy,
444
550
  compression_parameters,
445
- is_compact
551
+ is_compact,
552
+ table_data['crc_check_chance'],
553
+ table_data['extensions']
446
554
  )
447
555
  end
448
556
  end
449
557
 
450
558
  class V2_0_x < V1_2_x
451
- SELECT_KEYSPACE = 'SELECT * FROM system.schema_keyspaces WHERE keyspace_name = ?'.freeze
452
- SELECT_KEYSPACE_TABLES = 'SELECT * FROM system.schema_columnfamilies WHERE keyspace_name = ?'.freeze
453
- SELECT_KEYSPACE_COLUMNS = 'SELECT * FROM system.schema_columns WHERE keyspace_name = ?'.freeze
454
- SELECT_TABLE = 'SELECT * FROM system.schema_columnfamilies WHERE keyspace_name = ? AND columnfamily_name = ?'.freeze
455
- SELECT_TABLE_COLUMNS = 'SELECT * FROM system.schema_columns WHERE keyspace_name = ? AND columnfamily_name = ?'.freeze
559
+ SELECT_KEYSPACE =
560
+ 'SELECT * FROM system.schema_keyspaces WHERE keyspace_name = ?'.freeze
561
+ SELECT_KEYSPACE_TABLES =
562
+ 'SELECT * FROM system.schema_columnfamilies WHERE keyspace_name = ?'.freeze
563
+ SELECT_KEYSPACE_COLUMNS =
564
+ 'SELECT * FROM system.schema_columns WHERE keyspace_name = ?'.freeze
565
+ SELECT_TABLE =
566
+ 'SELECT * ' \
567
+ 'FROM system.schema_columnfamilies ' \
568
+ 'WHERE keyspace_name = ? AND columnfamily_name = ?'.freeze
569
+ SELECT_TABLE_COLUMNS =
570
+ 'SELECT * ' \
571
+ 'FROM system.schema_columns ' \
572
+ 'WHERE keyspace_name = ? AND columnfamily_name = ?'.freeze
456
573
 
457
574
  private
458
575
 
459
- def create_table(table_data, rows_columns)
576
+ def create_table(table_data, rows_columns, rows_indexes)
460
577
  keyspace_name = table_data['keyspace_name']
461
578
  table_name = table_data['columnfamily_name']
462
579
  comparator = @type_parser.parse(table_data['comparator'])
463
- table_columns = {}
464
- other_columns = []
465
580
  clustering_size = 0
466
581
 
582
+ # Separate out partition-key, clustering columns, other columns.
467
583
  partition_key = []
468
584
  clustering_columns = []
469
585
  clustering_order = []
586
+ other_columns = []
470
587
 
588
+ index_rows = []
471
589
  rows_columns.each do |row|
472
590
  next if row['column_name'].empty?
473
591
 
474
592
  column = create_column(row)
475
593
  type = row['type'].to_s
476
- index = row['component_index'] || 0
594
+ ind = row['component_index'] || 0
477
595
 
478
596
  case type.upcase
479
597
  when 'PARTITION_KEY'
480
- partition_key[index] = column
598
+ partition_key[ind] = column
481
599
  when 'CLUSTERING_KEY'
482
- clustering_columns[index] = column
483
- clustering_order[index] = column.order
600
+ clustering_columns[ind] = column
601
+ clustering_order[ind] = column.order
484
602
 
485
- if clustering_size.zero? || index == clustering_size
486
- clustering_size = index + 1
487
- end
603
+ clustering_size = ind + 1 if clustering_size.zero? || ind == clustering_size
488
604
  else
489
605
  other_columns << column
490
606
  end
491
- end
492
-
493
- partition_key.each do |column|
494
- table_columns[column.name] = column
495
- end
496
607
 
497
- clustering_columns.each do |column|
498
- table_columns[column.name] = column
499
- end
500
-
501
- other_columns.each do |column|
502
- table_columns[column.name] = column
608
+ # In C* 2.0.x, index info is in the column metadata; rows_indexes is nil.
609
+ index_rows << [column, row] unless row['index_type'].nil?
503
610
  end
504
611
 
505
612
  compaction_strategy = create_compaction_strategy(table_data)
506
- is_compact = (clustering_size != comparator.results.size - 1) || !comparator.collections
507
- table_options = create_table_options(table_data, compaction_strategy, is_compact)
508
-
509
- Table.new(keyspace_name, table_name, partition_key, clustering_columns,
510
- table_columns, table_options, clustering_order)
613
+ is_compact = (clustering_size != comparator.results.size - 1) ||
614
+ !comparator.collections
615
+ table_options =
616
+ create_table_options(table_data, compaction_strategy, is_compact)
617
+
618
+ table = Cassandra::Table.new(@schema.keyspace(keyspace_name),
619
+ table_name,
620
+ partition_key,
621
+ clustering_columns,
622
+ other_columns,
623
+ table_options,
624
+ clustering_order,
625
+ table_data['id'])
626
+
627
+ # Create Index objects and add them to the table.
628
+ index_rows.each do |column, row|
629
+ create_index(table, column, row)
630
+ end
631
+ table
511
632
  end
512
633
 
513
634
  def select_keyspace(connection, keyspace_name)
@@ -542,8 +663,11 @@ module Cassandra
542
663
 
543
664
  def create_table_options(table_data, compaction_strategy, is_compact)
544
665
  compression_parameters = ::JSON.load(table_data['compression_parameters'])
545
- compression_parameters['sstable_compression'].slice!(COMPRESSION_PACKAGE_PREFIX) if compression_parameters['sstable_compression']
546
- Table::Options.new(
666
+ if compression_parameters['sstable_compression']
667
+ compression_parameters['sstable_compression']
668
+ .slice!(COMPRESSION_PACKAGE_PREFIX)
669
+ end
670
+ Cassandra::ColumnContainer::Options.new(
547
671
  table_data['comment'],
548
672
  table_data['read_repair_chance'],
549
673
  table_data['local_read_repair_chance'],
@@ -560,15 +684,21 @@ module Cassandra
560
684
  nil,
561
685
  compaction_strategy,
562
686
  compression_parameters,
563
- is_compact
687
+ is_compact,
688
+ table_data['crc_check_chance'],
689
+ table_data['extensions']
564
690
  )
565
691
  end
566
692
  end
567
693
 
568
694
  class V2_1_x < V2_0_x
569
695
  SELECT_TYPES = 'SELECT * FROM system.schema_usertypes'.freeze
570
- SELECT_KEYSPACE_TYPES = 'SELECT * FROM system.schema_usertypes WHERE keyspace_name = ?'.freeze
571
- SELECT_TYPE = 'SELECT * FROM system.schema_usertypes WHERE keyspace_name = ? AND type_name = ?'.freeze
696
+ SELECT_KEYSPACE_TYPES =
697
+ 'SELECT * FROM system.schema_usertypes WHERE keyspace_name = ?'.freeze
698
+ SELECT_TYPE =
699
+ 'SELECT * ' \
700
+ 'FROM system.schema_usertypes ' \
701
+ 'WHERE keyspace_name = ? AND type_name = ?'.freeze
572
702
 
573
703
  private
574
704
 
@@ -607,8 +737,11 @@ module Cassandra
607
737
 
608
738
  def create_table_options(table_data, compaction_strategy, is_compact)
609
739
  compression_parameters = ::JSON.load(table_data['compression_parameters'])
610
- compression_parameters['sstable_compression'].slice!(COMPRESSION_PACKAGE_PREFIX) if compression_parameters['sstable_compression']
611
- Table::Options.new(
740
+ if compression_parameters['sstable_compression']
741
+ compression_parameters['sstable_compression']
742
+ .slice!(COMPRESSION_PACKAGE_PREFIX)
743
+ end
744
+ Cassandra::ColumnContainer::Options.new(
612
745
  table_data['comment'],
613
746
  table_data['read_repair_chance'],
614
747
  table_data['local_read_repair_chance'],
@@ -625,7 +758,9 @@ module Cassandra
625
758
  table_data['max_index_interval'],
626
759
  compaction_strategy,
627
760
  compression_parameters,
628
- is_compact
761
+ is_compact,
762
+ table_data['crc_check_chance'],
763
+ table_data['extensions']
629
764
  )
630
765
  end
631
766
  end
@@ -633,12 +768,23 @@ module Cassandra
633
768
  class V2_2_x < V2_1_x
634
769
  SELECT_FUNCTIONS = 'SELECT * FROM system.schema_functions'.freeze
635
770
  SELECT_AGGREGATES = 'SELECT * FROM system.schema_aggregates'.freeze
636
- SELECT_KEYSPACE_FUNCTIONS = 'SELECT * FROM system.schema_functions WHERE keyspace_name = ?'.freeze
637
- SELECT_KEYSPACE_AGGREGATES = 'SELECT * FROM system.schema_aggregates WHERE keyspace_name = ?'.freeze
638
- SELECT_FUNCTION = 'SELECT * FROM system.schema_functions WHERE keyspace_name = ? AND function_name = ? AND argument_types = ?'.freeze
639
- SELECT_AGGREGATE = 'SELECT * FROM system.schema_aggregates WHERE keyspace_name = ? AND aggregate_name = ? AND argument_types = ?'.freeze
640
-
641
- # parse an array of string argument types and return an array of [Cassandra::Type]s.
771
+ SELECT_KEYSPACE_FUNCTIONS =
772
+ 'SELECT * FROM system.schema_functions WHERE keyspace_name = ?'.freeze
773
+ SELECT_KEYSPACE_AGGREGATES =
774
+ 'SELECT * FROM system.schema_aggregates WHERE keyspace_name = ?'.freeze
775
+ SELECT_FUNCTION =
776
+ 'SELECT * ' \
777
+ 'FROM system.schema_functions ' \
778
+ 'WHERE keyspace_name = ? AND function_name = ? ' \
779
+ 'AND argument_types = ?'.freeze
780
+ SELECT_AGGREGATE =
781
+ 'SELECT * ' \
782
+ 'FROM system.schema_aggregates ' \
783
+ 'WHERE keyspace_name = ? AND aggregate_name = ? ' \
784
+ 'AND argument_types = ?'.freeze
785
+
786
+ # parse an array of string argument types and return an array of
787
+ # [Cassandra::Type]s.
642
788
  # @param connection a connection to a Cassandra node.
643
789
  # @param keyspace_name [String] name of the keyspace.
644
790
  # @param argument_types [Array<String>] array of argument types.
@@ -655,35 +801,59 @@ module Cassandra
655
801
  keyspace_name = function_data['keyspace_name']
656
802
  function_name = function_data['function_name']
657
803
  function_lang = function_data['language']
658
- function_type = @type_parser.parse(function_data['return_type']).results.first.first
804
+ function_type =
805
+ @type_parser.parse(function_data['return_type']).results.first.first
659
806
  function_body = function_data['body']
660
807
  called_on_null = function_data['called_on_null_input']
661
808
 
662
809
  arguments = []
663
810
 
664
- Array(function_data['argument_names']).zip(Array(function_data['argument_types'])) do |argument_name, fqcn|
811
+ Array(function_data['argument_names'])
812
+ .zip(Array(function_data['argument_types'])) do |argument_name, fqcn|
665
813
  argument_type = @type_parser.parse(fqcn).results.first.first
666
814
  arguments << Argument.new(argument_name, argument_type)
667
815
  end
668
816
 
669
- Function.new(keyspace_name, function_name, function_lang, function_type, arguments, function_body, called_on_null)
817
+ Cassandra::Function.new(keyspace_name,
818
+ function_name,
819
+ function_lang,
820
+ function_type,
821
+ arguments,
822
+ function_body,
823
+ called_on_null)
670
824
  end
671
825
 
672
826
  def create_aggregate(aggregate_data, functions)
673
827
  keyspace_name = aggregate_data['keyspace_name']
674
828
  aggregate_name = aggregate_data['aggregate_name']
675
- aggregate_type = @type_parser.parse(aggregate_data['return_type']).results.first.first
676
- argument_types = aggregate_data['argument_types'].map {|fqcn| @type_parser.parse(fqcn).results.first.first}.freeze
677
- state_type = @type_parser.parse(aggregate_data['state_type']).results.first.first
678
- initial_state = Util.encode_object(Protocol::Coder.read_value_v4(Protocol::CqlByteBuffer.new.append_bytes(aggregate_data['initcond']), state_type))
829
+ aggregate_type =
830
+ @type_parser.parse(aggregate_data['return_type']).results.first.first
831
+ argument_types = aggregate_data['argument_types'].map do |fqcn|
832
+ @type_parser.parse(fqcn).results.first.first
833
+ end.freeze
834
+ state_type =
835
+ @type_parser.parse(aggregate_data['state_type']).results.first.first
836
+ initial_state = Util.encode_object(
837
+ Protocol::Coder.read_value_v4(
838
+ Protocol::CqlByteBuffer.new.append_bytes(aggregate_data['initcond']),
839
+ state_type))
679
840
 
680
841
  # The state-function takes arguments: first the stype, then the args of the aggregate.
681
- state_function = functions[[aggregate_data['state_func'], [state_type].concat(argument_types)]]
842
+ state_function = functions.get(aggregate_data['state_func'],
843
+ [state_type].concat(argument_types))
682
844
 
683
845
  # The final-function takes an stype argument.
684
- final_function = functions[[aggregate_data['final_func'], [state_type]]]
846
+ final_function = functions.get(aggregate_data['final_func'],
847
+ [state_type])
685
848
 
686
- Aggregate.new(keyspace_name, aggregate_name, aggregate_type, argument_types, state_type, initial_state, state_function, final_function)
849
+ Aggregate.new(keyspace_name,
850
+ aggregate_name,
851
+ aggregate_type,
852
+ argument_types,
853
+ state_type,
854
+ initial_state,
855
+ state_function,
856
+ final_function)
687
857
  end
688
858
 
689
859
  def select_functions(connection)
@@ -720,32 +890,69 @@ module Cassandra
720
890
  end
721
891
 
722
892
  class V3_0_x < V2_2_x
723
- SELECT_KEYSPACES = "SELECT * FROM system_schema.keyspaces".freeze
724
- SELECT_TABLES = "SELECT * FROM system_schema.tables".freeze
725
- SELECT_COLUMNS = "SELECT * FROM system_schema.columns".freeze
726
- SELECT_TYPES = "SELECT * FROM system_schema.types".freeze
727
- SELECT_FUNCTIONS = "SELECT * FROM system_schema.functions".freeze
728
- SELECT_AGGREGATES = "SELECT * FROM system_schema.aggregates".freeze
729
- SELECT_INDEXES = "SELECT * FROM system_schema.indexes".freeze
730
- SELECT_VIEWS = "SELECT * FROM system_schema.materialized_views".freeze
731
-
732
- SELECT_KEYSPACE = 'SELECT * FROM system_schema.keyspaces WHERE keyspace_name = ?'.freeze
733
- SELECT_KEYSPACE_TABLES = 'SELECT * FROM system_schema.tables WHERE keyspace_name = ?'.freeze
734
- SELECT_KEYSPACE_COLUMNS = 'SELECT * FROM system_schema.columns WHERE keyspace_name = ?'.freeze
735
- SELECT_KEYSPACE_TYPES = "SELECT * FROM system_schema.types WHERE keyspace_name = ?".freeze
736
- SELECT_KEYSPACE_FUNCTIONS = 'SELECT * FROM system_schema.functions WHERE keyspace_name = ?'.freeze
737
- SELECT_KEYSPACE_AGGREGATES = 'SELECT * FROM system_schema.aggregates WHERE keyspace_name = ?'.freeze
738
-
739
- SELECT_TABLE = 'SELECT * FROM system_schema.tables WHERE keyspace_name = ? AND table_name = ?'.freeze
740
- SELECT_TABLE_COLUMNS = 'SELECT * FROM system_schema.columns WHERE keyspace_name = ? AND table_name = ?'.freeze
741
-
742
- SELECT_TYPE = 'SELECT * FROM system_schema.types WHERE keyspace_name = ? AND type_name = ?'.freeze
743
-
744
- SELECT_FUNCTION = 'SELECT * FROM system_schema.functions WHERE keyspace_name = ? AND function_name = ? AND argument_types = ?'.freeze
745
-
746
- SELECT_AGGREGATE = 'SELECT * FROM system_schema.aggregates WHERE keyspace_name = ? AND aggregate_name = ? AND argument_types = ?'.freeze
747
-
748
- # parse an array of string argument types and return an array of [Cassandra::Type]s.
893
+ SELECT_KEYSPACES = 'SELECT * FROM system_schema.keyspaces'.freeze
894
+ SELECT_TABLES = 'SELECT * FROM system_schema.tables'.freeze
895
+ SELECT_COLUMNS = 'SELECT * FROM system_schema.columns'.freeze
896
+ SELECT_TYPES = 'SELECT * FROM system_schema.types'.freeze
897
+ SELECT_FUNCTIONS = 'SELECT * FROM system_schema.functions'.freeze
898
+ SELECT_AGGREGATES = 'SELECT * FROM system_schema.aggregates'.freeze
899
+ SELECT_INDEXES = 'SELECT * FROM system_schema.indexes'.freeze
900
+ SELECT_VIEWS = 'SELECT * FROM system_schema.views'.freeze
901
+
902
+ SELECT_KEYSPACE =
903
+ 'SELECT * FROM system_schema.keyspaces WHERE keyspace_name = ?'.freeze
904
+ SELECT_KEYSPACE_TABLES =
905
+ 'SELECT * FROM system_schema.tables WHERE keyspace_name = ?'.freeze
906
+ SELECT_KEYSPACE_INDEXES =
907
+ 'SELECT * FROM system_schema.indexes WHERE keyspace_name = ?'.freeze
908
+ SELECT_KEYSPACE_COLUMNS =
909
+ 'SELECT * FROM system_schema.columns WHERE keyspace_name = ?'.freeze
910
+ SELECT_KEYSPACE_VIEWS =
911
+ 'SELECT * FROM system_schema.views WHERE keyspace_name = ?'.freeze
912
+ SELECT_KEYSPACE_TYPES =
913
+ 'SELECT * FROM system_schema.types WHERE keyspace_name = ?'.freeze
914
+ SELECT_KEYSPACE_FUNCTIONS =
915
+ 'SELECT * FROM system_schema.functions WHERE keyspace_name = ?'.freeze
916
+ SELECT_KEYSPACE_AGGREGATES =
917
+ 'SELECT * FROM system_schema.aggregates WHERE keyspace_name = ?'.freeze
918
+
919
+ SELECT_TABLE =
920
+ 'SELECT * ' \
921
+ 'FROM system_schema.tables ' \
922
+ 'WHERE keyspace_name = ? AND table_name = ?'.freeze
923
+ SELECT_TABLE_COLUMNS =
924
+ 'SELECT * ' \
925
+ 'FROM system_schema.columns ' \
926
+ 'WHERE keyspace_name = ? AND table_name = ?'.freeze
927
+ SELECT_TABLE_INDEXES =
928
+ 'SELECT * ' \
929
+ 'FROM system_schema.indexes ' \
930
+ 'WHERE keyspace_name = ? AND table_name = ?'.freeze
931
+
932
+ SELECT_VIEW =
933
+ 'SELECT * ' \
934
+ 'FROM system_schema.views ' \
935
+ 'WHERE keyspace_name = ? AND view_name = ?'.freeze
936
+
937
+ SELECT_TYPE =
938
+ 'SELECT * ' \
939
+ 'FROM system_schema.types ' \
940
+ 'WHERE keyspace_name = ? AND type_name = ?'.freeze
941
+
942
+ SELECT_FUNCTION =
943
+ 'SELECT * ' \
944
+ 'FROM system_schema.functions ' \
945
+ 'WHERE keyspace_name = ? AND function_name = ? ' \
946
+ 'AND argument_types = ?'.freeze
947
+
948
+ SELECT_AGGREGATE =
949
+ 'SELECT * ' \
950
+ 'FROM system_schema.aggregates ' \
951
+ 'WHERE keyspace_name = ? AND aggregate_name = ? ' \
952
+ 'AND argument_types = ?'.freeze
953
+
954
+ # parse an array of string argument types and return an array of
955
+ # [Cassandra::Type]s.
749
956
  # @param connection a connection to a Cassandra node.
750
957
  # @param keyspace_name [String] name of the keyspace.
751
958
  # @param argument_types [Array<String>] array of argument types.
@@ -767,6 +974,14 @@ module Cassandra
767
974
  send_select_request(connection, SELECT_TABLES)
768
975
  end
769
976
 
977
+ def select_indexes(connection)
978
+ send_select_request(connection, SELECT_INDEXES)
979
+ end
980
+
981
+ def select_materialized_views(connection)
982
+ send_select_request(connection, SELECT_VIEWS)
983
+ end
984
+
770
985
  def select_columns(connection)
771
986
  send_select_request(connection, SELECT_COLUMNS)
772
987
  end
@@ -801,6 +1016,18 @@ module Cassandra
801
1016
  send_select_request(connection, SELECT_KEYSPACE_COLUMNS, params, hints)
802
1017
  end
803
1018
 
1019
+ def select_keyspace_indexes(connection, keyspace_name)
1020
+ params = [keyspace_name]
1021
+ hints = [Types.varchar]
1022
+ send_select_request(connection, SELECT_KEYSPACE_INDEXES, params, hints)
1023
+ end
1024
+
1025
+ def select_keyspace_materialized_views(connection, keyspace_name)
1026
+ params = [keyspace_name]
1027
+ hints = [Types.varchar]
1028
+ send_select_request(connection, SELECT_KEYSPACE_VIEWS, params, hints)
1029
+ end
1030
+
804
1031
  def select_keyspace_types(connection, keyspace_name)
805
1032
  params = [keyspace_name]
806
1033
  hints = [Types.varchar]
@@ -826,11 +1053,26 @@ module Cassandra
826
1053
  end
827
1054
 
828
1055
  def select_table_columns(connection, keyspace_name, table_name)
1056
+ # This is identical to the 2.0 impl, but the SELECT_TABLE_COLUMNS query
1057
+ # is different between the two, so we need two impls. :(
1058
+ # Also, this method works fine for finding view columns as well.
829
1059
  params = [keyspace_name, table_name]
830
1060
  hints = [Types.varchar, Types.varchar]
831
1061
  send_select_request(connection, SELECT_TABLE_COLUMNS, params, hints)
832
1062
  end
833
1063
 
1064
+ def select_table_indexes(connection, keyspace_name, table_name)
1065
+ params = [keyspace_name, table_name]
1066
+ hints = [Types.varchar, Types.varchar]
1067
+ send_select_request(connection, SELECT_TABLE_INDEXES, params, hints)
1068
+ end
1069
+
1070
+ def select_materialized_view(connection, keyspace_name, view_name)
1071
+ params = [keyspace_name, view_name]
1072
+ hints = [Types.varchar, Types.varchar]
1073
+ send_select_request(connection, SELECT_VIEW, params, hints)
1074
+ end
1075
+
834
1076
  def select_type(connection, keyspace_name, type_name)
835
1077
  params = [keyspace_name, type_name]
836
1078
  hints = [Types.varchar, Types.varchar]
@@ -860,29 +1102,50 @@ module Cassandra
860
1102
 
861
1103
  arguments = []
862
1104
 
863
- function_data['argument_names'].zip(function_data['argument_types']) do |argument_name, argument_type|
864
- arguments << Argument.new(argument_name, @type_parser.parse(argument_type, types).first)
1105
+ function_data['argument_names']
1106
+ .zip(function_data['argument_types']) do |argument_name, argument_type|
1107
+ arguments << Argument.new(argument_name,
1108
+ @type_parser.parse(argument_type, types).first)
865
1109
  end
866
1110
 
867
- Function.new(keyspace_name, function_name, function_lang, function_type, arguments, function_body, called_on_null)
1111
+ Cassandra::Function.new(keyspace_name,
1112
+ function_name,
1113
+ function_lang,
1114
+ function_type,
1115
+ arguments,
1116
+ function_body,
1117
+ called_on_null)
868
1118
  end
869
1119
 
870
1120
  def create_aggregate(aggregate_data, functions, types = nil)
871
1121
  keyspace_name = aggregate_data['keyspace_name']
872
1122
  aggregate_name = aggregate_data['aggregate_name']
873
1123
  types ||= @schema.keyspace(keyspace_name).send(:raw_types)
874
- aggregate_type = @type_parser.parse(aggregate_data['return_type'], types).first
875
- argument_types = aggregate_data['argument_types'].map {|argument_type| @type_parser.parse(argument_type, types).first}.freeze
1124
+ aggregate_type =
1125
+ @type_parser.parse(aggregate_data['return_type'], types).first
1126
+ argument_types = aggregate_data['argument_types'].map do |argument_type|
1127
+ @type_parser.parse(argument_type, types).first
1128
+ end.freeze
876
1129
  state_type = @type_parser.parse(aggregate_data['state_type'], types).first
877
1130
  initial_state = aggregate_data['initcond'] || 'null'
878
1131
 
879
- # The state-function takes arguments: first the stype, then the args of the aggregate.
880
- state_function = functions[[aggregate_data['state_func'], [state_type].concat(argument_types)]]
1132
+ # The state-function takes arguments: first the stype, then the args of the
1133
+ # aggregate.
1134
+ state_function = functions.get(aggregate_data['state_func'],
1135
+ [state_type].concat(argument_types))
881
1136
 
882
1137
  # The final-function takes an stype argument.
883
- final_function = functions[[aggregate_data['final_func'], [state_type]]]
1138
+ final_function = functions.get(aggregate_data['final_func'],
1139
+ [state_type])
884
1140
 
885
- Aggregate.new(keyspace_name, aggregate_name, aggregate_type, argument_types, state_type, initial_state, state_function, final_function)
1141
+ Aggregate.new(keyspace_name,
1142
+ aggregate_name,
1143
+ aggregate_type,
1144
+ argument_types,
1145
+ state_type,
1146
+ initial_state,
1147
+ state_function,
1148
+ final_function)
886
1149
  end
887
1150
 
888
1151
  def create_types(rows_types, types)
@@ -914,43 +1177,60 @@ module Cassandra
914
1177
 
915
1178
  break if skipped_rows.empty?
916
1179
 
917
- if rows_size == skipped_rows.size
918
- raise "Unable to resolve circular references among UDTs when parsing"
919
- else
920
- rows_types, skipped_rows = skipped_rows, rows_types
921
- end
1180
+ raise 'Unable to resolve circular references among UDTs when parsing' if rows_size == skipped_rows.size
1181
+
1182
+ rows_types, skipped_rows = skipped_rows, rows_types
922
1183
  end
923
1184
  end
924
1185
 
925
- def create_keyspace(keyspace_data, rows_tables, rows_columns,
926
- rows_types, rows_functions, rows_aggregates)
1186
+ def create_keyspace(keyspace_data, rows_tables, rows_columns, rows_types,
1187
+ rows_functions, rows_aggregates, rows_views, rows_indexes)
927
1188
  keyspace_name = keyspace_data['keyspace_name']
928
1189
  replication = create_replication(keyspace_data)
929
1190
 
930
1191
  types = ::Hash.new
931
1192
  create_types(rows_types, types)
932
1193
 
933
- # We want the functions hash to be keyed on [name, arg-types-list].
934
- # Similarly for the aggregates hash.
935
-
936
- functions = rows_functions.each_with_object({}) do |row, collector|
937
- func = create_function(row, types)
938
- collector[[func.name, func.argument_types]] = func
1194
+ # Create a FunctionCollection for the functions and aggregates.
1195
+ functions = Cassandra::FunctionCollection.new
1196
+ rows_functions.each do |row|
1197
+ functions.add_or_update(create_function(row, types))
939
1198
  end
940
1199
 
941
- aggregates = rows_aggregates.each_with_object({}) do |row, collector|
942
- agg = create_aggregate(row, functions, types)
943
- collector[[agg.name, agg.argument_types]] = agg
1200
+ aggregates = Cassandra::FunctionCollection.new
1201
+ rows_aggregates.each do |row|
1202
+ aggregates.add_or_update(create_aggregate(row, functions, types))
944
1203
  end
945
1204
 
1205
+ # lookup_columns is a hash of <table-name, rows_columns for that table>.
1206
+ # However, views are analogous to tables in this context, so we get
1207
+ # view columns organized by view-name also.
1208
+
946
1209
  lookup_columns = map_rows_by(rows_columns, 'table_name')
947
- tables = rows_tables.each_with_object({}) do |row, tables|
1210
+ lookup_indexes = map_rows_by(rows_indexes, 'table_name')
1211
+ tables = rows_tables.each_with_object({}) do |row, h|
948
1212
  table_name = row['table_name']
949
- tables[table_name] = create_table(row, lookup_columns[table_name], types)
1213
+ h[table_name] = create_table(row, lookup_columns[table_name],
1214
+ lookup_indexes[table_name], types)
950
1215
  end
951
1216
 
952
- Keyspace.new(keyspace_name, keyspace_data['durable_writes'],
953
- replication, tables, types, functions, aggregates)
1217
+ views = rows_views.each_with_object({}) do |row, h|
1218
+ view_name = row['view_name']
1219
+ base_table = tables[row['base_table_name']]
1220
+ h[view_name] = create_materialized_view(row,
1221
+ lookup_columns[view_name],
1222
+ base_table,
1223
+ types)
1224
+ end
1225
+
1226
+ Keyspace.new(keyspace_name,
1227
+ keyspace_data['durable_writes'],
1228
+ replication,
1229
+ tables,
1230
+ types,
1231
+ functions,
1232
+ aggregates,
1233
+ views)
954
1234
  end
955
1235
 
956
1236
  def create_replication(keyspace_data)
@@ -964,14 +1244,14 @@ module Cassandra
964
1244
  options = table_data['compaction']
965
1245
  klass = options.delete('class')
966
1246
  klass.slice!('org.apache.cassandra.db.compaction.')
967
- Table::Compaction.new(klass, options)
1247
+ ColumnContainer::Compaction.new(klass, options)
968
1248
  end
969
1249
 
970
1250
  def create_table_options(table_data, compaction_strategy, is_compact)
971
1251
  compression = table_data['compression']
972
1252
  compression['class'].slice!(COMPRESSION_PACKAGE_PREFIX) if compression['class']
973
1253
 
974
- Table::Options.new(
1254
+ Cassandra::ColumnContainer::Options.new(
975
1255
  table_data['comment'],
976
1256
  table_data['read_repair_chance'],
977
1257
  table_data['dclocal_read_repair_chance'],
@@ -988,76 +1268,146 @@ module Cassandra
988
1268
  table_data['max_index_interval'],
989
1269
  compaction_strategy,
990
1270
  compression,
991
- is_compact
1271
+ is_compact,
1272
+ table_data['crc_check_chance'],
1273
+ table_data['extensions']
992
1274
  )
993
1275
  end
994
1276
 
995
1277
  def create_column(column_data, types)
996
1278
  name = column_data['column_name']
997
- is_static = (column_data['kind'].to_s.upcase == 'STATIC')
1279
+ is_static = column_data['kind'].to_s.casecmp('STATIC').zero?
998
1280
  order = column_data['clustering_order'] == 'desc' ? :desc : :asc
999
- type, is_frozen = @type_parser.parse(column_data['type'], types)
1281
+ if column_data['type'][0] == "'"
1282
+ # This is a custom column type.
1283
+ type = Types.custom(column_data['type'].slice(1, column_data['type'].length - 2))
1284
+ is_frozen = false
1285
+ else
1286
+ type, is_frozen = @type_parser.parse(column_data['type'], types)
1287
+ end
1000
1288
 
1001
- Column.new(name, type, order, nil, is_static, is_frozen)
1289
+ Column.new(name, type, order, is_static, is_frozen)
1002
1290
  end
1003
1291
 
1004
- def create_table(table_data, rows_columns, types = nil)
1292
+ def create_table(table_data, rows_columns, rows_indexes, types = nil)
1005
1293
  keyspace_name = table_data['keyspace_name']
1006
1294
  table_name = table_data['table_name']
1007
1295
  table_flags = table_data['flags']
1008
- table_columns = {}
1009
- other_columns = []
1010
- clustering_size = 0
1011
1296
 
1012
1297
  is_dense = table_flags.include?('dense')
1013
1298
  is_super = table_flags.include?('super')
1014
1299
  is_compound = table_flags.include?('compound')
1015
1300
  is_compact = is_super || is_dense || !is_compound
1301
+ is_static_compact = !is_super && !is_dense && !is_compound
1016
1302
 
1303
+ # Separate out partition-key, clustering columns, other columns.
1017
1304
  partition_key = []
1018
1305
  clustering_columns = []
1019
1306
  clustering_order = []
1020
- types ||= @schema.keyspace(keyspace_name).send(:raw_types)
1307
+ other_columns = []
1308
+ types ||= @schema.keyspace(keyspace_name).send(:raw_types)
1021
1309
 
1022
1310
  rows_columns.each do |row|
1023
1311
  next if row['column_name'].empty?
1024
1312
 
1025
- column = create_column(row, types)
1026
1313
  kind = row['kind'].to_s
1027
1314
  index = row['position'] || 0
1028
1315
 
1316
+ if is_static_compact
1317
+ if kind.casecmp('CLUSTERING').zero? || kind.casecmp('REGULAR').zero?
1318
+ # Skip clustering columns in static-compact tables; they are internal to C*.
1319
+ # Oddly so are regular columns.
1320
+ next
1321
+ end
1322
+ if kind.casecmp('STATIC').zero?
1323
+ # Coerce static type to regular.
1324
+ kind = 'REGULAR'
1325
+ row['kind'] = 'regular'
1326
+ end
1327
+ end
1328
+
1329
+ column = create_column(row, types)
1029
1330
  case kind.upcase
1030
1331
  when 'PARTITION_KEY'
1031
1332
  partition_key[index] = column
1032
1333
  when 'CLUSTERING'
1033
1334
  clustering_columns[index] = column
1034
1335
  clustering_order[index] = column.order
1035
-
1036
- if clustering_size.zero? || index == clustering_size
1037
- clustering_size = index + 1
1038
- end
1039
1336
  else
1040
1337
  other_columns << column
1041
1338
  end
1042
1339
  end
1043
1340
 
1044
- partition_key.each do |column|
1045
- table_columns[column.name] = column
1341
+ # Default the crc_check_chance to 1.0 (Java driver does this, so we
1342
+ # should, too).
1343
+ table_data['crc_check_chance'] ||= 1.0
1344
+ compaction_strategy = create_compaction_strategy(table_data)
1345
+ table_options =
1346
+ create_table_options(table_data, compaction_strategy, is_compact)
1347
+
1348
+ table = Cassandra::Table.new(@schema.keyspace(keyspace_name),
1349
+ table_name,
1350
+ partition_key,
1351
+ clustering_columns,
1352
+ other_columns,
1353
+ table_options,
1354
+ clustering_order,
1355
+ table_data['id'])
1356
+ rows_indexes.each do |row|
1357
+ create_index(table, row)
1046
1358
  end
1359
+ table
1360
+ end
1047
1361
 
1048
- clustering_columns.each do |column|
1049
- table_columns[column.name] = column
1050
- end
1362
+ def create_index(table, row_index)
1363
+ options = row_index['options']
1364
+ table.add_index(Cassandra::Index.new(table, row_index['index_name'],
1365
+ row_index['kind'].downcase.to_sym,
1366
+ options['target'], options))
1367
+ end
1368
+
1369
+ def create_materialized_view(view_data, rows_columns, base_table, types = nil)
1370
+ keyspace_name = view_data['keyspace_name']
1371
+ view_name = view_data['view_name']
1372
+ include_all_columns = view_data['include_all_columns']
1373
+ where_clause = view_data['where_clause']
1374
+
1375
+ # Separate out partition key, clustering columns, other columns
1376
+ partition_key = []
1377
+ clustering_columns = []
1378
+ other_columns = []
1379
+ types ||= @schema.keyspace(keyspace_name).send(:raw_types)
1380
+
1381
+ rows_columns.each do |row|
1382
+ next if row['column_name'].empty?
1383
+
1384
+ column = create_column(row, types)
1385
+ kind = row['kind'].to_s
1386
+ index = row['position'] || 0
1051
1387
 
1052
- other_columns.each do |column|
1053
- table_columns[column.name] = column
1388
+ case kind.upcase
1389
+ when 'PARTITION_KEY'
1390
+ partition_key[index] = column
1391
+ when 'CLUSTERING'
1392
+ clustering_columns[index] = column
1393
+ else
1394
+ other_columns << column
1395
+ end
1054
1396
  end
1055
1397
 
1056
- compaction_strategy = create_compaction_strategy(table_data)
1057
- table_options = create_table_options(table_data, compaction_strategy, is_compact)
1398
+ compaction_strategy = create_compaction_strategy(view_data)
1399
+ view_options = create_table_options(view_data, compaction_strategy, false)
1058
1400
 
1059
- Table.new(keyspace_name, table_name, partition_key, clustering_columns,
1060
- table_columns, table_options, clustering_order)
1401
+ MaterializedView.new(@schema.keyspace(keyspace_name),
1402
+ view_name,
1403
+ partition_key,
1404
+ clustering_columns,
1405
+ other_columns,
1406
+ view_options,
1407
+ include_all_columns,
1408
+ where_clause,
1409
+ base_table,
1410
+ view_data['id'])
1061
1411
  end
1062
1412
  end
1063
1413
 
@@ -1109,6 +1459,13 @@ module Cassandra
1109
1459
  return Ione::Future.failed(e)
1110
1460
  end
1111
1461
 
1462
+ def fetch_materialized_view(connection, keyspace_name, view_name)
1463
+ find_fetcher(connection)
1464
+ .fetch_materialized_view(connection, keyspace_name, view_name)
1465
+ rescue => e
1466
+ return Ione::Future.failed(e)
1467
+ end
1468
+
1112
1469
  def fetch_type(connection, keyspace_name, type_name)
1113
1470
  find_fetcher(connection)
1114
1471
  .fetch_type(connection, keyspace_name, type_name)
@@ -1130,13 +1487,16 @@ module Cassandra
1130
1487
  return Ione::Future.failed(e)
1131
1488
  end
1132
1489
 
1133
- # parse an array of string argument types and return an array of [Cassandra::Type]s.
1490
+ # parse an array of string argument types and return an array of
1491
+ # [Cassandra::Type]s.
1134
1492
  # @param connection a connection to a Cassandra node.
1135
1493
  # @param keyspace_name [String] name of the keyspace.
1136
1494
  # @param argument_types [Array<String>] array of argument types.
1137
1495
  # @return [Array<Cassandra::Type>] array of parsed types.
1138
1496
  def parse_argument_types(connection, keyspace_name, argument_types)
1139
- find_fetcher(connection).parse_argument_types(connection, keyspace_name, argument_types)
1497
+ find_fetcher(connection).parse_argument_types(connection,
1498
+ keyspace_name,
1499
+ argument_types)
1140
1500
  end
1141
1501
 
1142
1502
  private
@@ -1147,21 +1507,21 @@ module Cassandra
1147
1507
  unless host
1148
1508
  ips = @registry.hosts.map(&:ip)
1149
1509
  raise Errors::ClientError,
1150
- "unable to find release version for current host, " \
1510
+ 'unable to find release version for current host, ' \
1151
1511
  "connected to #{connection.host}, but cluster contains " \
1152
1512
  "#{ips}."
1153
1513
  end
1154
1514
 
1155
1515
  version = host.release_version
1156
1516
  unless version
1157
- raise Errors::ClientError, "unable to determine release " \
1517
+ raise Errors::ClientError, 'unable to determine release ' \
1158
1518
  "version for host: #{host.inspect}"
1159
1519
  end
1160
1520
 
1161
1521
  @fetchers[version] ||= begin
1162
1522
  current = @versions.find {|v| v.matches?(version)}
1163
1523
  unless current
1164
- raise Errors::ClientError, "unsupported release version " \
1524
+ raise Errors::ClientError, 'unsupported release version ' \
1165
1525
  "#{version.inspect}."
1166
1526
  end
1167
1527
  current.fetcher