datastax_rails 2.0.18 → 2.1.23
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/config/solrconfig.xml.erb +7 -7
- data/lib/datastax_rails/associations/collection_association.rb +4 -4
- data/lib/datastax_rails/associations/has_many_association.rb +1 -1
- data/lib/datastax_rails/attribute_methods/dirty.rb +6 -0
- data/lib/datastax_rails/attribute_methods/primary_key.rb +9 -1
- data/lib/datastax_rails/attribute_methods/read.rb +2 -2
- data/lib/datastax_rails/attribute_methods/typecasting.rb +4 -7
- data/lib/datastax_rails/attribute_methods.rb +25 -0
- data/lib/datastax_rails/autosave_association.rb +3 -3
- data/lib/datastax_rails/base.rb +33 -11
- data/lib/datastax_rails/column.rb +25 -15
- data/lib/datastax_rails/connection.rb +1 -1
- data/lib/datastax_rails/cql/base.rb +31 -19
- data/lib/datastax_rails/cql/select.rb +2 -2
- data/lib/datastax_rails/dynamic_model.rb +1 -1
- data/lib/datastax_rails/errors.rb +3 -0
- data/lib/datastax_rails/instrumentation/controller_runtime.rb +52 -0
- data/lib/datastax_rails/instrumentation/log_subscriber.rb +92 -0
- data/lib/datastax_rails/instrumentation.rb +4 -0
- data/lib/datastax_rails/persistence.rb +49 -17
- data/lib/datastax_rails/railtie.rb +7 -0
- data/lib/datastax_rails/reflection.rb +16 -12
- data/lib/datastax_rails/relation/batches.rb +1 -1
- data/lib/datastax_rails/relation/finder_methods.rb +5 -5
- data/lib/datastax_rails/relation/modification_methods.rb +11 -26
- data/lib/datastax_rails/relation/search_methods.rb +10 -11
- data/lib/datastax_rails/relation.rb +81 -50
- data/lib/datastax_rails/scoping.rb +1 -1
- data/lib/datastax_rails/serialization.rb +10 -6
- data/lib/datastax_rails/serializers/xml_serializer.rb +3 -1
- data/lib/datastax_rails/tasks/ds.rake +25 -26
- data/lib/datastax_rails/timestamps.rb +1 -1
- data/lib/datastax_rails/types/dynamic_set.rb +4 -0
- data/lib/datastax_rails/version.rb +1 -1
- data/lib/datastax_rails/wide_storage_model.rb +3 -1
- data/lib/datastax_rails.rb +1 -0
- data/spec/datastax_rails/attribute_methods/read_spec.rb +33 -0
- data/spec/datastax_rails/attribute_methods/typecasting_spec.rb +25 -0
- data/spec/datastax_rails/base_spec.rb +1 -1
- data/spec/datastax_rails/callbacks_spec.rb +6 -0
- data/spec/datastax_rails/column_spec.rb +20 -0
- data/spec/datastax_rails/cql/base_spec.rb +1 -1
- data/spec/datastax_rails/cql/select_spec.rb +7 -1
- data/spec/datastax_rails/persistence_spec.rb +22 -3
- data/spec/datastax_rails/relation/finder_methods_spec.rb +13 -0
- data/spec/datastax_rails/relation/search_methods_spec.rb +37 -12
- data/spec/datastax_rails/serialization_spec.rb +17 -0
- data/spec/dummy/log/development.log +0 -24195
- data/spec/dummy/log/test.log +20 -15610
- data/spec/factories/hobbies.rb +1 -0
- data/spec/factories/jobs.rb +7 -0
- data/spec/factories/people.rb +1 -0
- data/spec/factories/person_roles.rb +7 -0
- data/spec/factories/roles.rb +6 -0
- data/spec/factories/uuid_keys.rb +6 -0
- data/spec/feature/associations_spec.rb +26 -0
- data/spec/support/models.rb +82 -0
- metadata +19 -4
- data/spec/dummy/log/production.log +0 -2
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'active_support/core_ext/module/attr_internal'
|
2
|
+
|
3
|
+
module DatastaxRails
|
4
|
+
module Instrumentation
|
5
|
+
# Hooks into ActionController to display Solr and CQL runtime
|
6
|
+
#
|
7
|
+
# @see https://github.com/rails/rails/blob/master/activerecord/lib/active_record/railties/controller_runtime.rb
|
8
|
+
#
|
9
|
+
module ControllerRuntime
|
10
|
+
extend ActiveSupport::Concern
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
attr_internal :solr_runtime
|
15
|
+
attr_internal :cql_runtime
|
16
|
+
|
17
|
+
def process_action(action, *args)
|
18
|
+
DatastaxRails::Instrumentation::LogSubscriber.reset_solr_runtime
|
19
|
+
DatastaxRails::Instrumentation::LogSubscriber.reset_cql_runtime
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
def cleanup_view_runtime
|
24
|
+
solr_rt_before_render = DatastaxRails::Instrumentation::LogSubscriber.reset_solr_runtime
|
25
|
+
cql_rt_before_render = DatastaxRails::Instrumentation::LogSubscriber.reset_cql_runtime
|
26
|
+
self.solr_runtime = (solr_runtime || 0) + solr_rt_before_render
|
27
|
+
self.cql_runtime = (cql_runtime || 0) + cql_rt_before_render
|
28
|
+
runtime = super
|
29
|
+
solr_rt_after_render = DatastaxRails::Instrumentation::LogSubscriber.reset_solr_runtime
|
30
|
+
cql_rt_after_render = DatastaxRails::Instrumentation::LogSubscriber.reset_cql_runtime
|
31
|
+
self.solr_runtime += solr_rt_after_render
|
32
|
+
self.cql_runtime += cql_rt_after_render
|
33
|
+
runtime - solr_rt_after_render - cql_rt_after_render
|
34
|
+
end
|
35
|
+
|
36
|
+
def append_info_to_payload(payload)
|
37
|
+
super
|
38
|
+
payload[:solr_runtime] = (solr_runtime || 0) + DatastaxRails::Instrumentation::LogSubscriber.reset_solr_runtime
|
39
|
+
payload[:cql_runtime] = (cql_runtime || 0) + DatastaxRails::Instrumentation::LogSubscriber.reset_cql_runtime
|
40
|
+
end
|
41
|
+
|
42
|
+
module ClassMethods
|
43
|
+
def log_process_action(payload)
|
44
|
+
messages, solr_runtime, cql_runtime = super, payload[:solr_runtime], payload[:cql_runtime]
|
45
|
+
messages << ('Solr: %.1fms' % solr_runtime.to_f) if solr_runtime
|
46
|
+
messages << ('CQL: %.1fms' % cql_runtime.to_f) if cql_runtime
|
47
|
+
messages
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module DatastaxRails
|
2
|
+
module Instrumentation
|
3
|
+
# A log subscriber to attach to Datastax related events
|
4
|
+
#
|
5
|
+
# @see https://github.com/rails/rails/blob/master/activerecord/lib/active_record/log_subscriber.rb
|
6
|
+
#
|
7
|
+
class LogSubscriber < ActiveSupport::LogSubscriber
|
8
|
+
def initialize(*args)
|
9
|
+
super
|
10
|
+
@odd = false
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.solr_runtime=(value)
|
14
|
+
Thread.current['datastax_solr_runtime'] = value
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.solr_runtime
|
18
|
+
Thread.current['datastax_solr_runtime'] ||= 0
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.cql_runtime=(value)
|
22
|
+
Thread.current['datastax_cql_runtime'] = value
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.cql_runtime
|
26
|
+
Thread.current['datastax_cql_runtime'] ||= 0
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.reset_solr_runtime
|
30
|
+
rt, self.solr_runtime = solr_runtime, 0
|
31
|
+
rt
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.reset_cql_runtime
|
35
|
+
rt, self.cql_runtime = cql_runtime, 0
|
36
|
+
rt
|
37
|
+
end
|
38
|
+
|
39
|
+
# Intercept `solr.datastax_rails` events, and display them in the Rails log
|
40
|
+
def solr(event)
|
41
|
+
self.class.solr_runtime += event.duration
|
42
|
+
return unless logger.debug? && DatastaxRails::Base.log_solr_queries
|
43
|
+
|
44
|
+
payload = event.payload
|
45
|
+
|
46
|
+
name = "#{payload[:klass]} #{payload[:name]} (#{event.duration.round(1)}ms)"
|
47
|
+
search = payload[:search].inspect.gsub(/:(\w+)=>/, '\1: ')
|
48
|
+
|
49
|
+
if odd?
|
50
|
+
name = color(name, CYAN, true)
|
51
|
+
search = color(search, nil, true)
|
52
|
+
else
|
53
|
+
name = color(name, MAGENTA, true)
|
54
|
+
end
|
55
|
+
|
56
|
+
debug " #{name} #{search}"
|
57
|
+
end
|
58
|
+
|
59
|
+
# Intercept `cql.datastax_rails` events, and display them in the Rails log
|
60
|
+
def cql(event)
|
61
|
+
self.class.cql_runtime += event.duration
|
62
|
+
return unless logger.debug? && DatastaxRails::Base.log_cql_queries
|
63
|
+
|
64
|
+
payload = event.payload
|
65
|
+
|
66
|
+
name = "#{payload[:klass]} #{payload[:name]} (#{event.duration.round(1)}ms)"
|
67
|
+
cql = payload[:cql]
|
68
|
+
binds = nil
|
69
|
+
results = payload[:result_count]
|
70
|
+
|
71
|
+
unless (payload[:binds] || []).empty?
|
72
|
+
binds = ' ' + payload[:binds].inspect
|
73
|
+
end
|
74
|
+
|
75
|
+
if odd?
|
76
|
+
name = color(name, CYAN, true)
|
77
|
+
cql = color(cql, nil, true)
|
78
|
+
else
|
79
|
+
name = color(name, MAGENTA, true)
|
80
|
+
end
|
81
|
+
|
82
|
+
debug " #{name} #{cql}#{binds} - #{results} results"
|
83
|
+
end
|
84
|
+
|
85
|
+
def odd?
|
86
|
+
@odd = !@odd
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
DatastaxRails::Instrumentation::LogSubscriber.attach_to :datastax_rails
|
@@ -29,7 +29,7 @@ module DatastaxRails
|
|
29
29
|
# keys = keys.flat_map { |k| attribute_definitions[primary_key].type_cast(k) }
|
30
30
|
keys.each do |key|
|
31
31
|
typecast_key = {}
|
32
|
-
key.each { |k, v| typecast_key[k] = attribute_definitions[k].
|
32
|
+
key.each { |k, v| typecast_key[k] = attribute_definitions[k].type_cast_for_cql3(v) }
|
33
33
|
|
34
34
|
ActiveSupport::Notifications.instrument('remove.datastax_rails', column_family: column_family, key: key) do
|
35
35
|
c = cql.delete(typecast_key)
|
@@ -60,11 +60,12 @@ module DatastaxRails
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
# Write a record to cassandra.
|
63
|
+
# Write a full record to cassandra.
|
64
64
|
#
|
65
65
|
# @param [DatastaxRails::Base] record the record that we are writing
|
66
66
|
# @param [Hash] options a hash containing various options
|
67
67
|
# @option options [Symbol] :consistency the consistency to set for the Cassandra operation (e.g., ALL)
|
68
|
+
# @option options [Symbol] :new_record whether or not this is a new record (i.e., INSERT vs UPDATE)
|
68
69
|
def write(record, options = {})
|
69
70
|
level = (options[:consistency] || default_consistency).to_s.upcase
|
70
71
|
if valid_consistency?(level)
|
@@ -77,9 +78,37 @@ module DatastaxRails
|
|
77
78
|
key: key.to_s,
|
78
79
|
attributes: record.attributes) do
|
79
80
|
if (storage_method == :solr)
|
80
|
-
write_with_solr(record, options)
|
81
|
+
write_with_solr(record.id_for_update, encode_attributes(record, false), options)
|
81
82
|
else
|
82
|
-
write_with_cql(record, options)
|
83
|
+
write_with_cql(record.id_for_update, encode_attributes(record, true), options)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Write one or more attributes directly to cassandra. Bypasses all normal validation and callbacks.
|
90
|
+
# Record must be already persisted.
|
91
|
+
#
|
92
|
+
# @param [DatastaxRails::Base] record the record that we are writing
|
93
|
+
# @param [Hash] options a hash containing various options
|
94
|
+
# @option options [Symbol] :consistency the consistency to set for the Cassandra operation (e.g., ALL)
|
95
|
+
# @raise [NotPersistedError] if the record isn't persisted
|
96
|
+
def write_attribute(record, attributes, options = {})
|
97
|
+
fail NotPersistedError if record.new_record?
|
98
|
+
level = (options[:consistency] || default_consistency).to_s.upcase
|
99
|
+
if valid_consistency?(level)
|
100
|
+
options[:consistency] = level
|
101
|
+
else
|
102
|
+
fail ArgumentError, "'#{level}' is not a valid Cassandra consistency level"
|
103
|
+
end
|
104
|
+
record.id.tap do |key|
|
105
|
+
ActiveSupport::Notifications.instrument('update.datastax_rails', column_family: column_family,
|
106
|
+
key: key.to_s,
|
107
|
+
attributes: record.attributes) do
|
108
|
+
if (storage_method == :solr)
|
109
|
+
write_with_solr(record.id_for_update, encode_attributes(record, false, attributes), options)
|
110
|
+
else
|
111
|
+
write_with_cql(record.id_for_update, encode_attributes(record, true, attributes), options)
|
83
112
|
end
|
84
113
|
end
|
85
114
|
end
|
@@ -102,13 +131,17 @@ module DatastaxRails
|
|
102
131
|
# @param [DatastaxRails::Base] record the record whose attributes we're encoding
|
103
132
|
# @param [Boolean] cql True if we're formatting for CQL, otherwise False
|
104
133
|
# @return [Hash] a new hash with attributes encoded for storage
|
105
|
-
def encode_attributes(record, cql)
|
134
|
+
def encode_attributes(record, cql, attributes = {})
|
106
135
|
encoded = {}
|
107
136
|
Types::DirtyCollection.ignore_modifications do
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
137
|
+
if attributes.empty?
|
138
|
+
record.send(cql ? 'changed' : 'column_names').each do |column_name|
|
139
|
+
attributes[column_name] = record.read_attribute(column_name)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
attributes.each do |k, v|
|
143
|
+
encoded[k.to_s] = cql ? attribute_definitions[k].type_cast_for_cql3(v) :
|
144
|
+
attribute_definitions[k].type_cast_for_solr(v)
|
112
145
|
end
|
113
146
|
end
|
114
147
|
encoded
|
@@ -116,19 +149,17 @@ module DatastaxRails
|
|
116
149
|
|
117
150
|
private
|
118
151
|
|
119
|
-
def write_with_cql(
|
120
|
-
encoded = encode_attributes(record, true)
|
152
|
+
def write_with_cql(id, encoded, options)
|
121
153
|
if options[:new_record]
|
122
154
|
cql.insert.columns(encoded).using(options[:consistency]).execute
|
123
155
|
else
|
124
|
-
cql.update(
|
156
|
+
cql.update(id).columns(encoded).using(options[:consistency]).execute
|
125
157
|
end
|
126
158
|
end
|
127
159
|
|
128
|
-
def write_with_solr(
|
129
|
-
|
130
|
-
xml_doc
|
131
|
-
solr_connection.update(data: xml_doc, params: { replacefields: false, cl: options[:consistency] })
|
160
|
+
def write_with_solr(id, encoded, options)
|
161
|
+
xml_doc = RSolr::Xml::Generator.new.add(encoded)
|
162
|
+
solr_connection.update(data: xml_doc, params: { cl: options[:consistency] })
|
132
163
|
end
|
133
164
|
end
|
134
165
|
|
@@ -151,6 +182,7 @@ module DatastaxRails
|
|
151
182
|
@destroyed = true
|
152
183
|
freeze
|
153
184
|
end
|
185
|
+
alias_method :destroy_without_callbacks, :destroy
|
154
186
|
|
155
187
|
# TODO: Make this work
|
156
188
|
# def touch(name = nil)
|
@@ -190,7 +222,7 @@ module DatastaxRails
|
|
190
222
|
end
|
191
223
|
|
192
224
|
# Updates the attributes of the model from the passed-in hash and saves the
|
193
|
-
# record If the object is invalid, the saving will fail and false will be returned.
|
225
|
+
# record. If the object is invalid, the saving will fail and false will be returned.
|
194
226
|
def update_attributes(attributes, _options = {})
|
195
227
|
assign_attributes(attributes)
|
196
228
|
save
|
@@ -27,6 +27,13 @@ module DatastaxRails
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
30
|
+
|
31
|
+
# Instrumentation
|
32
|
+
require 'datastax_rails/instrumentation/log_subscriber'
|
33
|
+
require 'datastax_rails/instrumentation/controller_runtime'
|
34
|
+
ActiveSupport.on_load(:action_controller) do
|
35
|
+
include DatastaxRails::Instrumentation::ControllerRuntime
|
36
|
+
end
|
30
37
|
end
|
31
38
|
|
32
39
|
rake_tasks do
|
@@ -185,18 +185,22 @@ module DatastaxRails
|
|
185
185
|
@type ||= options[:as] && "#{options[:as]}_type"
|
186
186
|
end
|
187
187
|
|
188
|
+
def primary_key_column
|
189
|
+
@primary_key_column ||= klass.columns.find { |c| c.name == klass.primary_key }
|
190
|
+
end
|
191
|
+
|
188
192
|
def association_foreign_key
|
189
193
|
@association_foreign_key ||= options[:association_foreign_key] || class_name.foreign_key
|
190
194
|
end
|
191
195
|
|
192
196
|
# klass option is necessary to support loading polymorphic associations
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
197
|
+
def association_primary_key(klass = nil)
|
198
|
+
options[:primary_key] || primary_key(klass || self.klass)
|
199
|
+
end
|
200
|
+
|
201
|
+
def datastax_rails_primary_key
|
202
|
+
@datastax_rails_primary_key ||= options[:primary_key] || primary_key(datastax_rails)
|
203
|
+
end
|
200
204
|
|
201
205
|
def check_validity!
|
202
206
|
check_validity_of_inverse!
|
@@ -303,9 +307,9 @@ module DatastaxRails
|
|
303
307
|
end
|
304
308
|
end
|
305
309
|
|
306
|
-
|
307
|
-
|
308
|
-
|
310
|
+
def primary_key(klass)
|
311
|
+
klass.primary_key || raise(UnknownPrimaryKey.new(klass))
|
312
|
+
end
|
309
313
|
end
|
310
314
|
|
311
315
|
# Holds all the meta-data about a :through association as it was specified
|
@@ -385,7 +389,7 @@ module DatastaxRails
|
|
385
389
|
# of relevant reflections, plus any :source_type or polymorphic :as constraints.
|
386
390
|
def conditions
|
387
391
|
@conditions ||= begin
|
388
|
-
conditions = source_reflection.conditions.map
|
392
|
+
conditions = source_reflection.conditions.map(&:dup)
|
389
393
|
|
390
394
|
# Add to it the conditions from this reflection if necessary.
|
391
395
|
conditions.first << options[:conditions] if options[:conditions]
|
@@ -434,7 +438,7 @@ module DatastaxRails
|
|
434
438
|
#
|
435
439
|
def source_reflection_names
|
436
440
|
@source_reflection_names ||=
|
437
|
-
(options[:source] ? [options[:source]] : [name.to_s.singularize, name]).map
|
441
|
+
(options[:source] ? [options[:source]] : [name.to_s.singularize, name]).map(&:to_sym)
|
438
442
|
end
|
439
443
|
|
440
444
|
def source_options
|
@@ -85,7 +85,7 @@ module DatastaxRails
|
|
85
85
|
records = start ? relation.where(@klass.primary_key).greater_than(start).to_a : relation.to_a
|
86
86
|
while records.size > 0
|
87
87
|
records_size = records.size
|
88
|
-
offset = records.last.
|
88
|
+
offset = records.last.__id
|
89
89
|
yield records
|
90
90
|
|
91
91
|
break if records_size < batch_size
|
@@ -81,14 +81,14 @@ module DatastaxRails
|
|
81
81
|
# Post.find_by "published_at < ?", 2.weeks.ago
|
82
82
|
def find_by(*args)
|
83
83
|
where_values << escape_attributes(args.first)
|
84
|
-
first
|
84
|
+
dont_escape.first
|
85
85
|
end
|
86
86
|
|
87
87
|
# Like <tt>find_by</tt>, except that if no record is found, raises
|
88
88
|
# an <tt>DatastaxRails::RecordNotFound</tt> error.
|
89
89
|
def find_by!(*args)
|
90
90
|
where_values << escape_attributes(args.first)
|
91
|
-
first!
|
91
|
+
dont_escape.first!
|
92
92
|
end
|
93
93
|
|
94
94
|
# A convenience wrapper for <tt>find(:first, *args)</tt>. You can pass in all the
|
@@ -155,7 +155,7 @@ module DatastaxRails
|
|
155
155
|
escaped = {}
|
156
156
|
conditions.each do |k, v|
|
157
157
|
if v.is_a?(String)
|
158
|
-
escaped[k] = v.gsub(/(
|
158
|
+
escaped[k] = v.gsub(/([^\w\- ])/, '\\\\\1')
|
159
159
|
else
|
160
160
|
escaped[k] = v
|
161
161
|
end
|
@@ -183,7 +183,7 @@ module DatastaxRails
|
|
183
183
|
end
|
184
184
|
|
185
185
|
def find_one(id)
|
186
|
-
key = @klass.attribute_definitions[@klass.primary_key].
|
186
|
+
key = @klass.attribute_definitions[@klass.primary_key].type_cast_for_cql3(id)
|
187
187
|
key || fail(RecordNotFound, "Couldn't find #{@klass.name} with an invalid ID=#{id}")
|
188
188
|
|
189
189
|
with_cassandra.where(@klass.primary_key => key).first ||
|
@@ -192,7 +192,7 @@ module DatastaxRails
|
|
192
192
|
|
193
193
|
def find_some(ids)
|
194
194
|
keys = ids.map do |id|
|
195
|
-
@klass.attribute_definitions[@klass.primary_key].
|
195
|
+
@klass.attribute_definitions[@klass.primary_key].type_cast_for_cql3(id) ||
|
196
196
|
fail(RecordNotFound, "Couldn't find #{@klass.name} with an invalid ID=#{id}")
|
197
197
|
end
|
198
198
|
result = with_cassandra.where(@klass.primary_key => keys).all
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module DatastaxRails
|
2
2
|
module ModificationMethods
|
3
|
-
# Destroys the records matching
|
3
|
+
# Destroys the records matching this relation by instantiating each
|
4
4
|
# record and calling its +destroy+ method. Each object's callbacks are
|
5
5
|
# executed (including <tt>:dependent</tt> association options and
|
6
6
|
# +before_destroy+/+after_destroy+ Observer methods). Returns the
|
@@ -10,35 +10,20 @@ module DatastaxRails
|
|
10
10
|
#
|
11
11
|
# Note: Instantiation, callback execution, and deletion of each
|
12
12
|
# record can be time consuming when you're removing many records at
|
13
|
-
# once. However, it is necessary to perform it this way
|
14
|
-
#
|
13
|
+
# once. However, it is necessary to perform it this way since we have
|
14
|
+
# to get the results from SOLR (most likely) in order to know what to delete.
|
15
15
|
#
|
16
|
-
#
|
17
|
-
# the requisite callbacks. (at least not yet)
|
18
|
-
#
|
19
|
-
# ==== Parameters
|
20
|
-
#
|
21
|
-
# * +conditions+ - A string, array, or hash that specifies which records
|
22
|
-
# to destroy. If omitted, all records matching the current relation are
|
23
|
-
# destroyed. See the Conditions section in the introduction to
|
24
|
-
# DatastaxRails::Base for more information.
|
25
|
-
#
|
26
|
-
# ==== Examples
|
27
|
-
#
|
28
|
-
# Person.destroy_all(:status => "inactive")
|
16
|
+
# Person.destroy_all
|
29
17
|
# Person.where(:age => 0..18).destroy_all
|
30
18
|
# Person.where_not(:status => "active").destroy_all
|
31
|
-
def destroy_all
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
reset
|
38
|
-
ret
|
19
|
+
def destroy_all
|
20
|
+
to_a.each(&:destroy).tap { |_| reset }
|
21
|
+
end
|
22
|
+
|
23
|
+
# Like +destroy_all+ but will not run callbacks. It will still have to instantiate the objects.
|
24
|
+
def delete_all
|
25
|
+
select(klass.primary_key).to_a.each(&:destroy_without_callbacks).tap { |_| reset }
|
39
26
|
end
|
40
|
-
# TODO: Find a way to delete from both without instantiating
|
41
|
-
alias_method :delete_all, :destroy_all
|
42
27
|
|
43
28
|
# Destroy an object (or multiple objects) that has the given id, the object is instantiated first,
|
44
29
|
# therefore all callbacks and filters are fired off before the object is deleted. This method is
|
@@ -397,8 +397,6 @@ module DatastaxRails
|
|
397
397
|
r.where_values << { k => value }
|
398
398
|
end
|
399
399
|
attributes.delete(k)
|
400
|
-
else
|
401
|
-
attributes[k] = solr_format(k, v)
|
402
400
|
end
|
403
401
|
end
|
404
402
|
r.where_values << attributes unless attributes.empty?
|
@@ -441,8 +439,6 @@ module DatastaxRails
|
|
441
439
|
r.where_not_values << { k => value }
|
442
440
|
end
|
443
441
|
attributes.delete(k)
|
444
|
-
else
|
445
|
-
attributes[k] = solr_format(k, v)
|
446
442
|
end
|
447
443
|
end
|
448
444
|
r.where_not_values << attributes unless attributes.empty?
|
@@ -545,7 +541,8 @@ module DatastaxRails
|
|
545
541
|
when value.is_a?(Time) || value.is_a?(DateTime) || value.is_a?(Date)
|
546
542
|
column.type_cast_for_solr(value)
|
547
543
|
when value.is_a?(Array) || value.is_a?(Set)
|
548
|
-
|
544
|
+
value = value.to_a.compact if column.primary
|
545
|
+
value.map { |v| column.type_cast_for_solr(v, column.options[:holds]).to_s.gsub(/ /, '\\ ') }.join(' OR ')
|
549
546
|
when value.is_a?(Fixnum)
|
550
547
|
value < 0 ? "\\#{value}" : value
|
551
548
|
when value.is_a?(Range)
|
@@ -554,6 +551,8 @@ module DatastaxRails
|
|
554
551
|
solr_escape(downcase_query(value.gsub(/ /, '\\ ')))
|
555
552
|
when value.is_a?(FalseClass), value.is_a?(TrueClass)
|
556
553
|
value.to_s
|
554
|
+
# when value.is_a?(::Cql::Uuid)
|
555
|
+
# value.to_s
|
557
556
|
else
|
558
557
|
value
|
559
558
|
end
|
@@ -570,9 +569,9 @@ module DatastaxRails
|
|
570
569
|
def equal_to(value) #:nodoc:
|
571
570
|
@relation.clone.tap do |r|
|
572
571
|
if @invert
|
573
|
-
r.where_not_values << { @attribute =>
|
572
|
+
r.where_not_values << { @attribute => value }
|
574
573
|
else
|
575
|
-
r.where_values << { @attribute =>
|
574
|
+
r.where_values << { @attribute => value }
|
576
575
|
end
|
577
576
|
end
|
578
577
|
end
|
@@ -580,9 +579,9 @@ module DatastaxRails
|
|
580
579
|
def greater_than(value) #:nodoc:
|
581
580
|
@relation.clone.tap do |r|
|
582
581
|
if @invert
|
583
|
-
r.less_than_values << { @attribute =>
|
582
|
+
r.less_than_values << { @attribute => value }
|
584
583
|
else
|
585
|
-
r.greater_than_values << { @attribute =>
|
584
|
+
r.greater_than_values << { @attribute => value }
|
586
585
|
end
|
587
586
|
end
|
588
587
|
end
|
@@ -590,9 +589,9 @@ module DatastaxRails
|
|
590
589
|
def less_than(value) #:nodoc:
|
591
590
|
@relation.clone.tap do |r|
|
592
591
|
if @invert
|
593
|
-
r.greater_than_values << { @attribute =>
|
592
|
+
r.greater_than_values << { @attribute => value }
|
594
593
|
else
|
595
|
-
r.less_than_values << { @attribute =>
|
594
|
+
r.less_than_values << { @attribute => value }
|
596
595
|
end
|
597
596
|
end
|
598
597
|
end
|