cassandra-driver 3.0.3-java → 3.1.0-java

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +46 -31
  3. data/lib/cassandra.rb +35 -44
  4. data/lib/cassandra/cluster.rb +40 -11
  5. data/lib/cassandra/cluster/client.rb +193 -159
  6. data/lib/cassandra/cluster/connector.rb +12 -10
  7. data/lib/cassandra/cluster/control_connection.rb +38 -10
  8. data/lib/cassandra/cluster/options.rb +8 -4
  9. data/lib/cassandra/cluster/registry.rb +1 -2
  10. data/lib/cassandra/cluster/schema/fetchers.rb +122 -26
  11. data/lib/cassandra/column_container.rb +9 -4
  12. data/lib/cassandra/custom_data.rb +24 -22
  13. data/lib/cassandra/driver.rb +30 -13
  14. data/lib/cassandra/errors.rb +12 -2
  15. data/lib/cassandra/execution/options.rb +52 -16
  16. data/lib/cassandra/execution/profile.rb +150 -0
  17. data/lib/cassandra/execution/profile_manager.rb +71 -0
  18. data/lib/cassandra/execution/trace.rb +5 -4
  19. data/lib/cassandra/executors.rb +1 -1
  20. data/lib/cassandra/index.rb +1 -1
  21. data/lib/cassandra/keyspace.rb +36 -1
  22. data/lib/cassandra/protocol.rb +5 -0
  23. data/lib/cassandra/protocol/coder.rb +2 -1
  24. data/lib/cassandra/protocol/cql_byte_buffer.rb +21 -0
  25. data/lib/cassandra/protocol/responses/read_failure_error_response.rb +10 -4
  26. data/lib/cassandra/protocol/responses/write_failure_error_response.rb +14 -8
  27. data/lib/cassandra/protocol/v3.rb +2 -1
  28. data/lib/cassandra/protocol/v4.rb +58 -20
  29. data/lib/cassandra/result.rb +1 -1
  30. data/lib/cassandra/session.rb +43 -16
  31. data/lib/cassandra/statements/bound.rb +5 -1
  32. data/lib/cassandra/statements/prepared.rb +8 -3
  33. data/lib/cassandra/table.rb +72 -0
  34. data/lib/cassandra/trigger.rb +67 -0
  35. data/lib/cassandra/types.rb +12 -24
  36. data/lib/cassandra/udt.rb +3 -6
  37. data/lib/cassandra/uuid/generator.rb +6 -3
  38. data/lib/cassandra/version.rb +1 -1
  39. data/lib/cassandra_murmur3.jar +0 -0
  40. metadata +5 -2
@@ -122,11 +122,8 @@ module Cassandra
122
122
  ssl: @connection_options.ssl) do |connection|
123
123
  raise Errors::ClientError, 'Not connected, reactor stopped' unless connection
124
124
 
125
- if @connection_options.nodelay?
126
- connection.to_io.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
127
- else
128
- connection.to_io.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 0)
129
- end
125
+ connection.to_io.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY,
126
+ @connection_options.nodelay? ? 1 : 0)
130
127
 
131
128
  Protocol::CqlProtocolHandler.new(connection,
132
129
  @reactor,
@@ -225,10 +222,12 @@ module Cassandra
225
222
  ::Ione::Future.resolved(connection)
226
223
  when Protocol::ErrorResponse
227
224
  ::Ione::Future.failed(
228
- r.to_error(nil, VOID_STATEMENT, VOID_OPTIONS, EMPTY_LIST, :one, 0))
225
+ r.to_error(nil, VOID_STATEMENT, VOID_OPTIONS, EMPTY_LIST, :one, 0)
226
+ )
229
227
  else
230
228
  ::Ione::Future.failed(
231
- Errors::InternalError.new("Unexpected response #{r.inspect}"))
229
+ Errors::InternalError.new("Unexpected response #{r.inspect}")
230
+ )
232
231
  end
233
232
  end
234
233
  end
@@ -244,7 +243,8 @@ module Cassandra
244
243
  VOID_OPTIONS,
245
244
  EMPTY_LIST,
246
245
  :one,
247
- 0)
246
+ 0
247
+ )
248
248
  end
249
249
 
250
250
  def request_options(connection)
@@ -291,10 +291,12 @@ module Cassandra
291
291
  ::Ione::Future.resolved(connection)
292
292
  when Protocol::ErrorResponse
293
293
  ::Ione::Future.failed(
294
- r.to_error(nil, VOID_STATEMENT, VOID_OPTIONS, EMPTY_LIST, :one, 0))
294
+ r.to_error(nil, VOID_STATEMENT, VOID_OPTIONS, EMPTY_LIST, :one, 0)
295
+ )
295
296
  else
296
297
  ::Ione::Future.failed(
297
- Errors::InternalError.new("Unexpected response #{r.inspect}"))
298
+ Errors::InternalError.new("Unexpected response #{r.inspect}")
299
+ )
298
300
  end
299
301
  end
300
302
  end
@@ -36,8 +36,10 @@ module Cassandra
36
36
  @address_resolver = address_resolution_policy
37
37
  @connector = connector
38
38
  @connection_options = connection_options
39
+ @connection = nil
39
40
  @schema_fetcher = schema_fetcher
40
41
  @refreshing_statuses = ::Hash.new(false)
42
+ @refresh_schema_future = nil
41
43
  @status = :closed
42
44
  @refreshing_hosts = false
43
45
  @refreshing_host = ::Hash.new(false)
@@ -88,7 +90,8 @@ module Cassandra
88
90
  (@status == :closing || @status == :closed) ||
89
91
  @load_balancing_policy.distance(host) == :ignore
90
92
  return connect_to_first_available(
91
- @load_balancing_policy.plan(nil, VOID_STATEMENT, VOID_OPTIONS))
93
+ @load_balancing_policy.plan(nil, VOID_STATEMENT, VOID_OPTIONS)
94
+ )
92
95
  end
93
96
  end
94
97
 
@@ -146,18 +149,20 @@ module Cassandra
146
149
 
147
150
  private
148
151
 
149
- SELECT_LOCAL = Protocol::QueryRequest.new(
152
+ SELECT_LOCAL = Protocol::QueryRequest.new(
150
153
  'SELECT * ' \
151
154
  'FROM system.local',
152
155
  EMPTY_LIST,
153
156
  EMPTY_LIST,
154
- :one)
155
- SELECT_PEERS = Protocol::QueryRequest.new(
157
+ :one
158
+ )
159
+ SELECT_PEERS = Protocol::QueryRequest.new(
156
160
  'SELECT * ' \
157
161
  'FROM system.peers',
158
162
  EMPTY_LIST,
159
163
  EMPTY_LIST,
160
- :one)
164
+ :one
165
+ )
161
166
 
162
167
  SELECT_PEER_QUERY =
163
168
  'SELECT * ' \
@@ -229,7 +234,9 @@ module Cassandra
229
234
  refresh_schema_async_wrapper
230
235
  end
231
236
  when 'DOWN'
232
- @registry.host_down(event.address)
237
+ # RUBY-164: Don't mark host down if there are active connections. We have
238
+ # logic in connector.rb to call host_down when all connections to a node are lost,
239
+ # so that covers the requirement.
233
240
  when 'NEW_NODE'
234
241
  address = event.address
235
242
 
@@ -445,7 +452,7 @@ module Cassandra
445
452
 
446
453
  peers.shuffle!
447
454
  peers.each do |data|
448
- ip = peer_ip(data)
455
+ ip = peer_ip(data, connection.host)
449
456
  next unless ip
450
457
  ips << ip
451
458
  @registry.host_found(ip, data)
@@ -665,9 +672,30 @@ Control connection failed and is unlikely to recover.
665
672
  @connector.connect(host)
666
673
  end
667
674
 
668
- def peer_ip(data)
669
- ip = data['rpc_address']
670
- ip = data['peer'] if ip == '0.0.0.0'
675
+ def peer_ip(data, host_address)
676
+ peer = data['peer']
677
+
678
+ return nil unless peer && data['host_id'] && data['data_center'] && data['rack'] && data['tokens']
679
+
680
+ rpc_address = data['rpc_address']
681
+
682
+ if rpc_address.nil?
683
+ @logger.info("The system.peers row for '#{data['peer']}' has no rpc_address. This is likely " \
684
+ 'a gossip or snitch issue. This host will be ignored.')
685
+ return nil
686
+ end
687
+
688
+ if peer == host_address || rpc_address == host_address
689
+ # Some DSE versions were inserting a line for the local node in peers (with mostly null values).
690
+ # This has been fixed, but if we detect that's the case, ignore it as it's not really a big deal.
691
+
692
+ @logger.debug("System.peers on node #{host_address} has a line for itself. This is not normal but is a " \
693
+ 'known problem of some DSE versions. Ignoring the entry.')
694
+ return nil
695
+ end
696
+
697
+ ip = rpc_address
698
+ ip = peer if ip == '0.0.0.0'
671
699
 
672
700
  @address_resolver.resolve(ip)
673
701
  end
@@ -25,7 +25,7 @@ module Cassandra
25
25
  attr_reader :auth_provider, :compressor, :connect_timeout, :credentials,
26
26
  :heartbeat_interval, :idle_timeout, :port, :schema_refresh_delay,
27
27
  :schema_refresh_timeout, :ssl, :custom_type_handlers
28
- attr_boolean :protocol_negotiable, :synchronize_schema, :nodelay
28
+ attr_boolean :protocol_negotiable, :synchronize_schema, :nodelay, :allow_beta_protocol
29
29
 
30
30
  attr_accessor :protocol_version
31
31
 
@@ -46,7 +46,8 @@ module Cassandra
46
46
  schema_refresh_timeout,
47
47
  nodelay,
48
48
  requests_per_connection,
49
- custom_types)
49
+ custom_types,
50
+ allow_beta_protocol)
50
51
  @logger = logger
51
52
  @protocol_version = protocol_version
52
53
  @credentials = credentials
@@ -61,6 +62,7 @@ module Cassandra
61
62
  @schema_refresh_delay = schema_refresh_delay
62
63
  @schema_refresh_timeout = schema_refresh_timeout
63
64
  @nodelay = nodelay
65
+ @allow_beta_protocol = allow_beta_protocol
64
66
  @custom_type_handlers = {}
65
67
  custom_types.each do |type_klass|
66
68
  @custom_type_handlers[type_klass.type] = type_klass
@@ -71,12 +73,14 @@ module Cassandra
71
73
  @requests_per_connection = requests_per_connection
72
74
 
73
75
  # If @protocol_version is nil, it means we want the driver to negotiate the
74
- # protocol starting with our known max (4). If @protocol_version is not nil,
76
+ # protocol starting with our known max. If @protocol_version is not nil,
75
77
  # it means the user wants us to use a particular version, so we should not
76
78
  # support negotiation.
77
79
 
78
80
  @protocol_negotiable = @protocol_version.nil?
79
- @protocol_version ||= 4
81
+ @protocol_version ||= allow_beta_protocol ?
82
+ Cassandra::Protocol::Versions::BETA_VERSION :
83
+ Cassandra::Protocol::Versions::MAX_SUPPORTED_VERSION
80
84
  end
81
85
 
82
86
  def compression
@@ -170,8 +170,7 @@ module Cassandra
170
170
  Array(data['tokens']).freeze,
171
171
  :up,
172
172
  data['broadcast_address'],
173
- data['listen_address']
174
- )
173
+ data['listen_address'])
175
174
  end
176
175
 
177
176
  def toggle_up(host)
@@ -34,8 +34,9 @@ module Cassandra
34
34
  select_functions(connection),
35
35
  select_aggregates(connection),
36
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|
37
+ select_indexes(connection),
38
+ select_triggers(connection))
39
+ .map do |rows_keyspaces, rows_tables, rows_columns, rows_types, rows_functions, rows_aggregates, rows_views, rows_indexes, rows_triggers|
39
40
  lookup_tables = map_rows_by(rows_tables, 'keyspace_name')
40
41
  lookup_columns = map_rows_by(rows_columns, 'keyspace_name')
41
42
  lookup_types = map_rows_by(rows_types, 'keyspace_name')
@@ -43,6 +44,7 @@ module Cassandra
43
44
  lookup_aggregates = map_rows_by(rows_aggregates, 'keyspace_name')
44
45
  lookup_views = map_rows_by(rows_views, 'keyspace_name')
45
46
  lookup_indexes = map_rows_by(rows_indexes, 'keyspace_name')
47
+ lookup_triggers = map_rows_by(rows_triggers, 'keyspace_name')
46
48
 
47
49
  rows_keyspaces.map do |keyspace_data|
48
50
  name = keyspace_data['keyspace_name']
@@ -54,7 +56,8 @@ module Cassandra
54
56
  lookup_functions[name],
55
57
  lookup_aggregates[name],
56
58
  lookup_views[name],
57
- lookup_indexes[name])
59
+ lookup_indexes[name],
60
+ lookup_triggers[name])
58
61
  end
59
62
  end
60
63
  end
@@ -67,8 +70,9 @@ module Cassandra
67
70
  select_keyspace_functions(connection, keyspace_name),
68
71
  select_keyspace_aggregates(connection, keyspace_name),
69
72
  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|
73
+ select_keyspace_indexes(connection, keyspace_name),
74
+ select_keyspace_triggers(connection, keyspace_name))
75
+ .map do |rows_keyspaces, rows_tables, rows_columns, rows_types, rows_functions, rows_aggregates, rows_views, rows_indexes, rows_triggers|
72
76
  if rows_keyspaces.empty?
73
77
  nil
74
78
  else
@@ -79,7 +83,8 @@ module Cassandra
79
83
  rows_functions,
80
84
  rows_aggregates,
81
85
  rows_views,
82
- rows_indexes)
86
+ rows_indexes,
87
+ rows_triggers)
83
88
  end
84
89
  end
85
90
  end
@@ -87,14 +92,16 @@ module Cassandra
87
92
  def fetch_table(connection, keyspace_name, table_name)
88
93
  Ione::Future.all(select_table(connection, keyspace_name, table_name),
89
94
  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)|
95
+ select_table_indexes(connection, keyspace_name, table_name),
96
+ select_table_triggers(connection, keyspace_name, table_name))
97
+ .map do |(rows_tables, rows_columns, rows_indexes, rows_triggers)|
92
98
  if rows_tables.empty?
93
99
  nil
94
100
  else
95
101
  create_table(rows_tables.first,
96
102
  rows_columns,
97
- rows_indexes)
103
+ rows_indexes,
104
+ rows_triggers)
98
105
  end
99
106
  end
100
107
  end
@@ -168,6 +175,10 @@ module Cassandra
168
175
  FUTURE_EMPTY_LIST
169
176
  end
170
177
 
178
+ def select_triggers(connection)
179
+ FUTURE_EMPTY_LIST
180
+ end
181
+
171
182
  def select_types(connection)
172
183
  FUTURE_EMPTY_LIST
173
184
  end
@@ -200,6 +211,10 @@ module Cassandra
200
211
  FUTURE_EMPTY_LIST
201
212
  end
202
213
 
214
+ def select_keyspace_triggers(connection, keyspace_name)
215
+ FUTURE_EMPTY_LIST
216
+ end
217
+
203
218
  def select_keyspace_types(connection, keyspace_name)
204
219
  FUTURE_EMPTY_LIST
205
220
  end
@@ -228,6 +243,10 @@ module Cassandra
228
243
  FUTURE_EMPTY_LIST
229
244
  end
230
245
 
246
+ def select_table_triggers(connection, keyspace_name, table_name)
247
+ FUTURE_EMPTY_LIST
248
+ end
249
+
231
250
  def select_type(connection, keyspace_name, type_name)
232
251
  FUTURE_EMPTY_LIST
233
252
  end
@@ -243,7 +262,8 @@ module Cassandra
243
262
  def send_select_request(connection, cql, params = EMPTY_LIST, types = EMPTY_LIST)
244
263
  backtrace = caller
245
264
  connection.send_request(
246
- Protocol::QueryRequest.new(cql, params, types, :one)).map do |r|
265
+ Protocol::QueryRequest.new(cql, params, types, :one)
266
+ ).map do |r|
247
267
  case r
248
268
  when Protocol::RowsResultResponse
249
269
  r.rows
@@ -348,7 +368,7 @@ module Cassandra
348
368
 
349
369
  def create_keyspace(keyspace_data, rows_tables, rows_columns,
350
370
  rows_types, rows_functions, rows_aggregates,
351
- rows_views, rows_indexes)
371
+ rows_views, rows_indexes, rows_triggers)
352
372
  keyspace_name = keyspace_data['keyspace_name']
353
373
  replication = create_replication(keyspace_data)
354
374
  types = rows_types.each_with_object({}) do |row, h|
@@ -367,10 +387,14 @@ module Cassandra
367
387
  end
368
388
 
369
389
  lookup_columns = map_rows_by(rows_columns, 'columnfamily_name')
390
+ lookup_indexes = map_rows_by(rows_indexes, 'columnfamily_name')
391
+ lookup_triggers = map_rows_by(rows_triggers, 'columnfamily_name')
370
392
  tables = rows_tables.each_with_object({}) do |row, h|
371
393
  table_name = row['columnfamily_name']
372
- # rows_indexes is nil for C* < 3.0.
373
- h[table_name] = create_table(row, lookup_columns[table_name], nil)
394
+ h[table_name] = create_table(row,
395
+ lookup_columns[table_name],
396
+ lookup_indexes[table_name],
397
+ lookup_triggers[table_name])
374
398
  end
375
399
 
376
400
  Keyspace.new(keyspace_name,
@@ -383,7 +407,7 @@ module Cassandra
383
407
  {})
384
408
  end
385
409
 
386
- def create_table(table_data, rows_columns, rows_indexes)
410
+ def create_table(table_data, rows_columns, rows_indexes, rows_triggers)
387
411
  keyspace_name = table_data['keyspace_name']
388
412
  table_name = table_data['columnfamily_name']
389
413
  key_validator = @type_parser.parse(table_data['key_validator'])
@@ -461,7 +485,7 @@ module Cassandra
461
485
  column = create_column(row)
462
486
  other_columns << column
463
487
 
464
- # In C* 1.2.x, index info is in the column metadata; rows_indexes is nil.
488
+ # In C* 1.2.x, index info is in the column metadata; rows_indexes is [].
465
489
  index_rows << [column, row] unless row['index_type'].nil?
466
490
  end
467
491
 
@@ -485,7 +509,8 @@ module Cassandra
485
509
  # Most of this logic was taken from the Java driver.
486
510
  options = {}
487
511
  # For some versions of C*, this field could have a literal string 'null' value.
488
- if !row_column['index_options'].nil? && row_column['index_options'] != 'null' && !row_column['index_options'].empty?
512
+ if !row_column['index_options'].nil? && row_column['index_options'] != 'null' &&
513
+ !row_column['index_options'].empty?
489
514
  options = ::JSON.load(row_column['index_options'])
490
515
  end
491
516
  column_name = Util.escape_name(column.name)
@@ -548,18 +573,24 @@ module Cassandra
548
573
  compression_parameters,
549
574
  is_compact,
550
575
  table_data['crc_check_chance'],
551
- table_data['extensions']
576
+ table_data['extensions'],
577
+ nil
552
578
  )
553
579
  end
554
580
  end
555
581
 
556
582
  class V2_0_x < V1_2_x
583
+ SELECT_TRIGGERS = 'SELECT * FROM system.schema_triggers'.freeze
584
+
557
585
  SELECT_KEYSPACE =
558
586
  'SELECT * FROM system.schema_keyspaces WHERE keyspace_name = ?'.freeze
559
587
  SELECT_KEYSPACE_TABLES =
560
588
  'SELECT * FROM system.schema_columnfamilies WHERE keyspace_name = ?'.freeze
561
589
  SELECT_KEYSPACE_COLUMNS =
562
590
  'SELECT * FROM system.schema_columns WHERE keyspace_name = ?'.freeze
591
+ SELECT_KEYSPACE_TRIGGERS =
592
+ 'SELECT * FROM system.schema_triggers WHERE keyspace_name = ?'.freeze
593
+
563
594
  SELECT_TABLE =
564
595
  'SELECT * ' \
565
596
  'FROM system.schema_columnfamilies ' \
@@ -568,10 +599,14 @@ module Cassandra
568
599
  'SELECT * ' \
569
600
  'FROM system.schema_columns ' \
570
601
  'WHERE keyspace_name = ? AND columnfamily_name = ?'.freeze
602
+ SELECT_TABLE_TRIGGERS =
603
+ 'SELECT * ' \
604
+ 'FROM system.schema_triggers ' \
605
+ 'WHERE keyspace_name = ? AND columnfamily_name = ?'.freeze
571
606
 
572
607
  private
573
608
 
574
- def create_table(table_data, rows_columns, rows_indexes)
609
+ def create_table(table_data, rows_columns, rows_indexes, rows_triggers)
575
610
  keyspace_name = table_data['keyspace_name']
576
611
  table_name = table_data['columnfamily_name']
577
612
  comparator = @type_parser.parse(table_data['comparator'])
@@ -598,7 +633,7 @@ module Cassandra
598
633
  clustering_columns[ind] = column
599
634
  clustering_order[ind] = column.order
600
635
 
601
- clustering_size = ind + 1 if clustering_size.zero? || ind == clustering_size
636
+ clustering_size += 1
602
637
  else
603
638
  other_columns << column
604
639
  end
@@ -626,9 +661,21 @@ module Cassandra
626
661
  index_rows.each do |column, row|
627
662
  create_index(table, column, row)
628
663
  end
664
+
665
+ # Create Trigger objects and add them to the table.
666
+ rows_triggers.each do |row_trigger|
667
+ table.add_trigger(Cassandra::Trigger.new(table,
668
+ row_trigger['trigger_name'],
669
+ row_trigger['trigger_options']))
670
+ end
671
+
629
672
  table
630
673
  end
631
674
 
675
+ def select_triggers(connection)
676
+ send_select_request(connection, SELECT_TRIGGERS)
677
+ end
678
+
632
679
  def select_keyspace(connection, keyspace_name)
633
680
  params = [keyspace_name]
634
681
  hints = [Types.varchar]
@@ -647,6 +694,12 @@ module Cassandra
647
694
  send_select_request(connection, SELECT_KEYSPACE_COLUMNS, params, hints)
648
695
  end
649
696
 
697
+ def select_keyspace_triggers(connection, keyspace_name)
698
+ params = [keyspace_name]
699
+ hints = [Types.varchar]
700
+ send_select_request(connection, SELECT_KEYSPACE_TRIGGERS, params, hints)
701
+ end
702
+
650
703
  def select_table(connection, keyspace_name, table_name)
651
704
  params = [keyspace_name, table_name]
652
705
  hints = [Types.varchar, Types.varchar]
@@ -659,6 +712,12 @@ module Cassandra
659
712
  send_select_request(connection, SELECT_TABLE_COLUMNS, params, hints)
660
713
  end
661
714
 
715
+ def select_table_triggers(connection, keyspace_name, table_name)
716
+ params = [keyspace_name, table_name]
717
+ hints = [Types.varchar, Types.varchar]
718
+ send_select_request(connection, SELECT_TABLE_TRIGGERS, params, hints)
719
+ end
720
+
662
721
  def create_table_options(table_data, compaction_strategy, is_compact)
663
722
  compression_parameters = ::JSON.load(table_data['compression_parameters'])
664
723
  if compression_parameters['sstable_compression']
@@ -684,7 +743,8 @@ module Cassandra
684
743
  compression_parameters,
685
744
  is_compact,
686
745
  table_data['crc_check_chance'],
687
- table_data['extensions']
746
+ table_data['extensions'],
747
+ nil
688
748
  )
689
749
  end
690
750
  end
@@ -758,7 +818,8 @@ module Cassandra
758
818
  compression_parameters,
759
819
  is_compact,
760
820
  table_data['crc_check_chance'],
761
- table_data['extensions']
821
+ table_data['extensions'],
822
+ nil
762
823
  )
763
824
  end
764
825
  end
@@ -834,7 +895,9 @@ module Cassandra
834
895
  initial_state = Util.encode_object(
835
896
  Protocol::Coder.read_value_v4(
836
897
  Protocol::CqlByteBuffer.new.append_bytes(aggregate_data['initcond']),
837
- state_type, nil))
898
+ state_type, nil
899
+ )
900
+ )
838
901
 
839
902
  # The state-function takes arguments: first the stype, then the args of the aggregate.
840
903
  state_function = functions.get(aggregate_data['state_func'],
@@ -896,6 +959,7 @@ module Cassandra
896
959
  SELECT_AGGREGATES = 'SELECT * FROM system_schema.aggregates'.freeze
897
960
  SELECT_INDEXES = 'SELECT * FROM system_schema.indexes'.freeze
898
961
  SELECT_VIEWS = 'SELECT * FROM system_schema.views'.freeze
962
+ SELECT_TRIGGERS = 'SELECT * FROM system_schema.triggers'.freeze
899
963
 
900
964
  SELECT_KEYSPACE =
901
965
  'SELECT * FROM system_schema.keyspaces WHERE keyspace_name = ?'.freeze
@@ -913,6 +977,8 @@ module Cassandra
913
977
  'SELECT * FROM system_schema.functions WHERE keyspace_name = ?'.freeze
914
978
  SELECT_KEYSPACE_AGGREGATES =
915
979
  'SELECT * FROM system_schema.aggregates WHERE keyspace_name = ?'.freeze
980
+ SELECT_KEYSPACE_TRIGGERS =
981
+ 'SELECT * FROM system_schema.triggers WHERE keyspace_name = ?'.freeze
916
982
 
917
983
  SELECT_TABLE =
918
984
  'SELECT * ' \
@@ -926,6 +992,10 @@ module Cassandra
926
992
  'SELECT * ' \
927
993
  'FROM system_schema.indexes ' \
928
994
  'WHERE keyspace_name = ? AND table_name = ?'.freeze
995
+ SELECT_TABLE_TRIGGERS =
996
+ 'SELECT * ' \
997
+ 'FROM system_schema.triggers ' \
998
+ 'WHERE keyspace_name = ? AND table_name = ?'.freeze
929
999
 
930
1000
  SELECT_VIEW =
931
1001
  'SELECT * ' \
@@ -984,6 +1054,10 @@ module Cassandra
984
1054
  send_select_request(connection, SELECT_COLUMNS)
985
1055
  end
986
1056
 
1057
+ def select_triggers(connection)
1058
+ send_select_request(connection, SELECT_TRIGGERS)
1059
+ end
1060
+
987
1061
  def select_types(connection)
988
1062
  send_select_request(connection, SELECT_TYPES)
989
1063
  end
@@ -1026,6 +1100,12 @@ module Cassandra
1026
1100
  send_select_request(connection, SELECT_KEYSPACE_VIEWS, params, hints)
1027
1101
  end
1028
1102
 
1103
+ def select_keyspace_triggers(connection, keyspace_name)
1104
+ params = [keyspace_name]
1105
+ hints = [Types.varchar]
1106
+ send_select_request(connection, SELECT_KEYSPACE_TRIGGERS, params, hints)
1107
+ end
1108
+
1029
1109
  def select_keyspace_types(connection, keyspace_name)
1030
1110
  params = [keyspace_name]
1031
1111
  hints = [Types.varchar]
@@ -1071,6 +1151,12 @@ module Cassandra
1071
1151
  send_select_request(connection, SELECT_VIEW, params, hints)
1072
1152
  end
1073
1153
 
1154
+ def select_table_triggers(connection, keyspace_name, table_name)
1155
+ params = [keyspace_name, table_name]
1156
+ hints = [Types.varchar, Types.varchar]
1157
+ send_select_request(connection, SELECT_TABLE_TRIGGERS, params, hints)
1158
+ end
1159
+
1074
1160
  def select_type(connection, keyspace_name, type_name)
1075
1161
  params = [keyspace_name, type_name]
1076
1162
  hints = [Types.varchar, Types.varchar]
@@ -1182,7 +1268,7 @@ module Cassandra
1182
1268
  end
1183
1269
 
1184
1270
  def create_keyspace(keyspace_data, rows_tables, rows_columns, rows_types,
1185
- rows_functions, rows_aggregates, rows_views, rows_indexes)
1271
+ rows_functions, rows_aggregates, rows_views, rows_indexes, rows_triggers)
1186
1272
  keyspace_name = keyspace_data['keyspace_name']
1187
1273
  replication = create_replication(keyspace_data)
1188
1274
 
@@ -1206,10 +1292,11 @@ module Cassandra
1206
1292
 
1207
1293
  lookup_columns = map_rows_by(rows_columns, 'table_name')
1208
1294
  lookup_indexes = map_rows_by(rows_indexes, 'table_name')
1295
+ lookup_triggers = map_rows_by(rows_triggers, 'table_name')
1209
1296
  tables = rows_tables.each_with_object({}) do |row, h|
1210
1297
  table_name = row['table_name']
1211
1298
  h[table_name] = create_table(row, lookup_columns[table_name],
1212
- lookup_indexes[table_name], types)
1299
+ lookup_indexes[table_name], lookup_triggers[table_name], types)
1213
1300
  end
1214
1301
 
1215
1302
  views = rows_views.each_with_object({}) do |row, h|
@@ -1266,7 +1353,8 @@ module Cassandra
1266
1353
  compression,
1267
1354
  is_compact,
1268
1355
  table_data['crc_check_chance'],
1269
- table_data['extensions']
1356
+ table_data['extensions'],
1357
+ table_data['cdc']
1270
1358
  )
1271
1359
  end
1272
1360
 
@@ -1285,7 +1373,7 @@ module Cassandra
1285
1373
  Column.new(name, type, order, is_static, is_frozen)
1286
1374
  end
1287
1375
 
1288
- def create_table(table_data, rows_columns, rows_indexes, types = nil)
1376
+ def create_table(table_data, rows_columns, rows_indexes, rows_triggers, types = nil)
1289
1377
  keyspace_name = table_data['keyspace_name']
1290
1378
  table_name = table_data['table_name']
1291
1379
  table_flags = table_data['flags']
@@ -1352,6 +1440,14 @@ module Cassandra
1352
1440
  rows_indexes.each do |row|
1353
1441
  create_index(table, row)
1354
1442
  end
1443
+
1444
+ # Create Trigger objects and add them to the table.
1445
+ rows_triggers.each do |row_trigger|
1446
+ table.add_trigger(Cassandra::Trigger.new(table,
1447
+ row_trigger['trigger_name'],
1448
+ row_trigger['options']))
1449
+ end
1450
+
1355
1451
  table
1356
1452
  end
1357
1453