add postgresql support
This commit is contained in:
parent
5f6c13b26b
commit
d74a2c448f
6
Gemfile
6
Gemfile
|
@ -6,6 +6,12 @@ gem "rails", "4.0.2"
|
||||||
# Use mysql2 as the database for Active Record
|
# Use mysql2 as the database for Active Record
|
||||||
gem "mysql2", ">= 0.3.14"
|
gem "mysql2", ">= 0.3.14"
|
||||||
|
|
||||||
|
# Use PostgreSQL as the database for Active Record
|
||||||
|
# gem "pg"
|
||||||
|
#
|
||||||
|
# NOTE: If you use PostgreSQL, you must still leave enabled the above mysql2 gem
|
||||||
|
# for Sphinx full text search to function.
|
||||||
|
|
||||||
# Use Rails3-style mass assignment security
|
# Use Rails3-style mass assignment security
|
||||||
gem "protected_attributes"
|
gem "protected_attributes"
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,29 @@
|
||||||
class Keystore < ActiveRecord::Base
|
class Keystore < ActiveRecord::Base
|
||||||
validates_presence_of :key
|
self.primary_key = "key"
|
||||||
|
|
||||||
attr_accessible nil
|
validates_presence_of :key
|
||||||
|
|
||||||
def self.get(key)
|
def self.get(key)
|
||||||
self.where(:key => key).first
|
self.where(:key => key).first
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.value_for(key)
|
||||||
|
self.where(:key => key).first.try(:value)
|
||||||
|
end
|
||||||
|
|
||||||
def self.put(key, value)
|
def self.put(key, value)
|
||||||
if Keystore.connection.adapter_name == "SQLite"
|
if Keystore.connection.adapter_name == "SQLite"
|
||||||
Keystore.connection.execute("INSERT OR REPLACE INTO " <<
|
Keystore.connection.execute("INSERT OR REPLACE INTO " <<
|
||||||
"#{Keystore.table_name} (`key`, `value`) VALUES " <<
|
"#{Keystore.table_name} (`key`, `value`) VALUES " <<
|
||||||
"(#{q(key)}, #{q(value)})")
|
"(#{q(key)}, #{q(value)})")
|
||||||
else
|
elsif Keystore.connection.adapter_name =~ /Mysql/
|
||||||
Keystore.connection.execute("INSERT INTO #{Keystore.table_name} (" +
|
Keystore.connection.execute("INSERT INTO #{Keystore.table_name} (" +
|
||||||
"`key`, `value`) VALUES (#{q(key)}, #{q(value)}) ON DUPLICATE KEY " +
|
"`key`, `value`) VALUES (#{q(key)}, #{q(value)}) ON DUPLICATE KEY " +
|
||||||
"UPDATE `value` = #{q(value)}")
|
"UPDATE `value` = #{q(value)}")
|
||||||
|
else
|
||||||
|
kv = self.find_or_create_key_for_update(key, value)
|
||||||
|
kv.value = value
|
||||||
|
kv.save!
|
||||||
end
|
end
|
||||||
|
|
||||||
true
|
true
|
||||||
|
@ -26,8 +34,6 @@ class Keystore < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.incremented_value_for(key, amount = 1)
|
def self.incremented_value_for(key, amount = 1)
|
||||||
new_value = nil
|
|
||||||
|
|
||||||
Keystore.transaction do
|
Keystore.transaction do
|
||||||
if Keystore.connection.adapter_name == "SQLite"
|
if Keystore.connection.adapter_name == "SQLite"
|
||||||
Keystore.connection.execute("INSERT OR IGNORE INTO " <<
|
Keystore.connection.execute("INSERT OR IGNORE INTO " <<
|
||||||
|
@ -35,16 +41,36 @@ class Keystore < ActiveRecord::Base
|
||||||
"(#{q(key)}, 0)")
|
"(#{q(key)}, 0)")
|
||||||
Keystore.connection.execute("UPDATE #{Keystore.table_name} " <<
|
Keystore.connection.execute("UPDATE #{Keystore.table_name} " <<
|
||||||
"SET `value` = `value` + #{q(amount)} WHERE `key` = #{q(key)}")
|
"SET `value` = `value` + #{q(amount)} WHERE `key` = #{q(key)}")
|
||||||
else
|
elsif Keystore.connection.adapter_name =~ /Mysql/
|
||||||
Keystore.connection.execute("INSERT INTO #{Keystore.table_name} (" +
|
Keystore.connection.execute("INSERT INTO #{Keystore.table_name} (" +
|
||||||
"`key`, `value`) VALUES (#{q(key)}, #{q(amount)}) ON DUPLICATE KEY " +
|
"`key`, `value`) VALUES (#{q(key)}, #{q(amount)}) ON DUPLICATE KEY " +
|
||||||
"UPDATE `value` = `value` + #{q(amount)}")
|
"UPDATE `value` = `value` + #{q(amount)}")
|
||||||
|
else
|
||||||
|
kv = self.find_or_create_key_for_update(key, 0)
|
||||||
|
kv.value = kv.value.to_i + amount
|
||||||
|
kv.save!
|
||||||
|
return kv.value
|
||||||
end
|
end
|
||||||
|
|
||||||
new_value = self.value_for(key)
|
self.value_for(key)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return new_value
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.decrement_value_for(key, amount = -1)
|
def self.decrement_value_for(key, amount = -1)
|
||||||
|
@ -54,8 +80,4 @@ class Keystore < ActiveRecord::Base
|
||||||
def self.decremented_value_for(key, amount = -1)
|
def self.decremented_value_for(key, amount = -1)
|
||||||
self.incremented_value_for(key, amount)
|
self.incremented_value_for(key, amount)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.value_for(key)
|
|
||||||
self.get(key).try(:value)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
class KeystoreBigint < ActiveRecord::Migration
|
class KeystoreBigint < ActiveRecord::Migration
|
||||||
def up
|
def up
|
||||||
execute("ALTER TABLE keystores CHANGE value value BIGINT")
|
change_column :keystores, :value, :integer, :limit => 8
|
||||||
end
|
end
|
||||||
|
|
||||||
def down
|
def down
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
class ChangeTablesToUtf8mb4 < ActiveRecord::Migration
|
class ChangeTablesToUtf8mb4 < ActiveRecord::Migration
|
||||||
def up
|
def up
|
||||||
|
return if connection.adapter_name !~ /Mysql/
|
||||||
|
|
||||||
[ "comments", "invitations", "messages", "moderations", "stories", "users" ].each do |t|
|
[ "comments", "invitations", "messages", "moderations", "stories", "users" ].each do |t|
|
||||||
execute("alter table #{t} convert to character set utf8mb4")
|
execute("alter table #{t} convert to character set utf8mb4")
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue