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
@@ -10,46 +10,29 @@ module DatastaxRails
|
|
10
10
|
@fields = []
|
11
11
|
@copy_fields = []
|
12
12
|
@fulltext_fields = []
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
@fields.push({ :name => attr.name,
|
18
|
-
:type => coder.options[:solr_type].to_s,
|
19
|
-
:indexed => (coder.options[:indexed] == :solr || coder.options[:indexed] == :both).to_s,
|
20
|
-
:stored => coder.options[:stored].to_s,
|
21
|
-
:multi_valued => coder.options[:multi_valued].to_s })
|
22
|
-
end
|
23
|
-
if coder.options[:sortable] && coder.options[:tokenized]
|
24
|
-
@fields.push({ :name => "sort_" + attr.name,
|
25
|
-
:type => "string",
|
26
|
-
:indexed => true,
|
27
|
-
:stored => false,
|
28
|
-
:multi_valued => false })
|
29
|
-
@copy_fields.push({ :source => attr.name, :dest => "sort_" + attr.name }) if (coder.options[:indexed] || coder.options[:stored])
|
30
|
-
end
|
31
|
-
if coder.options[:fulltext]
|
32
|
-
@fulltext_fields << attr.name if (coder.options[:indexed] || coder.options[:stored])
|
33
|
-
end
|
13
|
+
if model <= WideStorageModel
|
14
|
+
@primary_key = "(#{model.primary_key},#{model.cluster_by})"
|
15
|
+
else
|
16
|
+
@primary_key = model.primary_key
|
34
17
|
end
|
35
|
-
|
36
|
-
|
18
|
+
@custom_fields = ""
|
19
|
+
@columns = model.attribute_definitions.values
|
37
20
|
@fields.sort! {|a,b| a[:name] <=> b[:name]}
|
38
21
|
@copy_fields.sort! {|a,b| a[:source] <=> b[:source]}
|
39
22
|
@fulltext_fields.sort!
|
40
23
|
|
41
24
|
if Rails.root.join('config','solr',"#{model.column_family}-schema.xml.erb").exist?
|
42
25
|
say "Using custom schema for #{model.name}", :subitem
|
43
|
-
ERB.new(Rails.root.join('config','solr',"#{model.column_family}-schema.xml.erb").read).result(binding)
|
26
|
+
ERB.new(Rails.root.join('config','solr',"#{model.column_family}-schema.xml.erb").read, 0, '>').result(binding)
|
44
27
|
else
|
45
|
-
ERB.new(File.read(File.join(File.dirname(__FILE__),"..","..","..","config","schema.xml.erb"))).result(binding)
|
28
|
+
ERB.new(File.read(File.join(File.dirname(__FILE__),"..","..","..","config","schema.xml.erb")), 0, '>').result(binding)
|
46
29
|
end
|
47
30
|
end
|
48
31
|
|
49
32
|
# Sends a command to Solr instructing it to reindex the data. The data is reindexed in the background,
|
50
33
|
# and the new index is swapped in once it is finished.
|
51
|
-
def reindex_solr(model)
|
52
|
-
url = "#{DatastaxRails::Base.solr_base_url}/admin/cores?action=RELOAD&name=#{DatastaxRails::Base.config[:keyspace]}.#{model.column_family}&reindex=true&deleteAll
|
34
|
+
def reindex_solr(model, destructive=false)
|
35
|
+
url = "#{DatastaxRails::Base.solr_base_url}/admin/cores?action=RELOAD&name=#{DatastaxRails::Base.config[:keyspace]}.#{model.column_family}&reindex=true&deleteAll=#{destructive.to_s}"
|
53
36
|
say "Posting reindex command to '#{url}'", :subitem
|
54
37
|
`curl -s -X POST '#{url}'`
|
55
38
|
say "Reindexing will run in the background", :subitem
|
@@ -89,11 +72,11 @@ module DatastaxRails
|
|
89
72
|
stopwords_digest = Digest::SHA1.hexdigest(stopwords)
|
90
73
|
schema_digest = Digest::SHA1.hexdigest(schema)
|
91
74
|
|
92
|
-
newcf = !
|
75
|
+
newcf = !column_exists?(model.column_family, 'solr_query')
|
93
76
|
force ||= newcf
|
94
77
|
|
95
|
-
results = DatastaxRails::Cql::Select.new(SchemaMigration, ['*']).conditions(:
|
96
|
-
sm_digests =
|
78
|
+
results = DatastaxRails::Cql::Select.new(SchemaMigration, ['*']).conditions(:cf => model.column_family).execute
|
79
|
+
sm_digests = results.first || {}
|
97
80
|
|
98
81
|
solr_url = "#{DatastaxRails::Base.solr_base_url}/resource/#{@keyspace}.#{model.column_family}"
|
99
82
|
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module DatastaxRails
|
2
|
+
class SchemaCache
|
3
|
+
attr_reader :primary_keys, :tables
|
4
|
+
attr_reader :connection
|
5
|
+
|
6
|
+
def initialize(conn)
|
7
|
+
@connection = conn
|
8
|
+
@tables = {}
|
9
|
+
|
10
|
+
@columns = Hash.new do |h, table_name|
|
11
|
+
h[table_name] = connection.columns(table_name, "#{table_name} Columns")
|
12
|
+
end
|
13
|
+
|
14
|
+
@columns_hash = Hash.new do |h, table_name|
|
15
|
+
h[table_name] = Hash[columns[table_name].map { |col|
|
16
|
+
[col.name, col]
|
17
|
+
}]
|
18
|
+
end
|
19
|
+
|
20
|
+
@primary_keys = Hash.new do |h, table_name|
|
21
|
+
h[table_name] = table_exists?(table_name) ? connection.primary_key(table_name) : nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# A cached lookup for table existence.
|
26
|
+
def table_exists?(name)
|
27
|
+
return @tables[name] if @tables.key? name
|
28
|
+
|
29
|
+
@tables[name] = connection.table_exists?(name)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Get the columns for a table
|
33
|
+
def columns(table = nil)
|
34
|
+
if table
|
35
|
+
@columns[table]
|
36
|
+
else
|
37
|
+
@columns
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Get the columns for a table as a hash, key is the column name
|
42
|
+
# value is the column object.
|
43
|
+
def columns_hash(table = nil)
|
44
|
+
if table
|
45
|
+
@columns_hash[table]
|
46
|
+
else
|
47
|
+
@columns_hash
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Clears out internal caches
|
52
|
+
def clear!
|
53
|
+
@columns.clear
|
54
|
+
@columns_hash.clear
|
55
|
+
@primary_keys.clear
|
56
|
+
@tables.clear
|
57
|
+
end
|
58
|
+
|
59
|
+
# Clear out internal caches for table with +table_name+.
|
60
|
+
def clear_table_cache!(table_name)
|
61
|
+
@columns.delete table_name
|
62
|
+
@columns_hash.delete table_name
|
63
|
+
@primary_keys.delete table_name
|
64
|
+
@tables.delete table_name
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -1,25 +1,98 @@
|
|
1
1
|
module DatastaxRails
|
2
|
+
# = DatastaxRails Timestamps
|
3
|
+
#
|
4
|
+
# DatastaxRails automatically timestamps create and update operations if the
|
5
|
+
# table has fields named <tt>created_at</tt> or <tt>updated_at</tt>.
|
6
|
+
#
|
7
|
+
# Timestamping can be turned off by setting:
|
8
|
+
#
|
9
|
+
# DatastaxRails::Base.record_timestamps = false
|
2
10
|
module Timestamps
|
3
11
|
extend ActiveSupport::Concern
|
4
12
|
|
5
13
|
included do
|
6
|
-
|
7
|
-
|
14
|
+
class_attribute :record_timestamps
|
15
|
+
self.record_timestamps = true
|
16
|
+
end
|
8
17
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
18
|
+
def initialize_dup(other) # :nodoc:
|
19
|
+
clear_timestamp_attributes
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def _create_record(*args)
|
26
|
+
if self.record_timestamps
|
27
|
+
current_time = current_time_from_proper_timezone
|
28
|
+
|
29
|
+
all_timestamp_attributes.each do |column|
|
30
|
+
if respond_to?(column) && respond_to?("#{column}=") && self.send(column).nil?
|
31
|
+
write_attribute(column.to_s, current_time)
|
32
|
+
end
|
15
33
|
end
|
16
34
|
end
|
17
35
|
|
18
|
-
|
19
|
-
|
20
|
-
|
36
|
+
super
|
37
|
+
end
|
38
|
+
|
39
|
+
def _update_record(*args)
|
40
|
+
if should_record_timestamps?
|
41
|
+
current_time = current_time_from_proper_timezone
|
42
|
+
|
43
|
+
timestamp_attributes_for_update_in_model.each do |column|
|
44
|
+
column = column.to_s
|
45
|
+
next if attribute_changed?(column)
|
46
|
+
write_attribute(column, current_time)
|
21
47
|
end
|
22
48
|
end
|
49
|
+
super
|
50
|
+
end
|
51
|
+
|
52
|
+
def should_record_timestamps?
|
53
|
+
self.record_timestamps && (changed? || (attributes.keys & self.class.serialized_attributes.keys).present?)
|
54
|
+
end
|
55
|
+
|
56
|
+
def timestamp_attributes_for_create_in_model
|
57
|
+
timestamp_attributes_for_create.select { |c| self.class.column_names.include?(c.to_s) }
|
58
|
+
end
|
59
|
+
|
60
|
+
def timestamp_attributes_for_update_in_model
|
61
|
+
timestamp_attributes_for_update.select { |c| self.class.column_names.include?(c.to_s) }
|
62
|
+
end
|
63
|
+
|
64
|
+
def all_timestamp_attributes_in_model
|
65
|
+
timestamp_attributes_for_create_in_model + timestamp_attributes_for_update_in_model
|
66
|
+
end
|
67
|
+
|
68
|
+
def timestamp_attributes_for_update
|
69
|
+
[:updated_at]
|
70
|
+
end
|
71
|
+
|
72
|
+
def timestamp_attributes_for_create
|
73
|
+
[:created_at]
|
74
|
+
end
|
75
|
+
|
76
|
+
def all_timestamp_attributes
|
77
|
+
timestamp_attributes_for_create + timestamp_attributes_for_update
|
78
|
+
end
|
79
|
+
|
80
|
+
def max_updated_column_timestamp
|
81
|
+
if (timestamps = timestamp_attributes_for_update.map { |attr| self[attr] }.compact).present?
|
82
|
+
timestamps.map { |ts| ts.to_time }.max
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def current_time_from_proper_timezone
|
87
|
+
self.class.default_timezone == :utc ? Time.now.utc : Time.now
|
88
|
+
end
|
89
|
+
|
90
|
+
# Clear attributes and changed_attributes
|
91
|
+
def clear_timestamp_attributes
|
92
|
+
all_timestamp_attributes_in_model.each do |attribute_name|
|
93
|
+
self[attribute_name] = nil
|
94
|
+
changed_attributes.delete(attribute_name)
|
95
|
+
end
|
23
96
|
end
|
24
97
|
end
|
25
98
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# An extension to normal arrays and hashes that allow for tracking of dirty values. This is
|
2
|
+
# used by ActiveModel's change tracking framework.
|
3
|
+
module DatastaxRails
|
4
|
+
module Types
|
5
|
+
module DirtyCollection
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
attr_accessor :record, :name
|
10
|
+
|
11
|
+
methods = [:<<, :delete, :[]=, :add, :subtract, :store, :push, :pop, :unshift, :shift, :insert, :clear] +
|
12
|
+
ActiveSupport::HashWithIndifferentAccess.instance_methods(true).select{|m| m.to_s.ends_with?('!')} +
|
13
|
+
Array.instance_methods(true).select{|m| m.to_s.ends_with?('!')} +
|
14
|
+
Set.instance_methods(true).select{|m| m.to_s.ends_with?('!')}
|
15
|
+
|
16
|
+
methods.each do |m|
|
17
|
+
if self.instance_methods.include?(m)
|
18
|
+
alias_method "___#{m}", m
|
19
|
+
original_method = self.instance_method(m)
|
20
|
+
define_method(m) do |*args, &block|
|
21
|
+
modifying do
|
22
|
+
original_method.bind(self).call(*args, &block)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize(record, name, collection)
|
30
|
+
@record = record
|
31
|
+
@name = name.to_s
|
32
|
+
|
33
|
+
super(collection)
|
34
|
+
organize_collection
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete(obj)
|
38
|
+
modifying do
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.ignore_modifications
|
44
|
+
original = $dsr_ignore_modifications
|
45
|
+
$dsr_ignore_modifications = true
|
46
|
+
result = yield
|
47
|
+
$dsr_ignore_modifications = original
|
48
|
+
result
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def modifying
|
53
|
+
# So there's a problem with overriding the map! method on Array.
|
54
|
+
# When we do the update to record.attributes, HashWithIndifferentAccess
|
55
|
+
# calls .map! on our Array. This causes infinite recursion which
|
56
|
+
# I find is generally not a desired behavior. We use a variable
|
57
|
+
# to tell if we've already hijacked the call.
|
58
|
+
if $dsr_ignore_modifications
|
59
|
+
yield
|
60
|
+
else
|
61
|
+
DirtyCollection.ignore_modifications do
|
62
|
+
unless record.changed_attributes.key?(name)
|
63
|
+
original = dup
|
64
|
+
end
|
65
|
+
|
66
|
+
result = yield
|
67
|
+
|
68
|
+
organize_collection
|
69
|
+
|
70
|
+
if !record.changed_attributes.key?(name) && original != self
|
71
|
+
record.changed_attributes[name] = original
|
72
|
+
end
|
73
|
+
|
74
|
+
record.attributes[name] = self
|
75
|
+
|
76
|
+
result
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# A hook to allow implementing classes to muck with the collection
|
82
|
+
# before we check it for equality.
|
83
|
+
def organize_collection
|
84
|
+
# No-op
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module DatastaxRails
|
2
|
+
module Types
|
3
|
+
# A collection type that allows you to store ordered arrays in Cassandra.
|
4
|
+
# Changes are tracked by hooking into ActiveModel's built-in change
|
5
|
+
# tracking.
|
6
|
+
class DynamicList < Array
|
7
|
+
include DirtyCollection
|
8
|
+
|
9
|
+
def initialize(record, name, collection)
|
10
|
+
super(record, name, collection || [])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module DatastaxRails
|
2
|
+
module Types
|
3
|
+
# A collection type that allows you to store key/value pairs in Cassandra.
|
4
|
+
# Changes are tracked by hooking into ActiveModel's built-in change
|
5
|
+
# tracking.
|
6
|
+
#
|
7
|
+
# Keys are converted to have the name of the collection prefixed
|
8
|
+
# to them as this is how the Solr/Cassandra integration converts
|
9
|
+
# between them and dynamic fields.
|
10
|
+
class DynamicMap < ActiveSupport::HashWithIndifferentAccess
|
11
|
+
include DirtyCollection
|
12
|
+
|
13
|
+
def dup
|
14
|
+
self.class.new(record, name, self).tap do |new_hash|
|
15
|
+
new_hash.default = default
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def [](key)
|
20
|
+
super(convert_key(key))
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
def convert_key(key)
|
25
|
+
unless key.to_s.starts_with?(name)
|
26
|
+
key = name + key.to_s
|
27
|
+
end
|
28
|
+
super(key)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module DatastaxRails
|
2
|
+
module Types
|
3
|
+
# A collection type that allows you to store an un-ordered, unique
|
4
|
+
# set of entries. Changes are tracked by hooking into ActiveModel's
|
5
|
+
# built-in change tracking.
|
6
|
+
class DynamicSet < Set
|
7
|
+
include DirtyCollection
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -1,12 +1,11 @@
|
|
1
1
|
module DatastaxRails
|
2
2
|
module SolrRepair
|
3
3
|
def repair_solr
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
encoded = {}
|
5
|
+
self.attributes.keys.each do |column_name|
|
6
|
+
value = self.read_attribute(column_name)
|
7
|
+
encoded[column_name.to_s] = self.class.column_for_attribute(column_name).type_cast_for_solr(value)
|
8
8
|
end
|
9
|
-
encoded = self.class.encode_attributes(my_attrs).merge(:id => self.id)
|
10
9
|
xml_doc = RSolr::Xml::Generator.new.add(encoded)
|
11
10
|
self.class.solr_connection.update(:data => xml_doc, :params => {:replacefields => false})
|
12
11
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module DatastaxRails
|
2
|
-
class RecordInvalid <
|
2
|
+
class RecordInvalid < DatastaxRailsError
|
3
3
|
attr_reader :record
|
4
4
|
def initialize(record)
|
5
5
|
@record = record
|
@@ -11,14 +11,10 @@ module DatastaxRails
|
|
11
11
|
extend ActiveSupport::Concern
|
12
12
|
include ActiveModel::Validations
|
13
13
|
|
14
|
-
included do
|
15
|
-
define_model_callbacks :validation
|
16
|
-
define_callbacks :validate, :scope => :name
|
17
|
-
end
|
18
|
-
|
19
14
|
module ClassMethods
|
20
15
|
def create!(attributes = {})
|
21
16
|
new(attributes).tap do |object|
|
17
|
+
yield(object) if block_given?
|
22
18
|
object.save!
|
23
19
|
end
|
24
20
|
end
|
@@ -34,11 +30,9 @@ module DatastaxRails
|
|
34
30
|
# Validations with no <tt>:on</tt> option will run no matter the context. Validations with
|
35
31
|
# some <tt>:on</tt> option will only run in the specified context.
|
36
32
|
def valid?(context = nil)
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
errors.empty? && output
|
41
|
-
end
|
33
|
+
context ||= (new_record? ? :create : :update)
|
34
|
+
output = super(context)
|
35
|
+
errors.empty? && output
|
42
36
|
end
|
43
37
|
|
44
38
|
def save(options={})
|
@@ -51,7 +45,7 @@ module DatastaxRails
|
|
51
45
|
|
52
46
|
protected
|
53
47
|
def perform_validations(options={})
|
54
|
-
|
48
|
+
options[:validate] == false || valid?(options[:context])
|
55
49
|
end
|
56
50
|
end
|
57
51
|
end
|