-
-
Save vikks/2480047 to your computer and use it in GitHub Desktop.
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
local namespace = KEYS[1] | |
local attributes = ARGV | |
local model = { | |
id = namespace .. ":id", | |
all = namespace .. ":all", | |
uniques = namespace .. ":uniques", | |
indices = namespace .. ":indices", | |
key = namespace .. ":%s" | |
} | |
local meta = { | |
uniques = redis.call("SMEMBERS", model.uniques), | |
indices = redis.call("SMEMBERS", model.indices) | |
} | |
local function dict(list) | |
local ret = {} | |
for i = 1, #list, 2 do | |
ret[list[i]] = list[i + 1] | |
end | |
return ret | |
end | |
local function list(table) | |
local atts = {} | |
for k, v in pairs(table) do | |
atts[#atts + 1] = k | |
atts[#atts + 1] = v | |
end | |
return atts | |
end | |
local function non_unique(table) | |
for _, att in ipairs(meta.uniques) do | |
local key = model.uniques .. ":" .. att | |
local existing = redis.call("HGET", key, table[att]) | |
if existing then return att end | |
end | |
end | |
local function save_uniques(table, id) | |
for _, att in ipairs(meta.uniques) do | |
local key = model.uniques .. ":" .. att | |
redis.call("HSET", key, table[att], id) | |
end | |
end | |
local function save_indices(table, id) | |
for _, att in ipairs(meta.indices) do | |
local key = model.indices .. ":" .. att .. ":" .. table[att] | |
redis.call("SADD", key, id) | |
end | |
end | |
local this = dict(attributes) | |
local not_unique = non_unique(this) | |
if not_unique then | |
return { 500, { not_unique, "not_unique" }} | |
end | |
local id = redis.call("INCR", model.id) | |
local key = model.key:format(id) | |
save_uniques(this, id) | |
save_indices(this, id) | |
redis.call("DEL", key) | |
redis.call("HMSET", key, unpack(list(this))) |
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
# encoding: UTF-8 | |
require File.expand_path("./helper", File.dirname(__FILE__)) | |
$VERBOSE = false | |
def redis | |
Ohm.redis | |
end | |
setup do | |
redis.sadd("User:uniques", "email") | |
redis.sadd("User:indices", "fname") | |
redis.sadd("User:indices", "lname") | |
redis.hset("User:uniques:email", "foo@bar.com", 1) | |
Ohm::Lua.new("./test/lua", redis) | |
end | |
test "returns the unique constraint error" do |lua| | |
res = lua.run("create", | |
keys: ["User"], | |
argv: ["email", "foo@bar.com"]) | |
assert_equal [500, ["email", "not_unique"]], res | |
end | |
test "returns the unique constraint error" do |lua| | |
res = lua.run("create", | |
keys: ["User"], | |
argv: ["email", "bar@baz.com"]) | |
assert_equal "1", redis.hget("User:uniques:email", "bar@baz.com") | |
end | |
test "saves the attributes" do |lua| | |
res = lua.run("create", | |
keys: ["User"], | |
argv: ["email", "bar@baz.com", "fname", "John", "lname", "Doe"]) | |
assert_equal "bar@baz.com", redis.hget("User:1", "email") | |
assert_equal "John", redis.hget("User:1", "fname") | |
assert_equal "Doe", redis.hget("User:1", "lname") | |
end | |
test "indexes fname / lname" do |lua| | |
res = lua.run("create", | |
keys: ["User"], | |
argv: ["email", "bar@baz.com", "fname", "John", "lname", "Doe"]) | |
assert redis.sismember("User:indices:fname:John", 1) | |
assert redis.sismember("User:indices:lname:Doe", 1) | |
end | |
__END__ | |
require "sequel" | |
DB = Sequel.connect("postgres://cyx@localhost/postgres") | |
DB[:users].truncate | |
t = Benchmark.measure do | |
1000.times do |i| | |
DB[:users].insert(email: "foo#{i}@bar.com", fname: "John#{i}", lname: "Doe#{i}") | |
end | |
end | |
puts t | |
puts Ohm.redis.keys("User:*").inspect |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment