/
ado.rb
85 lines (73 loc) · 2.02 KB
/
ado.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
Sequel.require 'adapters/utils/date_format'
require 'win32ole'
module Sequel
# The ADO adapter provides connectivity to ADO databases in Windows. ADO
# databases can be opened using a URL with the ado schema:
#
# DB = Sequel.connect('ado://mydb')
#
# or using the Sequel.ado method:
#
# DB = Sequel.ado('mydb')
#
module ADO
class Database < Sequel::Database
set_adapter_scheme :ado
def initialize(opts)
super(opts)
opts[:driver] ||= 'SQL Server'
case opts[:driver]
when 'SQL Server'
Sequel.require 'adapters/shared/mssql'
extend Sequel::MSSQL::DatabaseMethods
end
end
def connect(server)
opts = server_opts(server)
s = "driver=#{opts[:driver]};server=#{opts[:host]};database=#{opts[:database]}#{";uid=#{opts[:user]};pwd=#{opts[:password]}" if opts[:user]}"
handle = WIN32OLE.new('ADODB.Connection')
handle.Open(s)
handle
end
def dataset(opts = nil)
ADO::Dataset.new(self, opts)
end
def execute(sql, opts={})
log_info(sql)
synchronize(opts[:server]) do |conn|
r = conn.Execute(sql)
yield(r) if block_given?
r
end
end
alias_method :do, :execute
private
def disconnect_connection(conn)
conn.Close
end
end
class Dataset < Sequel::Dataset
include Dataset::SQLStandardDateFormat
def fetch_rows(sql)
execute(sql) do |s|
@columns = s.Fields.extend(Enumerable).map do |column|
name = column.Name.empty? ? '(no column name)' : column.Name
output_identifier(name)
end
unless s.eof
s.moveFirst
s.getRows.transpose.each {|r| yield hash_row(r)}
end
end
self
end
private
def hash_row(row)
@columns.inject({}) do |m, c|
m[c] = row.shift
m
end
end
end
end
end