kasket 4.10.4 → 4.12.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a786cf4a5580eadc1ad695d662795a160dde563176371c9c0176542eadc1da6c
4
- data.tar.gz: b9261e224b6aaec4327931a5d723b3fb872cca314a6a5b68681c61b357945fdc
3
+ metadata.gz: 52a098184223192a1d4a6cd6a92363dd5f9324b4d2c56da1fa33769402e0c602
4
+ data.tar.gz: 4fca1aba72b41281fb71f91a61ba18d96edb93cb60ff94924c63fe7353bd96d7
5
5
  SHA512:
6
- metadata.gz: daea000b865281f12ae6fd70752f4d1418dadb00a3747452f7db9aa52230c071b8d87b23a37cd0b43a0d3a6db292c418293d25d3b97872f7a597b49b5bb81e5a
7
- data.tar.gz: f3625ddb2690f619d1f93aa2bcfdff5c72dd3b0f6debe2f19646ef6fba030d206ccab0e920fed37d0869eb8532cb1cc44adbc0d7955cfe215e938327465817ea
6
+ metadata.gz: 4aa6be9f52ab44578929a3e66fa2ddfb71a6d935e00d13e80258fe4ec413ac69cae42666512e3711c189edf03e6e011ecd64a13d9a210449edc292aeea098680
7
+ data.tar.gz: 0131bde86df784810b892da100e6e5c26e40620071c6169def6f7cbb7f176775ed981c7174c2be247a1c188053b755dab6469d9cd39e51104921f57d73721f72
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Kasket
2
2
 
3
3
  ### Puts a cap on your queries
4
- A caching layer for ActiveRecord (3.x and 4.x)
4
+ A caching layer for ActiveRecord.
5
5
 
6
6
  Developed and used by [Zendesk](http://zendesk.com).
7
7
 
@@ -137,6 +137,20 @@ Absolutely, but Cache Money does so much more.
137
137
  * The Cache Money code is overly complex.
138
138
  * Cache Money seems abandoned.
139
139
 
140
+ ## Development
141
+
142
+ Run the tests with:
143
+
144
+ ```
145
+ $ rake test
146
+ ```
147
+
148
+ Access a dev console running on the local test DB:
149
+
150
+ ```
151
+ $ bin/console
152
+ ```
153
+
140
154
  ## Note on Patches/Pull Requests
141
155
 
142
156
  * Fork the project.
@@ -101,12 +101,8 @@ module Kasket
101
101
  def kasket_quoted_value_for_column(value, column)
102
102
  if column
103
103
  conn = connection
104
- casted_value =
105
- case ActiveRecord::VERSION::MAJOR
106
- when 3 then column.type_cast(value)
107
- when 4 then column.type_cast_for_database(value)
108
- else conn.type_cast_from_column(column, value)
109
- end
104
+ type = conn.lookup_cast_type_from_column(column)
105
+ casted_value = conn.type_cast(type.serialize(value))
110
106
  conn.quote(casted_value).downcase
111
107
  else
112
108
  value.to_s
@@ -8,20 +8,13 @@ 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
12
- def find_by_sql_with_kasket(*args)
13
- sql = args[0]
14
-
11
+ def find_by_sql_with_kasket(sql, binds = [], *restargs, **kwargs, &blk)
15
12
  if use_kasket?
16
13
  query = if sql.respond_to?(:to_kasket_query)
17
- if ActiveRecord::VERSION::MAJOR < 5
18
- sql.to_kasket_query(self, args[1])
14
+ if ActiveRecord::VERSION::STRING < '5.2'
15
+ sql.to_kasket_query(self, binds.map(&:value_for_database))
19
16
  else
20
- if ActiveRecord::VERSION::STRING < '5.2'
21
- sql.to_kasket_query(self, args[1].map(&:value_for_database))
22
- else
23
- sql.to_kasket_query(self)
24
- end
17
+ sql.to_kasket_query(self)
25
18
  end
26
19
  else
27
20
  kasket_parser.parse(sanitize_sql(sql))
@@ -30,7 +23,7 @@ module Kasket
30
23
 
31
24
  if query && has_kasket_index_on?(query[:index])
32
25
  if query[:key].is_a?(Array)
33
- find_by_sql_with_kasket_on_id_array(query[:key])
26
+ filter_pending_records(find_by_sql_with_kasket_on_id_array(query[:key]))
34
27
  else
35
28
  if value = Kasket.cache.read(query[:key])
36
29
  # Identified a specific edge case where memcached server returns 0x00 binary protocol response with no data
@@ -41,7 +34,7 @@ module Kasket
41
34
  # The code in this first condition of TrueClass === true will
42
35
  # skip the kasket cache for these specific objects and go directly to SQL for retrieval.
43
36
  result_set = if value.is_a?(TrueClass)
44
- find_by_sql_without_kasket(*args)
37
+ find_by_sql_without_kasket(sql, binds, *restargs, **kwargs, &blk)
45
38
  elsif value.is_a?(Array)
46
39
  filter_pending_records(find_by_sql_with_kasket_on_id_array(value))
47
40
  else
@@ -55,11 +48,11 @@ module Kasket
55
48
 
56
49
  ActiveSupport::Notifications.instrument('instantiation.active_record', payload) { result_set }
57
50
  else
58
- store_in_kasket(query[:key], find_by_sql_without_kasket(*args))
51
+ store_in_kasket(query[:key], find_by_sql_without_kasket(sql, binds, *restargs, **kwargs, &blk))
59
52
  end
60
53
  end
61
54
  else
62
- find_by_sql_without_kasket(*args)
55
+ find_by_sql_without_kasket(sql, binds, *restargs, **kwargs, &blk)
63
56
  end
64
57
  end
65
58
 
@@ -1,12 +1,9 @@
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
5
- def to_kasket_query(binds = nil)
4
+ def to_kasket_query
6
5
  if arel.is_a?(Arel::SelectManager)
7
- if ActiveRecord::VERSION::MAJOR < 5
8
- arel.to_kasket_query(klass, (binds || bind_values))
9
- elsif ActiveRecord::VERSION::STRING < '5.2'
6
+ if ActiveRecord::VERSION::STRING < '5.2'
10
7
  arel.to_kasket_query(klass, (@values[:where].to_h.values + Array(@values[:limit])))
11
8
  else
12
9
  arel.to_kasket_query(klass)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Kasket
3
- VERSION = '4.10.4'
3
+ VERSION = '4.12.0'
4
4
  class Version
5
5
  MAJOR = Kasket::VERSION.split('.')[0]
6
6
  MINOR = Kasket::VERSION.split('.')[1]
@@ -49,7 +49,7 @@ module Kasket
49
49
 
50
50
  def visit_Arel_Nodes_SelectCore(node, *_)
51
51
  return :unsupported if node.groups.any?
52
- return :unsupported if ActiveRecord::VERSION::MAJOR < 5 ? node.having : node.havings.present?
52
+ return :unsupported if node.havings.present?
53
53
  return :unsupported if node.set_quantifier
54
54
  return :unsupported if !node.source || node.source.empty?
55
55
  return :unsupported if node.projections.empty?
@@ -65,6 +65,14 @@ module Kasket
65
65
  return unless (column_names - projection_names).empty?
66
66
  end
67
67
 
68
+ # un-optimize AR 6.1 by adding a redundant And node to hit visitor below
69
+ if ActiveRecord::VERSION::STRING.start_with? "6.1"
70
+ if node.wheres.size == 1
71
+ n = node.wheres[0]
72
+ node.wheres[0] = Arel::Nodes::And.new([n]) unless n.is_a?(Arel::Nodes::And)
73
+ end
74
+ end
75
+
68
76
  parts = [visit(node.source)]
69
77
 
70
78
  parts += node.wheres.map {|where| visit(where) }
@@ -73,11 +81,7 @@ module Kasket
73
81
  end
74
82
 
75
83
  def visit_Arel_Nodes_Limit(node, *_)
76
- if ActiveRecord::VERSION::MAJOR < 5
77
- { limit: node.value.to_i }
78
- else
79
- { limit: visit(node.value).to_i }
80
- end
84
+ { limit: visit(node.value).to_i }
81
85
  end
82
86
 
83
87
  def visit_Arel_Nodes_JoinSource(node, *_)
@@ -106,6 +110,8 @@ module Kasket
106
110
  [left, visit(node.right)]
107
111
  end
108
112
 
113
+ alias_method :visit_Arel_Nodes_HomogeneousIn, :visit_Arel_Nodes_In
114
+
109
115
  def visit_Arel_Nodes_Equality(node, *_)
110
116
  right =
111
117
  case node.right
@@ -134,14 +140,10 @@ module Kasket
134
140
  end
135
141
 
136
142
  def visit_Arel_Nodes_BindParam(node, *_)
137
- if ActiveRecord::VERSION::MAJOR < 5
138
- visit(@binds.shift[1])
143
+ if ActiveRecord::VERSION::STRING < '5.2'
144
+ visit(@binds.shift)
139
145
  else
140
- if ActiveRecord::VERSION::STRING < '5.2'
141
- visit(@binds.shift)
142
- else
143
- visit(node.value.value) unless node.value.value.nil?
144
- end
146
+ visit(node.value.value) unless node.value.value.nil?
145
147
  end
146
148
  end
147
149
 
@@ -157,6 +159,15 @@ module Kasket
157
159
  else quoted(node.val)
158
160
  end
159
161
  end
162
+ else # R52: val -> value
163
+ def visit_Arel_Nodes_Casted(node, *_)
164
+ v = node.value
165
+ case v
166
+ when nil then nil
167
+ when String then v
168
+ else quoted(v)
169
+ end
170
+ end
160
171
  end
161
172
 
162
173
  def visit_TrueClass(_node)
@@ -8,14 +8,14 @@ module Kasket
8
8
  end
9
9
  end
10
10
 
11
- def update_counters_with_kasket_clearing(*args)
11
+ def update_counters_with_kasket_clearing(*args, **kwargs)
12
12
  remove_from_kasket(args[0])
13
- update_counters_without_kasket_clearing(*args)
13
+ update_counters_without_kasket_clearing(*args, **kwargs)
14
14
  end
15
15
 
16
- def transaction_with_kasket_disabled(*args)
16
+ def transaction_with_kasket_disabled(*args, **kwargs)
17
17
  without_kasket do
18
- transaction_without_kasket_disabled(*args) { yield }
18
+ transaction_without_kasket_disabled(*args, **kwargs) { yield }
19
19
  end
20
20
  end
21
21
  end
@@ -41,11 +41,7 @@ module Kasket
41
41
  attribute_sets = [attributes]
42
42
 
43
43
  previous_changes = options[:previous_changes]
44
- previous_changes ||= if respond_to?(:saved_changes)
45
- saved_changes.transform_values(&:first)
46
- else
47
- previous_changes() # keep parens or rename the local var
48
- end
44
+ previous_changes ||= saved_changes.transform_values(&:first)
49
45
  if previous_changes.present?
50
46
  old_attributes = previous_changes.each_with_object({}) do |(attribute, (old, _)), all|
51
47
  all[attribute.to_s] = old
@@ -93,23 +89,14 @@ module Kasket
93
89
  super
94
90
  end
95
91
 
96
- if ActiveRecord::VERSION::MAJOR == 3
97
- def update_column(column, value)
98
- previous_changes = { column => [attributes[column.to_s], value] }
99
- result = super
100
- clear_kasket_indices(previous_changes: previous_changes)
101
- result
102
- end
103
- else
104
- def update_columns(new_attributes)
105
- previous_attributes = attributes
106
- previous_changes = new_attributes.each_with_object({}) do |(k, v), all|
107
- all[k] = [previous_attributes[k.to_s], v]
108
- end
109
- result = super
110
- clear_kasket_indices(previous_changes: previous_changes)
111
- result
92
+ def update_columns(new_attributes)
93
+ previous_attributes = attributes
94
+ previous_changes = new_attributes.each_with_object({}) do |(k, v), all|
95
+ all[k] = [previous_attributes[k.to_s], v]
112
96
  end
97
+ result = super
98
+ clear_kasket_indices(previous_changes: previous_changes)
99
+ result
113
100
  end
114
101
 
115
102
  def kasket_after_commit_dummy
@@ -124,13 +111,13 @@ module Kasket
124
111
  Kasket.add_pending_record(self, _destroyed = true)
125
112
  end
126
113
 
127
- def committed!(*)
114
+ def committed!(*args, **kwargs)
128
115
  Kasket.clear_pending_records
129
116
  kasket_after_commit if persisted? || destroyed?
130
117
  super
131
118
  end
132
119
 
133
- def rolledback!(*)
120
+ def rolledback!(*args, **kwargs)
134
121
  Kasket.clear_pending_records
135
122
  super
136
123
  end
@@ -148,10 +135,6 @@ module Kasket
148
135
  model_class.after_destroy :kasket_after_destroy
149
136
  model_class.after_commit :kasket_after_commit_dummy
150
137
 
151
- if ActiveRecord::VERSION::MAJOR == 3 || (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 0)
152
- model_class.after_touch :kasket_after_commit
153
- end
154
-
155
138
  class << model_class
156
139
  alias_method :transaction_without_kasket_disabled, :transaction
157
140
  alias_method :transaction, :transaction_with_kasket_disabled
data/lib/kasket.rb CHANGED
@@ -31,11 +31,8 @@ module Kasket
31
31
  CONFIGURATION[:default_expires_in] = options[:default_expires_in] if options[:default_expires_in]
32
32
 
33
33
  ActiveRecord::Base.extend(Kasket::ConfigurationMixin)
34
-
35
- if defined?(ActiveRecord::Relation)
36
- ActiveRecord::Relation.include Kasket::RelationMixin
37
- Arel::SelectManager.include Kasket::SelectManagerMixin
38
- end
34
+ ActiveRecord::Relation.include(Kasket::RelationMixin)
35
+ Arel::SelectManager.include(Kasket::SelectManagerMixin)
39
36
  end
40
37
 
41
38
  def self.cache_store=(options)
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.10.4
4
+ version: 4.12.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: 2022-09-02 00:00:00.000000000 Z
12
+ date: 2023-03-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -17,20 +17,20 @@ dependencies:
17
17
  requirements:
18
18
  - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: '4.2'
20
+ version: '5.1'
21
21
  - - "<"
22
22
  - !ruby/object:Gem::Version
23
- version: '6.1'
23
+ version: '7'
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
28
  - - ">="
29
29
  - !ruby/object:Gem::Version
30
- version: '4.2'
30
+ version: '5.1'
31
31
  - - "<"
32
32
  - !ruby/object:Gem::Version
33
- version: '6.1'
33
+ version: '7'
34
34
  description: puts a cap on your queries
35
35
  email:
36
36
  - mick@zendesk.com
@@ -61,7 +61,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
61
61
  requirements:
62
62
  - - ">="
63
63
  - !ruby/object:Gem::Version
64
- version: 2.5.0
64
+ version: 2.6.0
65
65
  required_rubygems_version: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - ">="