datastax_rails 1.2.3 → 2.0.3

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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +20 -8
  4. data/config/schema.xml.erb +22 -19
  5. data/config/solrconfig.xml.erb +1 -1
  6. data/lib/cql-rb_extensions.rb +27 -0
  7. data/lib/datastax_rails.rb +13 -17
  8. data/lib/datastax_rails/associations/association.rb +1 -4
  9. data/lib/datastax_rails/associations/collection_proxy.rb +0 -13
  10. data/lib/datastax_rails/attribute_assignment.rb +28 -91
  11. data/lib/datastax_rails/attribute_methods.rb +109 -44
  12. data/lib/datastax_rails/attribute_methods/before_type_cast.rb +71 -0
  13. data/lib/datastax_rails/attribute_methods/dirty.rb +52 -11
  14. data/lib/datastax_rails/attribute_methods/primary_key.rb +87 -0
  15. data/lib/datastax_rails/attribute_methods/read.rb +120 -0
  16. data/lib/datastax_rails/attribute_methods/typecasting.rb +52 -21
  17. data/lib/datastax_rails/attribute_methods/write.rb +59 -0
  18. data/lib/datastax_rails/base.rb +227 -236
  19. data/lib/datastax_rails/cassandra_only_model.rb +25 -19
  20. data/lib/datastax_rails/column.rb +384 -0
  21. data/lib/datastax_rails/connection.rb +12 -13
  22. data/lib/datastax_rails/cql/alter_column_family.rb +0 -1
  23. data/lib/datastax_rails/cql/base.rb +15 -3
  24. data/lib/datastax_rails/cql/column_family.rb +2 -2
  25. data/lib/datastax_rails/cql/create_column_family.rb +7 -18
  26. data/lib/datastax_rails/cql/delete.rb +4 -9
  27. data/lib/datastax_rails/cql/insert.rb +2 -8
  28. data/lib/datastax_rails/cql/select.rb +4 -4
  29. data/lib/datastax_rails/cql/update.rb +8 -17
  30. data/lib/datastax_rails/dynamic_model.rb +98 -0
  31. data/lib/datastax_rails/payload_model.rb +19 -31
  32. data/lib/datastax_rails/persistence.rb +39 -54
  33. data/lib/datastax_rails/railtie.rb +1 -0
  34. data/lib/datastax_rails/reflection.rb +1 -1
  35. data/lib/datastax_rails/relation.rb +20 -20
  36. data/lib/datastax_rails/relation/batches.rb +18 -16
  37. data/lib/datastax_rails/relation/facet_methods.rb +1 -1
  38. data/lib/datastax_rails/relation/finder_methods.rb +6 -10
  39. data/lib/datastax_rails/relation/search_methods.rb +62 -48
  40. data/lib/datastax_rails/rsolr_client_wrapper.rb +1 -1
  41. data/lib/datastax_rails/schema/cassandra.rb +34 -62
  42. data/lib/datastax_rails/schema/migrator.rb +9 -24
  43. data/lib/datastax_rails/schema/solr.rb +13 -30
  44. data/lib/datastax_rails/schema_cache.rb +67 -0
  45. data/lib/datastax_rails/timestamps.rb +84 -11
  46. data/lib/datastax_rails/types/dirty_collection.rb +88 -0
  47. data/lib/datastax_rails/types/dynamic_list.rb +14 -0
  48. data/lib/datastax_rails/types/dynamic_map.rb +32 -0
  49. data/lib/datastax_rails/types/dynamic_set.rb +10 -0
  50. data/lib/datastax_rails/util/solr_repair.rb +4 -5
  51. data/lib/datastax_rails/validations.rb +6 -12
  52. data/lib/datastax_rails/validations/uniqueness.rb +0 -4
  53. data/lib/datastax_rails/version.rb +1 -1
  54. data/lib/datastax_rails/wide_storage_model.rb +13 -29
  55. data/lib/schema_migration.rb +4 -0
  56. data/spec/datastax_rails/associations_spec.rb +0 -1
  57. data/spec/datastax_rails/attribute_methods_spec.rb +9 -6
  58. data/spec/datastax_rails/base_spec.rb +26 -0
  59. data/spec/datastax_rails/column_spec.rb +238 -0
  60. data/spec/datastax_rails/cql/select_spec.rb +1 -1
  61. data/spec/datastax_rails/cql/update_spec.rb +2 -2
  62. data/spec/datastax_rails/persistence_spec.rb +29 -15
  63. data/spec/datastax_rails/relation/batches_spec.rb +5 -5
  64. data/spec/datastax_rails/relation/finder_methods_spec.rb +0 -20
  65. data/spec/datastax_rails/relation/search_methods_spec.rb +8 -0
  66. data/spec/datastax_rails/relation_spec.rb +7 -0
  67. data/spec/datastax_rails/schema/migrator_spec.rb +5 -10
  68. data/spec/datastax_rails/schema/solr_spec.rb +1 -1
  69. data/spec/datastax_rails/types/dynamic_list_spec.rb +20 -0
  70. data/spec/datastax_rails/types/dynamic_map_spec.rb +22 -0
  71. data/spec/datastax_rails/types/dynamic_set_spec.rb +16 -0
  72. data/spec/dummy/config/application.rb +2 -1
  73. data/spec/dummy/config/datastax.yml +6 -3
  74. data/spec/dummy/config/environments/development.rb +4 -5
  75. data/spec/dummy/config/environments/test.rb +0 -5
  76. data/spec/dummy/log/development.log +18 -0
  77. data/spec/dummy/log/test.log +36 -0
  78. data/spec/feature/dynamic_fields_spec.rb +9 -0
  79. data/spec/feature/overloaded_tables_spec.rb +24 -0
  80. data/spec/spec_helper.rb +1 -1
  81. data/spec/support/default_consistency_shared_examples.rb +2 -2
  82. data/spec/support/models.rb +28 -14
  83. metadata +212 -188
  84. data/lib/datastax_rails/identity.rb +0 -64
  85. data/lib/datastax_rails/identity/abstract_key_factory.rb +0 -29
  86. data/lib/datastax_rails/identity/custom_key_factory.rb +0 -37
  87. data/lib/datastax_rails/identity/hashed_natural_key_factory.rb +0 -10
  88. data/lib/datastax_rails/identity/natural_key_factory.rb +0 -39
  89. data/lib/datastax_rails/identity/uuid_key_factory.rb +0 -27
  90. data/lib/datastax_rails/type.rb +0 -16
  91. data/lib/datastax_rails/types.rb +0 -9
  92. data/lib/datastax_rails/types/array_type.rb +0 -86
  93. data/lib/datastax_rails/types/base_type.rb +0 -42
  94. data/lib/datastax_rails/types/binary_type.rb +0 -19
  95. data/lib/datastax_rails/types/boolean_type.rb +0 -22
  96. data/lib/datastax_rails/types/date_type.rb +0 -23
  97. data/lib/datastax_rails/types/float_type.rb +0 -18
  98. data/lib/datastax_rails/types/integer_type.rb +0 -18
  99. data/lib/datastax_rails/types/string_type.rb +0 -16
  100. data/lib/datastax_rails/types/text_type.rb +0 -15
  101. data/lib/datastax_rails/types/time_type.rb +0 -23
  102. data/spec/datastax_rails/types/float_type_spec.rb +0 -31
  103. data/spec/datastax_rails/types/integer_type_spec.rb +0 -31
  104. data/spec/datastax_rails/types/time_type_spec.rb +0 -28
@@ -11,6 +11,8 @@ module DatastaxRails
11
11
  #
12
12
  # Model.where(:name => 'johndoe', :active => true).allow_filtering
13
13
  #
14
+ # NOTE that this only applies when doing a search via a cassandra index.
15
+ #
14
16
  # @return [DatastaxRails::Relation] a new Relation object
15
17
  def allow_filtering
16
18
  clone.tap do |r|
@@ -24,14 +26,22 @@ module DatastaxRails
24
26
  #
25
27
  # Model.consistency(:local_quorum).find("12345")
26
28
  #
27
- # Note that Solr searches (basically anything but find by id) don't allow you
28
- # to specify the consistency level. DSR sort of gets around this by taking the
29
- # search results and then going to Cassandra to retrieve the objects by ID using
30
- # the consistency you specified. However, it is possible that you might not get
31
- # all of the records you are expecting if the SOLR node you were talking to hasn't
32
- # been updated yet with the results. In practice, this should not happen for
33
- # records that were created over your connection, but it is possible for other
34
- # connections to create records that you can't see yet.
29
+ # Note that Solr searches don't allow you to specify the consistency level.
30
+ # DSR sort of gets around this by taking the search results and then going
31
+ # to Cassandra to retrieve the objects by ID using the consistency you specified.
32
+ # However, it is possible that you might not get all of the records you are
33
+ # expecting if the SOLR node you were talking to hasn't been updated yet with
34
+ # the results. In practice, this should not happen for records that were created
35
+ # over your connection, but it is possible for other connections to create records
36
+ # that you can't see yet.
37
+ #
38
+ # Valid consistency levels are:
39
+ # * :any
40
+ # * :one
41
+ # * :quorum
42
+ # * :local_quorum (if using Network Topology)
43
+ # * :each_quorum (if using Network Topology)
44
+ # * :all
35
45
  #
36
46
  # @param level [Symbol, String] the level to set the consistency at
37
47
  # @return [DatastaxRails::Relation] a new Relation object
@@ -118,7 +128,8 @@ module DatastaxRails
118
128
 
119
129
  # WillPaginate compatible method for paginating
120
130
  #
121
- # Model.paginate(:page => 2, :per_page => 10)
131
+ # Model.paginate(page: 2, per_page: 10)
132
+ #
122
133
  # @param options [Hash] the options to pass to paginate
123
134
  # @option options [String, Fixnum] :page the page number to retrieve
124
135
  # @option options [String, Fixnum] :per_page the number of records to include on a page
@@ -144,7 +155,7 @@ module DatastaxRails
144
155
  # after-the-fact as the groups are returned as hash of Collection objects.
145
156
  #
146
157
  # Because SOLR is doing the grouping work, we can only group on single-valued
147
- # fields (i.e., not +text+ or +array+ attributes). In the future, SOLR may
158
+ # fields (i.e., not +text+ or collections). In the future, SOLR may
148
159
  # support grouping on multi-valued fields.
149
160
  #
150
161
  # NOTE: Group names will be lower-cased
@@ -172,11 +183,11 @@ module DatastaxRails
172
183
  # the value is :desc
173
184
  #
174
185
  # Model.order(:name)
175
- # Model.order(:name => :desc)
186
+ # Model.order(name: :desc)
176
187
  #
177
188
  # WARNING: If this call is combined with #with_cassandra, you can only
178
- # order on the clustering column of the primary key. If this doesn't
179
- # mean anything to you, then you probably don't want to use these together.
189
+ # order on the cluster_by column. If this doesn't mean anything to you,
190
+ # then you probably don't want to use these together.
180
191
  #
181
192
  # @param attribute [Symbol, String, Hash] the attribute to sort by and optionally the direction to sort in
182
193
  # @return [DatastaxRails::Relation] a new Relation object
@@ -243,12 +254,13 @@ module DatastaxRails
243
254
  #
244
255
  # The exception to this rule is when an attribute is lazy-loaded (e.g., binary).
245
256
  # In that case, it is never retrieved until you call the getter method.
246
- def select(value = Proc.new)
257
+ def select(*fields)
247
258
  if block_given?
248
- to_a.select {|*block_args| value.call(*block_args) }
259
+ to_a.select {|*block_args| yield(*block_args) }
249
260
  else
261
+ railse ArgumentError, 'Call this with at least one field' if fields.empty?
250
262
  clone.tap do |r|
251
- r.select_values += Array.wrap(value)
263
+ r.select_values += fields
252
264
  end
253
265
  end
254
266
  end
@@ -256,10 +268,10 @@ module DatastaxRails
256
268
  # Reverses the order of the results. The following are equivalent:
257
269
  #
258
270
  # Model.order(:name).reverse_order
259
- # Model.order(:name => :desc)
271
+ # Model.order(name: :desc)
260
272
  #
261
273
  # Model.order(:name).reverse_order.reverse_order
262
- # Model.order(:name => :asc)
274
+ # Model.order(name: :asc)
263
275
  #
264
276
  # @return [DatastaxRails::Relation] a new Relation object
265
277
  def reverse_order
@@ -268,9 +280,8 @@ module DatastaxRails
268
280
  end
269
281
  end
270
282
 
271
- # By default, DatastaxRails uses the LuceneQueryParser. Note that this
272
- # is a change from the underlying Sunspot gem. Sunspot defaults to the
273
- # +disMax+ query parser. If you want to use that, then pass that in here.
283
+ # By default, DatastaxRails uses the LuceneQueryParser. disMax
284
+ # is also supported. eDisMax probably works as well.
274
285
  #
275
286
  # *This only applies to fulltext queries*
276
287
  #
@@ -287,12 +298,12 @@ module DatastaxRails
287
298
  end
288
299
 
289
300
  # Have SOLR compute stats for a given numeric field. Status computed include:
290
- # * min
291
- # * max
292
- # * sum
293
- # * sum of squares
294
- # * mean
295
- # * standard deviation
301
+ # * min
302
+ # * max
303
+ # * sum
304
+ # * sum of squares
305
+ # * mean
306
+ # * standard deviation
296
307
  #
297
308
  # Model.compute_stats(:price)
298
309
  # Model.compute_stats(:price, :quantity)
@@ -340,14 +351,14 @@ module DatastaxRails
340
351
  end
341
352
 
342
353
  # Specifies restrictions (scoping) on the result set. Expects a hash
343
- # in the form +attribute => value+ for equality comparisons.
354
+ # in the form +attribute: value+ for equality comparisons.
344
355
  #
345
- # Model.where(:group_id => '1234', :active => 'Y')
356
+ # Model.where(group_id: '1234', active: true)
346
357
  #
347
358
  # The value of the comparison does not need to be a scalar. For example:
348
359
  #
349
- # Model.where(:name => ["Bob", "Tom", "Sally"])
350
- # Model.where(:age => 18..65)
360
+ # Model.where(name: ["Bob", "Tom", "Sally"]) # Finds where name is any of the three names
361
+ # Model.where(age: 18..65) # Finds where age is anywhere in the range
351
362
  #
352
363
  # Inequality comparisons such as greater_than and less_than are
353
364
  # specified via chaining:
@@ -359,8 +370,8 @@ module DatastaxRails
359
370
  # that can be done with a single call. This is useful for remote APIs and
360
371
  # such.
361
372
  #
362
- # Model.where(:created_at => {:greater_than => 1.day.ago})
363
- # Model.where(:age => {:less_than => 65})
373
+ # Model.where(:created_at => {greater_than: 1.day.ago})
374
+ # Model.where(:age => {less_than: 65})
364
375
  #
365
376
  # NOTE: Due to the way SOLR handles range queries, all greater/less than
366
377
  # queries are actually greater/less than or equal to queries.
@@ -371,7 +382,7 @@ module DatastaxRails
371
382
  # @return [DatastaxRails::Relation] a new Relation object
372
383
  def where(attribute)
373
384
  return self if attribute.blank?
374
- if attribute.is_a?(Symbol)
385
+ if attribute.is_a?(Symbol) || attribute.is_a?(String)
375
386
  WhereProxy.new(self, attribute)
376
387
  else
377
388
  clone.tap do |r|
@@ -397,14 +408,14 @@ module DatastaxRails
397
408
  end
398
409
 
399
410
  # Specifies restrictions (scoping) that should not match the result set.
400
- # Expects a hash in the form +attribute => value+.
411
+ # Expects a hash in the form +attribute: value+.
401
412
  #
402
- # Model.where_not(:group_id => '1234', :active => 'N')
413
+ # Model.where_not(group_id: '1234', active: false)
403
414
  #
404
415
  # Passing an array will search for records where none of the array entries
405
416
  # are present
406
417
  #
407
- # Model.where_not(:group_id => ['1234', '5678'])
418
+ # Model.where_not(group_id: ['1234', '5678'])
408
419
  #
409
420
  # The above would find all models where group id is neither 1234 or 5678.
410
421
  #
@@ -446,9 +457,9 @@ module DatastaxRails
446
457
  #
447
458
  # You can also pass in an options hash with the following options:
448
459
  #
449
- # * :fields => list of fields to search instead of the default of all fields
460
+ # * :fields => list of fields to search instead of the default of all fields
450
461
  #
451
- # Model.fulltext("john smith", :fields => [:title])
462
+ # Model.fulltext("john smith", fields: [:title])
452
463
  #
453
464
  # @param query [String] a fulltext query to pass to solr
454
465
  # @param opts [Hash] an optional options hash to modify the fulltext query
@@ -474,12 +485,12 @@ module DatastaxRails
474
485
  # In addition to the array of field names to highlight, you can pass in an
475
486
  # options hash with the following options:
476
487
  #
477
- # * :snippets => number of highlight snippets to return
478
- # * :fragsize => number of characters for each snippet length
479
- # * :pre_tag => text which appears before a highlighted term
480
- # * :post_tag => text which appears after a highlighted term
481
- # * :merge_contiguous => collapse contiguous fragments into a single fragment
482
- # * :use_fast_vector => enables the Solr FastVectorHighlighter
488
+ # * :snippets => number of highlight snippets to return
489
+ # * :fragsize => number of characters for each snippet length
490
+ # * :pre_tag => text which appears before a highlighted term
491
+ # * :post_tag => text which appears after a highlighted term
492
+ # * :merge_contiguous => collapse contiguous fragments into a single fragment
493
+ # * :use_fast_vector => enables the Solr FastVectorHighlighter
483
494
  #
484
495
  # Note: When enabling +:use_fast_vector+, the highlighted fields must be also have
485
496
  # +:term_vectors+, +:term_positions+, and +:term_offsets+ enabled.
@@ -529,11 +540,11 @@ module DatastaxRails
529
540
  return value unless use_solr_value
530
541
  case
531
542
  when value.is_a?(Time)
532
- value.utc.strftime(DatastaxRails::Types::TimeType::FORMAT)
543
+ value.utc.strftime(DatastaxRails::Column::Format::SOLR_TIME_FORMAT)
533
544
  when value.is_a?(DateTime)
534
- value.to_time.utc.strftime(DatastaxRails::Types::TimeType::FORMAT)
545
+ value.to_time.utc.strftime(DatastaxRails::Column::Format::SOLR_TIME_FORMAT)
535
546
  when value.is_a?(Date)
536
- value.strftime(DatastaxRails::Types::TimeType::FORMAT)
547
+ value.strftime(DatastaxRails::Column::Format::SOLR_TIME_FORMAT)
537
548
  when value.is_a?(Array)
538
549
  value.collect {|v| v.to_s.gsub(/ /,"\\ ") }.join(" OR ")
539
550
  when value.is_a?(Fixnum)
@@ -549,6 +560,9 @@ module DatastaxRails
549
560
  end
550
561
  end
551
562
 
563
+ # WhereProxy objects act as a placeholder for queries in which #where does not include a value.
564
+ # In this case, #where must be chained with #greater_than, #less_than, or #equal_to to return
565
+ # a new relation.
552
566
  class WhereProxy #:nodoc:
553
567
  def initialize(relation, attribute, invert = false) #:nodoc:
554
568
  @relation, @attribute, @invert = relation, attribute, invert
@@ -15,7 +15,7 @@ module DatastaxRails
15
15
  end
16
16
  @rsolr.__send__(sym, *args, &block)
17
17
  rescue Errno::ECONNREFUSED
18
- tries ||= DatastaxRails::Base.thrift_client.options[:retries] + 1
18
+ tries ||= 3
19
19
  tries -= 1
20
20
  if tries > 0
21
21
  # Force cassandra connection to roll
@@ -8,9 +8,9 @@ module DatastaxRails
8
8
  unless column_exists?(model.column_family.to_s, attribute.to_s)
9
9
  count += 1
10
10
  say "Adding column '#{attribute}'", :subitem
11
- DatastaxRails::Cql::AlterColumnFamily.new(model.column_family).add(attribute => :text).execute
11
+ DatastaxRails::Cql::AlterColumnFamily.new(model.column_family).add(attribute => definition.cql_type).execute
12
12
  end
13
- if(definition.indexed == :cassandra)
13
+ if(definition.options[:cql_index] && !definition.options[:solr_index])
14
14
  unless index_exists?(model.column_family.to_s, attribute.to_s)
15
15
  if index_exists?(model.column_family.to_s, attribute.to_s)
16
16
  count += 1
@@ -21,12 +21,12 @@ module DatastaxRails
21
21
  say "Creating cassandra index on #{attribute.to_s}", :subitem
22
22
  DatastaxRails::Cql::CreateIndex.new(cassandra_index_cql_name(model.column_family.to_s, attribute.to_s)).on(model.column_family.to_s).column(attribute.to_s).execute
23
23
  end
24
- elsif(definition.indexed == :both)
24
+ elsif(definition.options[:cql_index])
25
25
  unless column_exists?(model.column_family.to_s, "__#{attribute.to_s}")
26
26
  # Create and populate the new column
27
27
  count += 1
28
28
  say "Adding column '__#{attribute}'", :subitem
29
- DatastaxRails::Cql::AlterColumnFamily.new(model.column_family).add("__#{attribute.to_s}" => model.attribute_definitions[attribute].coder.options[:cassandra_type]).execute
29
+ DatastaxRails::Cql::AlterColumnFamily.new(model.column_family).add("__#{attribute.to_s}" => definition.cql_type).execute
30
30
  say "Populating column '__#{attribute}' (this might take a while)", :subitem
31
31
  export = "echo \"copy #{model.column_family.to_s} (key, #{attribute.to_s}) TO 'dsr_export.csv';\" | cqlsh #{model.current_server}"
32
32
  import = "echo \"copy #{model.column_family.to_s} (key, __#{attribute.to_s}) FROM 'dsr_export.csv';\" | cqlsh #{model.current_server}"
@@ -44,34 +44,18 @@ module DatastaxRails
44
44
  count
45
45
  end
46
46
 
47
- # Creates a payload column family via CQL
48
- def create_payload_column_family(model)
49
- say "Creating Payload Column Family", :subitem
50
- columns = {:chunk => :int, :payload => :text}
51
- DatastaxRails::Cql::CreateColumnFamily.new(model.column_family).key_name(:digest).key_columns("digest, chunk").key_type(:text).columns(columns).with("COMPACT STORAGE").execute
52
- end
53
-
54
- # Creates a wide-storage column family via CQL
55
- def create_wide_storage_column_family(model)
56
- say "Creating Wide-Storage Column Family", :subitem
57
- key_name = model.key_factory.attributes.join
58
- cluster_by = model.cluster_by.keys.first
59
- cluster_dir = model.cluster_by.values.first
60
- key_columns = "#{key_name}, #{cluster_by}"
61
- columns = {}
62
- model.attribute_definitions.each {|k,v| columns[k] = v.coder.options[:cassandra_type] unless k.to_s == key_name}
63
- DatastaxRails::Cql::CreateColumnFamily.new(model.column_family).key_name(key_name).key_columns(key_columns).key_type(:text).columns(columns).
64
- with("CLUSTERING ORDER BY (#{cluster_by} #{cluster_dir.to_s.upcase})").execute
65
- end
66
-
67
- # Creates a regular cassandra-only column family via CQL
68
- def create_cassandra_column_family(model)
69
- say "Creating Cassandra-Only Column Family", :subitem
70
- key_name = "key"
71
- key_columns = "#{key_name}"
47
+ # Creates a CQL3 backed column family
48
+ def create_cql3_column_family(model)
49
+ say "Creating Column Family via CQL3", :subitem
72
50
  columns = {}
73
- model.attribute_definitions.each {|k,v| columns[k] = v.coder.options[:cassandra_type]}
74
- DatastaxRails::Cql::CreateColumnFamily.new(model.column_family).key_name(key_name).key_columns(key_columns).key_type(:text).columns(columns).execute
51
+ model.attribute_definitions.each {|k,col| columns[k] = col.cql_type}
52
+ pk = model.primary_key.to_s
53
+ if(model.respond_to?(:cluster_by) && model.cluster_by.present?)
54
+ pk += ", #{model.cluster_by.to_s}"
55
+ end
56
+ cql = DatastaxRails::Cql::CreateColumnFamily.new(model.column_family).primary_key(pk).columns(columns)
57
+ cql.with(model.create_options) if model.create_options
58
+ cql.execute
75
59
  end
76
60
 
77
61
  # Creates the named keyspace
@@ -79,7 +63,7 @@ module DatastaxRails
79
63
  opts = { :name => keyspace.to_s,
80
64
  :strategy_class => 'org.apache.cassandra.locator.NetworkTopologyStrategy'}.with_indifferent_access.merge(options)
81
65
 
82
- if(connection.keyspaces.collect(&:name).include?(keyspace.to_s))
66
+ if(keyspace_exists?(keyspace.to_s))
83
67
  say "Keyspace #{keyspace.to_s} already exists"
84
68
  return false
85
69
  else
@@ -98,26 +82,6 @@ module DatastaxRails
98
82
  DatastaxRails::Cql::DropKeyspace.new(@keyspace.to_s).execute
99
83
  end
100
84
 
101
- # Checks the Cassandra system tables to see if the key column is named properly. This is
102
- # a migration method to handle the fact that Solr used to create column families with "KEY"
103
- # instead of the now default "key".
104
- def check_key_name(cf)
105
- count = 0
106
- if(cf.respond_to?(:column_family))
107
- cf = cf.column_family
108
- end
109
- klass = OpenStruct.new(:column_family => 'system.schema_columnfamilies', :default_consistency => 'QUORUM')
110
- cql = DatastaxRails::Cql::ColumnFamily.new(klass)
111
- results = CassandraCQL::Result.new(cql.select("key_alias, key_aliases").conditions('keyspace_name' => @keyspace, 'columnfamily_name' => cf).execute)
112
- result = results.fetch
113
- if(result && (result['key_alias'] == 'KEY' || result['key_aliases'].include?('KEY')) && (result['key_aliases'].blank? || !result['key_aliases'].include?('key')))
114
- count += 1
115
- say "Renaming KEY column", :subitem
116
- DatastaxRails::Cql::AlterColumnFamily.new(cf).rename("KEY",'key').execute
117
- end
118
- count
119
- end
120
-
121
85
  # Computes the expected solr index name as reported by CQL.
122
86
  def solr_index_cql_name(cf, column)
123
87
  "#{@keyspace}_#{cf.to_s}_#{column.to_s}_index"
@@ -128,27 +92,35 @@ module DatastaxRails
128
92
  "#{cf.to_s}_#{column.to_s}_idx"
129
93
  end
130
94
 
95
+ # Checks the Cassandra system tables to see if a keyspace exists
96
+ def keyspace_exists?(keyspace)
97
+ klass = OpenStruct.new(:column_family => 'system.schema_keyspaces', :default_consistency => 'QUORUM')
98
+ cql = DatastaxRails::Cql::ColumnFamily.new(klass)
99
+ results = cql.select("count(*)").conditions('keyspace_name' => keyspace).execute
100
+ results.first['count'].to_i > 0
101
+ end
102
+
131
103
  # Checks the Cassandra system tables to see if a column family exists
132
104
  def column_family_exists?(cf)
133
105
  klass = OpenStruct.new(:column_family => 'system.schema_columnfamilies', :default_consistency => 'QUORUM')
134
106
  cql = DatastaxRails::Cql::ColumnFamily.new(klass)
135
- results = CassandraCQL::Result.new(cql.select("count(*)").conditions('keyspace_name' => @keyspace, 'columnfamily_name' => cf).execute)
136
- results.fetch['count'] > 0
107
+ results = cql.select("count(*)").conditions('keyspace_name' => @keyspace, 'columnfamily_name' => cf).execute
108
+ results.first['count'] > 0
137
109
  end
138
110
 
139
111
  # Checks the Cassandra system tables to see if a column exists on a column family
140
112
  def column_exists?(cf, col)
141
113
  klass = OpenStruct.new(:column_family => 'system.schema_columns', :default_consistency => 'QUORUM')
142
114
  cql = DatastaxRails::Cql::ColumnFamily.new(klass)
143
- results = CassandraCQL::Result.new(cql.select("count(*)").conditions('keyspace_name' => @keyspace, 'columnfamily_name' => cf, 'column_name' => col).execute)
144
- exists = results.fetch['count'] > 0
115
+ results = cql.select("count(*)").conditions('keyspace_name' => @keyspace, 'columnfamily_name' => cf, 'column_name' => col).execute
116
+ exists = results.first['count'] > 0
145
117
  unless exists
146
- # We need to check if it's part of the primary key (ugh)
118
+ # We need to check if it's part of an alias (ugh)
147
119
  klass = OpenStruct.new(:column_family => 'system.schema_columnfamilies', :default_consistency => 'QUORUM')
148
120
  cql = DatastaxRails::Cql::ColumnFamily.new(klass)
149
- results = CassandraCQL::Result.new(cql.select("column_aliases, key_aliases").conditions('keyspace_name' => @keyspace, 'columnfamily_name' => cf).execute)
150
- row = results.fetch
151
- exists = row['key_aliases'].include?(col.to_s) || row['column_aliases'].include?(col.to_s)
121
+ results = cql.select("column_aliases, key_aliases, value_alias").conditions('keyspace_name' => @keyspace, 'columnfamily_name' => cf).execute
122
+ row = results.first
123
+ exists = row['key_aliases'].include?(col.to_s) || row['column_aliases'].include?(col.to_s) || (row['value_alias'] && row['value_alias'].include?(col.to_s))
152
124
  end
153
125
  exists
154
126
  end
@@ -157,8 +129,8 @@ module DatastaxRails
157
129
  def index_exists?(cf, col)
158
130
  klass = OpenStruct.new(:column_family => 'system.schema_columns', :default_consistency => 'QUORUM')
159
131
  cql = DatastaxRails::Cql::ColumnFamily.new(klass)
160
- results = CassandraCQL::Result.new(cql.select("index_name").conditions('keyspace_name' => @keyspace, 'columnfamily_name' => cf, 'column_name' => col).execute)
161
- results.fetch['index_name'] != nil
132
+ results = cql.select("index_name").conditions('keyspace_name' => @keyspace, 'columnfamily_name' => cf, 'column_name' => col).execute
133
+ results.first['index_name'] != nil
162
134
  end
163
135
  end
164
136
  end
@@ -33,28 +33,15 @@ module DatastaxRails
33
33
  def migrate_one(model, force = false)
34
34
  count = 0
35
35
  say_with_time("Migrating #{model.name} to latest version") do
36
- if model.payload_model?
37
- unless column_family_exists?(model.column_family.to_s)
38
- create_payload_column_family(model)
39
- count += 1
40
- end
41
- elsif model.wide_storage_model?
42
- unless column_family_exists?(model.column_family.to_s)
43
- create_wide_storage_column_family(model)
44
- count += 1
45
- end
46
- count += check_missing_schema(model)
47
- elsif model <= DatastaxRails::CassandraOnlyModel
48
- unless column_family_exists?(model.column_family.to_s)
49
- create_cassandra_column_family(model)
50
- count += 1
51
- end
52
- count += check_key_name(model)
53
- count += check_missing_schema(model)
54
- else
55
- count += check_key_name(model)
36
+ unless column_family_exists?(model.column_family.to_s)
37
+ create_cql3_column_family(model)
38
+ count += 1
39
+ end
40
+
41
+ count += check_missing_schema(model)
42
+
43
+ unless model <= DatastaxRails::CassandraOnlyModel
56
44
  count += upload_solr_configuration(model, force)
57
- count += check_missing_schema(model)
58
45
  end
59
46
  end
60
47
  count
@@ -70,10 +57,8 @@ module DatastaxRails
70
57
  def check_schema_migrations
71
58
  unless column_family_exists?('schema_migrations')
72
59
  say "Creating schema_migrations column family"
73
- connection.execute_cql_query(DatastaxRails::Cql::CreateColumnFamily.new('schema_migrations').key_type(:text).columns(:digest => :text, :solrconfig => :text, :stopwords => :text).to_cql)
60
+ DatastaxRails::Cql::CreateColumnFamily.new('schema_migrations').primary_key('cf').columns(:cf => :text, :digest => :text, :solrconfig => :text, :stopwords => :text).execute
74
61
  end
75
-
76
- check_key_name('schema_migrations')
77
62
  end
78
63
 
79
64
  def write(text="")