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
@@ -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
|