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