ydbi 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/ChangeLog +3699 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +25 -0
  6. data/Rakefile +8 -0
  7. data/TODO +44 -0
  8. data/bench/bench.rb +79 -0
  9. data/bin/dbi +518 -0
  10. data/bin/test_broken_dbi +37 -0
  11. data/build/Rakefile.dbi.rb +60 -0
  12. data/build/rake_task_lib.rb +187 -0
  13. data/doc/DBD_SPEC.rdoc +88 -0
  14. data/doc/DBI_SPEC.rdoc +157 -0
  15. data/doc/homepage/contact.html +62 -0
  16. data/doc/homepage/development.html +124 -0
  17. data/doc/homepage/index.html +83 -0
  18. data/doc/homepage/ruby-dbi.css +91 -0
  19. data/examples/test1.pl +39 -0
  20. data/examples/test1.rb +20 -0
  21. data/examples/xmltest.rb +8 -0
  22. data/lib/dbd/Mysql.rb +137 -0
  23. data/lib/dbd/ODBC.rb +89 -0
  24. data/lib/dbd/Pg.rb +188 -0
  25. data/lib/dbd/SQLite.rb +97 -0
  26. data/lib/dbd/SQLite3.rb +124 -0
  27. data/lib/dbd/mysql/database.rb +405 -0
  28. data/lib/dbd/mysql/driver.rb +125 -0
  29. data/lib/dbd/mysql/statement.rb +188 -0
  30. data/lib/dbd/odbc/database.rb +128 -0
  31. data/lib/dbd/odbc/driver.rb +38 -0
  32. data/lib/dbd/odbc/statement.rb +137 -0
  33. data/lib/dbd/pg/database.rb +516 -0
  34. data/lib/dbd/pg/exec.rb +47 -0
  35. data/lib/dbd/pg/statement.rb +160 -0
  36. data/lib/dbd/pg/tuples.rb +121 -0
  37. data/lib/dbd/pg/type.rb +209 -0
  38. data/lib/dbd/sqlite/database.rb +151 -0
  39. data/lib/dbd/sqlite/statement.rb +125 -0
  40. data/lib/dbd/sqlite3/database.rb +201 -0
  41. data/lib/dbd/sqlite3/statement.rb +78 -0
  42. data/lib/dbi.rb +336 -0
  43. data/lib/dbi/base_classes.rb +12 -0
  44. data/lib/dbi/base_classes/database.rb +135 -0
  45. data/lib/dbi/base_classes/driver.rb +47 -0
  46. data/lib/dbi/base_classes/statement.rb +171 -0
  47. data/lib/dbi/binary.rb +25 -0
  48. data/lib/dbi/columninfo.rb +107 -0
  49. data/lib/dbi/exceptions.rb +65 -0
  50. data/lib/dbi/handles.rb +49 -0
  51. data/lib/dbi/handles/database.rb +241 -0
  52. data/lib/dbi/handles/driver.rb +60 -0
  53. data/lib/dbi/handles/statement.rb +408 -0
  54. data/lib/dbi/row.rb +269 -0
  55. data/lib/dbi/sql.rb +22 -0
  56. data/lib/dbi/sql/preparedstatement.rb +115 -0
  57. data/lib/dbi/sql_type_constants.rb +75 -0
  58. data/lib/dbi/trace.rb +91 -0
  59. data/lib/dbi/types.rb +218 -0
  60. data/lib/dbi/typeutil.rb +109 -0
  61. data/lib/dbi/utils.rb +60 -0
  62. data/lib/dbi/utils/date.rb +59 -0
  63. data/lib/dbi/utils/tableformatter.rb +112 -0
  64. data/lib/dbi/utils/time.rb +52 -0
  65. data/lib/dbi/utils/timestamp.rb +96 -0
  66. data/lib/dbi/utils/xmlformatter.rb +73 -0
  67. data/lib/dbi/version.rb +3 -0
  68. data/prototypes/types2.rb +237 -0
  69. data/readme.md +274 -0
  70. data/setup.rb +1585 -0
  71. data/test/DBD_TESTS +50 -0
  72. data/test/TESTING +16 -0
  73. data/test/dbd/general/test_database.rb +206 -0
  74. data/test/dbd/general/test_statement.rb +326 -0
  75. data/test/dbd/general/test_types.rb +296 -0
  76. data/test/dbd/mysql/base.rb +26 -0
  77. data/test/dbd/mysql/down.sql +19 -0
  78. data/test/dbd/mysql/test_blob.rb +18 -0
  79. data/test/dbd/mysql/test_new_methods.rb +7 -0
  80. data/test/dbd/mysql/test_patches.rb +111 -0
  81. data/test/dbd/mysql/up.sql +28 -0
  82. data/test/dbd/odbc/base.rb +30 -0
  83. data/test/dbd/odbc/down.sql +19 -0
  84. data/test/dbd/odbc/test_new_methods.rb +12 -0
  85. data/test/dbd/odbc/test_ping.rb +10 -0
  86. data/test/dbd/odbc/test_statement.rb +44 -0
  87. data/test/dbd/odbc/test_transactions.rb +58 -0
  88. data/test/dbd/odbc/up.sql +33 -0
  89. data/test/dbd/postgresql/base.rb +31 -0
  90. data/test/dbd/postgresql/down.sql +31 -0
  91. data/test/dbd/postgresql/test_arrays.rb +179 -0
  92. data/test/dbd/postgresql/test_async.rb +121 -0
  93. data/test/dbd/postgresql/test_blob.rb +36 -0
  94. data/test/dbd/postgresql/test_bytea.rb +87 -0
  95. data/test/dbd/postgresql/test_ping.rb +10 -0
  96. data/test/dbd/postgresql/test_timestamp.rb +77 -0
  97. data/test/dbd/postgresql/test_transactions.rb +58 -0
  98. data/test/dbd/postgresql/testdbipg.rb +307 -0
  99. data/test/dbd/postgresql/up.sql +60 -0
  100. data/test/dbd/sqlite/base.rb +32 -0
  101. data/test/dbd/sqlite/test_database.rb +30 -0
  102. data/test/dbd/sqlite/test_driver.rb +68 -0
  103. data/test/dbd/sqlite/test_statement.rb +112 -0
  104. data/test/dbd/sqlite/up.sql +25 -0
  105. data/test/dbd/sqlite3/base.rb +32 -0
  106. data/test/dbd/sqlite3/test_database.rb +77 -0
  107. data/test/dbd/sqlite3/test_driver.rb +67 -0
  108. data/test/dbd/sqlite3/test_statement.rb +88 -0
  109. data/test/dbd/sqlite3/up.sql +33 -0
  110. data/test/dbi/tc_columninfo.rb +94 -0
  111. data/test/dbi/tc_date.rb +88 -0
  112. data/test/dbi/tc_dbi.rb +184 -0
  113. data/test/dbi/tc_row.rb +256 -0
  114. data/test/dbi/tc_sqlbind.rb +168 -0
  115. data/test/dbi/tc_statementhandle.rb +29 -0
  116. data/test/dbi/tc_time.rb +77 -0
  117. data/test/dbi/tc_timestamp.rb +142 -0
  118. data/test/dbi/tc_types.rb +268 -0
  119. data/test/ts_dbd.rb +131 -0
  120. data/test/ts_dbi.rb +16 -0
  121. data/ydbi.gemspec +24 -0
  122. metadata +224 -0
@@ -0,0 +1,405 @@
1
+ module DBI::DBD::Mysql
2
+ #
3
+ # Models the DBI::BaseDatabase API to create DBI::DatabaseHandle objects.
4
+ #
5
+ class Database < DBI::BaseDatabase
6
+ include Util
7
+
8
+ #
9
+ # Hash to translate MySQL type names to DBI SQL type constants
10
+ #
11
+ # Only used in #mysql_type_info.
12
+ #
13
+ #--
14
+ # Eli Green:
15
+ # The hope is that we don't ever need to just assume the default values.
16
+ # However, in some cases (notably floats and doubles), I have seen
17
+ # "show fields from table" return absolutely zero information about size
18
+ # and precision. Sigh. I probably should have made a struct to store
19
+ # this info in ... but I didn't.
20
+ #++
21
+ MYSQL_to_XOPEN = {
22
+ "TINYINT" => [DBI::SQL_TINYINT, 1, nil],
23
+ "SMALLINT" => [DBI::SQL_SMALLINT, 6, nil],
24
+ "MEDIUMINT" => [DBI::SQL_SMALLINT, 6, nil],
25
+ "INT" => [DBI::SQL_INTEGER, 11, nil],
26
+ "INTEGER" => [DBI::SQL_INTEGER, 11, nil],
27
+ "BIGINT" => [DBI::SQL_BIGINT, 25, nil],
28
+ "INT24" => [DBI::SQL_BIGINT, 25, nil],
29
+ "REAL" => [DBI::SQL_REAL, 12, nil],
30
+ "FLOAT" => [DBI::SQL_FLOAT, 12, nil],
31
+ "DECIMAL" => [DBI::SQL_DECIMAL, 12, nil],
32
+ "NUMERIC" => [DBI::SQL_NUMERIC, 12, nil],
33
+ "DOUBLE" => [DBI::SQL_DOUBLE, 22, nil],
34
+ "CHAR" => [DBI::SQL_CHAR, 1, nil],
35
+ "VARCHAR" => [DBI::SQL_VARCHAR, 255, nil],
36
+ "DATE" => [DBI::SQL_DATE, 10, nil],
37
+ "TIME" => [DBI::SQL_TIME, 8, nil],
38
+ "TIMESTAMP" => [DBI::SQL_TIMESTAMP, 19, nil],
39
+ "DATETIME" => [DBI::SQL_TIMESTAMP, 19, nil],
40
+ "TINYBLOB" => [DBI::SQL_BINARY, 255, nil],
41
+ "BLOB" => [DBI::SQL_VARBINARY, 65535, nil],
42
+ "MEDIUMBLOB" => [DBI::SQL_VARBINARY, 16277215, nil],
43
+ "LONGBLOB" => [DBI::SQL_LONGVARBINARY, 2147483657, nil],
44
+ "TINYTEXT" => [DBI::SQL_VARCHAR, 255, nil],
45
+ "TEXT" => [DBI::SQL_LONGVARCHAR, 65535, nil],
46
+ "MEDIUMTEXT" => [DBI::SQL_LONGVARCHAR, 16277215, nil],
47
+ "LONGTEXT" => [DBI::SQL_LONGVARCHAR, 2147483657, nil],
48
+ "ENUM" => [DBI::SQL_CHAR, 255, nil],
49
+ "SET" => [DBI::SQL_CHAR, 255, nil],
50
+ "BIT" => [DBI::SQL_BIT, 8, nil],
51
+ nil => [DBI::SQL_OTHER, nil, nil]
52
+ }
53
+
54
+
55
+ #
56
+ # This maps type names to DBI Types.
57
+ #
58
+ TYPE_MAP = {}
59
+
60
+ ::Mysql::Field.constants.grep(/^TYPE_/).each do |const|
61
+ mysql_type = MysqlField.const_get(const) # numeric type code
62
+ coercion_method = DBI::Type::Varchar # default coercion method
63
+ case const.to_s
64
+ when 'TYPE_TINY'
65
+ mysql_type_name = 'TINYINT'
66
+ coercion_method = DBI::Type::Integer
67
+ when 'TYPE_SHORT'
68
+ mysql_type_name = 'SMALLINT'
69
+ coercion_method = DBI::Type::Integer
70
+ when 'TYPE_INT24'
71
+ mysql_type_name = 'MEDIUMINT'
72
+ coercion_method = DBI::Type::Integer
73
+ when 'TYPE_LONG'
74
+ mysql_type_name = 'INT'
75
+ coercion_method = DBI::Type::Integer
76
+ when 'TYPE_LONGLONG'
77
+ mysql_type_name = 'BIGINT'
78
+ coercion_method = DBI::Type::Integer
79
+ when 'TYPE_FLOAT'
80
+ mysql_type_name = 'FLOAT'
81
+ coercion_method = DBI::Type::Float
82
+ when 'TYPE_DOUBLE'
83
+ mysql_type_name = 'DOUBLE'
84
+ coercion_method = DBI::Type::Float
85
+ when 'TYPE_VAR_STRING', 'TYPE_STRING'
86
+ mysql_type_name = 'VARCHAR' # questionable?
87
+ coercion_method = DBI::Type::Varchar
88
+ when 'TYPE_DATE'
89
+ mysql_type_name = 'DATE'
90
+ coercion_method = DBI::DBD::Mysql::Type::Date
91
+ when 'TYPE_TIME'
92
+ mysql_type_name = 'TIME'
93
+ coercion_method = DBI::Type::Timestamp
94
+ when 'TYPE_DATETIME', 'TYPE_TIMESTAMP'
95
+ mysql_type_name = 'DATETIME'
96
+ coercion_method = DBI::Type::Timestamp
97
+ when 'TYPE_CHAR'
98
+ mysql_type_name = 'TINYINT' # questionable?
99
+ when 'TYPE_TINY_BLOB'
100
+ mysql_type_name = 'TINYBLOB' # questionable?
101
+ when 'TYPE_MEDIUM_BLOB'
102
+ mysql_type_name = 'MEDIUMBLOB' # questionable?
103
+ when 'TYPE_LONG_BLOB'
104
+ mysql_type_name = 'LONGBLOB' # questionable?
105
+ when 'TYPE_GEOMETRY'
106
+ mysql_type_name = 'BLOB' # questionable?
107
+ when 'TYPE_YEAR',
108
+ 'TYPE_DECIMAL', # questionable?
109
+ 'TYPE_BLOB', # questionable?
110
+ 'TYPE_ENUM',
111
+ 'TYPE_SET',
112
+ 'TYPE_BIT',
113
+ 'TYPE_NULL'
114
+ mysql_type_name = const.to_s.sub(/^TYPE_/, '')
115
+ else
116
+ mysql_type_name = 'UNKNOWN'
117
+ end
118
+ TYPE_MAP[mysql_type] = [mysql_type_name, coercion_method]
119
+ end
120
+ TYPE_MAP[nil] = ['UNKNOWN', DBI::Type::Varchar]
121
+ TYPE_MAP[246] = ['NUMERIC', DBI::Type::Decimal]
122
+
123
+ #
124
+ # Constructor. Attributes supported:
125
+ #
126
+ # * AutoCommit: Commit after each executed statement. This will raise
127
+ # a DBI::NotSupportedError if the backend does not support
128
+ # transactions.
129
+ #
130
+ def initialize(handle, attr)
131
+ super
132
+ # check server version to determine transaction capability
133
+ ver_str = @handle.get_server_info
134
+ major, minor, teeny = ver_str.split(".")
135
+ teeny.sub!(/\D*$/, "") # strip any non-numeric suffix if present
136
+ server_version = major.to_i*10000 + minor.to_i*100 + teeny.to_i
137
+ # It's not until 3.23.17 that SET AUTOCOMMIT,
138
+ # BEGIN, COMMIT, and ROLLBACK all are available
139
+ @have_transactions = (server_version >= 32317)
140
+ # assume that the connection begins in AutoCommit mode
141
+ @attr['AutoCommit'] = true
142
+ @mutex = Mutex.new
143
+ end
144
+
145
+ def disconnect
146
+ self.rollback unless @attr['AutoCommit']
147
+ @handle.close
148
+ rescue MyError => err
149
+ error(err)
150
+ end
151
+
152
+ def database_name
153
+ sth = Statement.new(self, @handle, "select DATABASE()", @mutex)
154
+ sth.execute
155
+ res = sth.fetch
156
+ sth.finish
157
+ return res[0]
158
+ end
159
+
160
+ def ping
161
+ begin
162
+ @handle.ping
163
+ return true
164
+ rescue MyError
165
+ return false
166
+ end
167
+ end
168
+
169
+ def tables
170
+ @handle.list_tables
171
+ rescue MyError => err
172
+ error(err)
173
+ end
174
+
175
+ #
176
+ # See DBI::BaseDatabase#columns.
177
+ #
178
+ # Extra attributes:
179
+ #
180
+ # * sql_type: XOPEN integer constant relating to type.
181
+ # * nullable: true if the column allows NULL as a value.
182
+ # * indexed: true if the column belongs to an index.
183
+ # * primary: true if the column is a part of a primary key.
184
+ # * unique: true if the values in this column are unique.
185
+ # * default: the default value if this column is not explicitly set.
186
+ #
187
+ def columns(table)
188
+ dbh = DBI::DatabaseHandle.new(self)
189
+ uniques = []
190
+ dbh.execute("SHOW INDEX FROM #{table}") do |sth|
191
+ sth.each do |row|
192
+ uniques << row[4] if row[1] == 0
193
+ end
194
+ end
195
+
196
+ ret = nil
197
+ dbh.execute("SHOW FIELDS FROM #{table}") do |sth|
198
+ ret = sth.collect do |row|
199
+ name, type, nullable, key, default, extra = row
200
+ #type = row[1]
201
+ #size = type[type.index('(')+1..type.index(')')-1]
202
+ #size = 0
203
+ #type = type[0..type.index('(')-1]
204
+
205
+ sqltype, type, size, decimal = mysql_type_info(row[1])
206
+ col = Hash.new
207
+ col['name'] = name
208
+ col['sql_type'] = sqltype
209
+ col['type_name'] = type
210
+ col['nullable'] = nullable == "YES"
211
+ col['indexed'] = key != ""
212
+ col['primary'] = key == "PRI"
213
+ col['unique'] = uniques.index(name) != nil
214
+ col['precision'] = size
215
+ col['scale'] = decimal
216
+ col['default'] = row[4]
217
+
218
+ case col['type_name']
219
+ when 'timestamp'
220
+ col['dbi_type'] = DBI::Type::Timestamp
221
+ end
222
+
223
+ col
224
+ end # collect
225
+ end # execute
226
+
227
+ ret
228
+ end
229
+
230
+ def do(stmt, *bindvars)
231
+ st = Statement.new(self, @handle, stmt, @mutex)
232
+ st.bind_params(*bindvars)
233
+ res = st.execute
234
+ st.finish
235
+ return res
236
+ rescue MyError => err
237
+ error(err)
238
+ end
239
+
240
+
241
+ def prepare(statement)
242
+ Statement.new(self, @handle, statement, @mutex)
243
+ end
244
+
245
+ #
246
+ # MySQL has several backends, some of which may not support commits.
247
+ # If the backend this database uses doesn't, calling this method will
248
+ # raise a DBI::NotSupportedError.
249
+ #
250
+ def commit
251
+ if @have_transactions
252
+ self.do("COMMIT")
253
+ else
254
+ raise NotSupportedError
255
+ end
256
+ rescue MyError => err
257
+ error(err)
258
+ end
259
+
260
+ #
261
+ # See #commit for information regarding transactionless database
262
+ # backends.
263
+ #
264
+ def rollback
265
+ if @have_transactions
266
+ self.do("ROLLBACK")
267
+ else
268
+ raise NotSupportedError
269
+ end
270
+ rescue MyError => err
271
+ error(err)
272
+ end
273
+
274
+
275
+ # def quote(value)
276
+ # case value
277
+ # when String
278
+ # "'#{@handle.quote(value)}'"
279
+ # when DBI::Binary
280
+ # "'#{@handle.quote(value.to_s)}'"
281
+ # when TrueClass
282
+ # "'1'"
283
+ # when FalseClass
284
+ # "'0'"
285
+ # else
286
+ # super
287
+ # end
288
+ # end
289
+
290
+ #
291
+ # See DBI::DBD::MySQL::Database.new for supported attributes and usage.
292
+ #
293
+ def []=(attr, value)
294
+ case attr
295
+ when 'AutoCommit'
296
+ if @have_transactions
297
+ self.do("SET AUTOCOMMIT=" + (value ? "1" : "0"))
298
+ else
299
+ raise NotSupportedError
300
+ end
301
+ else
302
+ raise NotSupportedError
303
+ end
304
+
305
+ @attr[attr] = value
306
+ end
307
+
308
+ private # -------------------------------------------------
309
+
310
+ #
311
+ # Given a type name, weans some basic information from that and returns
312
+ # it in a format similar to columns.
313
+ #
314
+ # Return is an array of +sqltype+, +type+, +size+, and +decimal+.
315
+ # +sqltype+ is the XOPEN type, and +type+ is the string with the
316
+ # parameters removed.
317
+ #
318
+ # +size+ and +decimal+ refer to +precision+ and +scale+ in most cases,
319
+ # but not always for all types. Please consult the documentation for
320
+ # your MySQL version.
321
+ #
322
+ #
323
+ def mysql_type_info(typedef)
324
+ sqltype, type, size, decimal = nil, nil, nil, nil
325
+
326
+ pos = typedef.index('(')
327
+ if not pos.nil?
328
+ type = typedef[0..pos-1]
329
+ size = typedef[pos+1..-2]
330
+ pos = size.index(',')
331
+ if not pos.nil?
332
+ size, decimal = size.split(',', 2)
333
+ decimal = decimal.to_i
334
+ end
335
+ size = size.to_i
336
+ else
337
+ type = typedef
338
+ end
339
+
340
+ type_info = MYSQL_to_XOPEN[type.upcase] || MYSQL_to_XOPEN[nil]
341
+ sqltype = type_info[0]
342
+ if size.nil? then size = type_info[1] end
343
+ if decimal.nil? then decimal = type_info[2] end
344
+ return sqltype, type, size, decimal
345
+ end
346
+
347
+ #--
348
+ # Driver-specific functions ------------------------------------------------
349
+ #++
350
+
351
+ public
352
+
353
+ def __createdb(db)
354
+ @handle.create_db(db)
355
+ end
356
+
357
+ def __dropdb(db)
358
+ @handle.drop_db(db)
359
+ end
360
+
361
+ def __shutdown
362
+ @handle.shutdown
363
+ end
364
+
365
+ def __reload
366
+ @handle.reload
367
+ end
368
+
369
+ def __insert_id
370
+ @handle.insert_id
371
+ end
372
+
373
+ def __thread_id
374
+ @handle.thread_id
375
+ end
376
+
377
+ def __info
378
+ @handle.info
379
+ end
380
+
381
+ def __host_info
382
+ @handle.host_info
383
+ end
384
+
385
+ def __proto_info
386
+ @handle.proto_info
387
+ end
388
+
389
+ def __server_info
390
+ @handle.server_info
391
+ end
392
+
393
+ def __client_info
394
+ @handle.client_info
395
+ end
396
+
397
+ def __client_version
398
+ @handle.client_version
399
+ end
400
+
401
+ def __stat
402
+ @handle.stat
403
+ end
404
+ end # class Database
405
+ end
@@ -0,0 +1,125 @@
1
+ module DBI::DBD::Mysql
2
+ #
3
+ # Models the DBI::BaseDriver API to create DBI::DriverHandle objects.
4
+ #
5
+ class Driver < DBI::BaseDriver
6
+ include Util
7
+
8
+ def initialize
9
+ super("0.4.0")
10
+ end
11
+
12
+ def default_user
13
+ ['', nil]
14
+ end
15
+
16
+ #
17
+ # Parameters in the dbname as follows:
18
+ #
19
+ # * host: host to connect to
20
+ # * port: port to connect to
21
+ # * socket: connect to a specific unix socket instead of a TCP socket.
22
+ # * flag: an OR'd collection of flags to pass to the lower-level
23
+ # connection attempt.
24
+ # * mysql_read_default_file: FIXME
25
+ # * mysql_read_default_group: FIXME
26
+ # * mysql_compression: FIXME
27
+ # * mysql_local_infile: FIXME
28
+ # * mysql_client_found_rows: FIXME boolean, modifies the 'flag'
29
+ # setting above.
30
+ def connect(dbname, user, auth, attr)
31
+ # connect to database server
32
+ hash = DBI::Utils.parse_params(dbname)
33
+
34
+ hash['host'] ||= 'localhost'
35
+
36
+ # these two connection parameters should be passed as numbers
37
+ hash['port'] = hash['port'].to_i unless hash['port'].nil?
38
+ hash['flag'] = hash['flag'].nil? ? 0 : hash['flag'] = hash['flag'].to_i
39
+
40
+ handle = ::Mysql.init
41
+
42
+ # Look for options in connect string to be handled
43
+ # through mysql_options() before connecting
44
+ !hash['mysql_read_default_file'].nil? and
45
+ handle.options(::Mysql::READ_DEFAULT_FILE,
46
+ hash['mysql_read_default_file'])
47
+ !hash['mysql_read_default_group'].nil? and
48
+ handle.options(::Mysql::READ_DEFAULT_GROUP,
49
+ hash['mysql_read_default_group'])
50
+ # The following options can be handled either using mysql_options()
51
+ # or in the flag argument to connect().
52
+ hash['mysql_compression'].to_i != 0 and
53
+ handle.options(::Mysql::OPT_COMPRESS, nil)
54
+ hash['mysql_local_infile'].to_i != 0 and
55
+ handle.options(::Mysql::OPT_LOCAL_INFILE, true)
56
+
57
+ # Look for options to be handled in the flags argument to connect()
58
+ if !hash['mysql_client_found_rows'].nil?
59
+ if hash['mysql_client_found_rows'].to_i != 0
60
+ hash['flag'] |= ::Mysql::CLIENT_FOUND_ROWS
61
+ else
62
+ hash['flag'] &= ~::Mysql::CLIENT_FOUND_ROWS
63
+ end
64
+ end
65
+
66
+ handle.connect(hash['host'], user, auth, hash['database'], hash['port'], hash['socket'], hash['flag'])
67
+
68
+ return Database.new(handle, attr)
69
+ rescue MyError => err
70
+ error(err)
71
+ end
72
+
73
+ def data_sources
74
+ handle = ::Mysql.new
75
+ res = handle.list_dbs.collect {|db| "dbi:Mysql:database=#{db}" }
76
+ handle.close
77
+ return res
78
+ rescue MyError => err
79
+ error(err)
80
+ end
81
+
82
+ #--
83
+ # Driver-specific functions ------------------------------------------------
84
+ #++
85
+
86
+ public
87
+
88
+ def __createdb(db, host, user, password, port=nil, sock=nil, flag=nil)
89
+ handle = ::Mysql.connect(host, user, password, nil, port, sock, flag)
90
+ begin
91
+ handle.create_db(db)
92
+ ensure
93
+ handle.close if handle
94
+ end
95
+ end
96
+
97
+ def __dropdb(db, host, user, password, port=nil, sock=nil, flag=nil)
98
+ handle = ::Mysql.connect(host, user, password, nil, port, sock, flag)
99
+ begin
100
+ handle.drop_db(db)
101
+ ensure
102
+ handle.close if handle
103
+ end
104
+ end
105
+
106
+ def __shutdown(host, user, password, port=nil, sock=nil, flag=nil)
107
+ handle = ::Mysql.connect(host, user, password, nil, port, sock, flag)
108
+ begin
109
+ handle.shutdown
110
+ ensure
111
+ handle.close if handle
112
+ end
113
+ end
114
+
115
+ def __reload(host, user, password, port=nil, sock=nil, flag=nil)
116
+ handle = ::Mysql.connect(host, user, password, nil, port, sock, flag)
117
+ begin
118
+ handle.reload
119
+ ensure
120
+ handle.close if handle
121
+ end
122
+ end
123
+
124
+ end # class Driver
125
+ end