forked from hacketyhack/hacketyhack
/
database.rb
119 lines (104 loc) · 3.35 KB
/
database.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
require 'uri'
require 'h-ety-h/sequel/schema'
module HH::Sequel
# A Database object represents a virtual connection to a database.
# The Database class is meant to be subclassed by database adapters in order
# to provide the functionality needed for executing queries.
class Database
# Constructs a new instance of a database connection with the specified
# options hash.
#
# Sequel::Database is an abstract class that is not useful by itself.
def initialize(opts = {})
@opts = opts
end
# Returns a new dataset with the from method invoked.
def from(*args); dataset.from(*args); end
# Returns a new dataset with the select method invoked.
def select(*args); dataset.select(*args); end
# Returns a new dataset with the from parameter set. For example,
# db[:posts].each {|p| puts p[:title]}
def [](table)
dataset.from(table)
end
# call-seq:
# db.execute(sql)
# db << sql
#
# Executes an sql query.
def <<(sql)
execute(sql)
end
# Returns a literal SQL representation of a value. This method is usually
# overriden in database adapters.
def literal(v)
case v
when String then "'%s'" % v
else v.to_s
end
end
# Creates a table. The easiest way to use this method is to provide a
# block:
# DB.create_table :posts do
# primary_key :id, :serial
# column :title, :text
# column :content, :text
# index :title
# end
def create_table(name, columns = nil, indexes = nil, &block)
if block
schema = Schema.new
schema.create_table(name, &block)
schema.create(self)
else
execute Schema.create_table_sql(name, columns, indexes)
end
end
# Drops a table.
def drop_table(name)
execute Schema.drop_table_sql(name)
end
# Performs a brute-force check for the existance of a table. This method is
# usually overriden in descendants.
def table_exists?(name)
from(name).first && true
rescue
false
end
@@adapters = Hash.new
# Sets the adapter scheme for the database class. Call this method in
# descendnants of Database to allow connection using a URL. For example:
# class DB2::Database < Sequel::Database
# set_adapter_scheme :db2
# ...
# end
def self.set_adapter_scheme(scheme)
@@adapters[scheme.to_sym] = self
end
# Converts a uri to an options hash. These options are then passed
# to a newly created database object.
def self.uri_to_options(uri)
{
:user => uri.user,
:password => uri.password,
:host => uri.host,
:port => uri.port,
:database => (uri.path =~ /\/(.*)/) && ($1)
}
end
# call-seq:
# Sequel::Database.connect(conn_string)
# Sequel.connect(conn_string)
#
# Creates a new database object based on the supplied connection string.
# The specified scheme determines the database class used, and the rest
# of the string specifies the connection options. For example:
# DB = Sequel.connect('sqlite:///blog.db')
def self.connect(conn_string)
uri = URI.parse(conn_string)
c = @@adapters[uri.scheme.to_sym]
raise "Invalid database scheme" unless c
c.new(c.uri_to_options(uri))
end
end
end