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.
- 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="")
|