Skip to content

Instantly share code, notes, and snippets.

@hawx
Created August 31, 2011 10:27
Show Gist options
  • Select an option

  • Save hawx/1183254 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

rstacruz commented Sep 6, 2011

Yay, PStore! brilliant.

@hawx
Copy link
Copy Markdown
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