diff options
Diffstat (limited to 'Master/tlpkg/tltcl/lib/tdbcmysql1.1.2/tdbcmysql.tcl')
-rw-r--r-- | Master/tlpkg/tltcl/lib/tdbcmysql1.1.2/tdbcmysql.tcl | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/Master/tlpkg/tltcl/lib/tdbcmysql1.1.2/tdbcmysql.tcl b/Master/tlpkg/tltcl/lib/tdbcmysql1.1.2/tdbcmysql.tcl new file mode 100644 index 00000000000..caa334c470d --- /dev/null +++ b/Master/tlpkg/tltcl/lib/tdbcmysql1.1.2/tdbcmysql.tcl @@ -0,0 +1,193 @@ +# tdbcmysql.tcl -- +# +# Class definitions and Tcl-level methods for the tdbc::mysql bridge. +# +# Copyright (c) 2008 by Kevin B. Kenny +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# RCS: @(#) $Id: tdbcmysql.tcl,v 1.47 2008/02/27 02:08:27 kennykb Exp $ +# +#------------------------------------------------------------------------------ + +package require tdbc + +::namespace eval ::tdbc::mysql { + + namespace export connection datasources drivers + +} + +#------------------------------------------------------------------------------ +# +# tdbc::mysql::connection -- +# +# Class representing a connection to a database through MYSQL. +# +#------------------------------------------------------------------------------- + +::oo::class create ::tdbc::mysql::connection { + + superclass ::tdbc::connection + + # The constructor is written in C. It takes alternating keywords + # and values pairs as its argumenta. (See the manual page for the + # available options.) + + variable foreignKeysStatement + + # The 'statementCreate' method delegates to the constructor of the + # statement class + + forward statementCreate ::tdbc::mysql::statement create + + # The 'columns' method returns a dictionary describing the tables + # in the database + + method columns {table {pattern %}} { + + # To return correct lengths of CHARACTER and BINARY columns, + # we need to know the maximum lengths of characters in each + # collation. We cache this information only once, on the first + # call to 'columns'. + + if {[my NeedCollationInfo]} { + my SetCollationInfo {*}[my allrows -as lists { + SELECT coll.id, cs.maxlen + FROM INFORMATION_SCHEMA.COLLATIONS coll, + INFORMATION_SCHEMA.CHARACTER_SETS cs + WHERE cs.CHARACTER_SET_NAME = coll.CHARACTER_SET_NAME + ORDER BY coll.id DESC + }] + } + + return [my Columns $table $pattern] + } + + # The 'preparecall' method gives a portable interface to prepare + # calls to stored procedures. It delegates to 'prepare' to do the + # actual work. + + method preparecall {call} { + regexp {^[[:space:]]*(?:([A-Za-z_][A-Za-z_0-9]*)[[:space:]]*=)?(.*)} \ + $call -> varName rest + if {$varName eq {}} { + my prepare "CALL $rest" + } else { + my prepare \\{:$varName=$rest\\} + } + } + + # The 'init', 'begintransaction', 'commit, 'rollback', 'tables' + # 'NeedCollationInfo', 'SetCollationInfo', and 'Columns' methods + # are implemented in C. + + # The 'BuildForeignKeysStatements' method builds a SQL statement to + # retrieve the foreign keys from a database. (It executes once the + # first time the 'foreignKeys' method is executed, and retains the + # prepared statements for reuse.) It is slightly nonstandard because + # MYSQL doesn't name the PRIMARY constraints uniquely. + + method BuildForeignKeysStatement {} { + + foreach {exists1 clause1} { + 0 {} + 1 { AND fkc.REFERENCED_TABLE_NAME = :primary} + } { + foreach {exists2 clause2} { + 0 {} + 1 { AND fkc.TABLE_NAME = :foreign} + } { + set stmt [my prepare " + SELECT rc.CONSTRAINT_SCHEMA AS \"foreignConstraintSchema\", + rc.CONSTRAINT_NAME AS \"foreignConstraintName\", + rc.UPDATE_RULE AS \"updateAction\", + rc.DELETE_RULE AS \"deleteAction\", + fkc.REFERENCED_TABLE_SCHEMA AS \"primarySchema\", + fkc.REFERENCED_TABLE_NAME AS \"primaryTable\", + fkc.REFERENCED_COLUMN_NAME AS \"primaryColumn\", + fkc.TABLE_SCHEMA AS \"foreignSchema\", + fkc.TABLE_NAME AS \"foreignTable\", + fkc.COLUMN_NAME AS \"foreignColumn\", + fkc.ORDINAL_POSITION AS \"ordinalPosition\" + FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc + INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE fkc + ON fkc.CONSTRAINT_NAME = rc.CONSTRAINT_NAME + AND fkc.CONSTRAINT_SCHEMA = rc.CONSTRAINT_SCHEMA + WHERE 1=1 + $clause1 + $clause2 +"] + dict set foreignKeysStatement $exists1 $exists2 $stmt + } + } + } +} + +#------------------------------------------------------------------------------ +# +# tdbc::mysql::statement -- +# +# The class 'tdbc::mysql::statement' models one statement against a +# database accessed through an MYSQL connection +# +#------------------------------------------------------------------------------ + +::oo::class create ::tdbc::mysql::statement { + + superclass ::tdbc::statement + + # The 'resultSetCreate' method forwards to the constructor of the + # result set. + + forward resultSetCreate ::tdbc::mysql::resultset create + + # Methods implemented in C: + # + # constructor connection SQLCode + # The constructor accepts the handle to the connection and the SQL code + # for the statement to prepare. It creates a subordinate namespace to + # hold the statement's active result sets, and then delegates to the + # 'init' method, written in C, to do the actual work of preparing the + # statement. + # params + # Returns descriptions of the parameters of a statement. + # paramtype paramname ?direction? type ?precision ?scale?? + # Declares the type of a parameter in the statement + +} + +#------------------------------------------------------------------------------ +# +# tdbc::mysql::resultset -- +# +# The class 'tdbc::mysql::resultset' models the result set that is +# produced by executing a statement against an MYSQL database. +# +#------------------------------------------------------------------------------ + +::oo::class create ::tdbc::mysql::resultset { + + superclass ::tdbc::resultset + + # Methods implemented in C include: + + # constructor statement ?dictionary? + # -- Executes the statement against the database, optionally providing + # a dictionary of substituted parameters (default is to get params + # from variables in the caller's scope). + # columns + # -- Returns a list of the names of the columns in the result. + # nextdict + # -- Stores the next row of the result set in the given variable in + # the caller's scope as a dictionary whose keys are + # column names and whose values are column values, or else + # as a list of cells. + # nextlist + # -- Stores the next row of the result set in the given variable in + # the caller's scope as a list of cells. + # rowcount + # -- Returns a count of rows affected by the statement, or -1 + # if the count of rows has not been determined. + +} |