/usr/lib/tcltk/tdbcmysql1.0.3/tdbcmysql.tcl is in tcl8.6-tdbc-mysql 1.0.3-1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 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.
}
|