2012-06-17 03:15:46 +02:00
|
|
|
class Keystore < ActiveRecord::Base
|
2014-01-09 06:01:45 +01:00
|
|
|
self.primary_key = "key"
|
2012-06-17 03:15:46 +02:00
|
|
|
|
2014-01-09 06:01:45 +01:00
|
|
|
validates_presence_of :key
|
2012-06-17 03:15:46 +02:00
|
|
|
|
|
|
|
def self.get(key)
|
2013-12-24 04:20:06 +01:00
|
|
|
self.where(:key => key).first
|
2012-06-17 03:15:46 +02:00
|
|
|
end
|
|
|
|
|
2014-01-09 06:01:45 +01:00
|
|
|
def self.value_for(key)
|
|
|
|
self.where(:key => key).first.try(:value)
|
|
|
|
end
|
|
|
|
|
2012-06-17 03:15:46 +02:00
|
|
|
def self.put(key, value)
|
2012-10-08 19:45:15 +02:00
|
|
|
if Keystore.connection.adapter_name == "SQLite"
|
2012-07-02 03:44:22 +02:00
|
|
|
Keystore.connection.execute("INSERT OR REPLACE INTO " <<
|
|
|
|
"#{Keystore.table_name} (`key`, `value`) VALUES " <<
|
|
|
|
"(#{q(key)}, #{q(value)})")
|
2014-01-09 06:01:45 +01:00
|
|
|
elsif Keystore.connection.adapter_name =~ /Mysql/
|
2012-07-02 03:44:22 +02:00
|
|
|
Keystore.connection.execute("INSERT INTO #{Keystore.table_name} (" +
|
2012-07-03 21:29:00 +02:00
|
|
|
"`key`, `value`) VALUES (#{q(key)}, #{q(value)}) ON DUPLICATE KEY " +
|
|
|
|
"UPDATE `value` = #{q(value)}")
|
2014-01-09 06:01:45 +01:00
|
|
|
else
|
|
|
|
kv = self.find_or_create_key_for_update(key, value)
|
|
|
|
kv.value = value
|
|
|
|
kv.save!
|
2012-07-02 03:44:22 +02:00
|
|
|
end
|
|
|
|
|
2012-06-17 03:15:46 +02:00
|
|
|
true
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.increment_value_for(key, amount = 1)
|
|
|
|
self.incremented_value_for(key, amount)
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.incremented_value_for(key, amount = 1)
|
2012-10-08 19:45:15 +02:00
|
|
|
Keystore.transaction do
|
|
|
|
if Keystore.connection.adapter_name == "SQLite"
|
|
|
|
Keystore.connection.execute("INSERT OR IGNORE INTO " <<
|
|
|
|
"#{Keystore.table_name} (`key`, `value`) VALUES " <<
|
|
|
|
"(#{q(key)}, 0)")
|
|
|
|
Keystore.connection.execute("UPDATE #{Keystore.table_name} " <<
|
|
|
|
"SET `value` = `value` + #{q(amount)} WHERE `key` = #{q(key)}")
|
2014-01-09 06:01:45 +01:00
|
|
|
elsif Keystore.connection.adapter_name =~ /Mysql/
|
2012-10-08 19:45:15 +02:00
|
|
|
Keystore.connection.execute("INSERT INTO #{Keystore.table_name} (" +
|
|
|
|
"`key`, `value`) VALUES (#{q(key)}, #{q(amount)}) ON DUPLICATE KEY " +
|
|
|
|
"UPDATE `value` = `value` + #{q(amount)}")
|
2014-01-09 06:01:45 +01:00
|
|
|
else
|
|
|
|
kv = self.find_or_create_key_for_update(key, 0)
|
|
|
|
kv.value = kv.value.to_i + amount
|
|
|
|
kv.save!
|
|
|
|
return kv.value
|
2012-10-08 19:45:15 +02:00
|
|
|
end
|
|
|
|
|
2014-01-09 06:01:45 +01:00
|
|
|
self.value_for(key)
|
2012-07-02 03:44:22 +02:00
|
|
|
end
|
2014-01-09 06:01:45 +01:00
|
|
|
end
|
2012-06-17 03:15:46 +02:00
|
|
|
|
2014-01-09 06:01:45 +01:00
|
|
|
def self.find_or_create_key_for_update(key, init = nil)
|
|
|
|
loop do
|
|
|
|
kv = self.lock(true).where(:key => key).first
|
|
|
|
return kv if kv
|
|
|
|
|
|
|
|
begin
|
|
|
|
self.create! do |kv|
|
|
|
|
kv.key = key
|
|
|
|
kv.value = init
|
|
|
|
kv.save!
|
|
|
|
end
|
|
|
|
rescue ActiveRecord::RecordNotUnique
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
end
|
2012-06-17 03:15:46 +02:00
|
|
|
end
|
2013-02-14 01:50:51 +01:00
|
|
|
|
2012-06-17 03:15:46 +02:00
|
|
|
def self.decrement_value_for(key, amount = -1)
|
|
|
|
self.increment_value_for(key, amount)
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.decremented_value_for(key, amount = -1)
|
|
|
|
self.incremented_value_for(key, amount)
|
|
|
|
end
|
|
|
|
end
|