datastax_rails 1.2.3 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
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="")