dbd-sqlanywhere 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +12 -12
- data/LICENSE +23 -23
- data/README +150 -129
- data/lib/dbd/SQLAnywhere.rb +176 -175
- data/lib/dbd/sqlanywhere/database.rb +255 -253
- data/lib/dbd/sqlanywhere/driver.rb +102 -58
- data/lib/dbd/sqlanywhere/statement.rb +211 -209
- metadata +2 -2
@@ -1,58 +1,102 @@
|
|
1
|
-
#====================================================
|
2
|
-
#
|
3
|
-
# Copyright 2008 iAnywhere Solutions, Inc.
|
4
|
-
#
|
5
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
# you may not use this file except in compliance with the License.
|
7
|
-
# You may obtain a copy of the License at
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
#
|
16
|
-
# See the License for the specific language governing permissions and
|
17
|
-
# limitations under the License.
|
18
|
-
#
|
19
|
-
# While not a requirement of the license, if you do modify this file, we
|
20
|
-
# would appreciate hearing about it. Please email sqlany_interfaces@sybase.com
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#====================================================
|
24
|
-
|
25
|
-
module DBI::DBD::SQLAnywhere
|
26
|
-
class Driver < DBI::BaseDriver
|
27
|
-
include Utility
|
28
|
-
|
29
|
-
def initialize
|
30
|
-
super("0.4.0")
|
31
|
-
end
|
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
|
-
|
1
|
+
#====================================================
|
2
|
+
#
|
3
|
+
# Copyright 2008-2009 iAnywhere Solutions, Inc.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
#
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
# While not a requirement of the license, if you do modify this file, we
|
20
|
+
# would appreciate hearing about it. Please email sqlany_interfaces@sybase.com
|
21
|
+
#
|
22
|
+
#
|
23
|
+
#====================================================
|
24
|
+
|
25
|
+
module DBI::DBD::SQLAnywhere
|
26
|
+
class Driver < DBI::BaseDriver
|
27
|
+
include Utility
|
28
|
+
|
29
|
+
def initialize
|
30
|
+
super("0.4.0")
|
31
|
+
end
|
32
|
+
|
33
|
+
# The DBNAME string can be specified in the following forms:
|
34
|
+
#
|
35
|
+
# "DBI:SQLAnywhere:"
|
36
|
+
# "DBI:SQLAnywhere:{ENG}"
|
37
|
+
# "DBI:SQLAnywhere:{ENG}:{DBN}"
|
38
|
+
# "DBI:SQLAnywhere:{CONNECTION_STRING}" # where CONNECTION_STRING ~= "key1=val1;key2=val2;..."
|
39
|
+
#
|
40
|
+
# For the first form, nothing will be added to the connection string. With the second and third forms
|
41
|
+
# the driver will add ENG and DBN to the connection string accordingly. The fourth form will pass
|
42
|
+
# the supplied connection string through unmolested.
|
43
|
+
#
|
44
|
+
# The user and auth can be passed into the function and they will be automatically appended to the
|
45
|
+
# connection string. Since Ruby DBI will automatically fill in the username and password with defaults if they are ommited,
|
46
|
+
# you should NEVER include a "UID=" or "PWD=" in your connection string or an exception will be thrown.
|
47
|
+
#
|
48
|
+
# Examples:
|
49
|
+
#
|
50
|
+
# Function Call ==> Generated Connection String
|
51
|
+
# ==============================================================================================
|
52
|
+
# DBI.connect("DBI:SQLAnywhere:") ==> "uid=dba;pwd=sql"
|
53
|
+
# DBI.connect("DBI:SQLAnywhere:Demo") ==> "eng=Demo;uid=dba;pwd=sql"
|
54
|
+
# DBI.connect("DBI:SQLAnywhere:Demo:Test") ==> "eng=Demo;dbn=Test;uid=dba;pwd=sql"
|
55
|
+
# DBI.connect("DBI:SQLAnywhere:Demo:Test", 'john', 'doe') ==> "eng=Demo;dbn=Test;uid=john;pwd=doe"
|
56
|
+
# DBI.connect("DBI:SQLAnywhere:eng=Demo;dbn=Test") ==> "eng=Demo;dbn=Test;uid=dba;pwd=sql"
|
57
|
+
# DBI.connect("DBI:SQLAnywhere:eng=Demo;dbn=Test;uid=john") ==> EXCEPTION! UID cannot be specified in the connection string
|
58
|
+
# DBI.connect("DBI:SQLAnywhere:CommLinks=tcpip(port=2638)") ==> "CommLinks=tcpip(port=2638);uid=dba;pwd=sql"
|
59
|
+
#
|
60
|
+
# The attr parameter is ignored.
|
61
|
+
|
62
|
+
def connect( dbname, user, auth, attr )
|
63
|
+
conn = SA.instance.api.sqlany_new_connection()
|
64
|
+
|
65
|
+
conn_str = ''
|
66
|
+
|
67
|
+
unless dbname.nil?
|
68
|
+
if dbname =~ /^[^=:;]+$/
|
69
|
+
conn_str = "eng=#{dbname};"
|
70
|
+
elsif dbname =~ /^[^=:;]+:[^=:;]+$/
|
71
|
+
eng_name, db_name = dbname.split(":")
|
72
|
+
conn_str = "eng=#{eng_name};dbn=#{db_name};"
|
73
|
+
else
|
74
|
+
conn_str = dbname;
|
75
|
+
conn_str << ';' unless conn_str.length == 0 or conn_str[conn_str.length - 1, 1] == ';'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
unless user.nil?
|
80
|
+
raise DBI::ProgrammingError.new("UID is specified twice. Once in the connection string AND once as a connect() parameter. It can only be specified once.") if conn_str =~ /uid=/i
|
81
|
+
conn_str << "uid=#{user};"
|
82
|
+
end
|
83
|
+
|
84
|
+
unless auth.nil?
|
85
|
+
raise DBI::ProgrammingError.new("PWD is specified twice. Once in the connection string AND once as a connect() parameter. It can only be specifed once.") if conn_str =~ /pwd=/i
|
86
|
+
conn_str << "pwd=#{auth};"
|
87
|
+
end
|
88
|
+
|
89
|
+
SA.instance.api.sqlany_connect(conn, conn_str)
|
90
|
+
return Database.new(conn, attr)
|
91
|
+
end
|
92
|
+
|
93
|
+
def default_user
|
94
|
+
return ['dba', 'sql']
|
95
|
+
end
|
96
|
+
|
97
|
+
def disconnect_all
|
98
|
+
SA.instance.api.sqlany_fini()
|
99
|
+
SA.instance.free_api
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -1,209 +1,211 @@
|
|
1
|
-
#====================================================
|
2
|
-
#
|
3
|
-
# Copyright 2008 iAnywhere Solutions, Inc.
|
4
|
-
#
|
5
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
# you may not use this file except in compliance with the License.
|
7
|
-
# You may obtain a copy of the License at
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
#
|
16
|
-
# See the License for the specific language governing permissions and
|
17
|
-
# limitations under the License.
|
18
|
-
#
|
19
|
-
# While not a requirement of the license, if you do modify this file, we
|
20
|
-
# would appreciate hearing about it. Please email sqlany_interfaces@sybase.com
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#====================================================
|
24
|
-
|
25
|
-
module DBI::DBD::SQLAnywhere
|
26
|
-
class Statement < DBI::BaseStatement
|
27
|
-
include Utility
|
28
|
-
|
29
|
-
|
30
|
-
# Conversion table between SQL Anywhere E-SQL types and DBI SQL Types
|
31
|
-
SQLANY_NATIVE_TYPES = {
|
32
|
-
0 => DBI::SQL_LONGVARCHAR,
|
33
|
-
384 => DBI::SQL_DATE,
|
34
|
-
388 => DBI::SQL_TIME,
|
35
|
-
392 => DBI::SQL_TIMESTAMP,
|
36
|
-
448 => DBI::SQL_VARCHAR,
|
37
|
-
452 => DBI::SQL_CHAR,
|
38
|
-
456 => DBI::SQL_LONGVARCHAR,
|
39
|
-
460 => DBI::SQL_LONGVARCHAR,
|
40
|
-
480 => DBI::SQL_DOUBLE,
|
41
|
-
482 => DBI::SQL_FLOAT,
|
42
|
-
484 => DBI::SQL_DECIMAL,
|
43
|
-
496 => DBI::SQL_INTEGER,
|
44
|
-
500 => DBI::SQL_SMALLINT,
|
45
|
-
524 => DBI::SQL_BINARY,
|
46
|
-
528 => DBI::SQL_LONGVARBINARY,
|
47
|
-
604 => DBI::SQL_TINYINT,
|
48
|
-
608 => DBI::SQL_BIGINT,
|
49
|
-
612 => DBI::SQL_INTEGER,
|
50
|
-
616 => DBI::SQL_SMALLINT,
|
51
|
-
620 => DBI::SQL_BIGINT,
|
52
|
-
624 => DBI::SQL_BIT,
|
53
|
-
640 => DBI::SQL_LONGVARCHAR
|
54
|
-
}
|
55
|
-
|
56
|
-
def initialize(handle, conn, bound = {} )
|
57
|
-
@handle = handle
|
58
|
-
@conn = conn
|
59
|
-
@arr = []
|
60
|
-
@bound = bound
|
61
|
-
@offset = -1
|
62
|
-
end
|
63
|
-
|
64
|
-
def __bound_param(name)
|
65
|
-
if !@bound[name].nil?
|
66
|
-
res, param = SA.instance.api.sqlany_get_bind_param_info(@handle, @bound[name])
|
67
|
-
raise error() if res == 0
|
68
|
-
return param.get_output()
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
# Although SQL Anywhere allows multiple result sets,
|
73
|
-
# the @fetchable variable disallows there use
|
74
|
-
#
|
75
|
-
#def __next_resultset
|
76
|
-
# return SA.instance.api.sqlany_get_next_result(@handle)
|
77
|
-
#end
|
78
|
-
|
79
|
-
def bind_param(param, value, attribs)
|
80
|
-
param -= 1
|
81
|
-
res, param_description = SA.instance.api.sqlany_describe_bind_param(@handle, param)
|
82
|
-
raise error() if res == 0 or param_description.nil?
|
83
|
-
do_bind!(@handle, param_description, value, param, @bound)
|
84
|
-
param_description.finish
|
85
|
-
end
|
86
|
-
|
87
|
-
def execute()
|
88
|
-
res = SA.instance.api.sqlany_execute(@handle)
|
89
|
-
raise error() if res == 0
|
90
|
-
end
|
91
|
-
|
92
|
-
def fetch()
|
93
|
-
return fetch_scroll(DBI::SQL_FETCH_NEXT, 1)
|
94
|
-
end
|
95
|
-
|
96
|
-
def fetch_all()
|
97
|
-
rows = []
|
98
|
-
loop {
|
99
|
-
new_row = self.fetch_scroll(DBI::SQL_FETCH_NEXT, 1)
|
100
|
-
break if new_row.nil?
|
101
|
-
rows << new_row.clone
|
102
|
-
}
|
103
|
-
return rows
|
104
|
-
end
|
105
|
-
|
106
|
-
def fetch_scroll(direction, offset)
|
107
|
-
res = 0
|
108
|
-
new_offset = @offset
|
109
|
-
|
110
|
-
case direction
|
111
|
-
when DBI::SQL_FETCH_NEXT
|
112
|
-
res = SA.instance.api.sqlany_fetch_next(@handle)
|
113
|
-
new_offset += 1
|
114
|
-
when DBI::SQL_FETCH_PRIOR
|
115
|
-
res = SA.instance.api.sqlany_fetch_absolute(@handle, @offset)
|
116
|
-
new_offset -= 1
|
117
|
-
when DBI::SQL_FETCH_FIRST
|
118
|
-
res = SA.instance.api.sqlany_fetch_absolute(@handle, 1)
|
119
|
-
new_offset = 0
|
120
|
-
when DBI::SQL_FETCH_LAST
|
121
|
-
res = SA.instance.api.sqlany_fetch_absolute(@handle, -1)
|
122
|
-
new_offset = self.rows() - 1
|
123
|
-
when DBI::SQL_FETCH_ABSOLUTE
|
124
|
-
res = SA.instance.api.sqlany_fetch_absolute(@handle, offset)
|
125
|
-
if offset <= 0
|
126
|
-
new_offset = self.rows() + offset
|
127
|
-
else
|
128
|
-
new_offset = offset - 1
|
129
|
-
end
|
130
|
-
when DBI::SQL_FETCH_RELATIVE
|
131
|
-
res = SA.instance.api.sqlany_fetch_absolute(@handle, @offset + offset + 1)
|
132
|
-
new_offset += offset
|
133
|
-
end
|
134
|
-
|
135
|
-
if (res == 1)
|
136
|
-
retrieve_row_data()
|
137
|
-
@offset = new_offset
|
138
|
-
return @arr
|
139
|
-
else
|
140
|
-
return nil
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
def column_info
|
145
|
-
columns = []
|
146
|
-
if !@handle.nil?
|
147
|
-
max_cols = SA.instance.api.sqlany_num_cols(@handle)
|
148
|
-
raise error() if max_cols == -1
|
149
|
-
max_cols.times do |cols|
|
150
|
-
columns << {}
|
151
|
-
res, holder, col_name, type, native_type, precision, scale, max_size, nullable = SA.instance.api.sqlany_get_column_info(@handle, cols)
|
152
|
-
raise error() if res == 0 or col_name.nil?
|
153
|
-
columns[cols]["name"] = col_name
|
154
|
-
sql_type = SQLANY_NATIVE_TYPES[native_type]
|
155
|
-
columns[cols]["sql_type"] = sql_type
|
156
|
-
columns[cols]["type_name"] = DBI::SQL_TYPE_NAMES[sql_type]
|
157
|
-
precision = max_size if precision == 0 and max_size != 0
|
158
|
-
columns[cols]["precision"] = precision
|
159
|
-
columns[cols]["scale"] = scale
|
160
|
-
columns[cols]["nullable"] = (nullable == 0)
|
161
|
-
|
162
|
-
columns[cols]["dbi_type"] = DBI::Type::Boolean if sql_type == DBI::SQL_BIT
|
163
|
-
end
|
164
|
-
end
|
165
|
-
return columns
|
166
|
-
end
|
167
|
-
|
168
|
-
def rows
|
169
|
-
if @handle.nil?
|
170
|
-
res = SA.instance.api.sqlany_affected_rows(@handle)
|
171
|
-
raise error() if res == -1
|
172
|
-
return res
|
173
|
-
else
|
174
|
-
0
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
def finish
|
179
|
-
if !@handle.nil?
|
180
|
-
SA.instance.api.sqlany_free_stmt(@handle);
|
181
|
-
@handle = nil
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
def cancel
|
186
|
-
end
|
187
|
-
|
188
|
-
protected
|
189
|
-
def error(*custom_msg)
|
190
|
-
code, msg = SA.instance.api.sqlany_error(@conn)
|
191
|
-
state = SA.instance.api.sqlany_sqlstate(@conn)
|
192
|
-
SA.instance.api.sqlany_clear_error(@conn)
|
193
|
-
if !custom_msg.nil?
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
max_cols
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
end
|
1
|
+
#====================================================
|
2
|
+
#
|
3
|
+
# Copyright 2008-2009 iAnywhere Solutions, Inc.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
#
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
# While not a requirement of the license, if you do modify this file, we
|
20
|
+
# would appreciate hearing about it. Please email sqlany_interfaces@sybase.com
|
21
|
+
#
|
22
|
+
#
|
23
|
+
#====================================================
|
24
|
+
|
25
|
+
module DBI::DBD::SQLAnywhere
|
26
|
+
class Statement < DBI::BaseStatement
|
27
|
+
include Utility
|
28
|
+
|
29
|
+
|
30
|
+
# Conversion table between SQL Anywhere E-SQL types and DBI SQL Types
|
31
|
+
SQLANY_NATIVE_TYPES = {
|
32
|
+
0 => DBI::SQL_LONGVARCHAR,
|
33
|
+
384 => DBI::SQL_DATE,
|
34
|
+
388 => DBI::SQL_TIME,
|
35
|
+
392 => DBI::SQL_TIMESTAMP,
|
36
|
+
448 => DBI::SQL_VARCHAR,
|
37
|
+
452 => DBI::SQL_CHAR,
|
38
|
+
456 => DBI::SQL_LONGVARCHAR,
|
39
|
+
460 => DBI::SQL_LONGVARCHAR,
|
40
|
+
480 => DBI::SQL_DOUBLE,
|
41
|
+
482 => DBI::SQL_FLOAT,
|
42
|
+
484 => DBI::SQL_DECIMAL,
|
43
|
+
496 => DBI::SQL_INTEGER,
|
44
|
+
500 => DBI::SQL_SMALLINT,
|
45
|
+
524 => DBI::SQL_BINARY,
|
46
|
+
528 => DBI::SQL_LONGVARBINARY,
|
47
|
+
604 => DBI::SQL_TINYINT,
|
48
|
+
608 => DBI::SQL_BIGINT,
|
49
|
+
612 => DBI::SQL_INTEGER,
|
50
|
+
616 => DBI::SQL_SMALLINT,
|
51
|
+
620 => DBI::SQL_BIGINT,
|
52
|
+
624 => DBI::SQL_BIT,
|
53
|
+
640 => DBI::SQL_LONGVARCHAR
|
54
|
+
}
|
55
|
+
|
56
|
+
def initialize(handle, conn, bound = {} )
|
57
|
+
@handle = handle
|
58
|
+
@conn = conn
|
59
|
+
@arr = []
|
60
|
+
@bound = bound
|
61
|
+
@offset = -1
|
62
|
+
end
|
63
|
+
|
64
|
+
def __bound_param(name)
|
65
|
+
if !@bound[name].nil?
|
66
|
+
res, param = SA.instance.api.sqlany_get_bind_param_info(@handle, @bound[name])
|
67
|
+
raise error() if res == 0
|
68
|
+
return param.get_output()
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Although SQL Anywhere allows multiple result sets,
|
73
|
+
# the @fetchable variable disallows there use
|
74
|
+
#
|
75
|
+
#def __next_resultset
|
76
|
+
# return SA.instance.api.sqlany_get_next_result(@handle)
|
77
|
+
#end
|
78
|
+
|
79
|
+
def bind_param(param, value, attribs)
|
80
|
+
param -= 1
|
81
|
+
res, param_description = SA.instance.api.sqlany_describe_bind_param(@handle, param)
|
82
|
+
raise error() if res == 0 or param_description.nil?
|
83
|
+
do_bind!(@handle, param_description, value, param, @bound)
|
84
|
+
param_description.finish
|
85
|
+
end
|
86
|
+
|
87
|
+
def execute()
|
88
|
+
res = SA.instance.api.sqlany_execute(@handle)
|
89
|
+
raise error() if res == 0
|
90
|
+
end
|
91
|
+
|
92
|
+
def fetch()
|
93
|
+
return fetch_scroll(DBI::SQL_FETCH_NEXT, 1)
|
94
|
+
end
|
95
|
+
|
96
|
+
def fetch_all()
|
97
|
+
rows = []
|
98
|
+
loop {
|
99
|
+
new_row = self.fetch_scroll(DBI::SQL_FETCH_NEXT, 1)
|
100
|
+
break if new_row.nil?
|
101
|
+
rows << new_row.clone
|
102
|
+
}
|
103
|
+
return rows
|
104
|
+
end
|
105
|
+
|
106
|
+
def fetch_scroll(direction, offset)
|
107
|
+
res = 0
|
108
|
+
new_offset = @offset
|
109
|
+
|
110
|
+
case direction
|
111
|
+
when DBI::SQL_FETCH_NEXT
|
112
|
+
res = SA.instance.api.sqlany_fetch_next(@handle)
|
113
|
+
new_offset += 1
|
114
|
+
when DBI::SQL_FETCH_PRIOR
|
115
|
+
res = SA.instance.api.sqlany_fetch_absolute(@handle, @offset)
|
116
|
+
new_offset -= 1
|
117
|
+
when DBI::SQL_FETCH_FIRST
|
118
|
+
res = SA.instance.api.sqlany_fetch_absolute(@handle, 1)
|
119
|
+
new_offset = 0
|
120
|
+
when DBI::SQL_FETCH_LAST
|
121
|
+
res = SA.instance.api.sqlany_fetch_absolute(@handle, -1)
|
122
|
+
new_offset = self.rows() - 1
|
123
|
+
when DBI::SQL_FETCH_ABSOLUTE
|
124
|
+
res = SA.instance.api.sqlany_fetch_absolute(@handle, offset)
|
125
|
+
if offset <= 0
|
126
|
+
new_offset = self.rows() + offset
|
127
|
+
else
|
128
|
+
new_offset = offset - 1
|
129
|
+
end
|
130
|
+
when DBI::SQL_FETCH_RELATIVE
|
131
|
+
res = SA.instance.api.sqlany_fetch_absolute(@handle, @offset + offset + 1)
|
132
|
+
new_offset += offset
|
133
|
+
end
|
134
|
+
|
135
|
+
if (res == 1)
|
136
|
+
retrieve_row_data()
|
137
|
+
@offset = new_offset
|
138
|
+
return @arr
|
139
|
+
else
|
140
|
+
return nil
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def column_info
|
145
|
+
columns = []
|
146
|
+
if !@handle.nil?
|
147
|
+
max_cols = SA.instance.api.sqlany_num_cols(@handle)
|
148
|
+
raise error() if max_cols == -1
|
149
|
+
max_cols.times do |cols|
|
150
|
+
columns << {}
|
151
|
+
res, holder, col_name, type, native_type, precision, scale, max_size, nullable = SA.instance.api.sqlany_get_column_info(@handle, cols)
|
152
|
+
raise error() if res == 0 or col_name.nil?
|
153
|
+
columns[cols]["name"] = col_name
|
154
|
+
sql_type = SQLANY_NATIVE_TYPES[native_type]
|
155
|
+
columns[cols]["sql_type"] = sql_type
|
156
|
+
columns[cols]["type_name"] = DBI::SQL_TYPE_NAMES[sql_type]
|
157
|
+
precision = max_size if precision == 0 and max_size != 0
|
158
|
+
columns[cols]["precision"] = precision
|
159
|
+
columns[cols]["scale"] = scale
|
160
|
+
columns[cols]["nullable"] = (nullable == 0)
|
161
|
+
|
162
|
+
columns[cols]["dbi_type"] = DBI::Type::Boolean if sql_type == DBI::SQL_BIT
|
163
|
+
end
|
164
|
+
end
|
165
|
+
return columns
|
166
|
+
end
|
167
|
+
|
168
|
+
def rows
|
169
|
+
if @handle.nil?
|
170
|
+
res = SA.instance.api.sqlany_affected_rows(@handle)
|
171
|
+
raise error() if res == -1
|
172
|
+
return res
|
173
|
+
else
|
174
|
+
0
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def finish
|
179
|
+
if !@handle.nil?
|
180
|
+
SA.instance.api.sqlany_free_stmt(@handle);
|
181
|
+
@handle = nil
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def cancel
|
186
|
+
end
|
187
|
+
|
188
|
+
protected
|
189
|
+
def error(*custom_msg)
|
190
|
+
code, msg = SA.instance.api.sqlany_error(@conn)
|
191
|
+
state = SA.instance.api.sqlany_sqlstate(@conn)
|
192
|
+
SA.instance.api.sqlany_clear_error(@conn)
|
193
|
+
if !custom_msg.nil?
|
194
|
+
if custom_msg.length != 0
|
195
|
+
msg = "#{custom_msg}. #{msg}"
|
196
|
+
end
|
197
|
+
end
|
198
|
+
return DBI::DatabaseError.new(msg, code, state)
|
199
|
+
end
|
200
|
+
|
201
|
+
def retrieve_row_data
|
202
|
+
max_cols = SA.instance.api.sqlany_num_cols(@handle)
|
203
|
+
raise error() if max_cols == -1
|
204
|
+
max_cols.times do |cols|
|
205
|
+
res, col_val = SA.instance.api.sqlany_get_column(@handle, cols)
|
206
|
+
raise error() if res == 0
|
207
|
+
@arr[cols] = col_val
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|