cassandra_model 0.9.3.2 → 0.9.18

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 (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: []