datastax_rails 2.0.18 → 2.1.23
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46adde0cefb47aa5fc3affe6dbd16645d8357050
|
4
|
+
data.tar.gz: 9664ee5c527d05bc1020d9bae17898fd386f319e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa9d465f640a3d72fbf096868b22976a56d39699005c1fbf656dc7394c26567fcc21570f0c8f27260d5a42f5053c308159a1baaeb07f8b752e200cfce85a12a7
|
7
|
+
data.tar.gz: 81221cc2ccf7b287a8842df07c839622d2ac7bd1f605c8042d5360e34c35ee8038b8eecbea1e771ca42d69c7854fe73c1442bbb4aac900cedc8fc93c120d36ad
|
data/config/solrconfig.xml.erb
CHANGED
@@ -47,7 +47,7 @@
|
|
47
47
|
that you fully re-index after changing this setting as it can
|
48
48
|
affect both how text is indexed and queried.
|
49
49
|
-->
|
50
|
-
<luceneMatchVersion>
|
50
|
+
<luceneMatchVersion>LUCENE_43</luceneMatchVersion>
|
51
51
|
|
52
52
|
<!-- Enable DSE Search new type mappings -->
|
53
53
|
<dseTypeMappingVersion>2</dseTypeMappingVersion>
|
@@ -336,30 +336,30 @@
|
|
336
336
|
and old cache.
|
337
337
|
-->
|
338
338
|
<filterCache class="solr.FastLRUCache"
|
339
|
-
size="
|
340
|
-
initialSize="
|
339
|
+
size="256"
|
340
|
+
initialSize="0"
|
341
341
|
autowarmCount="0"/>
|
342
342
|
|
343
343
|
<!-- Query Result Cache
|
344
344
|
|
345
345
|
Caches results of searches - ordered lists of document ids
|
346
346
|
(DocList) based on a query, a sort, and the range of documents requested.
|
347
|
-
-->
|
348
347
|
<queryResultCache class="solr.LRUCache"
|
349
348
|
size="512"
|
350
349
|
initialSize="512"
|
351
350
|
autowarmCount="0"/>
|
351
|
+
-->
|
352
352
|
|
353
353
|
<!-- Document Cache
|
354
354
|
|
355
355
|
Caches Lucene Document objects (the stored fields for each
|
356
356
|
document). Since Lucene internal document ids are transient,
|
357
357
|
this cache will not be autowarmed.
|
358
|
-
-->
|
359
358
|
<documentCache class="solr.LRUCache"
|
360
359
|
size="512"
|
361
360
|
initialSize="512"
|
362
361
|
autowarmCount="0"/>
|
362
|
+
-->
|
363
363
|
|
364
364
|
<!-- Field Value Cache
|
365
365
|
|
@@ -761,7 +761,7 @@
|
|
761
761
|
requires: -H 'Content-type:text/xml; charset=utf-8'
|
762
762
|
-->
|
763
763
|
<requestHandler name="/update"
|
764
|
-
class="solr.
|
764
|
+
class="solr.UpdateRequestHandler">
|
765
765
|
<!-- See below for information on defining
|
766
766
|
updateRequestProcessorChains that can be used by name
|
767
767
|
on each Update Request
|
@@ -776,7 +776,7 @@
|
|
776
776
|
http://wiki.apache.org/solr/javabin
|
777
777
|
-->
|
778
778
|
<requestHandler name="/update/javabin"
|
779
|
-
class="solr.
|
779
|
+
class="solr.UpdateRequestHandler" />
|
780
780
|
|
781
781
|
<!-- CSV Update Request Handler
|
782
782
|
http://wiki.apache.org/solr/UpdateCSV
|
@@ -29,7 +29,7 @@ module DatastaxRails
|
|
29
29
|
if !find_target? || loaded?
|
30
30
|
target.size
|
31
31
|
elsif !loaded? && target.is_a?(Array)
|
32
|
-
unsaved_records = target.select
|
32
|
+
unsaved_records = target.select(&:new_record?)
|
33
33
|
unsaved_records.size + scoped.count
|
34
34
|
else
|
35
35
|
scoped.count
|
@@ -75,8 +75,8 @@ module DatastaxRails
|
|
75
75
|
|
76
76
|
# Implements the ids writer method, e.g. foo.item_ids= for Foo.has_many :items
|
77
77
|
def ids_writer(ids)
|
78
|
-
ids = Array.wrap(ids).reject
|
79
|
-
replace(klass.find(ids).index_by
|
78
|
+
ids = Array.wrap(ids).reject(&:blank?)
|
79
|
+
replace(klass.find(ids).index_by(&:id).values_at(*ids))
|
80
80
|
end
|
81
81
|
|
82
82
|
def reset
|
@@ -274,7 +274,7 @@ module DatastaxRails
|
|
274
274
|
def delete_or_destroy(records, method)
|
275
275
|
records = records.flatten
|
276
276
|
records.each { |record| raise_on_type_mismatch(record) }
|
277
|
-
existing_records = records.reject
|
277
|
+
existing_records = records.reject(&:new_record?)
|
278
278
|
|
279
279
|
records.each { |record| callback(:before_remove, record) }
|
280
280
|
|
@@ -40,7 +40,7 @@ module DatastaxRails
|
|
40
40
|
# Deletes the records according to the <tt>:dependent</tt> option.
|
41
41
|
def delete_records(records, method)
|
42
42
|
if method == :destroy
|
43
|
-
records.each
|
43
|
+
records.each(&:destroy)
|
44
44
|
else
|
45
45
|
keys = records.map { |r| r[reflection.association_primary_key] }
|
46
46
|
scope = scoped.where(reflection.association_primary_key => keys)
|
@@ -13,7 +13,11 @@ module DatastaxRails
|
|
13
13
|
# Attempts to +save+ the record and clears changed attributes if successful.
|
14
14
|
def save(*) #:nodoc:
|
15
15
|
if (status = super)
|
16
|
+
# FIXME: This dup/replace mess is here to work around what APPEARS to be a bug in Rails
|
17
|
+
# See Issue #29 for details
|
18
|
+
attrs = @attributes.dup
|
16
19
|
@previously_changed = changes
|
20
|
+
@attributes = attrs
|
17
21
|
@changed_attributes.clear
|
18
22
|
end
|
19
23
|
status
|
@@ -22,7 +26,9 @@ module DatastaxRails
|
|
22
26
|
# Attempts to <tt>save!</tt> the record and clears changed attributes if successful.
|
23
27
|
def save!(*) #:nodoc:
|
24
28
|
super.tap do
|
29
|
+
attrs = @attributes.dup
|
25
30
|
@previously_changed = changes
|
31
|
+
@attributes = attrs
|
26
32
|
@changed_attributes.clear
|
27
33
|
end
|
28
34
|
end
|
@@ -14,7 +14,7 @@ module DatastaxRails
|
|
14
14
|
|
15
15
|
# Returns a primary key hash for updates. Wide models override this.
|
16
16
|
def id_for_update
|
17
|
-
{ self.class.primary_key.to_s =>
|
17
|
+
{ self.class.primary_key.to_s => __id }
|
18
18
|
end
|
19
19
|
|
20
20
|
# Returns the primary key value.
|
@@ -22,6 +22,10 @@ module DatastaxRails
|
|
22
22
|
read_attribute(self.class.primary_key)
|
23
23
|
end
|
24
24
|
|
25
|
+
def __id
|
26
|
+
self.class.column_for_attribute(self.class.primary_key).type_cast_for_cql3(id)
|
27
|
+
end
|
28
|
+
|
25
29
|
# Sets the primary key value.
|
26
30
|
def id=(value)
|
27
31
|
write_attribute(self.class.primary_key, value) if self.class.primary_key
|
@@ -81,6 +85,10 @@ module DatastaxRails
|
|
81
85
|
@primary_key = value && value.to_s
|
82
86
|
@quoted_primary_key = nil
|
83
87
|
end
|
88
|
+
|
89
|
+
def next_key
|
90
|
+
::Cql::TimeUuid::Generator.new.next.to_s
|
91
|
+
end
|
84
92
|
end
|
85
93
|
end
|
86
94
|
end
|
@@ -16,13 +16,13 @@ module DatastaxRails
|
|
16
16
|
# with expensive conversion methods, like time related columns (e.g.
|
17
17
|
# +created_at+, +updated_at+).
|
18
18
|
def cache_attributes(*attribute_names)
|
19
|
-
cached_attributes.merge attribute_names.map
|
19
|
+
cached_attributes.merge attribute_names.map(&:to_s)
|
20
20
|
end
|
21
21
|
|
22
22
|
# Returns the attributes which are cached. By default time related columns
|
23
23
|
# with datatype <tt>:datetime, :timestamp, :time, :date</tt> are cached.
|
24
24
|
def cached_attributes
|
25
|
-
@cached_attributes ||= columns.select { |c| cacheable_column?(c) }.map
|
25
|
+
@cached_attributes ||= columns.select { |c| cacheable_column?(c) }.map(&:name).to_set
|
26
26
|
end
|
27
27
|
|
28
28
|
# Returns +true+ if the provided attribute is being cached.
|
@@ -14,9 +14,6 @@ module DatastaxRails
|
|
14
14
|
self.readonly_attributes = []
|
15
15
|
end
|
16
16
|
|
17
|
-
# This is a hook for use by modules that need to do extra stuff to
|
18
|
-
# attributes when they are initialized. (e.g. attribute
|
19
|
-
# serialization)
|
20
17
|
def initialize_attributes(attributes) #:nodoc:
|
21
18
|
attrs = {}
|
22
19
|
attributes.each do |k, v|
|
@@ -89,11 +86,13 @@ module DatastaxRails
|
|
89
86
|
# @macro attr_doc
|
90
87
|
# @!method datetime(name, options = {})
|
91
88
|
# @macro attr_doc
|
89
|
+
# @!method double(name, options = {})
|
90
|
+
# @macro attr_doc
|
92
91
|
# @!method float(name, options = {})
|
93
92
|
# @macro attr_doc
|
94
93
|
# @!method integer(name, options = {})
|
95
94
|
# @macro attr_doc
|
96
|
-
# @!method
|
95
|
+
# @!method long(name, options = {})
|
97
96
|
# @macro attr_doc
|
98
97
|
# @!method string(name, options = {})
|
99
98
|
# @macro attr_doc
|
@@ -103,8 +102,6 @@ module DatastaxRails
|
|
103
102
|
# @macro attr_doc
|
104
103
|
# @!method timestamp(name, options = {})
|
105
104
|
# @macro attr_doc
|
106
|
-
# @!method time_with_zone(name, options = {})
|
107
|
-
# @macro attr_doc
|
108
105
|
# @!method uuid(name, options = {})
|
109
106
|
# @macro attr_doc
|
110
107
|
# @!method map(name, options = {})
|
@@ -115,7 +112,7 @@ module DatastaxRails
|
|
115
112
|
# @macro attr_doc
|
116
113
|
|
117
114
|
# The following sets up a bunch of nearly identical attribute methods
|
118
|
-
%w(array boolean date datetime float integer
|
115
|
+
%w(array boolean date datetime double float integer long string text time timestamp
|
119
116
|
uuid map set list).each do |type|
|
120
117
|
class_eval <<-EOV, __FILE__, __LINE__ + 1
|
121
118
|
def #{type}(name, options = {}) # def string(name, options = {})
|
@@ -142,6 +142,31 @@ module DatastaxRails
|
|
142
142
|
self.class.column_for_attribute(name)
|
143
143
|
end
|
144
144
|
|
145
|
+
# Returns an <tt>#inspect</tt>-like string for the value of the
|
146
|
+
# attribute +attr_name+. String attributes are truncated upto 50
|
147
|
+
# characters, and Date and Time attributes are returned in the
|
148
|
+
# <tt>:db</tt> format. Other attributes return the value of
|
149
|
+
# <tt>#inspect</tt> without modification.
|
150
|
+
#
|
151
|
+
# person = Person.create!(name: 'David Heinemeier Hansson ' * 3)
|
152
|
+
#
|
153
|
+
# person.attribute_for_inspect(:name)
|
154
|
+
# # => "\"David Heinemeier Hansson David Heinemeier Hansson D...\""
|
155
|
+
#
|
156
|
+
# person.attribute_for_inspect(:created_at)
|
157
|
+
# # => "\"2012-10-22 00:15:07\""
|
158
|
+
def attribute_for_inspect(attr_name)
|
159
|
+
value = read_attribute(attr_name)
|
160
|
+
|
161
|
+
if value.is_a?(String) && value.length > 50
|
162
|
+
"#{value[0..50]}...".inspect
|
163
|
+
elsif value.is_a?(Date) || value.is_a?(Time)
|
164
|
+
%("#{value.to_s(:db)}")
|
165
|
+
else
|
166
|
+
value.inspect
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
145
170
|
protected
|
146
171
|
|
147
172
|
def attribute_method?(name)
|
@@ -255,9 +255,9 @@ module DatastaxRails
|
|
255
255
|
if new_record
|
256
256
|
association && association.target
|
257
257
|
elsif autosave
|
258
|
-
association.target.select
|
258
|
+
association.target.select(&:changed_for_autosave?)
|
259
259
|
else
|
260
|
-
association.target.select
|
260
|
+
association.target.select(&:new_record?)
|
261
261
|
end
|
262
262
|
end
|
263
263
|
|
@@ -266,7 +266,7 @@ module DatastaxRails
|
|
266
266
|
def nested_records_changed_for_autosave?
|
267
267
|
self.class.reflect_on_all_autosave_associations.any? do |reflection|
|
268
268
|
association = association_instance_get(reflection.name)
|
269
|
-
association && Array.wrap(association.target).any?
|
269
|
+
association && Array.wrap(association.target).any?(&:changed_for_autosave?)
|
270
270
|
end
|
271
271
|
end
|
272
272
|
|
data/lib/datastax_rails/base.rb
CHANGED
@@ -37,9 +37,11 @@ module DatastaxRails #:nodoc:
|
|
37
37
|
# * binary - a large object that will not be indexed into SOLR (e.g., BLOB)
|
38
38
|
# * boolean - true/false values
|
39
39
|
# * date - a date without a time component
|
40
|
-
# *
|
41
|
-
# *
|
40
|
+
# * double - a 64-bit number in floating point notation
|
41
|
+
# * float - a 32-bit number in floating point notation
|
42
|
+
# * integer - a 32-bit signed integer
|
42
43
|
# * list - an ordered list of values of a single type
|
44
|
+
# * long - a 64-bit signed integer
|
43
45
|
# * map - a collection of key/value pairs of a single type (keys are always strings)
|
44
46
|
# * set - an un-ordered set of unique values of a single type
|
45
47
|
# * string - a generic string type that is not tokenized by default
|
@@ -366,10 +368,6 @@ module DatastaxRails #:nodoc:
|
|
366
368
|
include Serialization
|
367
369
|
include SolrRepair
|
368
370
|
|
369
|
-
# Stores the default scope for the class
|
370
|
-
class_attribute :default_scopes, instance_writer: false
|
371
|
-
self.default_scopes = []
|
372
|
-
|
373
371
|
# Stores the connection configuration information
|
374
372
|
class_attribute :config
|
375
373
|
|
@@ -397,6 +395,14 @@ module DatastaxRails #:nodoc:
|
|
397
395
|
# are stored on the same row.
|
398
396
|
class_attribute :cluster_by
|
399
397
|
|
398
|
+
# Toggle Solr query logging on and off
|
399
|
+
class_attribute :log_solr_queries
|
400
|
+
self.log_solr_queries = ENV['DEBUG_SOLR']
|
401
|
+
|
402
|
+
# Toggle CQL query logging on and off
|
403
|
+
class_attribute :log_cql_queries
|
404
|
+
self.log_cql_queries = ENV['DEBUG_CQL']
|
405
|
+
|
400
406
|
attr_reader :attributes
|
401
407
|
attr_reader :loaded_attributes
|
402
408
|
attr_accessor :key
|
@@ -468,8 +474,8 @@ module DatastaxRails #:nodoc:
|
|
468
474
|
# Intentionally avoid using #column_defaults since overridden defaults
|
469
475
|
# won't get written unless they get marked as changed
|
470
476
|
self.class.columns.each do |c|
|
471
|
-
attr, orig_value = c.name, c.
|
472
|
-
@changed_attributes[attr] = nil if _field_changed?(attr, orig_value, @attributes[attr])
|
477
|
+
attr, orig_value = c.name, c.empty_value
|
478
|
+
@changed_attributes[attr] = nil if _field_changed?(attr, orig_value, @attributes[attr.to_s])
|
473
479
|
end
|
474
480
|
end
|
475
481
|
|
@@ -484,6 +490,22 @@ module DatastaxRails #:nodoc:
|
|
484
490
|
@attributes.frozen?
|
485
491
|
end
|
486
492
|
|
493
|
+
# Returns the contents of the record as a nicely formatted string.
|
494
|
+
def inspect
|
495
|
+
# We check defined?(@attributes) not to issue warnings if the object is
|
496
|
+
# allocated but not initialized.
|
497
|
+
inspection = if defined?(@attributes) && @attributes
|
498
|
+
self.class.column_names.map do |name|
|
499
|
+
if has_attribute?(name)
|
500
|
+
"#{name}: #{attribute_for_inspect(name)}"
|
501
|
+
end
|
502
|
+
end.compact.join(', ')
|
503
|
+
else
|
504
|
+
'not initialized'
|
505
|
+
end
|
506
|
+
"#<#{self.class} #{inspection}>"
|
507
|
+
end
|
508
|
+
|
487
509
|
def to_param
|
488
510
|
id.to_s if persisted?
|
489
511
|
end
|
@@ -547,7 +569,7 @@ module DatastaxRails #:nodoc:
|
|
547
569
|
end
|
548
570
|
|
549
571
|
def models
|
550
|
-
descendants.reject
|
572
|
+
descendants.reject(&:abstract_class?)
|
551
573
|
end
|
552
574
|
|
553
575
|
def payload_model?
|
@@ -576,7 +598,7 @@ module DatastaxRails #:nodoc:
|
|
576
598
|
|
577
599
|
# Returns an array of attribute names as strings
|
578
600
|
def attribute_names
|
579
|
-
@attribute_names ||= attribute_definitions.keys.map
|
601
|
+
@attribute_names ||= attribute_definitions.keys.map(&:to_s)
|
580
602
|
end
|
581
603
|
alias_method :column_names, :attribute_names
|
582
604
|
|
@@ -601,7 +623,7 @@ module DatastaxRails #:nodoc:
|
|
601
623
|
|
602
624
|
def search_ids(&block)
|
603
625
|
search = solr_search(&block)
|
604
|
-
search.raw_results.map
|
626
|
+
search.raw_results.map(&:primary_key)
|
605
627
|
end
|
606
628
|
|
607
629
|
def valid_consistency?(level) #:nodoc:
|
@@ -51,7 +51,7 @@ module DatastaxRails
|
|
51
51
|
multi_valued: false, sortable: false,
|
52
52
|
tokenized: false, fulltext: false,
|
53
53
|
cql_index: false }
|
54
|
-
when :boolean, :date, :time, :timestamp, :datetime, :float, :integer, :uuid then
|
54
|
+
when :boolean, :date, :time, :timestamp, :datetime, :float, :integer, :uuid, :long, :double then
|
55
55
|
{ solr_index: true, solr_store: true,
|
56
56
|
multi_valued: false, sortable: true,
|
57
57
|
tokenized: false, fulltext: false,
|
@@ -78,7 +78,7 @@ module DatastaxRails
|
|
78
78
|
|
79
79
|
# Returns +true+ if the column is either of type integer, float or decimal.
|
80
80
|
def number?
|
81
|
-
[:
|
81
|
+
[:double, :float, :integer, :long].include?(type)
|
82
82
|
end
|
83
83
|
|
84
84
|
# Returns +true+ if the column is of type binary
|
@@ -94,12 +94,16 @@ module DatastaxRails
|
|
94
94
|
default.present?
|
95
95
|
end
|
96
96
|
|
97
|
+
def empty_value
|
98
|
+
extract_default(nil)
|
99
|
+
end
|
100
|
+
|
97
101
|
# Returns the Ruby class that corresponds to the abstract data type.
|
98
102
|
def klass
|
99
103
|
case type
|
100
|
-
when :integer
|
104
|
+
when :integer, :long then Fixnum
|
101
105
|
when :float then Float
|
102
|
-
when :
|
106
|
+
when :double then BigDecimal
|
103
107
|
when :timestamp, :time, :datetime then Time
|
104
108
|
when :date then Date
|
105
109
|
when :text, :string, :binary, :ascii then String
|
@@ -113,6 +117,7 @@ module DatastaxRails
|
|
113
117
|
|
114
118
|
# Casts value (which can be a String) to an appropriate instance.
|
115
119
|
def type_cast(value, record = nil, dest_type = nil) # rubocop:disable Style/CyclomaticComplexity
|
120
|
+
value = @default if value.nil?
|
116
121
|
return nil if value.nil?
|
117
122
|
return coder.load(value) if encoded?
|
118
123
|
|
@@ -121,7 +126,7 @@ module DatastaxRails
|
|
121
126
|
case dest_type || type
|
122
127
|
when :string, :text then value.to_s
|
123
128
|
when :ascii then value.force_encoding('ascii')
|
124
|
-
when :integer
|
129
|
+
when :integer, :long then klass.value_to_integer(value)
|
125
130
|
when :float then value.to_f
|
126
131
|
when :decimal then klass.value_to_decimal(value)
|
127
132
|
when :datetime, :timestamp then klass.string_to_time(value)
|
@@ -129,8 +134,11 @@ module DatastaxRails
|
|
129
134
|
when :date then klass.value_to_date(value)
|
130
135
|
when :binary then klass.binary_to_string(value)
|
131
136
|
when :boolean then klass.value_to_boolean(value)
|
132
|
-
when :uuid, :timeuuid
|
133
|
-
|
137
|
+
when :uuid, :timeuuid
|
138
|
+
uuid = klass.value_to_uuid(value)
|
139
|
+
uuid.is_a?(::Cql::Uuid) ? uuid.to_s : uuid
|
140
|
+
when :list, :set
|
141
|
+
wrap_collection(Array(value).map { |v| type_cast(v, record, @options[:holds]) }.reject(&:blank?), record)
|
134
142
|
when :map
|
135
143
|
wrap_collection(value.each { |k, v| value[k] = type_cast(v, record, @options[:holds]) }.stringify_keys, record)
|
136
144
|
else value
|
@@ -172,6 +180,7 @@ module DatastaxRails
|
|
172
180
|
when :date, :time, :datetime, :timestamp then value.to_time.utc.strftime(Format::SOLR_TIME_FORMAT)
|
173
181
|
when :list, :set then list_to_solr_value(value)
|
174
182
|
when :map then map_to_solr_value(value)
|
183
|
+
when :uuid, :timeuuid then value.to_s
|
175
184
|
else value
|
176
185
|
end
|
177
186
|
end
|
@@ -202,12 +211,12 @@ module DatastaxRails
|
|
202
211
|
end
|
203
212
|
|
204
213
|
def extract_default(default)
|
205
|
-
case type
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
214
|
+
default || case type
|
215
|
+
when :map then {}
|
216
|
+
when :list then []
|
217
|
+
when :set then Set.new
|
218
|
+
else default
|
219
|
+
end
|
211
220
|
end
|
212
221
|
|
213
222
|
# Used to convert from Strings to BLOBs
|
@@ -282,12 +291,13 @@ module DatastaxRails
|
|
282
291
|
when TrueClass, FalseClass
|
283
292
|
value ? 1 : 0
|
284
293
|
else
|
285
|
-
value.to_i rescue nil
|
294
|
+
value.blank? ? nil : value.to_i rescue nil
|
286
295
|
end
|
287
296
|
end
|
288
297
|
|
289
298
|
# convert something to a BigDecimal
|
290
299
|
def value_to_decimal(value)
|
300
|
+
return nil if value.blank?
|
291
301
|
# Using .class is faster than .is_a? and
|
292
302
|
# subclasses of BigDecimal will be handled
|
293
303
|
# in the else clause
|
@@ -374,6 +384,7 @@ module DatastaxRails
|
|
374
384
|
options[:cql_type] ||
|
375
385
|
case field_type.to_sym
|
376
386
|
when :integer then 'int'
|
387
|
+
when :long then 'bigint'
|
377
388
|
when :time, :date, :timestamp, :datetime then 'timestamp'
|
378
389
|
when :binary then 'blob'
|
379
390
|
when :list then "list<#{compute_cql_type(options[:holds], options)}>"
|
@@ -388,7 +399,6 @@ module DatastaxRails
|
|
388
399
|
options[:solr_type] ||
|
389
400
|
case field_type.to_sym
|
390
401
|
when :integer then 'int'
|
391
|
-
when :decimal then 'double'
|
392
402
|
when :timestamp, :time, :datetime then 'date'
|
393
403
|
when :list, :set, :map then compute_solr_type(options[:holds], options)
|
394
404
|
else field_type.to_s
|
@@ -4,6 +4,7 @@ module DatastaxRails
|
|
4
4
|
class Base
|
5
5
|
# Base initialize that sets the default consistency.
|
6
6
|
def initialize(klass, *_args)
|
7
|
+
@klass = klass
|
7
8
|
@consistency = klass.default_consistency.to_s.downcase.to_sym
|
8
9
|
@keyspace = DatastaxRails::Base.config[:keyspace]
|
9
10
|
@values = []
|
@@ -24,25 +25,36 @@ module DatastaxRails
|
|
24
25
|
# already been set up (Rails does this for you).
|
25
26
|
def execute
|
26
27
|
cql = to_cql
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
28
|
+
ActiveSupport::Notifications.instrument(
|
29
|
+
'cql.datastax_rails',
|
30
|
+
name: 'CQL',
|
31
|
+
cql: cql,
|
32
|
+
klass: @klass,
|
33
|
+
connection_id: DatastaxRails::Base.connection.object_id,
|
34
|
+
statement_name: self.class.name,
|
35
|
+
binds: @values) do |payload|
|
36
|
+
|
37
|
+
digest = Digest::MD5.digest cql
|
38
|
+
try_again = true
|
39
|
+
begin
|
40
|
+
DatastaxRails::Base.reconnect unless DatastaxRails::Base.connection
|
41
|
+
stmt = DatastaxRails::Base.statement_cache[digest] ||= DatastaxRails::Base.connection.prepare(cql)
|
42
|
+
if @consistency
|
43
|
+
results = stmt.execute(*@values, consistency: @consistency)
|
44
|
+
else
|
45
|
+
results = stmt.execute(*@values)
|
46
|
+
end
|
47
|
+
payload[:result_count] = results.respond_to?(:count) ? results.count : 'No'
|
48
|
+
results
|
49
|
+
rescue ::Cql::NotConnectedError
|
50
|
+
if try_again
|
51
|
+
Rails.logger.warn('Lost connection to Cassandra. Attempting to reconnect...')
|
52
|
+
try_again = false
|
53
|
+
DatastaxRails::Base.reconnect
|
54
|
+
retry
|
55
|
+
else
|
56
|
+
raise
|
57
|
+
end
|
46
58
|
end
|
47
59
|
end
|
48
60
|
end
|
@@ -2,7 +2,6 @@ module DatastaxRails #:nodoc:
|
|
2
2
|
module Cql #:nodoc:
|
3
3
|
class Select < Base #:nodoc:
|
4
4
|
def initialize(klass, select)
|
5
|
-
@klass = klass
|
6
5
|
@select = select.join(',')
|
7
6
|
@limit = nil
|
8
7
|
@conditions = {}
|
@@ -52,10 +51,11 @@ module DatastaxRails #:nodoc:
|
|
52
51
|
end
|
53
52
|
|
54
53
|
@conditions.each do |k, v|
|
55
|
-
if v.is_a?(Array)
|
54
|
+
if k.to_s == @klass.primary_key && v.is_a?(Array)
|
56
55
|
conditions << "\"#{k}\" IN (#{('?' * v.size).split(//).join(',')})"
|
57
56
|
@values += v
|
58
57
|
else
|
58
|
+
v = v.first if v.is_a?(Array)
|
59
59
|
conditions << "\"#{k}\" = ?"
|
60
60
|
@values << v
|
61
61
|
end
|
@@ -78,7 +78,7 @@ module DatastaxRails
|
|
78
78
|
class DynamicModel < WideStorageModel
|
79
79
|
self.abstract_class = true
|
80
80
|
|
81
|
-
PREFIXES = { string: :s_, text: :t_, boolean: :b_, date: :d_,
|
81
|
+
PREFIXES = { string: :s_, text: :t_, boolean: :b_, date: :d_, long: :l_, double: :db_,
|
82
82
|
timestamp: :ts_, integer: :i_, float: :f_, uuid: :u_ }.with_indifferent_access
|
83
83
|
|
84
84
|
class_attribute :group_by_attribute
|