kasket 4.9.1 → 4.10.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 +4 -4
- data/README.md +1 -1
- data/lib/kasket/query_parser.rb +21 -4
- data/lib/kasket/read_mixin.rb +5 -17
- data/lib/kasket/version.rb +1 -1
- data/lib/kasket/visitor.rb +9 -2
- metadata +6 -118
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b7ff0fe3b5afa5c01eb36fc7f89bfe94669b98340bb1537546fe6019b0d61db
|
4
|
+
data.tar.gz: d69c8e0d2f9303456f5f647867a67496b49d95e8af114f51ec54acf95947d257
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 610b4879bebfdd27f4796ce840aac305d30502702befab16623f8c1e7bd316dd7529ab5af4513d05e565b25cb716089e7b71ed34aad8c75099bf5493137c3e31
|
7
|
+
data.tar.gz: b6710e8aa232d3105822aec11431a8d3c76618c7d124e3e1773528c3decc3de57617ffa17f6a60425729e694a4cde8e281d74ed0bd7e88fcd3b34e371cae245b
|
data/README.md
CHANGED
data/lib/kasket/query_parser.rb
CHANGED
@@ -12,26 +12,43 @@ module Kasket
|
|
12
12
|
def initialize(model_class)
|
13
13
|
@model_class = model_class
|
14
14
|
|
15
|
-
@supported_query_pattern = /^select\s+(
|
15
|
+
@supported_query_pattern = /^select\s+(.+?)\s+from (?:`|")#{@model_class.table_name}(?:`|") where (.*?)(|\s+limit 1)\s*$/i
|
16
16
|
|
17
|
+
@star_pattern = /^((`|")#{@model_class.table_name}\2\.)?\*$/
|
17
18
|
# Matches: `users`.id, `users`.`id`, users.id, id
|
18
19
|
@table_and_column_pattern = /(?:(?:`|")?#{@model_class.table_name}(?:`|")?\.)?(?:`|")?([a-zA-Z]\w*)(?:`|")?/
|
19
20
|
# Matches: KEY = VALUE, (KEY = VALUE), ()(KEY = VALUE))
|
20
21
|
@key_eq_value_pattern = /^[\(\s]*#{@table_and_column_pattern}\s+(=|IN)\s+#{VALUE}[\)\s]*$/
|
21
22
|
end
|
22
23
|
|
24
|
+
##
|
25
|
+
# Parses a SQL query to produce a kasket query
|
26
|
+
#
|
27
|
+
# @param sql [String] the sql query to parse
|
28
|
+
# @return [Hash|nil] the kasket query, or nil if the sql query is not supported
|
23
29
|
def parse(sql)
|
24
30
|
if match = @supported_query_pattern.match(sql)
|
31
|
+
select = match[1]
|
32
|
+
unless @star_pattern.match? select
|
33
|
+
# If we're not selecting all columns using star, then ensure all columns are selected explicitly
|
34
|
+
select_columns = select.split(/\s*,\s*/).map do |s|
|
35
|
+
break unless column_match = @table_and_column_pattern.match(s)
|
36
|
+
|
37
|
+
column_match[1]
|
38
|
+
end.uniq
|
39
|
+
columns = @model_class.column_names
|
40
|
+
return unless columns.size == select_columns.size && (columns - select_columns).empty?
|
41
|
+
end
|
25
42
|
where = match[2]
|
26
43
|
limit = match[3]
|
27
44
|
|
28
45
|
query = {}
|
29
46
|
query[:attributes] = sorted_attribute_value_pairs(where)
|
30
|
-
return
|
47
|
+
return if query[:attributes].nil?
|
31
48
|
|
32
|
-
if query[:attributes].size > 1 && query[:attributes].map(&:last).any?
|
49
|
+
if query[:attributes].size > 1 && query[:attributes].map(&:last).any?(Array)
|
33
50
|
# this is a query with IN conditions AND other conditions
|
34
|
-
return
|
51
|
+
return
|
35
52
|
end
|
36
53
|
|
37
54
|
query[:index] = query[:attributes].map(&:first)
|
data/lib/kasket/read_mixin.rb
CHANGED
@@ -64,23 +64,11 @@ module Kasket
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def find_by_sql_with_kasket_on_id_array(keys)
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
# (https://github.com/petergoldstein/dalli/blob/v2.7.7/lib/dalli/server.rb#L148).
|
73
|
-
# Fall back to the database when this happens.
|
74
|
-
if e.message == "multi_response has completed"
|
75
|
-
key_attributes_map = missing_records_from_db(keys)
|
76
|
-
else
|
77
|
-
raise
|
78
|
-
end
|
79
|
-
else
|
80
|
-
found_keys, missing_keys = keys.partition {|k| key_attributes_map[k] }
|
81
|
-
found_keys.each {|k| key_attributes_map[k] = instantiate(key_attributes_map[k].dup) }
|
82
|
-
key_attributes_map.merge!(missing_records_from_db(missing_keys))
|
83
|
-
end
|
67
|
+
key_attributes_map = Kasket.cache.read_multi(*keys)
|
68
|
+
|
69
|
+
found_keys, missing_keys = keys.partition {|k| key_attributes_map[k] }
|
70
|
+
found_keys.each {|k| key_attributes_map[k] = instantiate(key_attributes_map[k].dup) }
|
71
|
+
key_attributes_map.merge!(missing_records_from_db(missing_keys))
|
84
72
|
|
85
73
|
key_attributes_map.values.compact
|
86
74
|
end
|
data/lib/kasket/version.rb
CHANGED
data/lib/kasket/visitor.rb
CHANGED
@@ -52,11 +52,18 @@ module Kasket
|
|
52
52
|
return :unsupported if ActiveRecord::VERSION::MAJOR < 5 ? node.having : node.havings.present?
|
53
53
|
return :unsupported if node.set_quantifier
|
54
54
|
return :unsupported if !node.source || node.source.empty?
|
55
|
-
return :unsupported if node.projections.
|
55
|
+
return :unsupported if node.projections.empty?
|
56
56
|
|
57
57
|
select = node.projections[0]
|
58
58
|
select = select.name if select.respond_to?(:name)
|
59
|
-
|
59
|
+
if select != '*'
|
60
|
+
# If we're not selecting all columns using star, then ensure all columns are selected explicitly
|
61
|
+
column_names = @model_class.column_names
|
62
|
+
return :unsupported unless node.projections.size == column_names.size
|
63
|
+
|
64
|
+
projection_names = node.projections.map { |p| p.name if p.respond_to?(:name) }.compact
|
65
|
+
return unless (column_names - projection_names).empty?
|
66
|
+
end
|
60
67
|
|
61
68
|
parts = [visit(node.source)]
|
62
69
|
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kasket
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mick Staugaard
|
8
8
|
- Eric Chapweske
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-04-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -31,118 +31,6 @@ dependencies:
|
|
31
31
|
- - "<"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '6.1'
|
34
|
-
- !ruby/object:Gem::Dependency
|
35
|
-
name: bump
|
36
|
-
requirement: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
type: :development
|
42
|
-
prerelease: false
|
43
|
-
version_requirements: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
- !ruby/object:Gem::Dependency
|
49
|
-
name: bundler
|
50
|
-
requirement: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
type: :development
|
56
|
-
prerelease: false
|
57
|
-
version_requirements: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
- !ruby/object:Gem::Dependency
|
63
|
-
name: minitest
|
64
|
-
requirement: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
type: :development
|
70
|
-
prerelease: false
|
71
|
-
version_requirements: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
- !ruby/object:Gem::Dependency
|
77
|
-
name: minitest-rg
|
78
|
-
requirement: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
type: :development
|
84
|
-
prerelease: false
|
85
|
-
version_requirements: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
- !ruby/object:Gem::Dependency
|
91
|
-
name: mocha
|
92
|
-
requirement: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
|
-
type: :development
|
98
|
-
prerelease: false
|
99
|
-
version_requirements: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
104
|
-
- !ruby/object:Gem::Dependency
|
105
|
-
name: rake
|
106
|
-
requirement: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ">="
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
111
|
-
type: :development
|
112
|
-
prerelease: false
|
113
|
-
version_requirements: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
- !ruby/object:Gem::Dependency
|
119
|
-
name: timecop
|
120
|
-
requirement: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - ">="
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
125
|
-
type: :development
|
126
|
-
prerelease: false
|
127
|
-
version_requirements: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - ">="
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '0'
|
132
|
-
- !ruby/object:Gem::Dependency
|
133
|
-
name: wwtd
|
134
|
-
requirement: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - ">="
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '0'
|
139
|
-
type: :development
|
140
|
-
prerelease: false
|
141
|
-
version_requirements: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - ">="
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: '0'
|
146
34
|
description: puts a cap on your queries
|
147
35
|
email:
|
148
36
|
- mick@zendesk.com
|
@@ -165,7 +53,7 @@ homepage: http://github.com/zendesk/kasket
|
|
165
53
|
licenses:
|
166
54
|
- Apache License Version 2.0
|
167
55
|
metadata: {}
|
168
|
-
post_install_message:
|
56
|
+
post_install_message:
|
169
57
|
rdoc_options: []
|
170
58
|
require_paths:
|
171
59
|
- lib
|
@@ -180,8 +68,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
180
68
|
- !ruby/object:Gem::Version
|
181
69
|
version: '0'
|
182
70
|
requirements: []
|
183
|
-
rubygems_version: 3.1
|
184
|
-
signing_key:
|
71
|
+
rubygems_version: 3.0.3.1
|
72
|
+
signing_key:
|
185
73
|
specification_version: 4
|
186
74
|
summary: A write back caching layer on active record
|
187
75
|
test_files: []
|