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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.rdoc +20 -8
- data/config/schema.xml.erb +22 -19
- data/config/solrconfig.xml.erb +1 -1
- data/lib/cql-rb_extensions.rb +27 -0
- data/lib/datastax_rails.rb +13 -17
- data/lib/datastax_rails/associations/association.rb +1 -4
- data/lib/datastax_rails/associations/collection_proxy.rb +0 -13
- data/lib/datastax_rails/attribute_assignment.rb +28 -91
- data/lib/datastax_rails/attribute_methods.rb +109 -44
- data/lib/datastax_rails/attribute_methods/before_type_cast.rb +71 -0
- data/lib/datastax_rails/attribute_methods/dirty.rb +52 -11
- data/lib/datastax_rails/attribute_methods/primary_key.rb +87 -0
- data/lib/datastax_rails/attribute_methods/read.rb +120 -0
- data/lib/datastax_rails/attribute_methods/typecasting.rb +52 -21
- data/lib/datastax_rails/attribute_methods/write.rb +59 -0
- data/lib/datastax_rails/base.rb +227 -236
- data/lib/datastax_rails/cassandra_only_model.rb +25 -19
- data/lib/datastax_rails/column.rb +384 -0
- data/lib/datastax_rails/connection.rb +12 -13
- data/lib/datastax_rails/cql/alter_column_family.rb +0 -1
- data/lib/datastax_rails/cql/base.rb +15 -3
- data/lib/datastax_rails/cql/column_family.rb +2 -2
- data/lib/datastax_rails/cql/create_column_family.rb +7 -18
- data/lib/datastax_rails/cql/delete.rb +4 -9
- data/lib/datastax_rails/cql/insert.rb +2 -8
- data/lib/datastax_rails/cql/select.rb +4 -4
- data/lib/datastax_rails/cql/update.rb +8 -17
- data/lib/datastax_rails/dynamic_model.rb +98 -0
- data/lib/datastax_rails/payload_model.rb +19 -31
- data/lib/datastax_rails/persistence.rb +39 -54
- data/lib/datastax_rails/railtie.rb +1 -0
- data/lib/datastax_rails/reflection.rb +1 -1
- data/lib/datastax_rails/relation.rb +20 -20
- data/lib/datastax_rails/relation/batches.rb +18 -16
- data/lib/datastax_rails/relation/facet_methods.rb +1 -1
- data/lib/datastax_rails/relation/finder_methods.rb +6 -10
- data/lib/datastax_rails/relation/search_methods.rb +62 -48
- data/lib/datastax_rails/rsolr_client_wrapper.rb +1 -1
- data/lib/datastax_rails/schema/cassandra.rb +34 -62
- data/lib/datastax_rails/schema/migrator.rb +9 -24
- data/lib/datastax_rails/schema/solr.rb +13 -30
- data/lib/datastax_rails/schema_cache.rb +67 -0
- data/lib/datastax_rails/timestamps.rb +84 -11
- data/lib/datastax_rails/types/dirty_collection.rb +88 -0
- data/lib/datastax_rails/types/dynamic_list.rb +14 -0
- data/lib/datastax_rails/types/dynamic_map.rb +32 -0
- data/lib/datastax_rails/types/dynamic_set.rb +10 -0
- data/lib/datastax_rails/util/solr_repair.rb +4 -5
- data/lib/datastax_rails/validations.rb +6 -12
- data/lib/datastax_rails/validations/uniqueness.rb +0 -4
- data/lib/datastax_rails/version.rb +1 -1
- data/lib/datastax_rails/wide_storage_model.rb +13 -29
- data/lib/schema_migration.rb +4 -0
- data/spec/datastax_rails/associations_spec.rb +0 -1
- data/spec/datastax_rails/attribute_methods_spec.rb +9 -6
- data/spec/datastax_rails/base_spec.rb +26 -0
- data/spec/datastax_rails/column_spec.rb +238 -0
- data/spec/datastax_rails/cql/select_spec.rb +1 -1
- data/spec/datastax_rails/cql/update_spec.rb +2 -2
- data/spec/datastax_rails/persistence_spec.rb +29 -15
- data/spec/datastax_rails/relation/batches_spec.rb +5 -5
- data/spec/datastax_rails/relation/finder_methods_spec.rb +0 -20
- data/spec/datastax_rails/relation/search_methods_spec.rb +8 -0
- data/spec/datastax_rails/relation_spec.rb +7 -0
- data/spec/datastax_rails/schema/migrator_spec.rb +5 -10
- data/spec/datastax_rails/schema/solr_spec.rb +1 -1
- data/spec/datastax_rails/types/dynamic_list_spec.rb +20 -0
- data/spec/datastax_rails/types/dynamic_map_spec.rb +22 -0
- data/spec/datastax_rails/types/dynamic_set_spec.rb +16 -0
- data/spec/dummy/config/application.rb +2 -1
- data/spec/dummy/config/datastax.yml +6 -3
- data/spec/dummy/config/environments/development.rb +4 -5
- data/spec/dummy/config/environments/test.rb +0 -5
- data/spec/dummy/log/development.log +18 -0
- data/spec/dummy/log/test.log +36 -0
- data/spec/feature/dynamic_fields_spec.rb +9 -0
- data/spec/feature/overloaded_tables_spec.rb +24 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/support/default_consistency_shared_examples.rb +2 -2
- data/spec/support/models.rb +28 -14
- metadata +212 -188
- data/lib/datastax_rails/identity.rb +0 -64
- data/lib/datastax_rails/identity/abstract_key_factory.rb +0 -29
- data/lib/datastax_rails/identity/custom_key_factory.rb +0 -37
- data/lib/datastax_rails/identity/hashed_natural_key_factory.rb +0 -10
- data/lib/datastax_rails/identity/natural_key_factory.rb +0 -39
- data/lib/datastax_rails/identity/uuid_key_factory.rb +0 -27
- data/lib/datastax_rails/type.rb +0 -16
- data/lib/datastax_rails/types.rb +0 -9
- data/lib/datastax_rails/types/array_type.rb +0 -86
- data/lib/datastax_rails/types/base_type.rb +0 -42
- data/lib/datastax_rails/types/binary_type.rb +0 -19
- data/lib/datastax_rails/types/boolean_type.rb +0 -22
- data/lib/datastax_rails/types/date_type.rb +0 -23
- data/lib/datastax_rails/types/float_type.rb +0 -18
- data/lib/datastax_rails/types/integer_type.rb +0 -18
- data/lib/datastax_rails/types/string_type.rb +0 -16
- data/lib/datastax_rails/types/text_type.rb +0 -15
- data/lib/datastax_rails/types/time_type.rb +0 -23
- data/spec/datastax_rails/types/float_type_spec.rb +0 -31
- data/spec/datastax_rails/types/integer_type_spec.rb +0 -31
- 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
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
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(:
|
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
|
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(:
|
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
|
179
|
-
#
|
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(
|
257
|
+
def select(*fields)
|
247
258
|
if block_given?
|
248
|
-
to_a.select {|*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 +=
|
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(:
|
271
|
+
# Model.order(name: :desc)
|
260
272
|
#
|
261
273
|
# Model.order(:name).reverse_order.reverse_order
|
262
|
-
# Model.order(:
|
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.
|
272
|
-
# is
|
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
|
-
#
|
291
|
-
#
|
292
|
-
#
|
293
|
-
#
|
294
|
-
#
|
295
|
-
#
|
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
|
354
|
+
# in the form +attribute: value+ for equality comparisons.
|
344
355
|
#
|
345
|
-
# Model.where(:
|
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(:
|
350
|
-
# Model.where(:
|
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 => {:
|
363
|
-
# Model.where(:age => {:
|
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
|
411
|
+
# Expects a hash in the form +attribute: value+.
|
401
412
|
#
|
402
|
-
# Model.where_not(:
|
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(:
|
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
|
-
#
|
460
|
+
# * :fields => list of fields to search instead of the default of all fields
|
450
461
|
#
|
451
|
-
# Model.fulltext("john smith", :
|
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
|
-
#
|
478
|
-
#
|
479
|
-
#
|
480
|
-
#
|
481
|
-
#
|
482
|
-
#
|
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::
|
543
|
+
value.utc.strftime(DatastaxRails::Column::Format::SOLR_TIME_FORMAT)
|
533
544
|
when value.is_a?(DateTime)
|
534
|
-
value.to_time.utc.strftime(DatastaxRails::
|
545
|
+
value.to_time.utc.strftime(DatastaxRails::Column::Format::SOLR_TIME_FORMAT)
|
535
546
|
when value.is_a?(Date)
|
536
|
-
value.strftime(DatastaxRails::
|
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
|
@@ -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 =>
|
11
|
+
DatastaxRails::Cql::AlterColumnFamily.new(model.column_family).add(attribute => definition.cql_type).execute
|
12
12
|
end
|
13
|
-
if(definition.
|
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.
|
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}" =>
|
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
|
48
|
-
def
|
49
|
-
say "Creating
|
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,
|
74
|
-
|
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(
|
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 =
|
136
|
-
results.
|
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 =
|
144
|
-
exists = results.
|
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
|
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 =
|
150
|
-
row = results.
|
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 =
|
161
|
-
results.
|
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
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
-
|
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="")
|