Class: Dynamini::TestClient
- Inherits:
-
Object
- Object
- Dynamini::TestClient
- Defined in:
- lib/dynamini/test_client.rb
Overview
In-memory database client for test purposes.
Instance Attribute Summary collapse
-
#data ⇒ Object
readonly
Returns the value of attribute data.
-
#hash_key_attr ⇒ Object
readonly
Returns the value of attribute hash_key_attr.
-
#range_key_attr ⇒ Object
readonly
Returns the value of attribute range_key_attr.
-
#secondary_index ⇒ Object
readonly
Returns the value of attribute secondary_index.
Instance Method Summary collapse
- #apply_filter_options(parent, args, start_val, end_val) ⇒ Object
-
#batch_get_item(args = {}) ⇒ Object
No range key support - use query instead.
-
#batch_write_item(request_options) ⇒ Object
TODO add range key support.
- #delete_item(args = {}) ⇒ Object
- #determine_hash_and_range(args) ⇒ Object
- #get_item(args = {}) ⇒ Object
- #get_secondary_hash_key(index) ⇒ Object
- #get_secondary_range_key(index) ⇒ Object
- #get_table(table_name) ⇒ Object
-
#initialize(hash_key_attr, range_key_attr = nil, secondary_index = nil) ⇒ TestClient
constructor
A new instance of TestClient.
- #primary_index_insertion(hash_key_value, range_key_value, updates, table) ⇒ Object
- #primary_only_hash_insertion(hash_key_value, updates, table) ⇒ Object
- #primary_with_range_insertion(hash_key_value, range_key_value, updates, table) ⇒ Object
- #query(args = {}) ⇒ Object
- #range_key_limits(tokens) ⇒ Object
- #reset ⇒ Object
- #secondary_index_query(args = {}, start_val = nil, end_val = nil) ⇒ Object
- #sort_records(records, index, args, start_val, end_val) ⇒ Object
- #update_item(args = {}) ⇒ Object
Constructor Details
#initialize(hash_key_attr, range_key_attr = nil, secondary_index = nil) ⇒ TestClient
9 10 11 12 13 14 |
# File 'lib/dynamini/test_client.rb', line 9 def initialize(hash_key_attr, range_key_attr = nil, secondary_index=nil) @data = {} @hash_key_attr = hash_key_attr @range_key_attr = range_key_attr @secondary_index = secondary_index end |
Instance Attribute Details
#data ⇒ Object (readonly)
Returns the value of attribute data.
7 8 9 |
# File 'lib/dynamini/test_client.rb', line 7 def data @data end |
#hash_key_attr ⇒ Object (readonly)
Returns the value of attribute hash_key_attr.
7 8 9 |
# File 'lib/dynamini/test_client.rb', line 7 def hash_key_attr @hash_key_attr end |
#range_key_attr ⇒ Object (readonly)
Returns the value of attribute range_key_attr.
7 8 9 |
# File 'lib/dynamini/test_client.rb', line 7 def range_key_attr @range_key_attr end |
#secondary_index ⇒ Object (readonly)
Returns the value of attribute secondary_index.
7 8 9 |
# File 'lib/dynamini/test_client.rb', line 7 def secondary_index @secondary_index end |
Instance Method Details
#apply_filter_options(parent, args, start_val, end_val) ⇒ Object
150 151 152 153 154 155 156 157 |
# File 'lib/dynamini/test_client.rb', line 150 def (parent, args, start_val, end_val) records = parent.values records = records.select { |record| record[@range_key_attr] >= start_val.to_f } if start_val records = records.select { |record| record[@range_key_attr] <= end_val.to_f } if end_val records = records.sort! { |a, b| b[@range_key_attr] <=> a[@range_key_attr] } if args[:scan_index_forward] == false records = records[0...args[:limit]] if args[:limit] records end |
#batch_get_item(args = {}) ⇒ Object
No range key support - use query instead.
73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/dynamini/test_client.rb', line 73 def batch_get_item(args = {}) responses = {} args[:request_items].each do |table_name, get_request| responses[table_name] = [] get_request[:keys].each do |key_hash| item = get_table(table_name)[key_hash.values.first] responses[table_name] << item unless item.nil? end end OpenStruct.new(responses: responses) end |
#batch_write_item(request_options) ⇒ Object
TODO add range key support
88 89 90 91 92 93 94 95 96 |
# File 'lib/dynamini/test_client.rb', line 88 def batch_write_item() [:request_items].each do |table_name, put_requests| put_requests.each do |request_hash| item = request_hash[:put_request][:item] key = item[hash_key_attr.to_s] get_table(table_name)[key] = item end end end |
#delete_item(args = {}) ⇒ Object
98 99 100 |
# File 'lib/dynamini/test_client.rb', line 98 def delete_item(args = {}) get_table(args[:table_name]).delete(args[:key][hash_key_attr]) end |
#determine_hash_and_range(args) ⇒ Object
132 133 134 135 136 137 138 139 |
# File 'lib/dynamini/test_client.rb', line 132 def determine_hash_and_range(args) if args[:index_name] index = secondary_index[args[:index_name].to_s] [index[:hash_key_name].to_s, index[:range_key_name].to_s] else [@hash_key_attr.to_s, @range_key_attr.to_s] end end |
#get_item(args = {}) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/dynamini/test_client.rb', line 60 def get_item(args = {}) table = get_table(args[:table_name]) hash_key_value = args[:key][hash_key_attr] range_key_value = args[:key][range_key_attr] attributes_hash = table[hash_key_value] attributes_hash = attributes_hash[range_key_value] if attributes_hash && range_key_value OpenStruct.new(item: attributes_hash) end |
#get_secondary_hash_key(index) ⇒ Object
178 179 180 |
# File 'lib/dynamini/test_client.rb', line 178 def get_secondary_hash_key(index) index[:hash_key_name] == @hash_key_attr ? index[:hash_key_name] : index[:hash_key_name].to_s end |
#get_secondary_range_key(index) ⇒ Object
182 183 184 |
# File 'lib/dynamini/test_client.rb', line 182 def get_secondary_range_key(index) index[:range_key_name] == @range_key_attr ? index[:range_key_name] : index[:range_key_name].to_s end |
#get_table(table_name) ⇒ Object
16 17 18 |
# File 'lib/dynamini/test_client.rb', line 16 def get_table(table_name) @data[table_name] ||= {} end |
#primary_index_insertion(hash_key_value, range_key_value, updates, table) ⇒ Object
36 37 38 39 40 41 42 |
# File 'lib/dynamini/test_client.rb', line 36 def primary_index_insertion(hash_key_value, range_key_value, updates, table) if range_key_value primary_with_range_insertion(hash_key_value, range_key_value, updates, table) else primary_only_hash_insertion(hash_key_value, updates, table) end end |
#primary_only_hash_insertion(hash_key_value, updates, table) ⇒ Object
54 55 56 |
# File 'lib/dynamini/test_client.rb', line 54 def primary_only_hash_insertion(hash_key_value, updates, table) table[hash_key_value] ? table[hash_key_value].merge!(updates) : table[hash_key_value] = updates end |
#primary_with_range_insertion(hash_key_value, range_key_value, updates, table) ⇒ Object
44 45 46 47 48 49 50 51 52 |
# File 'lib/dynamini/test_client.rb', line 44 def primary_with_range_insertion(hash_key_value, range_key_value, updates, table) updates.merge!(range_key_attr => range_key_value) if table[hash_key_value] && table[hash_key_value][range_key_value] table[hash_key_value][range_key_value].merge! updates else table[hash_key_value] ||= {} table[hash_key_value][range_key_value] = updates end end |
#query(args = {}) ⇒ Object
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/dynamini/test_client.rb', line 102 def query(args = {}) # Possible key condition structures: # "foo = val" # "foo = val AND bar <= val2" # "foo = val AND bar >= val2" # "foo = val AND bar BETWEEN val2 AND val3" attr_placeholders = args[:expression_attribute_values].merge(args[:expression_attribute_names]) attr_placeholders.each { |symbol, value| args[:key_condition_expression].gsub!(symbol, value.to_s) } tokens = args[:key_condition_expression].split(/\s+/) hash_key_name, range_key_name = determine_hash_and_range(args) inspect_for_correct_keys?(tokens, hash_key_name, range_key_name) start_val, end_val = range_key_limits(tokens) if args[:index_name] secondary_index_query(args, start_val, end_val) else hash_key = hash_key_value(args).is_a?(Integer) ? tokens[2].to_i : tokens[2] parent = get_table(args[:table_name])[hash_key] return OpenStruct.new(items: []) unless parent selected = (parent, args, start_val, end_val) OpenStruct.new(items: selected) end end |
#range_key_limits(tokens) ⇒ Object
141 142 143 144 145 146 147 148 |
# File 'lib/dynamini/test_client.rb', line 141 def range_key_limits(tokens) case tokens[5] when ">=" then [tokens[6], nil] when "<=" then [nil, tokens[6]] when "BETWEEN" then [tokens[6], tokens[8]] else [nil, nil] end end |
#reset ⇒ Object
186 187 188 |
# File 'lib/dynamini/test_client.rb', line 186 def reset @data = {} end |
#secondary_index_query(args = {}, start_val = nil, end_val = nil) ⇒ Object
159 160 161 162 163 164 165 166 |
# File 'lib/dynamini/test_client.rb', line 159 def secondary_index_query(args = {}, start_val = nil, end_val = nil) index = secondary_index[args[:index_name].to_s] table = get_table(args[:table_name]) records = @range_key_attr ? get_values(table) : table.values selected = sort_records(records, index, args, start_val, end_val) OpenStruct.new(items: selected) end |
#sort_records(records, index, args, start_val, end_val) ⇒ Object
168 169 170 171 172 173 174 175 176 |
# File 'lib/dynamini/test_client.rb', line 168 def sort_records(records, index, args, start_val, end_val) records = records.select { |record| record[get_secondary_hash_key(index)] == hash_key_value(args) } records = records.select { |record| record[get_secondary_range_key(index)] >= start_val.to_f } if start_val records = records.select { |record| record[get_secondary_range_key(index)] <= end_val.to_f } if end_val records = records.sort { |a, b| a[get_secondary_range_key(index)] <=> b[get_secondary_range_key(index)] } records = records.reverse if args[:scan_index_forward] == false records = records[0...args[:limit]] if args[:limit] records end |
#update_item(args = {}) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/dynamini/test_client.rb', line 20 def update_item(args = {}) table = get_table(args[:table_name]) keys = args[:key] hash_key_value = keys[hash_key_attr] range_key_value = keys[range_key_attr] updates = flatten_attribute_updates(args).merge( hash_key_attr => hash_key_value ) primary_index_insertion(hash_key_value, range_key_value, updates, table) if hash_key_value end |