Created
February 27, 2012 15:41
-
-
Save cyx/1924763 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 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) |
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
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 |
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.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