Skip to content

Instantly share code, notes, and snippets.

@cyx
Created February 27, 2012 15:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cyx/1924763 to your computer and use it in GitHub Desktop.
Save cyx/1924763 to your computer and use it in GitHub Desktop.
local namespace = KEYS[1]
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 attributes = ARGV
local function dict(list)
local ret = {}
for i = 1, #list, 2 do
ret[list[i]] = list[i + 1]
end
return ret
end
local function non_unique(table)
for _, att in ipairs(meta.uniques) do
local key = model.key:format("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.key:format("uniques:" .. att)
redis.call("HSET", key, table[att], id)
end
end
local function delete_indices()
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)
save_uniques(this, id)
KEYS = { "User:1" }
ARGV = { "fname", "John", "lname", "Doe" }
local _unflatten_attributes = function(list)
local ret = {}
for i = 1, #list, 2 do
ret[list[i]] = list[i + 1]
end
return ret
end
local _flatten_attributes = function(table)
local atts = {}
for k, v in pairs(table) do
atts[#atts + 1] = k
atts[#atts + 1] = v
end
return atts
end
local save = function (table)
redis.call("DEL", key)
redis.call("HMSET", key, _flatten_attributes(table))
end
local pp = function(table)
for i, v in ipairs(table) do
print(string.format("%d. %s", i, v))
end
end
local pph = function(table)
for k, v in pairs(table) do
print(string.format("%s => %s", k, v))
end
end
local key = KEYS[1]
local id = string.match(key, "(%w+)$")
local this = _unflatten_attributes(ARGV)
pp(_flatten_attributes({ fname="John", lname="Doe" }))
pph(this)
print(key)
print(id)
print(this.fname)
print(this.lname)
this.fname = "Quentin"
this.lname = "Tarantino"
print(this.fname)
print(this.lname)
-- 1 2 3 4 5 6 7
-- 2 email username 3 fname lname bday
--
--
-- 0 0 fname John lname Doe
# 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.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-uniques-indices",
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-uniques-indices",
keys: ["User"],
argv: ["email", "bar@baz.com"])
assert_equal "1", redis.hget("User:uniques:email", "bar@baz.com")
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