Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tree: 075de0d420
Fetching contributors…

Cannot retrieve contributors at this time

117 lines (94 sloc) 2.875 kB
require 'fileutils'
require 'pg'
module Hurl
class AbstractDB
def self.encode(object)
Zlib::Deflate.deflate Yajl::Encoder.encode(object)
end
def self.decode(object)
Yajl::Parser.parse(Zlib::Inflate.inflate(object)) rescue nil
end
def self.close
end
end
class PostgresDB < AbstractDB
CONN = PG::Connection::new(
ENV.fetch("POSTGRES_HOST", "localhost"),
ENV.fetch("POSTGRES_PORT", 5432),
:dbname => "hurls",
:user => ENV.fetch("POSTGRES_USER", "postgres"),
:password => ENV.fetch("POSTGRES_PASSWORD", "postgres")
)
def self.select_query(scope)
"SELECT content::bytea FROM %s WHERE id = $1 LIMIT 1" % CONN.escape_string(scope.to_s)
end
def self.find(scope, id)
CONN.exec(select_query(scope), [id], 1) do |result|
decode(result.getvalue(0, 0)) if result.num_tuples >= 1
end
end
def self.insert_query(scope)
"INSERT INTO %s VALUES ($1::varchar, $2::bytea)" % CONN.escape_string(scope.to_s)
end
def self.save(scope, id, content)
CONN.exec(insert_query(scope), [id, {:value => encode(content), :format => 1}])
end
def self.count(scope)
CONN.exec("SELECT COUNT(*) FROM %s" % CONN.escape_string(scope.to_s)) do |result|
result.getvalue(0, 0)
end
end
def self.close
CONN.finish
end
end
class RedisDB < AbstractDB
uri = URI.parse(ENV.fetch("REDISTOGO_URL", "redis://127.0.0.1:6379"))
CONNECTION = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
def self.find(scope, id)
decode(CONNECTION.get("hurl/#{scope}/#{id}"))
end
def self.save(scope, id, content)
CONNECTION.set("hurl/#{scope}/#{id}", encode(content))
end
def self.count(scope)
CONNECTION.keys("hurl/#{scope}/*").size
end
end
class FileDB < AbstractDB
DIR = File.expand_path(ENV['HURL_DB_DIR'] || "db")
def self.find(scope, id)
decode File.read(dir(scope, id) + id) if id && id.is_a?(String)
rescue Errno::ENOENT
nil
end
def self.save(scope, id, content)
File.open(dir(scope, id) + id, 'w') do |f|
f.puts encode(content)
end
true
end
def self.count(scope)
files = Dir["#{DIR}/#{scope}/**/**"].reject do |file|
File.directory?(file)
end
files.size
end
def self.dir(scope, id)
path = FileUtils.mkdir_p "#{DIR}/#{scope}/#{id[0...2]}/#{id[2...4]}/"
# In Ruby 1.9, mkdir_p always returns Array,
# while in 1.8 it returns String when it has only one item to return.
if path.is_a? Array
path[0]
else
path
end
end
end
db_backend = ENV.fetch("DB_BACKEND", "postgres")
DB = {
"file" => FileDB,
"redis" => RedisDB,
"postgres" => PostgresDB
}.fetch(db_backend)
end
Jump to Line
Something went wrong with that request. Please try again.