kasket 4.4.5 → 4.8.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 +5 -5
- data/README.md +23 -8
- data/lib/kasket.rb +7 -2
- data/lib/kasket/configuration_mixin.rb +13 -11
- data/lib/kasket/read_mixin.rb +5 -1
- data/lib/kasket/relation_mixin.rb +1 -1
- data/lib/kasket/version.rb +1 -1
- data/lib/kasket/visitor.rb +13 -4
- metadata +8 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e5cec0e5e944a74b977fd8e8113983160e1a5075eade70a499e6b16863abfde6
|
4
|
+
data.tar.gz: d9ee5a1d6a974e998191ad656b4b962b5a7ea74e0327be3944813790bf6e7e8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9aca01c0f69b403d2476b5db05b610604899f2a38f450b0c29d8f19b60f5f2e3e67777c172690672ae83a1a4ce14e316c85175989d5dd4df826afdbf6b8e530c
|
7
|
+
data.tar.gz: 1645f52ca823c5c628d9fa5c1aba45393feffc9ac3f0c0e70e1552582bd55de79df20f8870f72deca67d8e0faae036d5fc5d1fa67b7be80dcf836d86808b7c68
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Kasket [](https://circleci.com/gh/zendesk/kasket)
|
2
2
|
|
3
3
|
### Puts a cap on your queries
|
4
4
|
A caching layer for ActiveRecord (3.x and 4.x)
|
@@ -34,8 +34,8 @@ This will include the required modules into ActiveRecord.
|
|
34
34
|
By default, Kasket will cache each instance collection with a maximum length of 100.
|
35
35
|
You can override this by passing the `:max_collection_size` option to the `Kasket.setup` call:
|
36
36
|
|
37
|
-
```
|
38
|
-
Kasket.setup(:
|
37
|
+
```ruby
|
38
|
+
Kasket.setup(max_collection_size: 50)
|
39
39
|
```
|
40
40
|
|
41
41
|
#### Write-Through Caching
|
@@ -44,8 +44,8 @@ By default, when a model is saved, Kasket will invalidate cache entries by delet
|
|
44
44
|
You can pass ':write_through => true' to the `Kasket.setup` call to get write-through cache
|
45
45
|
semantics instead. In this mode, the model will be updated in the cache as well as the database.
|
46
46
|
|
47
|
-
```
|
48
|
-
Kasket.setup(:
|
47
|
+
```ruby
|
48
|
+
Kasket.setup(write_through: true)
|
49
49
|
```
|
50
50
|
|
51
51
|
## Configuring caching of your models
|
@@ -55,7 +55,7 @@ configuration.
|
|
55
55
|
|
56
56
|
If you have an `Account` model, you can can do the simplest caching configuration like:
|
57
57
|
|
58
|
-
```
|
58
|
+
```ruby
|
59
59
|
Account.has_kasket
|
60
60
|
```
|
61
61
|
|
@@ -65,7 +65,7 @@ All other calls (say, `Account.find_by_subdomain('zendesk')`) are untouched.
|
|
65
65
|
|
66
66
|
If you wanted to configure a caching index on the subdomain attribute of the Account model, you would simply write
|
67
67
|
|
68
|
-
```
|
68
|
+
```ruby
|
69
69
|
Account.has_kasket_on :subdomain
|
70
70
|
```
|
71
71
|
|
@@ -81,6 +81,7 @@ The goal of Kasket is to be as safe as possible to use, so the cache is expired
|
|
81
81
|
* When you save a model instance
|
82
82
|
* When your database schema changes
|
83
83
|
* When you install a new version of Kasket
|
84
|
+
* After a global or per-model TTL
|
84
85
|
* When you ask it to
|
85
86
|
|
86
87
|
### Cache expiry on instance save
|
@@ -96,12 +97,26 @@ If you somehow change your table schema, all cache entries for that table will a
|
|
96
97
|
|
97
98
|
All Kasket cache keys contain the Kasket version number, so upgrading Kasket will expire all Kasket cache entries.
|
98
99
|
|
100
|
+
### Cache expiry by TTL
|
101
|
+
|
102
|
+
Sometimes caches like memcache can become incoherent. One layer of mitigation for this problem is to specify the maximum length a value may stay in cache before being expired and re-calculated. You can configure an optional default TTL value at setup:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
Kasket.setup(default_expires_in: 24.hours)
|
106
|
+
```
|
107
|
+
|
108
|
+
You can further specify per-model TTL values:
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
Account.kasket_expires_in 5.minutes
|
112
|
+
```
|
113
|
+
|
99
114
|
### Manually expiring caches
|
100
115
|
|
101
116
|
If you have model methods that update the database behind the back of ActiveRecord, you need to mark these methods
|
102
117
|
as being dirty.
|
103
118
|
|
104
|
-
```
|
119
|
+
```ruby
|
105
120
|
Account.kasket_dirty_methods :update_last_action
|
106
121
|
```
|
107
122
|
|
data/lib/kasket.rb
CHANGED
@@ -15,7 +15,11 @@ module Kasket
|
|
15
15
|
autoload :SelectManagerMixin, 'kasket/select_manager_mixin'
|
16
16
|
autoload :RelationMixin, 'kasket/relation_mixin'
|
17
17
|
|
18
|
-
CONFIGURATION = {
|
18
|
+
CONFIGURATION = { # rubocop:disable Style/MutableConstant
|
19
|
+
max_collection_size: 100,
|
20
|
+
write_through: false,
|
21
|
+
default_expires_in: nil
|
22
|
+
}
|
19
23
|
|
20
24
|
module_function
|
21
25
|
|
@@ -23,7 +27,8 @@ module Kasket
|
|
23
27
|
return if ActiveRecord::Base.respond_to?(:has_kasket)
|
24
28
|
|
25
29
|
CONFIGURATION[:max_collection_size] = options[:max_collection_size] if options[:max_collection_size]
|
26
|
-
CONFIGURATION[:write_through]
|
30
|
+
CONFIGURATION[:write_through] = options[:write_through] if options[:write_through]
|
31
|
+
CONFIGURATION[:default_expires_in] = options[:default_expires_in] if options[:default_expires_in]
|
27
32
|
|
28
33
|
ActiveRecord::Base.extend(Kasket::ConfigurationMixin)
|
29
34
|
|
@@ -37,8 +37,8 @@ module Kasket
|
|
37
37
|
else
|
38
38
|
key = attribute_value_pairs.map do |attribute, value|
|
39
39
|
column = columns_hash[attribute.to_s]
|
40
|
-
value = nil if value.blank?
|
41
|
-
"#{attribute}=#{
|
40
|
+
value = nil if value.blank? && value != false
|
41
|
+
"#{attribute}=#{kasket_quoted_value_for_column(value, column)}"
|
42
42
|
end.join('/')
|
43
43
|
|
44
44
|
if key.size > (250 - kasket_key_prefix.size) || key =~ /\s/
|
@@ -91,21 +91,23 @@ module Kasket
|
|
91
91
|
@kasket_ttl = time
|
92
92
|
end
|
93
93
|
|
94
|
-
|
94
|
+
def kasket_ttl
|
95
|
+
@kasket_ttl ||= nil
|
96
|
+
@kasket_ttl || Kasket::CONFIGURATION[:default_expires_in]
|
97
|
+
end
|
95
98
|
|
96
99
|
private
|
97
100
|
|
98
|
-
def
|
101
|
+
def kasket_quoted_value_for_column(value, column)
|
99
102
|
if column
|
103
|
+
conn = connection
|
100
104
|
casted_value =
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
else
|
106
|
-
column.type_cast(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)
|
107
109
|
end
|
108
|
-
|
110
|
+
conn.quote(casted_value).downcase
|
109
111
|
else
|
110
112
|
value.to_s
|
111
113
|
end
|
data/lib/kasket/read_mixin.rb
CHANGED
@@ -16,7 +16,11 @@ module Kasket
|
|
16
16
|
if ActiveRecord::VERSION::MAJOR < 5
|
17
17
|
sql.to_kasket_query(self, args[1])
|
18
18
|
else
|
19
|
-
|
19
|
+
if ActiveRecord::VERSION::STRING < '5.2'
|
20
|
+
sql.to_kasket_query(self, args[1].map(&:value_for_database))
|
21
|
+
else
|
22
|
+
sql.to_kasket_query(self)
|
23
|
+
end
|
20
24
|
end
|
21
25
|
else
|
22
26
|
kasket_parser.parse(sanitize_sql(sql))
|
@@ -6,7 +6,7 @@ module Kasket
|
|
6
6
|
if ActiveRecord::VERSION::MAJOR < 5
|
7
7
|
arel.to_kasket_query(klass, (binds || bind_values))
|
8
8
|
else
|
9
|
-
arel.to_kasket_query(klass, (@values[:where].
|
9
|
+
arel.to_kasket_query(klass, (@values[:where].to_h.values + Array(@values[:limit])))
|
10
10
|
end
|
11
11
|
end
|
12
12
|
rescue TypeError # unsupported object in ast
|
data/lib/kasket/version.rb
CHANGED
data/lib/kasket/visitor.rb
CHANGED
@@ -119,11 +119,15 @@ module Kasket
|
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
|
-
def visit_Arel_Nodes_BindParam(
|
122
|
+
def visit_Arel_Nodes_BindParam(node, *_)
|
123
123
|
if ActiveRecord::VERSION::MAJOR < 5
|
124
124
|
visit(@binds.shift[1])
|
125
125
|
else
|
126
|
-
|
126
|
+
if ActiveRecord::VERSION::STRING < '5.2'
|
127
|
+
visit(@binds.shift)
|
128
|
+
else
|
129
|
+
visit(node.value.value) unless node.value.value.nil?
|
130
|
+
end
|
127
131
|
end
|
128
132
|
end
|
129
133
|
|
@@ -132,7 +136,11 @@ module Kasket
|
|
132
136
|
end
|
133
137
|
|
134
138
|
def visit_Arel_Nodes_Casted(node, *_)
|
135
|
-
|
139
|
+
case node.val
|
140
|
+
when nil then nil
|
141
|
+
when String then node.val
|
142
|
+
else quoted(node.val)
|
143
|
+
end
|
136
144
|
end
|
137
145
|
|
138
146
|
def visit_TrueClass(_node)
|
@@ -144,7 +152,6 @@ module Kasket
|
|
144
152
|
end
|
145
153
|
|
146
154
|
def quoted(node)
|
147
|
-
return node if node.is_a?(String)
|
148
155
|
@model_class.connection.quote(node)
|
149
156
|
end
|
150
157
|
|
@@ -155,6 +162,8 @@ module Kasket
|
|
155
162
|
|
156
163
|
alias_method :visit_String, :literal
|
157
164
|
alias_method :visit_Fixnum, :literal
|
165
|
+
alias_method :visit_Integer, :literal
|
166
|
+
alias_method :visit_Bignum, :literal
|
158
167
|
alias_method :visit_Arel_Nodes_SqlLiteral, :literal
|
159
168
|
end
|
160
169
|
end
|
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.
|
4
|
+
version: 4.8.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:
|
12
|
+
date: 2020-08-26 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: '
|
20
|
+
version: '4.2'
|
21
21
|
- - "<"
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: '
|
23
|
+
version: '6.1'
|
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: '
|
30
|
+
version: '4.2'
|
31
31
|
- - "<"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '6.1'
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: rake
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
@@ -173,15 +173,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
173
173
|
requirements:
|
174
174
|
- - ">="
|
175
175
|
- !ruby/object:Gem::Version
|
176
|
-
version: 2.
|
176
|
+
version: 2.3.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
|
-
|
184
|
-
rubygems_version: 2.6.13
|
183
|
+
rubygems_version: 3.1.4
|
185
184
|
signing_key:
|
186
185
|
specification_version: 4
|
187
186
|
summary: A write back caching layer on active record
|