Skip to content

Instantly share code, notes, and snippets.

@hawx
Created August 31, 2011 10:27
Show Gist options
  • Save hawx/1183254 to your computer and use it in GitHub Desktop.
Save hawx/1183254 to your computer and use it in GitHub Desktop.

Key-Value Store

Simplest key-value store that is usable (I think). Uses the stdlib PStore for storage which is not suited to storing large pieces of data, but isn't that the point of a key-value store?

GET / returns a json encoded array of keys (each as strings).

POST / creates a new key-value pair

GET /:key returns the value associated with the key

DELETE /:key deletes the key (and value)

Usage

To play around with it I'm using the htty gem (gem install htty).

$ ruby key_value.rb

$ htty http://0.0.0.0:4567
http://0.0.0.0:4567/> get
 200  OK -- 4 headers -- 2-character body
http://0.0.0.0:4567/> body
[]
http://0.0.0.0:4567/> query-set key value
http://0.0.0.0:4567/?key=value> post
 200  OK -- 3 headers -- 16-character body
http://0.0.0.0:4567/?key=value> query-clear
http://0.0.0.0:4567/> get
 200  OK -- 4 headers -- 7-character body
http://0.0.0.0:4567/> body
["key"]
http://0.0.0.0:4567/> cd /key
http://0.0.0.0:4567/key> get
 200  OK -- 4 headers -- 7-character body
http://0.0.0.0:4567/key> body
"value"
http://0.0.0.0:4567/key> delete
 200  OK -- 4 headers -- 7-character body
http://0.0.0.0:4567/key> get
 200  OK -- 4 headers -- 4-character body
http://0.0.0.0:4567/key> body
null
http://0.0.0.0:4567/key> cd /
http://0.0.0.0:4567/> get
 200  OK -- 4 headers -- 2-character body
http://0.0.0.0:4567/> body
[]
http://0.0.0.0:4567/> 
# http://www.ruby-doc.org/stdlib/libdoc/pstore/rdoc/classes/PStore.html
require 'pstore'
require 'sinatra'
require 'json'
PATH = File.expand_path('~/pstore')
STORE = PStore.new(PATH)
get '/' do
content_type :json
STORE.transaction { STORE.roots.to_json }
end
post '/' do
STORE.transaction do
params.each {|k,v| STORE[k] = v }
end
end
get '/:key' do
content_type :json
STORE.transaction { STORE[params[:key]].to_json }
end
delete '/:key' do
STORE.transaction { STORE.delete(params[:key]).to_json }
end
$: << File.dirname(__FILE__)
require 'key_value'
require 'minitest/autorun'
require 'rack/test'
require 'fileutils'
ENV['RACK_ENV'] = 'test'
class KeyValueTest < MiniTest::Unit::TestCase
include Rack::Test::Methods
def app
Sinatra::Application
end
def teardown
FileUtils.rm(PATH) if File.exist?(PATH)
end
def test_lists_keys
get '/'
assert last_response.ok?
assert_equal '[]', last_response.body
post '/?key=value'
get '/'
assert_equal '["key"]', last_response.body
end
def test_sets_and_gets_key_values
post '/?key=value'
assert last_response.ok?
get '/key'
assert last_response.ok?
assert_equal '"value"', last_response.body
end
def test_deletes_key
post '/?a=b'
get '/a'
assert_equal '"b"', last_response.body
delete '/a'
assert last_response.ok?
get '/a'
assert_equal 'null', last_response.body
end
end
@rstacruz
Copy link

rstacruz commented Sep 6, 2011

Yay, PStore! brilliant.

@hawx
Copy link
Author

hawx commented Sep 6, 2011

It's criminally underused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment