Skip to content

Commit f151790

Browse files
committed
KeyFieldsDetector. Refactor detecting logic
1 parent e6a132b commit f151790

File tree

1 file changed

+86
-35
lines changed

1 file changed

+86
-35
lines changed

lib/dynamoid/criteria/key_fields_detector.rb

Lines changed: 86 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,58 +20,109 @@ def contain_with_eq_operator?(field_name)
2020
end
2121
end
2222

23-
24-
attr_reader :hash_key, :range_key, :index_name
25-
2623
def initialize(query, source)
2724
@query = query
2825
@source = source
2926
@query = Query.new(query)
30-
31-
detect_keys
27+
@result = find_keys_in_query
3228
end
3329

3430
def key_present?
35-
@hash_key.present?
31+
@result.present?
32+
end
33+
34+
def hash_key
35+
@result && @result[:hash_key]
36+
end
37+
38+
def range_key
39+
@result && @result[:range_key]
40+
end
41+
42+
def index_name
43+
@result && @result[:index_name]
3644
end
3745

3846
private
3947

40-
def detect_keys
41-
# See if querying based on table hash key
42-
if @query.contain_with_eq_operator?(@source.hash_key)
43-
@hash_key = @source.hash_key
48+
def find_keys_in_query
49+
match_table_and_sort_key ||
50+
match_local_secondary_index ||
51+
match_global_secondary_index_and_sort_key ||
52+
match_table ||
53+
match_global_secondary_index
54+
end
55+
56+
# Use table's default range key
57+
def match_table_and_sort_key
58+
return unless @query.contain_with_eq_operator?(@source.hash_key)
59+
return unless @source.range_key
4460

45-
# Use table's default range key
46-
if @query.contain?(@source.range_key)
47-
@range_key = @source.range_key
48-
return
49-
end
61+
if @query.contain?(@source.range_key)
62+
{
63+
hash_key: @source.hash_key,
64+
range_key: @source.range_key
65+
}
66+
end
67+
end
5068

51-
# See if can use any local secondary index range key
52-
# Chooses the first LSI found that can be utilized for the query
53-
@source.local_secondary_indexes.each do |_, lsi|
54-
next unless @query.contain?(lsi.range_key)
69+
# See if can use any local secondary index range key
70+
# Chooses the first LSI found that can be utilized for the query
71+
def match_local_secondary_index
72+
return unless @query.contain_with_eq_operator?(@source.hash_key)
5573

56-
@range_key = lsi.range_key
57-
@index_name = lsi.name
58-
end
74+
lsi = @source.local_secondary_indexes.values.find do |lsi|
75+
@query.contain?(lsi.range_key)
76+
end
77+
78+
if lsi.present?
79+
{
80+
hash_key: @source.hash_key,
81+
range_key: lsi.range_key,
82+
index_name: lsi.name,
83+
}
84+
end
85+
end
86+
87+
# See if can use any global secondary index
88+
# Chooses the first GSI found that can be utilized for the query
89+
# GSI with range key involved into query conditions has higher priority
90+
# But only do so if projects ALL attributes otherwise we won't
91+
# get back full data
92+
def match_global_secondary_index_and_sort_key
93+
gsi = @source.global_secondary_indexes.values.find do |gsi|
94+
@query.contain_with_eq_operator?(gsi.hash_key) && gsi.projected_attributes == :all &&
95+
@query.contain?(gsi.range_key)
96+
end
97+
98+
if gsi.present?
99+
{
100+
hash_key: gsi.hash_key,
101+
range_key: gsi.range_key,
102+
index_name: gsi.name,
103+
}
104+
end
105+
end
106+
107+
def match_table
108+
return unless @query.contain_with_eq_operator?(@source.hash_key)
109+
110+
{
111+
hash_key: @source.hash_key,
112+
}
113+
end
59114

60-
return if @range_key.present?
115+
def match_global_secondary_index
116+
gsi = @source.global_secondary_indexes.values.find do |gsi|
117+
@query.contain_with_eq_operator?(gsi.hash_key) && gsi.projected_attributes == :all
61118
end
62119

63-
# See if can use any global secondary index
64-
# Chooses the last GSI found that can be utilized for the query
65-
# GSI with range key used in query has higher priority
66-
# But only do so if projects ALL attributes otherwise we won't
67-
# get back full data
68-
@source.global_secondary_indexes.each do |_, gsi|
69-
next unless @query.contain_with_eq_operator?(gsi.hash_key) && gsi.projected_attributes == :all
70-
next if @hash_key.present? && !@query.contain?(gsi.range_key)
71-
72-
@hash_key = gsi.hash_key
73-
@range_key = gsi.range_key
74-
@index_name = gsi.name
120+
if gsi.present?
121+
{
122+
hash_key: gsi.hash_key,
123+
range_key: gsi.range_key,
124+
index_name: gsi.name,
125+
}
75126
end
76127
end
77128
end

0 commit comments

Comments
 (0)