This commit is contained in:
ton
2023-10-05 02:17:01 +07:00
parent 6b7a8a3482
commit fef77e218f
5452 changed files with 919218 additions and 7 deletions

View File

@@ -0,0 +1,14 @@
# Index file to load the TDBC MySQL package.
if {![package vsatisfies [package provide Tcl] 8.6-]} {
return
}
if {[package vsatisfies [package provide Tcl] 9.0-]} {
package ifneeded tdbc::mysql 1.1.5 \
"[list source [file join $dir tdbcmysql.tcl]]\;\
[list load [file join $dir tcl9tdbcmysql115t.dll] [string totitle tdbcmysql]]"
} else {
package ifneeded tdbc::mysql 1.1.5 \
"[list source [file join $dir tdbcmysql.tcl]]\;\
[list load [file join $dir tdbcmysql115t.dll] [string totitle tdbcmysql]]"
}

View File

@@ -0,0 +1,175 @@
'\"
.\" tdbc_mysql.n --
.\"
.\" 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.
.TH "tdbc::mysql" n 8.6 Tcl "Tcl Database Connectivity"
.\" .so man.macros
.if t .wh -1.3i ^B
.nr ^l \n(.l
.ad b
.\" # BS - start boxed text
.\" # ^y = starting y location
.\" # ^b = 1
.de BS
.br
.mk ^y
.nr ^b 1u
.if n .nf
.if n .ti 0
.if n \l'\\n(.lu\(ul'
.if n .fi
..
.\" # BE - end boxed text (draw box now)
.de BE
.nf
.ti 0
.mk ^t
.ie n \l'\\n(^lu\(ul'
.el \{\
.\" Draw four-sided box normally, but don't draw top of
.\" box if the box started on an earlier page.
.ie !\\n(^b-1 \{\
\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.el \}\
\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.\}
.fi
.br
.nr ^b 0
..
.\" # CS - begin code excerpt
.de CS
.RS
.nf
.ta .25i .5i .75i 1i
..
.\" # CE - end code excerpt
.de CE
.fi
.RE
..
.BS
.SH "NAME"
tdbc::mysql \- TDBC-MYSQL bridge
.SH "SYNOPSIS"
package require \fBtdbc::mysql 1.0\fR
.sp
\fBtdbc::mysql::connection create\fR \fIdb\fR ?\fI-option value...\fR?
.br
\fBtdbc::mysql::connection new\fR ?\fI-option value...\fR?
.sp
\fBtdbc::mysql::datasources\fR ?\fB-system\fR|\fB-user\fR?
.sp
\fBtdbc::mysql::drivers\fR
.sp
\fBtdbc::mysql::datasource\fR \fIcommand\fR \fIdriverName\fR ?\fIkeyword\fR-\fIvalue\fR?...
.BE
.SH "DESCRIPTION"
.PP
The \fBtdbc::mysql\fR driver provides a database interface that conforms
to Tcl DataBase Connectivity (TDBC) and allows a Tcl script to connect
to a MySQL database.
.PP
Connection to an MYSQL database is established by invoking
\fBtdbc::mysql::connection create\fR, passing it the name to give the
database handle and a set of \fI-option-value\fR pairs. The available
options are enumerated under CONNECTION OPTIONS below.
As an alternative, \fBtdbc::mysql::connection new\fR may be used to create
a database connection with an automatically assigned name. The return value
from \fBtdbc::mysql::connection new\fR is the name that was chosen for the
connection handle.
.PP
The side effect of \fBtdbc::mysql::connection create\fR is to create a
new database connection.. See \fBtdbc::connection(n)\fR for the
details of how to use the connection to manipulate a database.
.SH "CONNECTION OPTIONS"
.PP
The \fBtdbc::mysql::connection create\fR object command supports the
\fB-encoding\fR, \fB-isolation\fR, \fB-readonly\fR and \fB-timeout\fR
options common to all TDBC drivers. The \fB-encoding\fR option will
always fail unless the encoding is \fButf-8\fR; the database connection
always uses UTF-8 encoding to be able to transfer arbitrary Unicode
characters. The \fB-readonly\fR option must be \fB0\fR, because
MySQL does not offer read-only connections.
.PP
In addition, the following options are recognized:
.IP "\fB-host\fR \fIhostname\fR"
Connects to the host specified by \fIhostname\fR. This option must be
set on the initial creation of the connection; it cannot be changed
after connecting. Default is to connect to the local host.
.IP "\fB-port\fR \fInumber\fR"
Connects to a MySQL server listening on the port specified by \fInumber\fR.
This option may not be changed after connecting. It is used only when
\fIhost\fR is specified and is not \fBlocalhost\fR.
.IP "\fB-socket\fR \fIpath\fR"
Connects to a MySQL server listening on the Unix socket or named
pipe specified by \fIpath\fR . This option may not be changed after connecting.
It is used only when \fI-host\fR is not specified or is \fBlocalhost\fR.
.IP "\fB-user\fR \fIname\fR"
Presents \fIname\fR as the user name to the MySQL server. Default is the
current user ID.
.IP "\fB-passwd\fR \fIpassword\fR"
.IP "\fB-password\fR \fIpassword\fR"
These two options are synonymous. They present the given \fIpassword\fR as
the user's password to the MySQL server. Default is not to present a password.
.IP "\fB-database\fR \fIname\fR"
.IP "\fB-db\fR \fIname\fR"
These two options are synonymous. They present the given \fIname\fR as the
name of the default database to use in MySQL queries. If not specified,
the default database for the current user is used.
.IP "\fB-interactive\fR \fIflag\fR"
The \fIflag\fR value must be a Boolean value. If it is \fBtrue\fR (or
any equivalent), the default timeout is set for an interactive user,
otherwise, the default timeout is set for a batch user. This option
is meaningful only on initial connection. When using the \fBconfigure\fR
method on a MySQL connection use the \fB-timeout\fR option to set the
timeout desired.
.IP \fB-ssl_ca\fR \fIstring\fR
.IP \fB-ssl_capath\fR \fIstring\fR
.IP \fB-ssl_cert\fR \fIstring\fR
.IP \fB-ssl_cipher\fR \fIstring\fR
.IP \fB-ssl_key\fR \fIstring\fR
These five options set the certificate authority, certificate authority
search path, SSL certificate, transfer cipher, and SSL key to the
given \fIstring\fR arguments. These options may be specified only
on initial connection to a database, not in the \fBconfigure\fR method
of an existing connection. Default is not to use SSL.
.SH EXAMPLES
.PP
.CS
tdbc::mysql::connection -user joe -passwd sesame -db joes_database
.CE
Connects to the MySQL server on the local host using the default
connection method, presenting user ID 'joe' and password 'sesame'.
Uses 'joes_database' as the default database name.
.SH "ADDITIONAL CONNECTION METHODS"
In addition to the usual methods on the tdbc::connection(n) object,
connections to a MySQL database support one additional method:
.IP "\fI$connection\fR \fBevaldirect\fR \fIsqlStatement\fR"
This method takes the given \fIsqlStatement\fR and interprets as
MySQL native SQL code and evaluates it without preparing it. The
statement may not contain variable substitutions. The result set
is returned as a list of lists, with each sublist being the list
of columns of a result row formatted as character strings. Note that
the string formatting is done by MySQL and not by Tcl, so details
like the appearance of floating point numbers may differ.
\fIThis command is not recommended\fR for anything where the usual
\fIprepare\fR or \fIpreparecall\fR methods work correctly. It is
provided so that data management language statements that are
not implemented in MySQL's prepared statement API, such as
\fBCREATE DATABASE\fR or \fBCREATE PROCEDURE\fR, can be executed.
.SH "SEE ALSO"
tdbc(n), tdbc::connection(n), tdbc::resultset(n), tdbc::statement(n)
.SH "KEYWORDS"
TDBC, SQL, MySQL, database, connectivity, connection
.SH "COPYRIGHT"
Copyright (c) 2009 by Kevin B. Kenny.
.\" Local Variables:
.\" mode: nroff
.\" End:
.\"

View File

@@ -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.
}

Binary file not shown.