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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/config/solrconfig.xml.erb +7 -7
  3. data/lib/datastax_rails/associations/collection_association.rb +4 -4
  4. data/lib/datastax_rails/associations/has_many_association.rb +1 -1
  5. data/lib/datastax_rails/attribute_methods/dirty.rb +6 -0
  6. data/lib/datastax_rails/attribute_methods/primary_key.rb +9 -1
  7. data/lib/datastax_rails/attribute_methods/read.rb +2 -2
  8. data/lib/datastax_rails/attribute_methods/typecasting.rb +4 -7
  9. data/lib/datastax_rails/attribute_methods.rb +25 -0
  10. data/lib/datastax_rails/autosave_association.rb +3 -3
  11. data/lib/datastax_rails/base.rb +33 -11
  12. data/lib/datastax_rails/column.rb +25 -15
  13. data/lib/datastax_rails/connection.rb +1 -1
  14. data/lib/datastax_rails/cql/base.rb +31 -19
  15. data/lib/datastax_rails/cql/select.rb +2 -2
  16. data/lib/datastax_rails/dynamic_model.rb +1 -1
  17. data/lib/datastax_rails/errors.rb +3 -0
  18. data/lib/datastax_rails/instrumentation/controller_runtime.rb +52 -0
  19. data/lib/datastax_rails/instrumentation/log_subscriber.rb +92 -0
  20. data/lib/datastax_rails/instrumentation.rb +4 -0
  21. data/lib/datastax_rails/persistence.rb +49 -17
  22. data/lib/datastax_rails/railtie.rb +7 -0
  23. data/lib/datastax_rails/reflection.rb +16 -12
  24. data/lib/datastax_rails/relation/batches.rb +1 -1
  25. data/lib/datastax_rails/relation/finder_methods.rb +5 -5
  26. data/lib/datastax_rails/relation/modification_methods.rb +11 -26
  27. data/lib/datastax_rails/relation/search_methods.rb +10 -11
  28. data/lib/datastax_rails/relation.rb +81 -50
  29. data/lib/datastax_rails/scoping.rb +1 -1
  30. data/lib/datastax_rails/serialization.rb +10 -6
  31. data/lib/datastax_rails/serializers/xml_serializer.rb +3 -1
  32. data/lib/datastax_rails/tasks/ds.rake +25 -26
  33. data/lib/datastax_rails/timestamps.rb +1 -1
  34. data/lib/datastax_rails/types/dynamic_set.rb +4 -0
  35. data/lib/datastax_rails/version.rb +1 -1
  36. data/lib/datastax_rails/wide_storage_model.rb +3 -1
  37. data/lib/datastax_rails.rb +1 -0
  38. data/spec/datastax_rails/attribute_methods/read_spec.rb +33 -0
  39. data/spec/datastax_rails/attribute_methods/typecasting_spec.rb +25 -0
  40. data/spec/datastax_rails/base_spec.rb +1 -1
  41. data/spec/datastax_rails/callbacks_spec.rb +6 -0
  42. data/spec/datastax_rails/column_spec.rb +20 -0
  43. data/spec/datastax_rails/cql/base_spec.rb +1 -1
  44. data/spec/datastax_rails/cql/select_spec.rb +7 -1
  45. data/spec/datastax_rails/persistence_spec.rb +22 -3
  46. data/spec/datastax_rails/relation/finder_methods_spec.rb +13 -0
  47. data/spec/datastax_rails/relation/search_methods_spec.rb +37 -12
  48. data/spec/datastax_rails/serialization_spec.rb +17 -0
  49. data/spec/dummy/log/development.log +0 -24195
  50. data/spec/dummy/log/test.log +20 -15610
  51. data/spec/factories/hobbies.rb +1 -0
  52. data/spec/factories/jobs.rb +7 -0
  53. data/spec/factories/people.rb +1 -0
  54. data/spec/factories/person_roles.rb +7 -0
  55. data/spec/factories/roles.rb +6 -0
  56. data/spec/factories/uuid_keys.rb +6 -0
  57. data/spec/feature/associations_spec.rb +26 -0
  58. data/spec/support/models.rb +82 -0
  59. metadata +19 -4
  60. data/spec/dummy/log/production.log +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 19e0c7c773fb3991c35ee3c5a4f76ec967d9041c
4
- data.tar.gz: 4a5033007b3009ea785e38935f0d0a7c5a6eb410
3
+ metadata.gz: 46adde0cefb47aa5fc3affe6dbd16645d8357050
4
+ data.tar.gz: 9664ee5c527d05bc1020d9bae17898fd386f319e
5
5
  SHA512:
6
- metadata.gz: f3ead232f919376053a15e813cec9d08630ff7ae4414300590ff2b8500077b9c6622a5347dec3d2ce5f25e22a528df05399843d8eff6587ef24df14ba1cc7be1
7
- data.tar.gz: 4f620b9de99f047c114386357424cd1516432f81a45c1c3d446d31343712cd67c4396f46d2dab624b75361026dd58905982553540e8872c8bed9d06a3b98eac5
6
+ metadata.gz: fa9d465f640a3d72fbf096868b22976a56d39699005c1fbf656dc7394c26567fcc21570f0c8f27260d5a42f5053c308159a1baaeb07f8b752e200cfce85a12a7
7
+ data.tar.gz: 81221cc2ccf7b287a8842df07c839622d2ac7bd1f605c8042d5360e34c35ee8038b8eecbea1e771ca42d69c7854fe73c1442bbb4aac900cedc8fc93c120d36ad
@@ -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>LUCENE_40</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="512"
340
- initialSize="512"
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.XmlUpdateRequestHandler">
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.BinaryUpdateRequestHandler" />
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 { |r| r.new_record? }
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 { |id| id.blank? }
79
- replace(klass.find(ids).index_by { |r| r.id }.values_at(*ids))
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 { |r| r.new_record? }
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 { |r| r.destroy }
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 => id }
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 { |attr| attr.to_s }
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 { |col| col.name }.to_set
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 json(name, options = {})
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 json string text time timestamp time_with_zone
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 { |record| record.changed_for_autosave? }
258
+ association.target.select(&:changed_for_autosave?)
259
259
  else
260
- association.target.select { |record| record.new_record? }
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? { |a| a.changed_for_autosave? }
269
+ association && Array.wrap(association.target).any?(&:changed_for_autosave?)
270
270
  end
271
271
  end
272
272
 
@@ -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
- # * float - a number in floating point notation
41
- # * integer - a whole, round number of any size
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.default
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 { |m|m.abstract_class? }
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 { |a|a.to_s }
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 { |result| result.primary_key }
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
- [:decimal, :double, :float, :integer].include?(type)
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 then Fixnum
104
+ when :integer, :long then Fixnum
101
105
  when :float then Float
102
- when :decimal, :double then BigDecimal
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 then klass.value_to_integer(value)
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 then klass.value_to_uuid(value)
133
- when :list, :set then wrap_collection(value.map { |v| type_cast(v, record, @options[:holds]) }, record)
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
- when :map then {} # lambda {|rec| DatastaxRails::Types::DynamicMap.new(rec, self.name.to_s, {})}
207
- when :list then [] # lambda {|rec| DatastaxRails::Types::DynamicList.new(rec, self.name.to_s, [])}
208
- when :set then Set.new # lambda {|set| DatastaxRails::Types::DynamicSet.new(rec, self.name.to_s, Set.new)}
209
- else default
210
- end
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
@@ -110,7 +110,7 @@ module DatastaxRails
110
110
  end
111
111
  self.connection = ::Cql::Client.connect(cql_options)
112
112
  end
113
-
113
+
114
114
  def ssl_type
115
115
  return false unless DatastaxRails::Base.config && DatastaxRails::Base.config[:ssl]
116
116
  config = DatastaxRails::Base.config
@@ -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
- puts cql if ENV['DEBUG_CQL'] == 'true'
28
- pp @values if ENV['DEBUG_CQL'] == 'true'
29
- digest = Digest::MD5.digest cql
30
- try_again = true
31
- begin
32
- stmt = DatastaxRails::Base.statement_cache[digest] ||= DatastaxRails::Base.connection.prepare(cql)
33
- if @consistency
34
- stmt.execute(*@values, consistency: @consistency)
35
- else
36
- stmt.execute(*@values)
37
- end
38
- rescue ::Cql::NotConnectedError
39
- if try_again
40
- Rails.logger.warn('Lost connection to Cassandra. Attempting to reconnect...')
41
- try_again = false
42
- DatastaxRails::Base.reconnect
43
- retry
44
- else
45
- raise
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
@@ -16,4 +16,7 @@ module DatastaxRails
16
16
 
17
17
  class UnknownAttributeError < DatastaxRailsError
18
18
  end
19
+
20
+ class NotPersistedError < DatastaxRailsError
21
+ end
19
22
  end