Created
September 30, 2021 07:47
-
-
Save Varun-garg/f9ddb7c63ec229225bef6cea4cdd7b65 to your computer and use it in GitHub Desktop.
small key value store
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'sinatra' | |
require 'json' | |
class Value | |
attr_accessor :type, :value | |
def initialize(value) | |
@value = value | |
if ['true', 'false'].include? value.downcase | |
@type = 'boolean' | |
elsif value.match(/^(\d)+$/) # integer or double | |
value = value.to_i | |
if value >= -2147483648 && value <= 2147483647 | |
@type = 'integer' | |
else | |
@type = 'double' | |
end | |
else | |
@type = 'string' | |
end | |
end | |
end | |
class SecondaryValue | |
attr_accessor :type, :primary_keys | |
def initialize() | |
@type = nil | |
@primary_keys = Set.new | |
end | |
def check_value(value) | |
return @type.nil? || @type == value.type | |
end | |
def insert_primary_key(key, type) | |
@type = type | |
primary_keys << key | |
end | |
end | |
db = Hash.new | |
secondary_db = Hash.new | |
lock = Mutex.new | |
get '/' do | |
'Hello world!' | |
end | |
post '/store' do | |
params = JSON.parse(request.body.read) | |
puts "params #{params}" | |
key = params['key'] | |
values = params["values"] | |
if db[key].nil? | |
db[key] = Hash.new | |
end | |
puts "key: #{key}" | |
puts "values: #{values}" | |
values.each do |value| | |
puts "debug: #{value}" | |
secondary_key = value["attribute_name"] | |
val = Value.new(value["attribute_value"]) | |
seondary_value = secondary_db[secondary_key] | |
if seondary_value.nil? | |
secondary_db[secondary_key] = SecondaryValue.new | |
seondary_value = secondary_db[secondary_key] | |
end | |
if !seondary_value.check_value(val) | |
status 403 | |
body "attribute: #{secondary_key} must be of type #{seondary_value.type}" | |
return | |
end | |
lock.synchronize do | |
db[key][secondary_key] = val | |
seondary_value.insert_primary_key(key, val.type) | |
end | |
end | |
'Success' | |
end | |
get '/fetch' do | |
key = params["key"] | |
puts "fetching key #{key}" | |
values = db[key] | |
if values.nil? | |
status 404 | |
body "no values set for #{key}" | |
return | |
end | |
results = [] | |
puts "values #{values.class} #{values}" | |
values.each do |key, value| | |
puts "key #{key}" | |
puts "value #{value}" | |
puts "value.value #{value.value}" | |
results << { | |
attribute_name: key, | |
attribute_value: value.value, | |
} | |
end | |
puts "values #{results}" | |
results.to_json | |
end | |
get '/delete' do | |
key = params["key"] | |
values = db[key] | |
if values.nil? | |
status 404 | |
body "no values set for #{key}" | |
return | |
end | |
results = [] | |
lock.synchronize do | |
values.each do |skey, value| | |
secondary_db[skey].primary_keys.delete key | |
if secondary_db[skey].primary_keys.size == 0 # optional? | |
secondary_db[skey].type = nil | |
end | |
end | |
db.delete key | |
end | |
'OK' | |
end | |
get '/stretch' do | |
secondary_key = params["attribute_name"] | |
search_value = Value.new params["attribute_value"] | |
results = [] | |
secondary_value = secondary_db[secondary_key] | |
if secondary_value && secondary_value.type == search_value.type | |
secondary_value.primary_keys.each do |key| | |
if db[key][secondary_key].value == search_value.value | |
results << key | |
end | |
end | |
end | |
status results.size == 0 ? 404 : 200 | |
results.to_json | |
end | |
get '/debug' do | |
"db #{db} \n secondary_db #{secondary_db}\n" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment