Skip to content

Instantly share code, notes, and snippets.

@h3rald
Created March 28, 2010 20:12
Show Gist options
  • Save h3rald/347002 to your computer and use it in GitHub Desktop.
Save h3rald/347002 to your computer and use it in GitHub Desktop.
SQLite-powered Key/Value Store
require 'yaml'
require 'digest/sha2'
require 'rubygems'
require 'sequel'
class LiteStore
attr_reader :artifacts
attr_reader :db
def initialize
# Initializes an in-memory SQLite DB
@db = Sequel.sqlite
@artifacts = @db[:artifacts]
# Default table
@db.create_table :artifacts do
String :key
String :content, :text => true
end
# An example index table
@db.create_table :message do
String :ref
String :content
index :content
end
end
def get(key)
@artifacts.first :key => key
end
def post(object)
key = Digest::SHA2.hexdigest(Time.now.to_s+rand(100).to_s)
@db.transaction do
@artifacts.insert :key => key, :content =>object.to_yaml
# TODO: Error handling
object.class.indices.each do |i|
@db[i.values[0]].insert :ref => key, :content => object.send(i.keys[0])
end
end
key
end
def put(key, object)
# TODO: Update indices
@artifacts.update :key => key, :content => object.to_yaml
key
end
def delete(key)
# TODO: Delete indices
@artifacts.delete :key => key
key
end
def find(*conditions) # "column <operator> value"
refs = []
# Find references in indexes based on conditions supplied -- Very basic for now!
conditions.each do |cond|
condition = cond.gsub /^(.+?)\s/, 'content ' # TODO: Error handling
result = @db[$1.to_sym].select(:ref).filter(condition).all
refs = (refs == []) ? result : refs & result
end
# get artifacts matching refs
@artifacts.filter(:key => refs.map{|v| v[:ref]}).all
end
end
class Object
class << self; attr_accessor :indices; end
def self.index(pair) # :property => :index_table
self.indices ||= []
self.indices << pair
end
end
######################
class Message
attr_accessor :text, :created_at
def initialize(message)
@text = message
@created_at = Time.now
end
end
Message.index :text => :message
a = Message.new "Test #1"
b = Message.new "Test #2"
ls = LiteStore.new
ls.post(a)
ls.post(b)
puts ls.find("message = 'Test #1'").to_yaml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment