/
connection.cr
57 lines (47 loc) · 1.78 KB
/
connection.cr
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
module ODBC
class Connection < DB::Connection
getter raw_conn
def initialize(context : DB::ConnectionContext)
# set up all the basic connection info
super(context)
conn_string = serialize_conn_string
# we could use the `SQL_NTS` macro to get the size, but since a `Slice` already knows its size
# there's never a need to tax the driver by having it calculate the size for us
conns_size = conn_string.size.to_i16
@env = ODBC.alloc_env
@raw_conn = ODBC.alloc_conn(@env)
result = LibODBC.driver_connect(@raw_conn,
nil,
conn_string,
conns_size,
nil,
0,
nil,
LibODBC::DriverConnect::SqlDriverComplete)
if result == LibODBC::SqlReturn::SqlSuccessWithInfo
puts ODBC.get_detail("SQLDriverConnect", @raw_conn, 1)
elsif result != LibODBC::SqlReturn::SqlSuccess
raise Errno.new("Error establishing connection to server")
end
end
def build_prepared_statement(query)
Statement.new(self, query)
end
def build_unprepared_statement(query)
Statement.new(self, query)
end
def do_close
LibODBC.disconnect(nil)
LibODBC.free_handle(ODBC::HandleType::SqlHandleEnv.value, @env)
LibODBC.free_handle(ODBC::HandleType::SqlHandleDbc, @raw_conn)
end
# :nodoc:
private def serialize_conn_string : Bytes
dsn = context.uri.host.not_nil!
user = context.uri.user
pass = context.uri.password
conn_string = "DSN=#{dsn};UID=#{user};PWD=#{pass}"
ODBC.encode_nts(conn_string)
end
end
end