cassandra_model 0.9.3.2 → 0.9.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +0 -0
  3. data/README.md +0 -0
  4. data/lib/cassandra_model/batch_reactor/future.rb +0 -0
  5. data/lib/cassandra_model/batch_reactor.rb +0 -0
  6. data/lib/cassandra_model/composite_record.rb +4 -2
  7. data/lib/cassandra_model/composite_record_static.rb +69 -37
  8. data/lib/cassandra_model/concurrency_helper.rb +19 -0
  9. data/lib/cassandra_model/connection_cache.rb +0 -0
  10. data/lib/cassandra_model/counter_record.rb +8 -4
  11. data/lib/cassandra_model/data_inquirer.rb +3 -3
  12. data/lib/cassandra_model/data_modelling.rb +0 -0
  13. data/lib/cassandra_model/data_set.rb +0 -0
  14. data/lib/cassandra_model/displayable_attributes.rb +30 -2
  15. data/lib/cassandra_model/global_callbacks.rb +0 -0
  16. data/lib/cassandra_model/logging.rb +0 -0
  17. data/lib/cassandra_model/meta_columns.rb +0 -0
  18. data/lib/cassandra_model/meta_table.rb +0 -0
  19. data/lib/cassandra_model/query_builder.rb +15 -6
  20. data/lib/cassandra_model/query_helper.rb +0 -0
  21. data/lib/cassandra_model/query_result.rb +0 -0
  22. data/lib/cassandra_model/raw_connection.rb +2 -14
  23. data/lib/cassandra_model/record.rb +103 -16
  24. data/lib/cassandra_model/record_debug.rb +25 -0
  25. data/lib/cassandra_model/result_paginator.rb +0 -0
  26. data/lib/cassandra_model/rotating_table.rb +3 -1
  27. data/lib/cassandra_model/single_token_batch.rb +0 -0
  28. data/lib/cassandra_model/single_token_counter_batch.rb +0 -0
  29. data/lib/cassandra_model/single_token_logged_batch.rb +0 -0
  30. data/lib/cassandra_model/single_token_unlogged_batch.rb +0 -0
  31. data/lib/cassandra_model/table_debug.rb +36 -0
  32. data/lib/cassandra_model/table_definition.rb +10 -3
  33. data/lib/cassandra_model/table_descriptor.rb +0 -0
  34. data/lib/cassandra_model/table_redux.rb +1 -0
  35. data/lib/cassandra_model/type_guessing.rb +8 -8
  36. data/lib/cassandra_model.rb +7 -0
  37. metadata +15 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 811a3063acc6a1abd58de21ba424e0784606718f
4
- data.tar.gz: af46520692a4f205f6cd8f996d928d09d50ef553
3
+ metadata.gz: be8e45a8dab05f33396f041ca36c48c5e1fe207b
4
+ data.tar.gz: a3ec0023e367251890116beb12ff834c281e2928
5
5
  SHA512:
6
- metadata.gz: 3e580bb73ed0999532c19b0a6ec881caa2b265ab0fead7bef262bd772d09eeac53885217777ee3a42245aaea02d6ee2c6f33f917e8cec5d67bb1ad1dd1b832d1
7
- data.tar.gz: f309db41c5212ce53996f4d5e3b71e3a1755e628a32ceeed0d3de36f451c984fb46b8406f702c15c1cdd9def00abc09f1a76b2b8e9819a1c26329b08a2b6f04c
6
+ metadata.gz: 530aee143ab413ec91369652ab008a735eaaeac79b9d562f5b5a137fde28ff8e3bf2b1058fb91b87a09bcab00fccc41ab8fe86139ea591ec15fdb553e72c67eb
7
+ data.tar.gz: 5b17cd82d99a77133afb742bdef04102b6399374f1c848bbecc29c495de43b85883c0bc12ce9f914d5ce0de86a503e64cd3a05e7698eed004d371d95f1c3a57c
data/LICENSE.txt CHANGED
File without changes
data/README.md CHANGED
File without changes
File without changes
File without changes
@@ -29,7 +29,9 @@ module CassandraModel
29
29
 
30
30
  def composite_rows
31
31
  (self.class.composite_defaults || []).map do |row|
32
- merged_attributes = attributes.merge(row)
32
+ merged_attributes = self.class.deferred_columns.inject(attributes.merge(row)) do |memo, column|
33
+ memo.merge!(column => public_send(column))
34
+ end
33
35
  self.class.new(merged_attributes, validate: false)
34
36
  end
35
37
  end
@@ -46,4 +48,4 @@ module CassandraModel
46
48
  end
47
49
  end
48
50
  end
49
- end
51
+ end
@@ -1,5 +1,8 @@
1
1
  module CassandraModel
2
2
  module CompositeRecordStatic
3
+ PK_MUTEX = Mutex.new
4
+ CK_MUTEX = Mutex.new
5
+
3
6
  extend Forwardable
4
7
 
5
8
  def_delegator :table_config, :composite_defaults=
@@ -26,16 +29,24 @@ module CassandraModel
26
29
 
27
30
  def composite_pk_map
28
31
  unless table_data.composite_pk_map
29
- table_data.composite_pk_map = {}
30
- columns
32
+ PK_MUTEX.synchronize do
33
+ return table_data.composite_pk_map if table_data.composite_pk_map
34
+
35
+ table_data.composite_pk_map = {}
36
+ columns
37
+ end
31
38
  end
32
39
  table_data.composite_pk_map
33
40
  end
34
41
 
35
42
  def composite_ck_map
36
43
  unless table_data.composite_ck_map
37
- table_data.composite_ck_map = {}
38
- columns
44
+ CK_MUTEX.synchronize do
45
+ return table_data.composite_ck_map if table_data.composite_ck_map
46
+
47
+ table_data.composite_ck_map = {}
48
+ columns
49
+ end
39
50
  end
40
51
  table_data.composite_ck_map
41
52
  end
@@ -63,8 +74,50 @@ module CassandraModel
63
74
  end
64
75
  end
65
76
 
77
+ def restriction_attributes(restriction)
78
+ updated_restriction = restriction.inject({}) do |memo, (key, value)|
79
+ updated_key = key_for_where_params(key)
80
+ memo.merge!(updated_key => value)
81
+ end
82
+
83
+ missing_keys = Set.new(internal_partition_key - updated_restriction.keys)
84
+ default_clause = composite_defaults.find { |row| (missing_keys ^ row.keys).empty? }
85
+ updated_restriction.merge!(default_clause) if default_clause
86
+ updated_restriction
87
+ end
88
+
89
+ def normalized_column(column)
90
+ column = super(column)
91
+
92
+ if column =~ /^rk_/ || column =~ /^ck_/
93
+ mapped_column(column)
94
+ else
95
+ column
96
+ end
97
+ end
98
+
99
+ def normalized_attributes(attributes)
100
+ attributes = super(attributes)
101
+
102
+ attributes.inject({}) do |memo, (column, value)|
103
+ memo.merge!(normalized_column(column) => value)
104
+ end
105
+ end
106
+
107
+ def select_columns(columns)
108
+ columns.map { |column| select_column(column) }
109
+ end
110
+
111
+ def select_column(column)
112
+ has_field?(column) ? column : mapped_column(column)
113
+ end
114
+
66
115
  private
67
116
 
117
+ def has_field?(column)
118
+ internal_columns.include?(column)
119
+ end
120
+
68
121
  def build_composite_map
69
122
  if table_config.composite_defaults
70
123
  table_config.composite_defaults.map { |row| row_composite_default(row) }
@@ -90,36 +143,27 @@ module CassandraModel
90
143
  end
91
144
 
92
145
  def select_clause(select)
93
- select = mapped_select_columns(select) if select
146
+ select = select_columns(select) if select
94
147
  super(select)
95
148
  end
96
149
 
97
150
  def order_by_clause(order_by)
98
- order_by = mapped_select_columns(order_by) if order_by
99
- super(order_by)
100
- end
101
-
102
- def mapped_select_columns(select)
103
- select.map do |column|
104
- if internal_columns.include?(column)
105
- column
106
- else
107
- mapped_column(column)
151
+ if order_by
152
+ order_by = [order_by] unless order_by.is_a?(Array)
153
+ order_by = order_by.map do |column|
154
+ if column.is_a?(Hash)
155
+ column, direction = column.first
156
+ {select_column(column) => direction}
157
+ else
158
+ select_column(column)
159
+ end
108
160
  end
109
161
  end
162
+ super(order_by)
110
163
  end
111
164
 
112
165
  def where_params(clause)
113
- updated_clause = clause.inject({}) do |memo, (key, value)|
114
- updated_key = key_for_where_params(key)
115
- memo.merge!(updated_key => value)
116
- end
117
-
118
- missing_keys = Set.new(internal_partition_key - updated_clause.keys)
119
- default_clause = composite_defaults.find { |row| (missing_keys ^ row.keys).empty? }
120
- updated_clause.merge!(default_clause) if default_clause
121
-
122
- super(updated_clause)
166
+ super restriction_attributes(clause)
123
167
  end
124
168
 
125
169
  def key_for_where_params(key)
@@ -149,18 +193,6 @@ module CassandraModel
149
193
  composite_pk_map[key] || key
150
194
  end
151
195
 
152
- def row_attributes(row)
153
- row = super(row)
154
-
155
- row.inject({}) do |memo, (column, value)|
156
- if column =~ /^rk_/ || column =~ /^ck_/
157
- memo.merge!(mapped_column(column) => value)
158
- else
159
- memo.merge!(column => value)
160
- end
161
- end
162
- end
163
-
164
196
  def mapped_column(column)
165
197
  (composite_ck_map[column] || composite_pk_map[column] || column)
166
198
  end
@@ -0,0 +1,19 @@
1
+ module CassandraModel
2
+ module ConcurrencyHelper
3
+ private
4
+
5
+ def safe_getset_variable(mutex, name, &block)
6
+ result = instance_variable_get(name)
7
+ return result if result
8
+
9
+ mutex.synchronize do
10
+ raise Cassandra::Errors::InvalidError.new('Connection invalidated!', 'Dummy') if !!@shutdown
11
+
12
+ result = instance_variable_get(name)
13
+ return result if result
14
+
15
+ instance_variable_set(name, block.call)
16
+ end
17
+ end
18
+ end
19
+ end
File without changes
@@ -5,16 +5,20 @@ module CassandraModel
5
5
  counter_clause = counter_clause(options)
6
6
  row_key = internal_primary_key.values
7
7
  statement = increment_statement(counter_clause)
8
+ column_values = options.values + row_key
9
+
10
+ validation_error = validate_primary_key!(statement, column_values)
11
+ return validation_error if validation_error
8
12
 
9
13
  future = if batch_reactor
10
- execute_async_in_batch(statement, options.values + row_key)
14
+ execute_async_in_batch(statement, column_values)
11
15
  else
12
- session.execute_async(statement, *options.values, *row_key, write_query_options)
16
+ session.execute_async(statement, *column_values, write_query_options)
13
17
  end
14
18
  future.on_success { execute_callback(:record_saved) }
15
19
  future.on_failure do |error|
16
20
  Logging.logger.error("Error incrementing #{self.class}: #{error}")
17
- execute_callback(:save_record_failed, error)
21
+ execute_callback(:save_record_failed, error, statement, column_values)
18
22
  end.then { self }
19
23
  end
20
24
 
@@ -29,7 +33,7 @@ module CassandraModel
29
33
  private
30
34
 
31
35
  def internal_primary_key
32
- internal_attributes.slice(*self.class.internal_primary_key)
36
+ self.class.internal_primary_key.inject({}) { |memo, key| memo.merge!(key => internal_attributes[key]) }
33
37
  end
34
38
 
35
39
  def increment_statement(counter_clause)
@@ -2,7 +2,7 @@ module CassandraModel
2
2
  class DataInquirer
3
3
  include TypeGuessing
4
4
 
5
- attr_reader :partition_key, :column_defaults, :is_sharding
5
+ attr_reader :partition_key, :column_defaults, :shard_column
6
6
 
7
7
  def initialize
8
8
  @partition_key = Hash.new { |hash, key| hash[key] = :text }
@@ -20,8 +20,8 @@ module CassandraModel
20
20
  self
21
21
  end
22
22
 
23
- def shards_queries
24
- @is_sharding = true
23
+ def shards_queries(column = :shard)
24
+ @shard_column = column
25
25
  end
26
26
 
27
27
  def composite_rows
File without changes
File without changes
@@ -5,6 +5,10 @@ module CassandraModel
5
5
  table_config.display_attributes = map ? map : columns
6
6
  end
7
7
 
8
+ def filter_display_attributes(*filter_columns)
9
+ table_config.display_attributes = columns - filter_columns
10
+ end
11
+
8
12
  def displayable_attributes
9
13
  table_config.display_attributes
10
14
  end
@@ -19,18 +23,42 @@ module CassandraModel
19
23
  if displayable_attributes
20
24
  displayable_attributes.is_a?(Hash) ? mapped_as_json : sliced_displayable_attributes
21
25
  else
22
- attributes
26
+ json_attributes
23
27
  end
24
28
  end
25
29
 
26
30
  private
27
31
 
32
+ def json_attributes
33
+ json_attributes = attributes.keys.inject({}) do |memo, column|
34
+ case column_type(column)
35
+ when :blob
36
+ when :timestamp
37
+ memo[column] = attributes[column].to_i
38
+ when :timeuuid
39
+ memo[column] = attributes[column].to_s
40
+ when :uuid
41
+ memo[column] = attributes[column].to_s
42
+ else
43
+ memo[column] = attributes[column]
44
+ end
45
+ memo
46
+ end
47
+ self.class.deferred_columns.inject(json_attributes) do |memo, column|
48
+ memo.merge!(column => public_send(column))
49
+ end
50
+ end
51
+
52
+ def column_type(column)
53
+ self.class.cassandra_columns[self.class.select_column(column)]
54
+ end
55
+
28
56
  def mapped_as_json
29
57
  sliced_displayable_attributes.inject({}) { |memo, (key, value)| memo.merge!(displayable_attributes[key] => value) }
30
58
  end
31
59
 
32
60
  def sliced_displayable_attributes
33
- attributes.slice(*displayable_attributes_slice)
61
+ json_attributes.slice(*displayable_attributes_slice)
34
62
  end
35
63
 
36
64
  def displayable_attributes_slice
File without changes
File without changes
File without changes
File without changes
@@ -82,15 +82,11 @@ module CassandraModel
82
82
  end
83
83
 
84
84
  def select(*columns)
85
- @options[:select] ||= []
86
- @options[:select].concat(columns)
87
- self
85
+ append_option(columns, :select)
88
86
  end
89
87
 
90
88
  def order(*columns)
91
- @options[:order_by] ||= []
92
- @options[:order_by].concat(columns)
93
- self
89
+ append_option(columns, :order_by)
94
90
  end
95
91
 
96
92
  def limit(limit)
@@ -110,6 +106,19 @@ module CassandraModel
110
106
 
111
107
  private
112
108
 
109
+ def append_option(columns, option)
110
+ @options[option] ||= []
111
+ if columns.first.is_a?(Hash)
112
+ columns = columns.first.map do |column, direction|
113
+ {column => direction}
114
+ end
115
+ @options[option].concat(columns)
116
+ else
117
+ @options[option].concat(columns)
118
+ end
119
+ self
120
+ end
121
+
113
122
  def pluck_values(columns, result)
114
123
  result.attributes.slice(*columns).values
115
124
  end
File without changes
File without changes
@@ -19,6 +19,8 @@ module CassandraModel
19
19
  timeout: 10
20
20
  }.freeze
21
21
 
22
+ include ConcurrencyHelper
23
+
22
24
  def initialize(config_name = nil)
23
25
  @config_name = config_name
24
26
  @statement_cache = {}
@@ -127,20 +129,6 @@ module CassandraModel
127
129
  end
128
130
  end
129
131
 
130
- def safe_getset_variable(mutex, name, &block)
131
- result = instance_variable_get(name)
132
- return result if result
133
-
134
- mutex.synchronize do
135
- raise Cassandra::Errors::InvalidError.new('Connection invalidated!', 'Dummy') if !!@shutdown
136
-
137
- result = instance_variable_get(name)
138
- return result if result
139
-
140
- instance_variable_set(name, block.call)
141
- end
142
- end
143
-
144
132
  def load_config
145
133
  if File.exists?(config_path)
146
134
  config = yaml_config || {}
@@ -3,9 +3,10 @@ require_relative 'meta_columns'
3
3
 
4
4
  module CassandraModel
5
5
  class Record
6
- extend CassandraModel::QueryHelper
7
- include CassandraModel::MetaColumns
8
- include CassandraModel::DisplayableAttributes
6
+ extend QueryHelper
7
+ include MetaColumns
8
+ include DisplayableAttributes
9
+ include RecordDebug
9
10
 
10
11
  attr_reader :attributes, :valid, :execution_info
11
12
 
@@ -25,6 +26,8 @@ module CassandraModel
25
26
  :composite_primary_key,
26
27
 
27
28
  :composite_shard_key,
29
+
30
+ :cassandra_columns,
28
31
  ) # Using this instead of OpenStruct, as there seems to be a bug in JRuby that causes this to get mangled over time
29
32
  ConfigureableAttributes = Struct.new(
30
33
  :table_name,
@@ -116,9 +119,21 @@ module CassandraModel
116
119
  end
117
120
 
118
121
  def inspected_attributes
119
- attributes.map do |key, value|
120
- %Q{#{key}: "#{value.to_s.truncate(53)}"}
121
- end * ', '
122
+ columns = self.class.cassandra_columns.map do |column, type|
123
+ self.class.normalized_column(column) unless type == :blob
124
+ end.compact.uniq
125
+
126
+ base_attributes = columns.map do |column|
127
+ if (value = attributes[column])
128
+ %Q{#{column}: "#{value.to_s.truncate(53)}"}
129
+ else
130
+ "#{column}: (empty)"
131
+ end
132
+ end
133
+ base_attributes += deferred_columns.map do |column|
134
+ %Q{#{column}: "#{public_send(column)}"}
135
+ end
136
+ base_attributes * ', '
122
137
  end
123
138
 
124
139
  protected
@@ -232,17 +247,56 @@ module CassandraModel
232
247
 
233
248
  def save_row_async(options)
234
249
  statement = statement(query_for_save(options))
250
+ save_column_values = column_values
251
+
252
+ validation_error = validate_primary_key!(statement, save_column_values)
253
+ return validation_error if validation_error
254
+
235
255
  future = if batch_reactor
236
- execute_async_in_batch(statement, column_values)
256
+ execute_async_in_batch(statement, save_column_values)
237
257
  else
238
- session.execute_async(statement, *column_values, write_query_options(options))
258
+ session.execute_async(statement, *save_column_values, write_query_options(options))
239
259
  end
240
260
  future.on_failure do |error|
241
- Logging.logger.error("Error saving #{self.class}: #{error}")
242
- execute_callback(:save_record_failed, error)
261
+ handle_save_error(error, save_column_values, statement)
243
262
  end
244
263
  end
245
264
 
265
+ def validate_primary_key!(statement, save_column_values)
266
+ missing_primary_columns = invalid_primary_key_parts
267
+ if missing_primary_columns.present?
268
+ error = invalid_key_error(missing_primary_columns, statement)
269
+ handle_save_error(error, save_column_values, statement)
270
+ Cassandra::Future.error(error)
271
+ end
272
+ end
273
+
274
+ def handle_save_error(error, save_column_values, statement)
275
+ Logging.logger.error("Error saving #{self.class}: #{error}")
276
+ execute_callback(:save_record_failed, error, statement, save_column_values)
277
+ end
278
+
279
+ def invalid_key_error(missing_primary_columns, statement)
280
+ Cassandra::Errors::InvalidError.new(missing_key_message(missing_primary_columns), statement)
281
+ end
282
+
283
+ def missing_key_message(missing_primary_columns)
284
+ "Invalid primary key parts #{missing_primary_columns.map(&:to_s).map(&:inspect) * ', '}"
285
+ end
286
+
287
+ def invalid_primary_key_parts
288
+ save_attributes = internal_attributes
289
+ if self.class.internal_partition_key.one? && save_attributes[internal_partition_key_part_one].blank?
290
+ [internal_partition_key_part_one]
291
+ else
292
+ self.class.internal_primary_key.select { |value| save_attributes[value].nil? }
293
+ end
294
+ end
295
+
296
+ def internal_partition_key_part_one
297
+ self.class.internal_partition_key.first
298
+ end
299
+
246
300
  def execute_callback(callback, *extra_params)
247
301
  GlobalCallbacks.call(callback, self, *extra_params)
248
302
  end
@@ -369,6 +423,32 @@ module CassandraModel
369
423
 
370
424
  alias :create! :create
371
425
 
426
+ def restriction_attributes(restriction)
427
+ restriction
428
+ end
429
+
430
+ def normalized_column(column)
431
+ column.to_sym
432
+ end
433
+
434
+ def normalized_attributes(attributes)
435
+ attributes.symbolize_keys
436
+ end
437
+
438
+ def select_columns(columns)
439
+ columns
440
+ end
441
+
442
+ def select_column(column)
443
+ column
444
+ end
445
+
446
+ def cassandra_columns
447
+ table_data.cassandra_columns ||= table.connection.keyspace.table(table_name).columns.inject({}) do |memo, column|
448
+ memo.merge!(column.name.to_sym => column.type)
449
+ end
450
+ end
451
+
372
452
  def request_async(clause, options = {})
373
453
  page_size = options[:page_size]
374
454
  trace = options[:trace]
@@ -398,7 +478,18 @@ module CassandraModel
398
478
  end
399
479
 
400
480
  def order_by_clause(order_by)
401
- " ORDER BY #{multi_csv_clause(order_by)}" if order_by
481
+ if order_by
482
+ order_by = [order_by] unless order_by.is_a?(Array)
483
+ ordering_columns = order_by.map do |column|
484
+ if column.is_a?(Hash)
485
+ column, direction = column.first
486
+ "#{column} #{direction.upcase}"
487
+ else
488
+ column
489
+ end
490
+ end
491
+ " ORDER BY #{multi_csv_clause(ordering_columns)}"
492
+ end
402
493
  end
403
494
 
404
495
  def first_async(clause = {}, options = {})
@@ -526,14 +617,10 @@ module CassandraModel
526
617
  end
527
618
 
528
619
  def record_from_result(row, execution_info, invalidate_result)
529
- attributes = row_attributes(row)
620
+ attributes = normalized_attributes(row)
530
621
  new(attributes, execution_info: execution_info).tap { |result| result.invalidate! if invalidate_result }
531
622
  end
532
623
 
533
- def row_attributes(row)
534
- row.symbolize_keys
535
- end
536
-
537
624
  def manual_shard(&block)
538
625
  before_save { attributes[shard_key] = instance_eval(&block) }
539
626
  end
@@ -0,0 +1,25 @@
1
+ module CassandraModel
2
+ module RecordDebug
3
+ DebugDump = Struct.new(
4
+ :record,
5
+ :klass,
6
+ :table,
7
+ :table_config,
8
+ :table_data,
9
+ :attributes,
10
+ :internal_attributes,
11
+ )
12
+
13
+ def debug
14
+ DebugDump.new(
15
+ self,
16
+ self.class,
17
+ self.class.table,
18
+ self.class.send(:table_config),
19
+ self.class.send(:table_data),
20
+ attributes,
21
+ internal_attributes,
22
+ )
23
+ end
24
+ end
25
+ end
File without changes
@@ -1,6 +1,7 @@
1
1
  module CassandraModel
2
2
  class RotatingTable
3
3
  extend Forwardable
4
+ include TableDebug
4
5
 
5
6
  def_delegators :first_table, :primary_key, :partition_key, :clustering_columns, :columns
6
7
  def_delegators :table, :connection, :name, :truncate!
@@ -14,6 +15,7 @@ module CassandraModel
14
15
  end
15
16
 
16
17
  def allow_truncation!
18
+ @allow_truncation = true
17
19
  tables.each(&:allow_truncation!)
18
20
  end
19
21
 
@@ -46,4 +48,4 @@ module CassandraModel
46
48
  end
47
49
 
48
50
  end
49
- end
51
+ end
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,36 @@
1
+ module CassandraModel
2
+ module TableDebug
3
+ Debug = Struct.new(
4
+ :name,
5
+ :table,
6
+ :rotating_tables,
7
+ :first_table,
8
+ :connection_name,
9
+ :connection,
10
+ :partition_key,
11
+ :clustering_columns,
12
+ :primary_key,
13
+ :columns,
14
+ :allows_truncation?,
15
+ :rotating_schedule,
16
+ )
17
+
18
+ def debug
19
+ first_table = (@tables.first if @tables)
20
+ Debug.new(
21
+ name,
22
+ table,
23
+ @tables,
24
+ first_table,
25
+ @connection_name,
26
+ connection,
27
+ partition_key,
28
+ clustering_columns,
29
+ primary_key,
30
+ columns,
31
+ !!@allow_truncation,
32
+ @schedule,
33
+ )
34
+ end
35
+ end
36
+ end
@@ -2,12 +2,19 @@ module CassandraModel
2
2
  class TableDefinition
3
3
  attr_reader :name
4
4
 
5
- def self.from_data_model(name, inquirer, data_set)
5
+ def self.from_data_model(table_name, inquirer, data_set)
6
6
  partition_key = inquirer_partition_key(inquirer)
7
- partition_key.merge!(rk_shard: :int) if inquirer.is_sharding
7
+ if inquirer.shard_column
8
+ if inquirer.shard_column.is_a?(Hash)
9
+ column_name, type = inquirer.shard_column.first
10
+ partition_key.merge!(:"rk_#{column_name}" => type)
11
+ else
12
+ partition_key.merge!(:"rk_#{inquirer.shard_column}" => :int)
13
+ end
14
+ end
8
15
  clustering_columns = table_set_clustering_columns(data_set)
9
16
  remaining_columns = table_set_remaining_columns(data_set)
10
- new(name: name, partition_key: partition_key,
17
+ new(name: table_name, partition_key: partition_key,
11
18
  clustering_columns: clustering_columns,
12
19
  remaining_columns: remaining_columns)
13
20
  end
File without changes
@@ -1,6 +1,7 @@
1
1
  module CassandraModel
2
2
  class TableRedux
3
3
  extend Forwardable
4
+ include TableDebug
4
5
 
5
6
  attr_reader :name
6
7
 
@@ -13,21 +13,21 @@ module TypeGuessing
13
13
  private
14
14
 
15
15
  def postfix_type
16
- if column =~ /_at$/
16
+ if column =~ /(^|_)at$/
17
17
  :timestamp
18
- elsif column =~ /_at_id$/
18
+ elsif column =~ /(^|_)at_id$/
19
19
  :timeuuid
20
- elsif column =~ /_id$/
20
+ elsif column =~ /(^|_)id$/
21
21
  :uuid
22
- elsif column =~ /_(price|average|stddev)$/
22
+ elsif column =~ /(^|_)(price|average|stddev)$/
23
23
  :double
24
- elsif column =~ /_(total|count)$/
24
+ elsif column =~ /(^|_)(total|count)$/
25
25
  counter_type
26
- elsif column =~ /_(year|day|month|index)$/
26
+ elsif column =~ /(^|_)(year|day|month|index)$/
27
27
  :int
28
- elsif column =~ /_data/
28
+ elsif column =~ /(^|_)data/
29
29
  :blob
30
- elsif column =~ /_map$/
30
+ elsif column =~ /(^|_)map$/
31
31
  'map<string, string>'
32
32
  end
33
33
  end
@@ -14,11 +14,16 @@
14
14
  # limitations under the License.
15
15
  #++
16
16
 
17
+ require 'yaml'
18
+ require 'logger'
17
19
  require 'concurrent'
18
20
  require 'cassandra'
21
+ require 'thomas_utils'
22
+ require 'batch_reactor'
19
23
  require 'active_support/all'
20
24
  require 'active_support/core_ext/class/attribute_accessors'
21
25
 
26
+ require 'cassandra_model/concurrency_helper'
22
27
  require 'cassandra_model/logging'
23
28
  require 'cassandra_model/global_callbacks'
24
29
  require 'cassandra_model/single_token_batch'
@@ -30,11 +35,13 @@ require 'cassandra_model/batch_reactor/future'
30
35
  require 'cassandra_model/raw_connection'
31
36
  require 'cassandra_model/connection_cache'
32
37
  require 'cassandra_model/table_definition'
38
+ require 'cassandra_model/table_debug'
33
39
  require 'cassandra_model/table_redux'
34
40
  require 'cassandra_model/result_paginator'
35
41
  require 'cassandra_model/query_result'
36
42
  require 'cassandra_model/query_builder'
37
43
  require 'cassandra_model/displayable_attributes'
44
+ require 'cassandra_model/record_debug'
38
45
  require 'cassandra_model/record'
39
46
  require 'cassandra_model/counter_record'
40
47
  require 'cassandra_model/table_descriptor'
metadata CHANGED
@@ -1,69 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cassandra_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3.2
4
+ version: 0.9.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas RM Rogers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-02 00:00:00.000000000 Z
11
+ date: 2015-12-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cassandra-driver
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activesupport
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '4.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '4.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: batch_reactor
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: 0.0.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.0.1
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: thomas_utils
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: 0.1.13
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: 0.1.13
69
69
  description: |-
@@ -81,6 +81,7 @@ files:
81
81
  - lib/cassandra_model/batch_reactor/future.rb
82
82
  - lib/cassandra_model/composite_record.rb
83
83
  - lib/cassandra_model/composite_record_static.rb
84
+ - lib/cassandra_model/concurrency_helper.rb
84
85
  - lib/cassandra_model/connection_cache.rb
85
86
  - lib/cassandra_model/counter_record.rb
86
87
  - lib/cassandra_model/data_inquirer.rb
@@ -96,12 +97,14 @@ files:
96
97
  - lib/cassandra_model/query_result.rb
97
98
  - lib/cassandra_model/raw_connection.rb
98
99
  - lib/cassandra_model/record.rb
100
+ - lib/cassandra_model/record_debug.rb
99
101
  - lib/cassandra_model/result_paginator.rb
100
102
  - lib/cassandra_model/rotating_table.rb
101
103
  - lib/cassandra_model/single_token_batch.rb
102
104
  - lib/cassandra_model/single_token_counter_batch.rb
103
105
  - lib/cassandra_model/single_token_logged_batch.rb
104
106
  - lib/cassandra_model/single_token_unlogged_batch.rb
107
+ - lib/cassandra_model/table_debug.rb
105
108
  - lib/cassandra_model/table_definition.rb
106
109
  - lib/cassandra_model/table_descriptor.rb
107
110
  - lib/cassandra_model/table_redux.rb
@@ -116,12 +119,12 @@ require_paths:
116
119
  - lib
117
120
  required_ruby_version: !ruby/object:Gem::Requirement
118
121
  requirements:
119
- - - '>='
122
+ - - ">="
120
123
  - !ruby/object:Gem::Version
121
124
  version: '0'
122
125
  required_rubygems_version: !ruby/object:Gem::Requirement
123
126
  requirements:
124
- - - '>='
127
+ - - ">="
125
128
  - !ruby/object:Gem::Version
126
129
  version: '0'
127
130
  requirements: []