kasket 4.8.0 → 4.9.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5cec0e5e944a74b977fd8e8113983160e1a5075eade70a499e6b16863abfde6
4
- data.tar.gz: d9ee5a1d6a974e998191ad656b4b962b5a7ea74e0327be3944813790bf6e7e8c
3
+ metadata.gz: e1399453146b7dcf0974eb42a7b80375291b2978415269d686ff66ccb77b9f53
4
+ data.tar.gz: 4649d5f06595e558f859472439733208e62229841901bf9dc81b602c3f78e07e
5
5
  SHA512:
6
- metadata.gz: 9aca01c0f69b403d2476b5db05b610604899f2a38f450b0c29d8f19b60f5f2e3e67777c172690672ae83a1a4ce14e316c85175989d5dd4df826afdbf6b8e530c
7
- data.tar.gz: 1645f52ca823c5c628d9fa5c1aba45393feffc9ac3f0c0e70e1552582bd55de79df20f8870f72deca67d8e0faae036d5fc5d1fa67b7be80dcf836d86808b7c68
6
+ metadata.gz: 7a6eeea3f1cdfe9bb349379cb07f4d13a21bfa0867ed09e9795746d91f74a69349ee15eb83d76e6f4776a717d8d4f2b8ce1479d41a095ac2e275502e3b54c99c
7
+ data.tar.gz: fd34ac51846f1748a47cf0de7b2c5f27ef843abe93429285e3830a8a8c3afb53822f7eab19452af3df5c99483323e1c0d9fd2a727ddda535626e58408a5a28e1
data/lib/kasket.rb CHANGED
@@ -17,8 +17,8 @@ module Kasket
17
17
 
18
18
  CONFIGURATION = { # rubocop:disable Style/MutableConstant
19
19
  max_collection_size: 100,
20
- write_through: false,
21
- default_expires_in: nil
20
+ write_through: false,
21
+ default_expires_in: nil
22
22
  }
23
23
 
24
24
  module_function
@@ -33,8 +33,8 @@ module Kasket
33
33
  ActiveRecord::Base.extend(Kasket::ConfigurationMixin)
34
34
 
35
35
  if defined?(ActiveRecord::Relation)
36
- ActiveRecord::Relation.send(:include, Kasket::RelationMixin)
37
- Arel::SelectManager.send(:include, Kasket::SelectManagerMixin)
36
+ ActiveRecord::Relation.include Kasket::RelationMixin
37
+ Arel::SelectManager.include Kasket::SelectManagerMixin
38
38
  end
39
39
  end
40
40
 
@@ -42,10 +42,15 @@ module Kasket
42
42
  @cache_store = ActiveSupport::Cache.lookup_store(options)
43
43
  end
44
44
 
45
- def self.cache
45
+ def self.cache_store
46
46
  @cache_store ||= Rails.cache
47
47
  end
48
48
 
49
+ # Alias cache_store to cache
50
+ class << self
51
+ alias_method :cache, :cache_store
52
+ end
53
+
49
54
  # Keys are the records being saved.
50
55
  # Values are either the saved record, or nil if the record has been destroyed.
51
56
  def self.pending_records
@@ -6,8 +6,8 @@ module Kasket
6
6
  # SELECT * FROM `users` WHERE (`users`.`id` = 2) LIMIT 1
7
7
  # 'SELECT * FROM \'posts\' WHERE (\'posts\'.\'id\' = 574019247) '
8
8
 
9
- AND = /\s+AND\s+/i
10
- VALUE = /'?(\d+|\?|(?:(?:[^']|''|\\')*))'?/ # Matches: 123, ?, '123', '12''3'
9
+ AND = /\s+AND\s+/i.freeze
10
+ VALUE = /'?(\d+|\?|(?:(?:[^']|''|\\')*))'?/.freeze # Matches: 123, ?, '123', '12''3'
11
11
 
12
12
  def initialize(model_class)
13
13
  @model_class = model_class
@@ -8,6 +8,7 @@ module Kasket
8
8
  end
9
9
  end
10
10
 
11
+ # *args can be replaced with (sql, *args) once we stop supporting Rails < 5.2
11
12
  def find_by_sql_with_kasket(*args)
12
13
  sql = args[0]
13
14
 
@@ -32,11 +33,27 @@ module Kasket
32
33
  find_by_sql_with_kasket_on_id_array(query[:key])
33
34
  else
34
35
  if value = Kasket.cache.read(query[:key])
35
- if value.is_a?(Array)
36
+ # Identified a specific edge case where memcached server returns 0x00 binary protocol response with no data
37
+ # when the node is being rebooted which causes the Dalli memcached client to return a TrueClass object instead of nil
38
+ # see: https://github.com/petergoldstein/dalli/blob/31dabf19d3dd94b348a00a59fe5a7b8fa80ce3ad/lib/dalli/server.rb#L520
39
+ # and: https://github.com/petergoldstein/dalli/issues/390
40
+ #
41
+ # The code in this first condition of TrueClass === true will
42
+ # skip the kasket cache for these specific objects and go directly to SQL for retrieval.
43
+ result_set = if value.is_a?(TrueClass)
44
+ find_by_sql_without_kasket(*args)
45
+ elsif value.is_a?(Array)
36
46
  filter_pending_records(find_by_sql_with_kasket_on_id_array(value))
37
47
  else
38
48
  filter_pending_records(Array.wrap(value).collect { |record| instantiate(record.dup) })
39
49
  end
50
+
51
+ payload = {
52
+ record_count: result_set.length,
53
+ class_name: to_s
54
+ }
55
+
56
+ ActiveSupport::Notifications.instrument('instantiation.active_record', payload) { result_set }
40
57
  else
41
58
  store_in_kasket(query[:key], find_by_sql_without_kasket(*args))
42
59
  end
@@ -80,7 +97,7 @@ module Kasket
80
97
  if records.size == 1
81
98
  records.first.store_in_kasket(key)
82
99
  elsif records.empty?
83
- ActiveRecord::Base.logger.info("[KASKET] would have stored an empty resultset") if ActiveRecord::Base.logger
100
+ ActiveRecord::Base.logger.debug("[KASKET] would have stored an empty resultset") if ActiveRecord::Base.logger
84
101
  elsif records.size <= Kasket::CONFIGURATION[:max_collection_size]
85
102
  if records.all?(&:kasket_cacheable?)
86
103
  instance_keys = records.map(&:store_in_kasket)
@@ -1,16 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
  module Kasket
3
3
  module RelationMixin
4
+ # binds can be removed when support for Rails < 5 is removed
4
5
  def to_kasket_query(binds = nil)
5
6
  if arel.is_a?(Arel::SelectManager)
6
7
  if ActiveRecord::VERSION::MAJOR < 5
7
8
  arel.to_kasket_query(klass, (binds || bind_values))
8
- else
9
+ elsif ActiveRecord::VERSION::STRING < '5.2'
9
10
  arel.to_kasket_query(klass, (@values[:where].to_h.values + Array(@values[:limit])))
11
+ else
12
+ arel.to_kasket_query(klass)
10
13
  end
11
14
  end
12
15
  rescue TypeError # unsupported object in ast
13
- return nil
16
+ nil
14
17
  end
15
18
  end
16
19
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  module Kasket
3
3
  module SelectManagerMixin
4
+ # binds can be removed once we stop supporting Rails < 5.2
4
5
  def to_kasket_query(klass, binds = [])
5
6
  begin
6
7
  query = Kasket::Visitor.new(klass, binds).accept(ast)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Kasket
3
- VERSION = '4.8.0'
3
+ VERSION = '4.9.0'
4
4
  class Version
5
5
  MAJOR = Kasket::VERSION.split('.')[0]
6
6
  MINOR = Kasket::VERSION.split('.')[1]
@@ -3,6 +3,7 @@ require 'arel'
3
3
 
4
4
  module Kasket
5
5
  class Visitor < Arel::Visitors::Visitor
6
+ # binds can be removed once we stop supporting Rails < 5.2
6
7
  def initialize(model_class, binds)
7
8
  @model_class = model_class
8
9
  @binds = binds.dup
@@ -75,6 +76,7 @@ module Kasket
75
76
  def visit_Arel_Nodes_JoinSource(node, *_)
76
77
  return :unsupported if !node.left || node.right.any?
77
78
  return :unsupported unless node.left.is_a?(Arel::Table)
79
+
78
80
  visit(node.left)
79
81
  end
80
82
 
@@ -85,6 +87,7 @@ module Kasket
85
87
  def visit_Arel_Nodes_And(node, *_)
86
88
  attributes = node.children.map { |child| visit(child) }
87
89
  return :unsupported if attributes.include?(:unsupported)
90
+
88
91
  attributes.sort! { |pair1, pair2| pair1[0].to_s <=> pair2[0].to_s }
89
92
  { attributes: attributes }
90
93
  end
@@ -112,8 +115,12 @@ module Kasket
112
115
  end
113
116
 
114
117
  def literal(node, *_)
115
- if node == '?'
116
- @binds.shift.last.to_s
118
+ if ActiveRecord::VERSION::STRING < '5.2'
119
+ if node == '?'
120
+ @binds.shift.last.to_s
121
+ else
122
+ node.to_s
123
+ end
117
124
  else
118
125
  node.to_s
119
126
  end
@@ -135,11 +142,13 @@ module Kasket
135
142
  node.map {|value| visit(value) }
136
143
  end
137
144
 
138
- def visit_Arel_Nodes_Casted(node, *_)
139
- case node.val
140
- when nil then nil
141
- when String then node.val
142
- else quoted(node.val)
145
+ if ActiveRecord::VERSION::STRING < '5.2'
146
+ def visit_Arel_Nodes_Casted(node, *_)
147
+ case node.val
148
+ when nil then nil
149
+ when String then node.val
150
+ else quoted(node.val)
151
+ end
143
152
  end
144
153
  end
145
154
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kasket
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.8.0
4
+ version: 4.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mick Staugaard
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-08-26 00:00:00.000000000 Z
12
+ date: 2021-07-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -32,7 +32,7 @@ dependencies:
32
32
  - !ruby/object:Gem::Version
33
33
  version: '6.1'
34
34
  - !ruby/object:Gem::Dependency
35
- name: rake
35
+ name: bump
36
36
  requirement: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
@@ -60,7 +60,7 @@ dependencies:
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  - !ruby/object:Gem::Dependency
63
- name: mocha
63
+ name: minitest
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
@@ -74,7 +74,7 @@ dependencies:
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  - !ruby/object:Gem::Dependency
77
- name: wwtd
77
+ name: minitest-rg
78
78
  requirement: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - ">="
@@ -88,7 +88,7 @@ dependencies:
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  - !ruby/object:Gem::Dependency
91
- name: bump
91
+ name: mocha
92
92
  requirement: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - ">="
@@ -102,7 +102,7 @@ dependencies:
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  - !ruby/object:Gem::Dependency
105
- name: minitest
105
+ name: rake
106
106
  requirement: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - ">="
@@ -116,7 +116,7 @@ dependencies:
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  - !ruby/object:Gem::Dependency
119
- name: minitest-rg
119
+ name: timecop
120
120
  requirement: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - ">="
@@ -130,7 +130,7 @@ dependencies:
130
130
  - !ruby/object:Gem::Version
131
131
  version: '0'
132
132
  - !ruby/object:Gem::Dependency
133
- name: timecop
133
+ name: wwtd
134
134
  requirement: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - ">="
@@ -173,14 +173,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
173
173
  requirements:
174
174
  - - ">="
175
175
  - !ruby/object:Gem::Version
176
- version: 2.3.0
176
+ version: 2.5.0
177
177
  required_rubygems_version: !ruby/object:Gem::Requirement
178
178
  requirements:
179
179
  - - ">="
180
180
  - !ruby/object:Gem::Version
181
181
  version: '0'
182
182
  requirements: []
183
- rubygems_version: 3.1.4
183
+ rubygems_version: 3.2.22
184
184
  signing_key:
185
185
  specification_version: 4
186
186
  summary: A write back caching layer on active record