Class: DBI::DBD::Mysql::Database

Inherits:
BaseDatabase show all
Includes:
Util
Defined in:
lib/dbd/mysql/database.rb

Overview

Models the DBI::BaseDatabase API to create DBI::DatabaseHandle objects.

Constant Summary collapse

MYSQL_to_XOPEN =

Hash to translate MySQL type names to DBI SQL type constants

Only used in #mysql_type_info.

– Eli Green:

The hope is that we don't ever need to just assume the default values.
However, in some cases (notably floats and doubles), I have seen
"show fields from table" return absolutely zero information about size
and precision. Sigh. I probably should have made a struct to store
this info in ... but I didn't.

++

{
            "TINYINT"    => [DBI::SQL_TINYINT, 1, nil],
            "SMALLINT"   => [DBI::SQL_SMALLINT, 6, nil],
            "MEDIUMINT"  => [DBI::SQL_SMALLINT, 6, nil],
            "INT"        => [DBI::SQL_INTEGER, 11, nil],
            "INTEGER"    => [DBI::SQL_INTEGER, 11, nil],
            "BIGINT"     => [DBI::SQL_BIGINT, 25, nil],
            "INT24"      => [DBI::SQL_BIGINT, 25, nil],
            "REAL"       => [DBI::SQL_REAL, 12, nil],
            "FLOAT"      => [DBI::SQL_FLOAT, 12, nil],
            "DECIMAL"    => [DBI::SQL_DECIMAL, 12, nil],
            "NUMERIC"    => [DBI::SQL_NUMERIC, 12, nil],
            "DOUBLE"     => [DBI::SQL_DOUBLE, 22, nil],
            "CHAR"       => [DBI::SQL_CHAR, 1, nil],
            "VARCHAR"    => [DBI::SQL_VARCHAR, 255, nil],
            "DATE"       => [DBI::SQL_DATE, 10, nil],
            "TIME"       => [DBI::SQL_TIME, 8, nil],
            "TIMESTAMP"  => [DBI::SQL_TIMESTAMP, 19, nil],
            "DATETIME"   => [DBI::SQL_TIMESTAMP, 19, nil],
            "TINYBLOB"   => [DBI::SQL_BINARY, 255, nil],
            "BLOB"       => [DBI::SQL_VARBINARY, 65535, nil],
            "MEDIUMBLOB" => [DBI::SQL_VARBINARY, 16277215, nil],
            "LONGBLOB"   => [DBI::SQL_LONGVARBINARY, 2147483657, nil],
            "TINYTEXT"   => [DBI::SQL_VARCHAR, 255, nil],
            "TEXT"       => [DBI::SQL_LONGVARCHAR, 65535, nil],
            "MEDIUMTEXT" => [DBI::SQL_LONGVARCHAR, 16277215, nil],
            "LONGTEXT"   => [DBI::SQL_LONGVARCHAR, 2147483657, nil],
            "ENUM"       => [DBI::SQL_CHAR, 255, nil],
            "SET"        => [DBI::SQL_CHAR, 255, nil],
            "BIT"        => [DBI::SQL_BIT, 8, nil],
            nil          => [DBI::SQL_OTHER, nil, nil]
}
TYPE_MAP =

This maps type names to DBI Types.

{}

Instance Method Summary collapse

Methods inherited from BaseDatabase

#[], #execute

Constructor Details

#initialize(handle, attr) ⇒ Database

Constructor. Attributes supported:

  • AutoCommit: Commit after each executed statement. This will raise a DBI::NotSupportedError if the backend does not support transactions.



130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/dbd/mysql/database.rb', line 130

def initialize(handle, attr)
    super
    # check server version to determine transaction capability
    ver_str = @handle.get_server_info
    major, minor, teeny = ver_str.split(".")
    teeny.sub!(/\D*$/, "")  # strip any non-numeric suffix if present
    server_version = major.to_i*10000 + minor.to_i*100 + teeny.to_i
    # It's not until 3.23.17 that SET AUTOCOMMIT,
    # BEGIN, COMMIT, and ROLLBACK all are available
    @have_transactions = (server_version >= 32317)
    # assume that the connection begins in AutoCommit mode
    @attr['AutoCommit'] = true
    @mutex = Mutex.new
end

Instance Method Details

#[]=(attr, value) ⇒ Object

See DBI::DBD::MySQL::Database.new for supported attributes and usage.



293
294
295
296
297
298
299
300
301
302
303
304
305
306
# File 'lib/dbd/mysql/database.rb', line 293

def []=(attr, value)
    case attr
    when 'AutoCommit'
        if @have_transactions
            self.do("SET AUTOCOMMIT=" + (value ? "1" : "0"))
        else
            raise NotSupportedError
        end
    else
        raise NotSupportedError
    end

    @attr[attr] = value
end

#__client_infoObject



393
394
395
# File 'lib/dbd/mysql/database.rb', line 393

def __client_info
    @handle.client_info
end

#__client_versionObject



397
398
399
# File 'lib/dbd/mysql/database.rb', line 397

def __client_version
    @handle.client_version
end

#__createdb(db) ⇒ Object



353
354
355
# File 'lib/dbd/mysql/database.rb', line 353

def __createdb(db)
    @handle.create_db(db)
end

#__dropdb(db) ⇒ Object



357
358
359
# File 'lib/dbd/mysql/database.rb', line 357

def __dropdb(db)
    @handle.drop_db(db)
end

#__host_infoObject



381
382
383
# File 'lib/dbd/mysql/database.rb', line 381

def __host_info
    @handle.host_info
end

#__infoObject



377
378
379
# File 'lib/dbd/mysql/database.rb', line 377

def __info
    @handle.info
end

#__insert_idObject



369
370
371
# File 'lib/dbd/mysql/database.rb', line 369

def __insert_id
    @handle.insert_id
end

#__proto_infoObject



385
386
387
# File 'lib/dbd/mysql/database.rb', line 385

def __proto_info
    @handle.proto_info
end

#__reloadObject



365
366
367
# File 'lib/dbd/mysql/database.rb', line 365

def __reload
    @handle.reload
end

#__server_infoObject



389
390
391
# File 'lib/dbd/mysql/database.rb', line 389

def __server_info
    @handle.server_info
end

#__shutdownObject



361
362
363
# File 'lib/dbd/mysql/database.rb', line 361

def __shutdown
    @handle.shutdown
end

#__statObject



401
402
403
# File 'lib/dbd/mysql/database.rb', line 401

def __stat
    @handle.stat
end

#__thread_idObject



373
374
375
# File 'lib/dbd/mysql/database.rb', line 373

def __thread_id
    @handle.thread_id
end

#columns(table) ⇒ Object

See DBI::BaseDatabase#columns.

Extra attributes:

  • sql_type: XOPEN integer constant relating to type.

  • nullable: true if the column allows NULL as a value.

  • indexed: true if the column belongs to an index.

  • primary: true if the column is a part of a primary key.

  • unique: true if the values in this column are unique.

  • default: the default value if this column is not explicitly set.



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/dbd/mysql/database.rb', line 187

def columns(table)
    dbh = DBI::DatabaseHandle.new(self)
    uniques = []
    dbh.execute("SHOW INDEX FROM #{table}") do |sth|
        sth.each do |row|
            uniques << row[4] if row[1] == 0
        end
    end

    ret = nil
    dbh.execute("SHOW FIELDS FROM #{table}") do |sth|
        ret = sth.collect do |row|
            name, type, nullable, key, default, extra = row
            #type = row[1]
            #size = type[type.index('(')+1..type.index(')')-1]
            #size = 0
            #type = type[0..type.index('(')-1]

            sqltype, type, size, decimal = mysql_type_info(row[1])
            col = Hash.new
            col['name']           = name
            col['sql_type']       = sqltype
            col['type_name']      = type
            col['nullable']       = nullable == "YES"
            col['indexed']        = key != ""
            col['primary']        = key == "PRI"
            col['unique']         = uniques.index(name) != nil
            col['precision']      = size
            col['scale']          = decimal
            col['default']        = row[4]

            case col['type_name']
            when 'timestamp'
                col['dbi_type'] = DBI::Type::Timestamp
            end

            col
        end # collect
    end # execute

    ret
end

#commitObject

MySQL has several backends, some of which may not support commits. If the backend this database uses doesn’t, calling this method will raise a DBI::NotSupportedError.



250
251
252
253
254
255
256
257
258
# File 'lib/dbd/mysql/database.rb', line 250

def commit
    if @have_transactions
        self.do("COMMIT")
    else
        raise NotSupportedError
    end
rescue MyError => err
    error(err)
end

#database_nameObject



152
153
154
155
156
157
158
# File 'lib/dbd/mysql/database.rb', line 152

def database_name
    sth = Statement.new(self, @handle, "select DATABASE()", @mutex)
    sth.execute
    res = sth.fetch
    sth.finish
    return res[0]
end

#disconnectObject



145
146
147
148
149
150
# File 'lib/dbd/mysql/database.rb', line 145

def disconnect
    self.rollback unless @attr['AutoCommit']
    @handle.close
rescue MyError => err
    error(err)
end

#do(stmt, *bindvars) ⇒ Object



230
231
232
233
234
235
236
237
238
# File 'lib/dbd/mysql/database.rb', line 230

def do(stmt, *bindvars)
    st = Statement.new(self, @handle, stmt, @mutex)
    st.bind_params(*bindvars)
    res = st.execute
    st.finish
    return res
rescue MyError => err
    error(err)
end

#pingObject



160
161
162
163
164
165
166
167
# File 'lib/dbd/mysql/database.rb', line 160

def ping
    begin
        @handle.ping
        return true
    rescue MyError
        return false
    end
end

#prepare(statement) ⇒ Object



241
242
243
# File 'lib/dbd/mysql/database.rb', line 241

def prepare(statement)
    Statement.new(self, @handle, statement, @mutex)
end

#rollbackObject

See #commit for information regarding transactionless database backends.



264
265
266
267
268
269
270
271
272
# File 'lib/dbd/mysql/database.rb', line 264

def rollback
    if @have_transactions
        self.do("ROLLBACK")
    else
        raise NotSupportedError
    end
rescue MyError => err
    error(err)
end

#tablesObject



169
170
171
172
173
# File 'lib/dbd/mysql/database.rb', line 169

def tables
    @handle.list_tables
rescue MyError => err
    error(err)
end