ydbi 0.5.0 → 0.5.1
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.
- checksums.yaml +4 -4
- data/ChangeLog +4 -0
- data/build/Rakefile.dbi.rb +4 -4
- data/lib/dbi/version.rb +1 -1
- data/test/dbi/tc_dbi.rb +1 -1
- metadata +9 -124
- data/.gitignore +0 -6
- data/Gemfile +0 -4
- data/Rakefile +0 -8
- data/TODO +0 -44
- data/bench/bench.rb +0 -79
- data/build/rake_task_lib.rb +0 -187
- data/doc/DBD_SPEC.rdoc +0 -88
- data/doc/DBI_SPEC.rdoc +0 -157
- data/doc/homepage/contact.html +0 -62
- data/doc/homepage/development.html +0 -124
- data/doc/homepage/index.html +0 -83
- data/doc/homepage/ruby-dbi.css +0 -91
- data/lib/dbd/Mysql.rb +0 -137
- data/lib/dbd/ODBC.rb +0 -89
- data/lib/dbd/Pg.rb +0 -188
- data/lib/dbd/SQLite.rb +0 -97
- data/lib/dbd/SQLite3.rb +0 -124
- data/lib/dbd/mysql/database.rb +0 -405
- data/lib/dbd/mysql/driver.rb +0 -125
- data/lib/dbd/mysql/statement.rb +0 -188
- data/lib/dbd/odbc/database.rb +0 -128
- data/lib/dbd/odbc/driver.rb +0 -38
- data/lib/dbd/odbc/statement.rb +0 -137
- data/lib/dbd/pg/database.rb +0 -516
- data/lib/dbd/pg/exec.rb +0 -47
- data/lib/dbd/pg/statement.rb +0 -160
- data/lib/dbd/pg/tuples.rb +0 -121
- data/lib/dbd/pg/type.rb +0 -209
- data/lib/dbd/sqlite/database.rb +0 -151
- data/lib/dbd/sqlite/statement.rb +0 -125
- data/lib/dbd/sqlite3/database.rb +0 -201
- data/lib/dbd/sqlite3/statement.rb +0 -78
- data/prototypes/types2.rb +0 -237
- data/setup.rb +0 -1585
- data/test/DBD_TESTS +0 -50
- data/test/TESTING +0 -16
- data/test/dbd/general/test_database.rb +0 -206
- data/test/dbd/general/test_statement.rb +0 -326
- data/test/dbd/general/test_types.rb +0 -296
- data/test/dbd/mysql/base.rb +0 -26
- data/test/dbd/mysql/down.sql +0 -19
- data/test/dbd/mysql/test_blob.rb +0 -18
- data/test/dbd/mysql/test_new_methods.rb +0 -7
- data/test/dbd/mysql/test_patches.rb +0 -111
- data/test/dbd/mysql/up.sql +0 -28
- data/test/dbd/odbc/base.rb +0 -30
- data/test/dbd/odbc/down.sql +0 -19
- data/test/dbd/odbc/test_new_methods.rb +0 -12
- data/test/dbd/odbc/test_ping.rb +0 -10
- data/test/dbd/odbc/test_statement.rb +0 -44
- data/test/dbd/odbc/test_transactions.rb +0 -58
- data/test/dbd/odbc/up.sql +0 -33
- data/test/dbd/postgresql/base.rb +0 -31
- data/test/dbd/postgresql/down.sql +0 -31
- data/test/dbd/postgresql/test_arrays.rb +0 -179
- data/test/dbd/postgresql/test_async.rb +0 -121
- data/test/dbd/postgresql/test_blob.rb +0 -36
- data/test/dbd/postgresql/test_bytea.rb +0 -87
- data/test/dbd/postgresql/test_ping.rb +0 -10
- data/test/dbd/postgresql/test_timestamp.rb +0 -77
- data/test/dbd/postgresql/test_transactions.rb +0 -58
- data/test/dbd/postgresql/testdbipg.rb +0 -307
- data/test/dbd/postgresql/up.sql +0 -60
- data/test/dbd/sqlite/base.rb +0 -32
- data/test/dbd/sqlite/test_database.rb +0 -30
- data/test/dbd/sqlite/test_driver.rb +0 -68
- data/test/dbd/sqlite/test_statement.rb +0 -112
- data/test/dbd/sqlite/up.sql +0 -25
- data/test/dbd/sqlite3/base.rb +0 -32
- data/test/dbd/sqlite3/test_database.rb +0 -77
- data/test/dbd/sqlite3/test_driver.rb +0 -67
- data/test/dbd/sqlite3/test_statement.rb +0 -88
- data/test/dbd/sqlite3/up.sql +0 -33
- data/test/ts_dbd.rb +0 -131
- data/ydbi.gemspec +0 -24
data/lib/dbd/mysql/statement.rb
DELETED
@@ -1,188 +0,0 @@
|
|
1
|
-
module DBI::DBD::Mysql
|
2
|
-
#
|
3
|
-
# Models the DBI::BaseStatement API to create DBI::StatementHandle objects.
|
4
|
-
#
|
5
|
-
class Statement < DBI::BaseStatement
|
6
|
-
include Util
|
7
|
-
|
8
|
-
def initialize(parent, handle, statement, mutex)
|
9
|
-
super(nil)
|
10
|
-
|
11
|
-
@parent, @handle, @mutex = parent, handle, mutex
|
12
|
-
@params = []
|
13
|
-
|
14
|
-
@prep_stmt = DBI::SQL::PreparedStatement.new(@parent, statement)
|
15
|
-
end
|
16
|
-
|
17
|
-
#
|
18
|
-
# See DBI::BaseStatement#bind_param. This method will also raise
|
19
|
-
# DBI::InterfaceError if +param+ is not a Fixnum, to prevent incorrect
|
20
|
-
# binding.
|
21
|
-
#
|
22
|
-
def bind_param(param, value, attribs)
|
23
|
-
raise InterfaceError, "only ? parameters supported" unless param.is_a? Fixnum
|
24
|
-
@params[param-1] = value
|
25
|
-
end
|
26
|
-
|
27
|
-
#
|
28
|
-
# See DBI::BaseStatement#execute. If DBI thinks this is a query via DBI::SQL.query?(),
|
29
|
-
# it will force the row processed count to 0. Otherwise, it will return
|
30
|
-
# what MySQL thinks is the row processed count.
|
31
|
-
#
|
32
|
-
def execute
|
33
|
-
sql = @prep_stmt.bind(@params)
|
34
|
-
@mutex.synchronize {
|
35
|
-
@handle.query_with_result = true
|
36
|
-
@res_handle = @handle.query(sql)
|
37
|
-
@column_info = self.column_info
|
38
|
-
@current_row = 0
|
39
|
-
@rows = DBI::SQL.query?(sql) ? 0 : @handle.affected_rows
|
40
|
-
}
|
41
|
-
rescue MyError => err
|
42
|
-
error(err)
|
43
|
-
end
|
44
|
-
|
45
|
-
def finish
|
46
|
-
@res_handle.free if @res_handle
|
47
|
-
rescue MyError => err
|
48
|
-
error(err)
|
49
|
-
end
|
50
|
-
|
51
|
-
#
|
52
|
-
# Helper method to aid #fetch. Do not call directly.
|
53
|
-
#
|
54
|
-
def fill_array(rowdata)
|
55
|
-
return nil if rowdata.nil?
|
56
|
-
return rowdata.dup
|
57
|
-
end
|
58
|
-
|
59
|
-
def fetch
|
60
|
-
@current_row += 1
|
61
|
-
fill_array(@res_handle.fetch_row)
|
62
|
-
rescue MyError => err
|
63
|
-
error(err)
|
64
|
-
end
|
65
|
-
|
66
|
-
#
|
67
|
-
# See DBI::BaseStatement#fetch_scroll. These additional constants are also supported:
|
68
|
-
#
|
69
|
-
# * DBI::SQL_FETCH_PRIOR: Fetch the row previous to the current one.
|
70
|
-
# * DBI::SQL_FETCH_FIRST: Fetch the first row.
|
71
|
-
# * DBI::SQL_FETCH_ABSOLUTE: Fetch the row at the offset provided.
|
72
|
-
# * DBI::SQL_FETCH_RELATIVE: Fetch the row at the current point + offset.
|
73
|
-
#
|
74
|
-
def fetch_scroll(direction, offset)
|
75
|
-
case direction
|
76
|
-
when DBI::SQL_FETCH_NEXT
|
77
|
-
@current_row += 1
|
78
|
-
fill_array(@res_handle.fetch_row)
|
79
|
-
when DBI::SQL_FETCH_PRIOR
|
80
|
-
@res_handle.data_seek(@current_row - 1)
|
81
|
-
fill_array(@res_handle.fetch_row)
|
82
|
-
when DBI::SQL_FETCH_FIRST
|
83
|
-
@current_row = 1
|
84
|
-
@res_handle.data_seek(@current_row - 1)
|
85
|
-
fill_array(@res_handle.fetch_row)
|
86
|
-
when DBI::SQL_FETCH_LAST
|
87
|
-
@current_row = @res_handle.num_rows
|
88
|
-
@res_handle.data_seek(@current_row - 1)
|
89
|
-
fill_array(@res_handle.fetch_row)
|
90
|
-
when DBI::SQL_FETCH_ABSOLUTE
|
91
|
-
@current_row = offset + 1
|
92
|
-
@res_handle.data_seek(@current_row - 1)
|
93
|
-
fill_array(@res_handle.fetch_row)
|
94
|
-
when DBI::SQL_FETCH_RELATIVE
|
95
|
-
@current_row += offset + 1
|
96
|
-
@res_handle.data_seek(@current_row - 1)
|
97
|
-
fill_array(@res_handle.fetch_row)
|
98
|
-
else
|
99
|
-
raise NotSupportedError
|
100
|
-
end
|
101
|
-
#end
|
102
|
-
end
|
103
|
-
|
104
|
-
#
|
105
|
-
# See DBI::BaseStatement#column_info, and DBI::DBD::Mysql::Database#columns.
|
106
|
-
#
|
107
|
-
# This method provides all the attributes the +columns+ method
|
108
|
-
# provides, and a few others:
|
109
|
-
#
|
110
|
-
# * mysql_type: These correspond to constants in the Mysql::Types
|
111
|
-
# package, in the lower-level 'mysql' package.
|
112
|
-
# * mysql_type_name: A text representation of +mysql_type+.
|
113
|
-
# * mysql_length: The length of the column.
|
114
|
-
# * mysql_max_length: The max length of the column. FIXME DESCRIBE
|
115
|
-
# DIFFERENCE
|
116
|
-
# * mysql_flags: Internal MySQL flags on this column.
|
117
|
-
#
|
118
|
-
def column_info
|
119
|
-
retval = []
|
120
|
-
|
121
|
-
return [] if @res_handle.nil?
|
122
|
-
|
123
|
-
unique_key_flag = MysqlField.const_get(:UNIQUE_KEY_FLAG)
|
124
|
-
multiple_key_flag = MysqlField.const_get(:MULTIPLE_KEY_FLAG)
|
125
|
-
indexed = (unique_key_flag | multiple_key_flag)
|
126
|
-
|
127
|
-
# Note: Cannot get 'default' column attribute because MysqlField.def
|
128
|
-
# is set only by mysql_list_fields()
|
129
|
-
|
130
|
-
@res_handle.fetch_fields.each {|col|
|
131
|
-
mysql_type_name, dbi_type = Database::TYPE_MAP[col.type] rescue [nil, nil]
|
132
|
-
xopen_info = Database::MYSQL_to_XOPEN[mysql_type_name] ||
|
133
|
-
Database::MYSQL_to_XOPEN[nil]
|
134
|
-
sql_type = xopen_info[0]
|
135
|
-
type_name = DBI::SQL_TYPE_NAMES[sql_type]
|
136
|
-
|
137
|
-
retval << {
|
138
|
-
# Standard Ruby DBI column attributes
|
139
|
-
'name' => col.name,
|
140
|
-
'sql_type' => sql_type,
|
141
|
-
'type_name' => type_name,
|
142
|
-
# XXX it seems mysql counts the literal decimal point when weighing in the "length".
|
143
|
-
'precision' => type_name == "NUMERIC" ? col.length - 2 : col.length,
|
144
|
-
'scale' => col.decimals,
|
145
|
-
'nullable' => !col.is_not_null?,
|
146
|
-
'indexed' => ((col.flags & indexed) != 0) ||
|
147
|
-
col.is_pri_key?,
|
148
|
-
'primary' => col.is_pri_key?,
|
149
|
-
'unique' => ((col.flags & unique_key_flag) != 0) ||
|
150
|
-
col.is_pri_key?,
|
151
|
-
# MySQL-specific attributes (signified by leading "mysql_")
|
152
|
-
'mysql_type' => col.type,
|
153
|
-
'mysql_type_name' => mysql_type_name,
|
154
|
-
'mysql_length' => col.length,
|
155
|
-
'mysql_max_length' => col.max_length,
|
156
|
-
'mysql_flags' => col.flags
|
157
|
-
}
|
158
|
-
|
159
|
-
if retval[-1]['sql_type'] == DBI::SQL_TINYINT and retval[-1]['precision'] == 1
|
160
|
-
retval[-1]['dbi_type'] = DBI::Type::Boolean
|
161
|
-
elsif dbi_type
|
162
|
-
retval[-1]['dbi_type'] = dbi_type
|
163
|
-
end
|
164
|
-
}
|
165
|
-
retval
|
166
|
-
rescue MyError => err
|
167
|
-
error(err)
|
168
|
-
end
|
169
|
-
|
170
|
-
def rows
|
171
|
-
@rows
|
172
|
-
end
|
173
|
-
|
174
|
-
# def []=(attr, value)
|
175
|
-
# case attr
|
176
|
-
# when 'mysql_use_result'
|
177
|
-
# @attr['mysql_store_result'] = ! value
|
178
|
-
# @attr['mysql_use_result'] = value
|
179
|
-
# when 'mysql_store_result'
|
180
|
-
# @attr['mysql_use_result'] = ! value
|
181
|
-
# @attr['mysql_store_result'] = value
|
182
|
-
# else
|
183
|
-
# raise NotSupportedError
|
184
|
-
# end
|
185
|
-
# end
|
186
|
-
|
187
|
-
end # class Statement
|
188
|
-
end
|
data/lib/dbd/odbc/database.rb
DELETED
@@ -1,128 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# See DBI::BaseDatabase.
|
3
|
-
#
|
4
|
-
class DBI::DBD::ODBC::Database < DBI::BaseDatabase
|
5
|
-
def disconnect
|
6
|
-
@handle.rollback
|
7
|
-
@handle.disconnect
|
8
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
9
|
-
raise DBI::DatabaseError.new(err.message)
|
10
|
-
end
|
11
|
-
|
12
|
-
def database_name
|
13
|
-
@handle.get_info('SQL_DATABASE_NAME')
|
14
|
-
end
|
15
|
-
|
16
|
-
def ping
|
17
|
-
@handle.connected?
|
18
|
-
end
|
19
|
-
|
20
|
-
#
|
21
|
-
# See DBI::BaseDatabase#columns. Additional Attributes:
|
22
|
-
#
|
23
|
-
# * nullable: boolean, true if NULLs are allowed in this column.
|
24
|
-
#
|
25
|
-
def columns(table)
|
26
|
-
cols = []
|
27
|
-
|
28
|
-
stmt = @handle.columns(table)
|
29
|
-
stmt.ignorecase = true
|
30
|
-
|
31
|
-
stmt.each_hash do |row|
|
32
|
-
info = Hash.new
|
33
|
-
cols << info
|
34
|
-
|
35
|
-
info['name'] = row['COLUMN_NAME']
|
36
|
-
info['type_name'] = row['TYPE_NAME']
|
37
|
-
info['sql_type'] = row['DATA_TYPE']
|
38
|
-
info['nullable'] =
|
39
|
-
case row['NULLABLE']
|
40
|
-
when 1
|
41
|
-
true
|
42
|
-
when 0
|
43
|
-
false
|
44
|
-
else
|
45
|
-
nil
|
46
|
-
end
|
47
|
-
info['precision'] = row['PRECISION']
|
48
|
-
info['scale'] = row['SCALE']
|
49
|
-
end
|
50
|
-
|
51
|
-
stmt.drop
|
52
|
-
cols
|
53
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
54
|
-
raise DBI::DatabaseError.new(err.message)
|
55
|
-
end
|
56
|
-
|
57
|
-
def tables
|
58
|
-
stmt = @handle.tables
|
59
|
-
stmt.ignorecase = true
|
60
|
-
tabs = []
|
61
|
-
stmt.each_hash {|row|
|
62
|
-
tabs << row["TABLE_NAME"]
|
63
|
-
}
|
64
|
-
stmt.drop
|
65
|
-
tabs
|
66
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
67
|
-
raise DBI::DatabaseError.new(err.message)
|
68
|
-
end
|
69
|
-
|
70
|
-
def prepare(statement)
|
71
|
-
DBI::DBD::ODBC::Statement.new(@handle.prepare(statement), statement)
|
72
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
73
|
-
raise DBI::DatabaseError.new(err.message)
|
74
|
-
end
|
75
|
-
|
76
|
-
def do(statement, *bindvars)
|
77
|
-
@handle.do(statement, *bindvars)
|
78
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
79
|
-
raise DBI::DatabaseError.new(err.message)
|
80
|
-
end
|
81
|
-
|
82
|
-
def execute(statement, *bindvars)
|
83
|
-
stmt = @handle.run(statement, *bindvars)
|
84
|
-
DBI::DBD::ODBC::Statement.new(stmt, statement)
|
85
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
86
|
-
raise DBI::DatabaseError.new(err.message)
|
87
|
-
end
|
88
|
-
|
89
|
-
#
|
90
|
-
# Additional Attributes on the DatabaseHandle:
|
91
|
-
#
|
92
|
-
# * AutoCommit: force a commit after each statement execution.
|
93
|
-
# * odbc_ignorecase: Be case-insensitive in operations.
|
94
|
-
# * odbc_timeout: Return after a certain time regardless of whether the operation returned anything.
|
95
|
-
#
|
96
|
-
def []=(attr, value)
|
97
|
-
case attr
|
98
|
-
when 'AutoCommit'
|
99
|
-
@handle.autocommit(value)
|
100
|
-
when 'odbc_ignorecase'
|
101
|
-
@handle.ignorecase(value)
|
102
|
-
when 'odbc_timeout'
|
103
|
-
@handle.timeout(value)
|
104
|
-
else
|
105
|
-
if attr =~ /^odbc_/ or attr != /_/
|
106
|
-
raise DBI::NotSupportedError, "Option '#{attr}' not supported"
|
107
|
-
else # option for some other driver - quitly ignore
|
108
|
-
return
|
109
|
-
end
|
110
|
-
end
|
111
|
-
@attr[attr] = value
|
112
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
113
|
-
raise DBI::DatabaseError.new(err.message)
|
114
|
-
end
|
115
|
-
|
116
|
-
def commit
|
117
|
-
@handle.commit
|
118
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
119
|
-
raise DBI::DatabaseError.new(err.message)
|
120
|
-
end
|
121
|
-
|
122
|
-
def rollback
|
123
|
-
@handle.rollback
|
124
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
125
|
-
raise DBI::DatabaseError.new(err.message)
|
126
|
-
end
|
127
|
-
|
128
|
-
end # class Database
|
data/lib/dbd/odbc/driver.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# See DBI::BaseDriver
|
3
|
-
#
|
4
|
-
class DBI::DBD::ODBC::Driver < DBI::BaseDriver
|
5
|
-
def initialize
|
6
|
-
super("0.4.0")
|
7
|
-
end
|
8
|
-
|
9
|
-
def data_sources
|
10
|
-
::ODBC.datasources.collect {|dsn| "dbi:ODBC:" + dsn.name }
|
11
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
12
|
-
raise DBI::DatabaseError.new(err.message)
|
13
|
-
end
|
14
|
-
|
15
|
-
def connect(dbname, user, auth, attr)
|
16
|
-
driver_attrs = dbname.split(';')
|
17
|
-
|
18
|
-
if driver_attrs.size > 1
|
19
|
-
# DNS-less connection
|
20
|
-
drv = ::ODBC::Driver.new
|
21
|
-
drv.name = 'Driver1'
|
22
|
-
driver_attrs.each do |param|
|
23
|
-
pv = param.split('=')
|
24
|
-
next if pv.size < 2
|
25
|
-
drv.attrs[pv[0]] = pv[1]
|
26
|
-
end
|
27
|
-
db = ::ODBC::Database.new
|
28
|
-
handle = db.drvconnect(drv)
|
29
|
-
else
|
30
|
-
# DNS given
|
31
|
-
handle = ::ODBC.connect(dbname, user, auth)
|
32
|
-
end
|
33
|
-
|
34
|
-
return DBI::DBD::ODBC::Database.new(handle, attr)
|
35
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
36
|
-
raise DBI::DatabaseError.new(err.message)
|
37
|
-
end
|
38
|
-
end
|
data/lib/dbd/odbc/statement.rb
DELETED
@@ -1,137 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# See DBI::BaseStatement.
|
3
|
-
#
|
4
|
-
class DBI::DBD::ODBC::Statement < DBI::BaseStatement
|
5
|
-
def initialize(handle, statement)
|
6
|
-
@statement = statement
|
7
|
-
@handle = handle
|
8
|
-
@params = []
|
9
|
-
@arr = []
|
10
|
-
end
|
11
|
-
|
12
|
-
#
|
13
|
-
# See DBI::BaseStatement#bind_param. This method will also raise
|
14
|
-
# DBI::InterfaceError if +param+ is not a Fixnum, to prevent incorrect
|
15
|
-
# binding.
|
16
|
-
#
|
17
|
-
def bind_param(param, value, attribs)
|
18
|
-
raise DBI::InterfaceError, "only ? parameters supported" unless param.is_a? Fixnum
|
19
|
-
@params[param-1] = value
|
20
|
-
end
|
21
|
-
|
22
|
-
def execute
|
23
|
-
@handle.execute(*@params)
|
24
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
25
|
-
raise DBI::DatabaseError.new(err.message)
|
26
|
-
end
|
27
|
-
|
28
|
-
def finish
|
29
|
-
@handle.drop
|
30
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
31
|
-
raise DBI::DatabaseError.new(err.message)
|
32
|
-
end
|
33
|
-
|
34
|
-
def cancel
|
35
|
-
@handle.cancel
|
36
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
37
|
-
raise DBI::DatabaseError.new(err.message)
|
38
|
-
end
|
39
|
-
|
40
|
-
def fetch
|
41
|
-
convert_row(@handle.fetch)
|
42
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
43
|
-
raise DBI::DatabaseError.new(err.message)
|
44
|
-
end
|
45
|
-
|
46
|
-
#
|
47
|
-
# See DBI::BaseStatement#fetch_scroll.
|
48
|
-
#
|
49
|
-
# ODBC has a native version of this method and the constnats in the ODBC
|
50
|
-
# driver themselves are supported. If you'd prefer to use DBI constants
|
51
|
-
# (recommended), you can use these which map to the ODBC functionality:
|
52
|
-
#
|
53
|
-
# * DBI::SQL_FETCH_FIRST
|
54
|
-
# * DBI::SQL_FETCH_LAST
|
55
|
-
# * DBI::SQL_FETCH_NEXT
|
56
|
-
# * DBI::SQL_FETCH_PRIOR
|
57
|
-
# * DBI::SQL_FETCH_ABSOLUTE
|
58
|
-
# * DBI::SQL_FETCH_RELATIVE
|
59
|
-
#
|
60
|
-
def fetch_scroll(direction, offset)
|
61
|
-
direction = case direction
|
62
|
-
when DBI::SQL_FETCH_FIRST then ::ODBC::SQL_FETCH_FIRST
|
63
|
-
when DBI::SQL_FETCH_LAST then ::ODBC::SQL_FETCH_LAST
|
64
|
-
when DBI::SQL_FETCH_NEXT then ::ODBC::SQL_FETCH_NEXT
|
65
|
-
when DBI::SQL_FETCH_PRIOR then ::ODBC::SQL_FETCH_PRIOR
|
66
|
-
when DBI::SQL_FETCH_ABSOLUTE then ::ODBC::SQL_FETCH_ABSOLUTE
|
67
|
-
when DBI::SQL_FETCH_RELATIVE then ::ODBC::SQL_FETCH_RELATIVE
|
68
|
-
else
|
69
|
-
direction
|
70
|
-
end
|
71
|
-
|
72
|
-
convert_row(@handle.fetch_scroll(direction, offset))
|
73
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
74
|
-
raise DBI::DatabaseError.new(err.message)
|
75
|
-
end
|
76
|
-
|
77
|
-
#
|
78
|
-
# See DBI::BaseStatement#column_info. These additional attributes are also
|
79
|
-
# supported:
|
80
|
-
#
|
81
|
-
# * table: the table this column came from, if available.
|
82
|
-
# * nullable: boolean, true if NULL is accepted as a value in this column.
|
83
|
-
# * searchable: FIXME DOCUMENT
|
84
|
-
# * length: FIXME DOCUMENT
|
85
|
-
# * unsigned: For numeric columns, whether or not the result value is signed.
|
86
|
-
#
|
87
|
-
def column_info
|
88
|
-
info = []
|
89
|
-
@handle.columns(true).each do |col|
|
90
|
-
info << {
|
91
|
-
'name' => col.name,
|
92
|
-
'table' => col.table,
|
93
|
-
'nullable' => col.nullable,
|
94
|
-
'searchable' => col.searchable,
|
95
|
-
'precision' => col.precision,
|
96
|
-
'scale' => col.scale,
|
97
|
-
'sql_type' => col.type,
|
98
|
-
'type_name' => DBI::SQL_TYPE_NAMES[col.type],
|
99
|
-
'length' => col.length,
|
100
|
-
'unsigned' => col.unsigned
|
101
|
-
}
|
102
|
-
end
|
103
|
-
info
|
104
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
105
|
-
raise DBI::DatabaseError.new(err.message)
|
106
|
-
end
|
107
|
-
|
108
|
-
#
|
109
|
-
# See DBI::BaseStatement#rows.
|
110
|
-
#
|
111
|
-
# For queries which DBI::SQL.query? returns true, will explicitly return 0.
|
112
|
-
# Otherwise, it will return the row processed count.
|
113
|
-
#
|
114
|
-
def rows
|
115
|
-
return 0 if DBI::SQL.query?(@statement)
|
116
|
-
return @handle.nrows
|
117
|
-
rescue DBI::DBD::ODBC::ODBCErr => err
|
118
|
-
raise DBI::DatabaseError.new(err.message)
|
119
|
-
end
|
120
|
-
|
121
|
-
private # -----------------------------------
|
122
|
-
|
123
|
-
# convert the ODBC datatypes to DBI datatypes
|
124
|
-
def convert_row(row)
|
125
|
-
return nil if row.nil?
|
126
|
-
row.collect do |col|
|
127
|
-
case col
|
128
|
-
when nil
|
129
|
-
nil
|
130
|
-
when ODBC::TimeStamp
|
131
|
-
DBI::Type::Timestamp.create col.year, col.month, col.day, col.hour, col.minute, col.second
|
132
|
-
else
|
133
|
-
col.to_s
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|