annotate CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/lib/tdbcmysql1.1.5/tdbcmysql.tcl @ 68:5028fdace37b

planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author jpayne
date Tue, 18 Mar 2025 16:23:26 -0400
parents
children
rev   line source
jpayne@68 1 # tdbcmysql.tcl --
jpayne@68 2 #
jpayne@68 3 # Class definitions and Tcl-level methods for the tdbc::mysql bridge.
jpayne@68 4 #
jpayne@68 5 # Copyright (c) 2008 by Kevin B. Kenny
jpayne@68 6 # See the file "license.terms" for information on usage and redistribution
jpayne@68 7 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
jpayne@68 8 #
jpayne@68 9 # RCS: @(#) $Id: tdbcmysql.tcl,v 1.47 2008/02/27 02:08:27 kennykb Exp $
jpayne@68 10 #
jpayne@68 11 #------------------------------------------------------------------------------
jpayne@68 12
jpayne@68 13 package require tdbc
jpayne@68 14
jpayne@68 15 ::namespace eval ::tdbc::mysql {
jpayne@68 16
jpayne@68 17 namespace export connection datasources drivers
jpayne@68 18
jpayne@68 19 }
jpayne@68 20
jpayne@68 21 #------------------------------------------------------------------------------
jpayne@68 22 #
jpayne@68 23 # tdbc::mysql::connection --
jpayne@68 24 #
jpayne@68 25 # Class representing a connection to a database through MYSQL.
jpayne@68 26 #
jpayne@68 27 #-------------------------------------------------------------------------------
jpayne@68 28
jpayne@68 29 ::oo::class create ::tdbc::mysql::connection {
jpayne@68 30
jpayne@68 31 superclass ::tdbc::connection
jpayne@68 32
jpayne@68 33 # The constructor is written in C. It takes alternating keywords
jpayne@68 34 # and values pairs as its argumenta. (See the manual page for the
jpayne@68 35 # available options.)
jpayne@68 36
jpayne@68 37 variable foreignKeysStatement
jpayne@68 38
jpayne@68 39 # The 'statementCreate' method delegates to the constructor of the
jpayne@68 40 # statement class
jpayne@68 41
jpayne@68 42 forward statementCreate ::tdbc::mysql::statement create
jpayne@68 43
jpayne@68 44 # The 'columns' method returns a dictionary describing the tables
jpayne@68 45 # in the database
jpayne@68 46
jpayne@68 47 method columns {table {pattern %}} {
jpayne@68 48
jpayne@68 49 # To return correct lengths of CHARACTER and BINARY columns,
jpayne@68 50 # we need to know the maximum lengths of characters in each
jpayne@68 51 # collation. We cache this information only once, on the first
jpayne@68 52 # call to 'columns'.
jpayne@68 53
jpayne@68 54 if {[my NeedCollationInfo]} {
jpayne@68 55 my SetCollationInfo {*}[my allrows -as lists {
jpayne@68 56 SELECT coll.id, cs.maxlen
jpayne@68 57 FROM INFORMATION_SCHEMA.COLLATIONS coll,
jpayne@68 58 INFORMATION_SCHEMA.CHARACTER_SETS cs
jpayne@68 59 WHERE cs.CHARACTER_SET_NAME = coll.CHARACTER_SET_NAME
jpayne@68 60 ORDER BY coll.id DESC
jpayne@68 61 }]
jpayne@68 62 }
jpayne@68 63
jpayne@68 64 return [my Columns $table $pattern]
jpayne@68 65 }
jpayne@68 66
jpayne@68 67 # The 'preparecall' method gives a portable interface to prepare
jpayne@68 68 # calls to stored procedures. It delegates to 'prepare' to do the
jpayne@68 69 # actual work.
jpayne@68 70
jpayne@68 71 method preparecall {call} {
jpayne@68 72 regexp {^[[:space:]]*(?:([A-Za-z_][A-Za-z_0-9]*)[[:space:]]*=)?(.*)} \
jpayne@68 73 $call -> varName rest
jpayne@68 74 if {$varName eq {}} {
jpayne@68 75 my prepare "CALL $rest"
jpayne@68 76 } else {
jpayne@68 77 my prepare \\{:$varName=$rest\\}
jpayne@68 78 }
jpayne@68 79 }
jpayne@68 80
jpayne@68 81 # The 'init', 'begintransaction', 'commit, 'rollback', 'tables'
jpayne@68 82 # 'NeedCollationInfo', 'SetCollationInfo', and 'Columns' methods
jpayne@68 83 # are implemented in C.
jpayne@68 84
jpayne@68 85 # The 'BuildForeignKeysStatements' method builds a SQL statement to
jpayne@68 86 # retrieve the foreign keys from a database. (It executes once the
jpayne@68 87 # first time the 'foreignKeys' method is executed, and retains the
jpayne@68 88 # prepared statements for reuse.) It is slightly nonstandard because
jpayne@68 89 # MYSQL doesn't name the PRIMARY constraints uniquely.
jpayne@68 90
jpayne@68 91 method BuildForeignKeysStatement {} {
jpayne@68 92
jpayne@68 93 foreach {exists1 clause1} {
jpayne@68 94 0 {}
jpayne@68 95 1 { AND fkc.REFERENCED_TABLE_NAME = :primary}
jpayne@68 96 } {
jpayne@68 97 foreach {exists2 clause2} {
jpayne@68 98 0 {}
jpayne@68 99 1 { AND fkc.TABLE_NAME = :foreign}
jpayne@68 100 } {
jpayne@68 101 set stmt [my prepare "
jpayne@68 102 SELECT rc.CONSTRAINT_SCHEMA AS \"foreignConstraintSchema\",
jpayne@68 103 rc.CONSTRAINT_NAME AS \"foreignConstraintName\",
jpayne@68 104 rc.UPDATE_RULE AS \"updateAction\",
jpayne@68 105 rc.DELETE_RULE AS \"deleteAction\",
jpayne@68 106 fkc.REFERENCED_TABLE_SCHEMA AS \"primarySchema\",
jpayne@68 107 fkc.REFERENCED_TABLE_NAME AS \"primaryTable\",
jpayne@68 108 fkc.REFERENCED_COLUMN_NAME AS \"primaryColumn\",
jpayne@68 109 fkc.TABLE_SCHEMA AS \"foreignSchema\",
jpayne@68 110 fkc.TABLE_NAME AS \"foreignTable\",
jpayne@68 111 fkc.COLUMN_NAME AS \"foreignColumn\",
jpayne@68 112 fkc.ORDINAL_POSITION AS \"ordinalPosition\"
jpayne@68 113 FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
jpayne@68 114 INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE fkc
jpayne@68 115 ON fkc.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
jpayne@68 116 AND fkc.CONSTRAINT_SCHEMA = rc.CONSTRAINT_SCHEMA
jpayne@68 117 WHERE 1=1
jpayne@68 118 $clause1
jpayne@68 119 $clause2
jpayne@68 120 "]
jpayne@68 121 dict set foreignKeysStatement $exists1 $exists2 $stmt
jpayne@68 122 }
jpayne@68 123 }
jpayne@68 124 }
jpayne@68 125 }
jpayne@68 126
jpayne@68 127 #------------------------------------------------------------------------------
jpayne@68 128 #
jpayne@68 129 # tdbc::mysql::statement --
jpayne@68 130 #
jpayne@68 131 # The class 'tdbc::mysql::statement' models one statement against a
jpayne@68 132 # database accessed through an MYSQL connection
jpayne@68 133 #
jpayne@68 134 #------------------------------------------------------------------------------
jpayne@68 135
jpayne@68 136 ::oo::class create ::tdbc::mysql::statement {
jpayne@68 137
jpayne@68 138 superclass ::tdbc::statement
jpayne@68 139
jpayne@68 140 # The 'resultSetCreate' method forwards to the constructor of the
jpayne@68 141 # result set.
jpayne@68 142
jpayne@68 143 forward resultSetCreate ::tdbc::mysql::resultset create
jpayne@68 144
jpayne@68 145 # Methods implemented in C:
jpayne@68 146 #
jpayne@68 147 # constructor connection SQLCode
jpayne@68 148 # The constructor accepts the handle to the connection and the SQL code
jpayne@68 149 # for the statement to prepare. It creates a subordinate namespace to
jpayne@68 150 # hold the statement's active result sets, and then delegates to the
jpayne@68 151 # 'init' method, written in C, to do the actual work of preparing the
jpayne@68 152 # statement.
jpayne@68 153 # params
jpayne@68 154 # Returns descriptions of the parameters of a statement.
jpayne@68 155 # paramtype paramname ?direction? type ?precision ?scale??
jpayne@68 156 # Declares the type of a parameter in the statement
jpayne@68 157
jpayne@68 158 }
jpayne@68 159
jpayne@68 160 #------------------------------------------------------------------------------
jpayne@68 161 #
jpayne@68 162 # tdbc::mysql::resultset --
jpayne@68 163 #
jpayne@68 164 # The class 'tdbc::mysql::resultset' models the result set that is
jpayne@68 165 # produced by executing a statement against an MYSQL database.
jpayne@68 166 #
jpayne@68 167 #------------------------------------------------------------------------------
jpayne@68 168
jpayne@68 169 ::oo::class create ::tdbc::mysql::resultset {
jpayne@68 170
jpayne@68 171 superclass ::tdbc::resultset
jpayne@68 172
jpayne@68 173 # Methods implemented in C include:
jpayne@68 174
jpayne@68 175 # constructor statement ?dictionary?
jpayne@68 176 # -- Executes the statement against the database, optionally providing
jpayne@68 177 # a dictionary of substituted parameters (default is to get params
jpayne@68 178 # from variables in the caller's scope).
jpayne@68 179 # columns
jpayne@68 180 # -- Returns a list of the names of the columns in the result.
jpayne@68 181 # nextdict
jpayne@68 182 # -- Stores the next row of the result set in the given variable in
jpayne@68 183 # the caller's scope as a dictionary whose keys are
jpayne@68 184 # column names and whose values are column values, or else
jpayne@68 185 # as a list of cells.
jpayne@68 186 # nextlist
jpayne@68 187 # -- Stores the next row of the result set in the given variable in
jpayne@68 188 # the caller's scope as a list of cells.
jpayne@68 189 # rowcount
jpayne@68 190 # -- Returns a count of rows affected by the statement, or -1
jpayne@68 191 # if the count of rows has not been determined.
jpayne@68 192
jpayne@68 193 }