3907 lines
84 KiB
Plaintext
3907 lines
84 KiB
Plaintext
# tdbcodbc.test --
|
|
#
|
|
# Tests for the tdbc::odbc 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: tdbcodbc.tcl,v 1.47 2008/02/27 02:08:27 kennykb Exp $
|
|
#
|
|
#------------------------------------------------------------------------------
|
|
|
|
package require tcltest 2
|
|
namespace import -force ::tcltest::*
|
|
loadTestedCommands
|
|
package require tdbc::odbc
|
|
|
|
# Test setup. Figure out what sort of database we have. Default on Windows
|
|
# is SQL Server Express, and on Unix is SQLite3
|
|
|
|
if {![info exists ::env(TDBCODBC_TEST_TYPE)] || $::env(TDBCODBC_TEST_TYPE) eq {default}} {
|
|
set testdir [makeDirectory tdbctest]
|
|
if {$tcl_platform(platform) eq {windows}} {
|
|
set ::env(TDBCODBC_TEST_TYPE) sqlserver
|
|
} else {
|
|
set ::env(TDBCODBC_TEST_TYPE) sqlite
|
|
}
|
|
}
|
|
|
|
# Jet and SQL Server are Windows-only
|
|
|
|
if {$::env(TDBCODBC_TEST_TYPE) in {jet sqlserver}} {
|
|
if {$::tcl_platform(platform) ne {windows}} {
|
|
puts "$::env(TDBCODBC_TEST_TYPE) testing is available on the\
|
|
Windows platform only"
|
|
removeDirectory tdbctest
|
|
cleanupTests
|
|
return
|
|
}
|
|
}
|
|
|
|
# Configure the selected database
|
|
|
|
switch -exact -- $::env(TDBCODBC_TEST_TYPE) {
|
|
|
|
jet {
|
|
|
|
# Begin by creating an empty .MDB file
|
|
|
|
set testdir [makeDirectory tdbctest]
|
|
set testFileName test.mdb
|
|
set testDBName [makeFile {} $testFileName $testdir]
|
|
set f [open [file join [file dirname [info script]] test.mdb] rb]
|
|
set emptyMDB [read $f]
|
|
close $f
|
|
set f [open $testDBName wb]
|
|
puts -nonewline $f $emptyMDB
|
|
close $f
|
|
|
|
# Set connection string
|
|
|
|
set testDBQ [file native [file normalize $testDBName]]
|
|
set connStr "DRIVER={Microsoft Access Driver (*.mdb)};FIL={MS Access};"
|
|
append connStr DBQ= $testDBQ
|
|
|
|
tcltest::testConstraint jet 1
|
|
|
|
}
|
|
sqlite {
|
|
|
|
# Begin with a nonexistent file for the test database
|
|
|
|
set testdir [makeDirectory tdbctest]
|
|
set testFileName test.db
|
|
set testDBName [file join $testdir $testFileName]
|
|
catch {file delete $testDBName}
|
|
|
|
# Set up the connection string
|
|
|
|
if {$::tcl_platform(platform) eq {windows}} {
|
|
set connStr "DRIVER=SQLite3 ODBC Driver;"
|
|
} else {
|
|
set connStr "DRIVER=SQLite3;"
|
|
}
|
|
append connStr Database= $testDBName
|
|
|
|
tcltest::testConstraint sqlite 1
|
|
}
|
|
sqlserver {
|
|
|
|
# Set up the connection string for 'tdbcTestDB' on the
|
|
# local machine using SQLEXPRESS
|
|
|
|
set dataSource "Provider=SQLNCLI"
|
|
append dataSource \; "Server=." \\ "SQLEXPRESS"
|
|
append dataSource \; "Initial Catalog=tdbcTestDB"
|
|
append dataSource \; "Trusted_Connection=yes"
|
|
set connStr "DRIVER=SQL Native Client;$dataSource"
|
|
|
|
tcltest::testConstraint sqlserver 1
|
|
}
|
|
}
|
|
|
|
tcltest::testConstraint odbcinst \
|
|
[expr {[namespace which -command ::tdbc::odbc::datasource] ne {}}]
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
test tdbc::odbc-1.1 {create a connection, wrong # args} {*}{
|
|
-body {
|
|
tdbc::odbc::connection create
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {wrong # args*}
|
|
}
|
|
|
|
test tdbc::odbc-1.2 {create a connection, connection string missing} {*}{
|
|
-body {
|
|
tdbc::odbc::connection create db
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {wrong # args*}
|
|
}
|
|
|
|
test tdbc::odbc-1.3 {create a connection, failure} {*}{
|
|
-body {
|
|
set status [catch {
|
|
tdbc::odbc::connection create db {DRIVER={rubbish}}
|
|
} result]
|
|
list $status $::errorCode
|
|
}
|
|
-match glob
|
|
-result {1 *}
|
|
}
|
|
|
|
|
|
tcltest::testConstraint connect \
|
|
[expr {[catch {tdbc::odbc::connection create ::db $::connStr}] == 0}]
|
|
catch {rename ::db {}}
|
|
|
|
test tdbc::odbc-1.4 {create a connection, successful} {*}{
|
|
-constraints connect
|
|
-body {
|
|
tdbc::odbc::connection create ::db $::connStr
|
|
}
|
|
-result ::db
|
|
-cleanup {
|
|
catch {rename ::db {}}
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------------------------
|
|
#
|
|
# The tests that follow all require a connection to a database.
|
|
|
|
if {![tcltest::testConstraint connect]} {
|
|
puts "tests requiring a db connection skipped."
|
|
removeDirectory tdbctest
|
|
cleanupTests
|
|
return
|
|
}
|
|
tdbc::odbc::connection create ::db $::connStr
|
|
catch {::db allrows {DROP TABLE people}}
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
test tdbc::odbc-2.1 {prepare statement, wrong # args} {*}{
|
|
-body {
|
|
::db prepare
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {wrong # args*}
|
|
}
|
|
|
|
test tdbc::odbc-2.2 {don't make a statement without a connection} {*}{
|
|
-body {
|
|
tdbc::odbc::statement create stmt rubbish moreRubbish
|
|
}
|
|
-returnCodes error
|
|
-result {rubbish does not refer to an object}
|
|
}
|
|
|
|
test tdbc::odbc-2.3 {don't make a statement without a connection} {*}{
|
|
-body {
|
|
tdbc::odbc::statement create stmt oo::class moreRubbish
|
|
}
|
|
-returnCodes error
|
|
-result {oo::class does not refer to an ODBC connection}
|
|
}
|
|
|
|
test tdbc::odbc-3.0 {prepare a valid statement} {*}{
|
|
-body {
|
|
set stmt [::db prepare {
|
|
CREATE TABLE people(
|
|
idnum INTEGER PRIMARY KEY NOT NULL,
|
|
name VARCHAR(40) NOT NULL
|
|
)
|
|
}]
|
|
}
|
|
-match glob
|
|
-result *Stmt*
|
|
-cleanup {
|
|
catch [rename $stmt {}]
|
|
}
|
|
}
|
|
|
|
test tdbc::odbc-3.1 {execute a valid statement with no results} {*}{
|
|
-body {
|
|
set stmt [::db prepare {
|
|
CREATE TABLE people(
|
|
idnum INTEGER PRIMARY KEY NOT NULL,
|
|
name VARCHAR(40) NOT NULL
|
|
)
|
|
}]
|
|
set rs [$stmt execute]
|
|
list [expr {[$rs rowcount] <= 0}] [$rs columns] [$rs nextrow nothing]
|
|
}
|
|
-result {1 {} 0}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
set stmt [::db prepare {
|
|
DROP TABLE people
|
|
}]
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
}
|
|
|
|
test tdbc::odbc-3.2 {result set: wrong # args} {*}{
|
|
-body {
|
|
set stmt [::db prepare {
|
|
CREATE TABLE people(
|
|
idnum INTEGER PRIMARY KEY NOT NULL,
|
|
name VARCHAR(40) NOT NULL
|
|
)
|
|
}]
|
|
$stmt execute with extra args
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {wrong # args*}
|
|
-cleanup {
|
|
catch [rename $stmt {}]
|
|
}
|
|
}
|
|
|
|
test tdbc::odbc-3.3 {result set: trying to create against a non-object} {*}{
|
|
-body {
|
|
tdbc::odbc::resultset create rs nothing
|
|
}
|
|
-returnCodes error
|
|
-result {nothing does not refer to an object}
|
|
}
|
|
|
|
test tdbc::odbc-3.4 {result set: trying to create against a non-statement} {*}{
|
|
-body {
|
|
tdbc::odbc::resultset create rs db
|
|
}
|
|
-returnCodes error
|
|
-result {db does not refer to an ODBC statement}
|
|
}
|
|
|
|
#-------------------------------------------------------------------------------
|
|
#
|
|
# Following tests need a 'people' table in the database
|
|
|
|
set stmt [::db prepare {
|
|
CREATE TABLE people(
|
|
idnum INTEGER PRIMARY KEY NOT NULL,
|
|
name VARCHAR(40) NOT NULL,
|
|
info INTEGER
|
|
)
|
|
}]
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
|
|
test tdbc::odbc-4.1 {execute an insert with no params} {*}{
|
|
-body {
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(1, 'fred', 0)
|
|
}]
|
|
set rs [$stmt execute]
|
|
list [$rs rowcount] [$rs columns] [$rs nextrow nothing]
|
|
}
|
|
-result {1 {} 0}
|
|
-cleanup {
|
|
catch {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
set stmt [::db prepare {
|
|
DELETE FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
}
|
|
}
|
|
|
|
test tdbc::odbc-4.2 {execute an insert with variable parameters} {*}{
|
|
-body {
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set idnum 1
|
|
set name fred
|
|
set rs [$stmt execute]
|
|
list [$rs rowcount] [$rs columns] [$rs nextrow nothing]
|
|
}
|
|
-result {1 {} 0}
|
|
-cleanup {
|
|
catch {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
set stmt [::db prepare {
|
|
DELETE FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
}
|
|
}
|
|
|
|
test tdbc::odbc-4.3 {execute an insert with dictionary parameters} {*}{
|
|
-body {
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set rs [$stmt execute {idnum 1 name fred}]
|
|
list [$rs rowcount] [$rs columns] [$rs nextrow nothing]
|
|
}
|
|
-result {1 {} 0}
|
|
-cleanup {
|
|
catch {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
set stmt [::db prepare {
|
|
DELETE FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
}
|
|
}
|
|
|
|
test tdbc::odbc-4.4 {bad dictionary} {*}{
|
|
-body {
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(:idnum, :name)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
$stmt execute {idnum 1 name}
|
|
}
|
|
-returnCodes error
|
|
-result {missing value to go with key}
|
|
-cleanup {
|
|
catch {
|
|
rename $stmt {}
|
|
set stmt [::db prepare {
|
|
DELETE FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
}
|
|
}
|
|
|
|
test tdbc::odbc-4.5 {missing parameter variable} {*}{
|
|
-constraints jet||sqlserver
|
|
-setup {
|
|
catch {unset idnum}
|
|
}
|
|
-body {
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set name fred
|
|
$stmt execute
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {*[nN]ull*}
|
|
-cleanup {
|
|
catch {
|
|
rename $stmt {}
|
|
set stmt [::db prepare {
|
|
DELETE FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
}
|
|
}
|
|
|
|
test tdbc::odbc-4.6 {missing parameter in dictionary} {*}{
|
|
-constraints jet||sqlserver
|
|
-body {
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
$stmt execute {name fred}
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {*[nN]ull*}
|
|
-cleanup {
|
|
catch {
|
|
rename $stmt {}
|
|
set stmt [::db prepare {
|
|
DELETE FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
}
|
|
}
|
|
|
|
test tdbc::odbc-4.7 {missing parameter - nullable} {*}{
|
|
-setup {
|
|
catch {unset info}
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(:idnum, :name, :info)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
$stmt paramtype info integer
|
|
set stmt2 [::db prepare {
|
|
SELECT name, info FROM people WHERE idnum = :idnum
|
|
}]
|
|
$stmt2 paramtype idnum integer
|
|
}
|
|
-body {
|
|
set name "mr. gravel"
|
|
set idnum 100
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
set rs [$stmt2 execute]
|
|
$rs nextrow -as dicts row
|
|
set row
|
|
}
|
|
-result {name {mr. gravel}}
|
|
-cleanup {
|
|
catch {rename $rs {}}
|
|
catch {
|
|
rename $stmt {}
|
|
rename $stmt2 {}
|
|
set stmt [::db prepare {
|
|
DELETE FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
}
|
|
}
|
|
|
|
test tdbc::odbc-4.8 {missing parameter in dictionary - nullable} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(:idnum, :name, :info)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
$stmt paramtype info integer
|
|
set stmt2 [::db prepare {
|
|
SELECT name, info FROM people WHERE idnum = :idnum
|
|
}]
|
|
$stmt2 paramtype idnum integer
|
|
}
|
|
-body {
|
|
set rs [$stmt execute {name {gary granite} idnum 200}]
|
|
rename $rs {}
|
|
set rs [$stmt2 execute {idnum 200}]
|
|
$rs nextrow -as dicts row
|
|
set row
|
|
}
|
|
-result {name {gary granite}}
|
|
-cleanup {
|
|
catch {rename $rs {}}
|
|
catch {
|
|
rename $stmt {}
|
|
rename $stmt2 {}
|
|
set stmt [::db prepare {
|
|
DELETE FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
}
|
|
}
|
|
|
|
test tdbc::odbc-4.9 {two result sets open against the same statement} {*}{
|
|
-body {
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set rs1 [$stmt execute {idnum 1 name fred}]
|
|
set rs2 [$stmt execute {idnum 2 name wilma}]
|
|
list [$rs1 rowcount] [$rs1 columns] [$rs1 nextrow nothing] \
|
|
[$rs2 rowcount] [$rs2 columns] [$rs2 nextrow nothing]
|
|
}
|
|
-result {1 {} 0 1 {} 0}
|
|
-cleanup {
|
|
catch {
|
|
rename $rs1 {}
|
|
rename $rs2 {}
|
|
rename $stmt {}
|
|
set stmt [::db prepare {
|
|
DELETE FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
}
|
|
}
|
|
|
|
test tdbc::odbc-4.10 {failed execution} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set rs [$stmt execute {idnum 1 name fred}]
|
|
rename $rs {}
|
|
}
|
|
-body {
|
|
set status [catch {$stmt execute {idnum 1 name barney}} result]
|
|
list $status $::errorCode
|
|
}
|
|
-cleanup {
|
|
rename $stmt {}
|
|
set stmt [::db prepare {
|
|
DELETE FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-match glob
|
|
-result {1 {TDBC * ODBC *}}
|
|
}
|
|
|
|
test tdbc::odbc-5.1 {paramtype - too few args} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
|
|
}]
|
|
}
|
|
-body {
|
|
$stmt paramtype idnum
|
|
}
|
|
-cleanup {
|
|
rename $stmt {}
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {wrong # args*}
|
|
}
|
|
|
|
test tdbc::odbc-5.2 {paramtype - just a direction} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
|
|
}]
|
|
}
|
|
-body {
|
|
$stmt paramtype idnum in
|
|
}
|
|
-cleanup {
|
|
rename $stmt {}
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {wrong # args*}
|
|
}
|
|
|
|
test tdbc::odbc-5.3 {paramtype - bad type} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
|
|
}]
|
|
}
|
|
-body {
|
|
$stmt paramtype idnum rubbish
|
|
}
|
|
-cleanup {
|
|
rename $stmt {}
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {bad SQL data type "rubbish":*}
|
|
}
|
|
|
|
test tdbc::odbc-5.4 {paramtype - bad scale} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
|
|
}]
|
|
}
|
|
-body {
|
|
$stmt paramtype idnum decimal rubbish
|
|
}
|
|
-cleanup {
|
|
rename $stmt {}
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {expected integer but got "rubbish"}
|
|
}
|
|
|
|
test tdbc::odbc-5.5 {paramtype - bad precision} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
|
|
}]
|
|
}
|
|
-body {
|
|
$stmt paramtype idnum decimal 12 rubbish
|
|
}
|
|
-cleanup {
|
|
rename $stmt {}
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {expected integer but got "rubbish"}
|
|
}
|
|
|
|
test tdbc::odbc-5.6 {paramtype - unknown parameter} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
|
|
}]
|
|
}
|
|
-body {
|
|
$stmt paramtype rubbish integer
|
|
}
|
|
-cleanup {
|
|
rename $stmt {}
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {unknown parameter "rubbish":*}
|
|
}
|
|
|
|
test tdbc::odbc-6.1 {rowcount - wrong args} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
INSERT INTO people(idnum, name, info) values(:idnum, :name, 0)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set rs [$stmt execute {idnum 1 name fred}]
|
|
}
|
|
-body {
|
|
$rs rowcount rubbish
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
set stmt [::db prepare {
|
|
DELETE FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result "wrong \# args*"
|
|
}
|
|
|
|
#-------------------------------------------------------------------------------
|
|
#
|
|
# next tests require data in the database
|
|
|
|
catch {
|
|
set stmt [db prepare {
|
|
INSERT INTO people(idnum, name, info) VALUES(:idnum, :name, NULL)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set idnum 1
|
|
foreach name {fred wilma pebbles barney betty bam-bam} {
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
incr idnum
|
|
}
|
|
rename $stmt {}
|
|
}
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
test tdbc::odbc-7.1 {columns - bad args} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT * FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
$rs columns rubbish
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {wrong # args*}
|
|
}
|
|
|
|
test tdbc::odbc-7.2 {columns - get column names} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT * FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
$rs columns
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-result {idnum name info}
|
|
}
|
|
|
|
test tdbc::odbc-8.1 {nextrow - as dicts} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people ORDER BY idnum
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
set idnum 1
|
|
set names {}
|
|
while {[$rs nextrow -- row]} {
|
|
if {$idnum != [dict get $row idnum]} {
|
|
binary scan [dict get $row idnum] c* v
|
|
binary scan [dict get $row name] c* v
|
|
error [list bad idnum [dict get $row idnum] should be $idnum]
|
|
}
|
|
lappend names [dict get $row name]
|
|
incr idnum
|
|
}
|
|
set names
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-result {fred wilma pebbles barney betty bam-bam}
|
|
}
|
|
|
|
test tdbc::odbc-8.2 {nextrow - as lists} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people ORDER BY idnum
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
set idnum 1
|
|
set names {}
|
|
while {[$rs nextrow -as lists -- row]} {
|
|
if {$idnum != [lindex $row 0]} {
|
|
error [list bad idnum [lindex $row 0] should be $idnum]
|
|
}
|
|
lappend names [lindex $row 1]
|
|
incr idnum
|
|
}
|
|
set names
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-result {fred wilma pebbles barney betty bam-bam}
|
|
}
|
|
|
|
test tdbc::odbc-8.3 {nextrow - bad cursor state} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people ORDER BY idnum
|
|
}]
|
|
}
|
|
-body {
|
|
set rs [$stmt execute]
|
|
set names {}
|
|
while {[$rs nextrow row]} {}
|
|
$rs nextrow row
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-result 0
|
|
}
|
|
|
|
test tdbc::odbc-8.4 {anonymous columns - dicts} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT COUNT(*), MAX(idnum) FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
list \
|
|
[$rs nextrow row] \
|
|
$row \
|
|
[$rs nextrow row]
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-match glob
|
|
-result {1 {* 6 * 6} 0}
|
|
};
|
|
|
|
test tdbc::odbc-8.5 {anonymous columns - lists} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT COUNT(*), MAX(idnum) FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
list [$rs nextrow -as lists row] \
|
|
$row \
|
|
[$rs nextrow -as lists row]
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-result {1 {6 6} 0}
|
|
};
|
|
|
|
test tdbc::odbc-8.6 {null results - dicts} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name, info FROM people WHERE name = 'fred'
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
list [$rs nextrow row] $row [$rs nextrow row]
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-result {1 {idnum 1 name fred} 0}
|
|
}
|
|
|
|
test tdbc::odbc-8.7 {null results - lists} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name, info FROM people WHERE name = 'fred'
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
list [$rs nextrow -as lists -- row] $row [$rs nextrow -as lists -- row]
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-result {1 {1 fred {}} 0}
|
|
}
|
|
|
|
test tdbc::odbc-8.8 {duplicate colunm names - dicts} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT p1.name, p2.name
|
|
FROM people p1, people p2
|
|
WHERE p1.idnum = 1 AND p2.idnum = p1.idnum + 1
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
list [$rs nextrow -as dicts -- row] $row [$rs nextrow -as dicts -- row]
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-match glob
|
|
-result {1 {*name* fred *name* wilma} 0}
|
|
}
|
|
|
|
|
|
test tdbc::odbc-9.1 {rs foreach var script} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
set result {}
|
|
$rs foreach row {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
$rs close
|
|
$stmt close
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-9.2 {stmt foreach var script} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
|
|
}
|
|
-body {
|
|
set result {}
|
|
$stmt foreach row {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-9.3 {db foreach var sqlcode script} {*}{
|
|
-body {
|
|
set result {}
|
|
db foreach row {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
} {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-9.4 {rs foreach -- var script} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
set result {}
|
|
$rs foreach -- row {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
$rs close
|
|
$stmt close
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-9.5 {stmt foreach -- var script} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
}
|
|
-body {
|
|
set result {}
|
|
$stmt foreach -- row {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-9.6 {db foreach -- var query script} {*}{
|
|
-body {
|
|
set result {}
|
|
db foreach -- row {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
} {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-9.7 {rs foreach -- -as lists} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
set result {}
|
|
$rs foreach -as lists row {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
$rs close
|
|
$stmt close
|
|
}
|
|
-result {{4 barney {}} {5 betty {}} {6 bam-bam {}}}
|
|
}
|
|
|
|
test tdbc::odbc-9.8 {stmt foreach -as lists} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
}
|
|
-body {
|
|
set result {}
|
|
$stmt foreach -as lists row {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-result {{4 barney {}} {5 betty {}} {6 bam-bam {}}}
|
|
}
|
|
|
|
test tdbc::odbc-9.9 {db foreach -as lists} {*}{
|
|
-body {
|
|
set result {}
|
|
db foreach -as lists row {
|
|
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
|
|
} {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-result {{4 barney {}} {5 betty {}} {6 bam-bam {}}}
|
|
}
|
|
|
|
test tdbc::odbc-9.10 {rs foreach -as lists --} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
set result {}
|
|
$rs foreach -as lists -- row {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
$rs close
|
|
$stmt close
|
|
}
|
|
-result {{4 barney {}} {5 betty {}} {6 bam-bam {}}}
|
|
}
|
|
|
|
test tdbc::odbc-9.11 {stmt foreach -as lists --} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
}
|
|
-body {
|
|
set result {}
|
|
$stmt foreach -as lists -- row {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-result {{4 barney {}} {5 betty {}} {6 bam-bam {}}}
|
|
}
|
|
|
|
test tdbc::odbc-9.12 {db foreach -as lists --} {*}{
|
|
-body {
|
|
set result {}
|
|
db foreach -as lists row {
|
|
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
|
|
} {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-result {{4 barney {}} {5 betty {}} {6 bam-bam {}}}
|
|
}
|
|
|
|
test tdbc::odbc-9.13 {rs foreach -as lists -columnsvar c --} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
set result {}
|
|
$rs foreach -as lists -columnsvar c -- row {
|
|
foreach cn $c cv $row {
|
|
lappend result $cn $cv
|
|
}
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
$rs close
|
|
$stmt close
|
|
}
|
|
-result {idnum 4 name barney idnum 5 name betty idnum 6 name bam-bam}
|
|
}
|
|
|
|
test tdbc::odbc-9.14 {stmt foreach -as lists -columnsvar c --} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
}
|
|
-body {
|
|
set result {}
|
|
$stmt foreach -as lists -columnsvar c -- row {
|
|
foreach cn $c cv $row {
|
|
lappend result $cn $cv
|
|
}
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-result {idnum 4 name barney idnum 5 name betty idnum 6 name bam-bam}
|
|
}
|
|
|
|
test tdbc::odbc-9.15 {db foreach -as lists -columnsvar c --} {*}{
|
|
-body {
|
|
set result {}
|
|
db foreach -as lists -columnsvar c -- row {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
} {
|
|
foreach cn $c cv $row {
|
|
lappend result $cn $cv
|
|
}
|
|
}
|
|
set result
|
|
}
|
|
-result {idnum 4 name barney idnum 5 name betty idnum 6 name bam-bam}
|
|
}
|
|
|
|
test tdbc::odbc-9.16 {rs foreach / break out of loop} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
set result {}
|
|
$rs foreach -as lists -- row {
|
|
if {[lindex $row 1] eq {betty}} break
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
$rs close
|
|
$stmt close
|
|
}
|
|
-result {{4 barney {}}}
|
|
}
|
|
|
|
test tdbc::odbc-9.17 {stmt foreach / break out of loop} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
}
|
|
-body {
|
|
set result {}
|
|
$stmt foreach -as lists -- row {
|
|
if {[lindex $row 1] eq {betty}} break
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-result {{4 barney {}}}
|
|
}
|
|
|
|
test tdbc::odbc-9.18 {db foreach / break out of loop} {*}{
|
|
-body {
|
|
set result {}
|
|
db foreach -as lists -- row {
|
|
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
|
|
} {
|
|
if {[lindex $row 1] eq {betty}} break
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-result {{4 barney {}}}
|
|
}
|
|
|
|
test tdbc::odbc-9.19 {rs foreach / continue in loop} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
set result {}
|
|
$rs foreach -as lists -- row {
|
|
if {[lindex $row 1] eq {betty}} continue
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
$rs close
|
|
$stmt close
|
|
}
|
|
-result {{4 barney {}} {6 bam-bam {}}}
|
|
}
|
|
|
|
test tdbc::odbc-9.20 {stmt foreach / continue in loop} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
}
|
|
-body {
|
|
set result {}
|
|
$stmt foreach -as lists -- row {
|
|
if {[lindex $row 1] eq {betty}} continue
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-result {{4 barney {}} {6 bam-bam {}}}
|
|
}
|
|
|
|
test tdbc::odbc-9.21 {db foreach / continue in loop} {*}{
|
|
-body {
|
|
set result {}
|
|
db foreach -as lists -- row {
|
|
SELECT idnum, name, info FROM people WHERE name LIKE 'b%'
|
|
} {
|
|
if {[lindex $row 1] eq {betty}} continue
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-result {{4 barney {}} {6 bam-bam {}}}
|
|
}
|
|
|
|
test tdbc::odbc-9.22 {rs foreach / return out of the loop} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
set rs [$stmt execute]
|
|
proc tdbcodbc-9.22 {rs} {
|
|
$rs foreach -as lists -- row {
|
|
if {[lindex $row 1] eq {betty}} {
|
|
return [lindex $row 0]
|
|
}
|
|
}
|
|
return failed
|
|
}
|
|
}
|
|
-body {
|
|
tdbcodbc-9.22 $rs
|
|
}
|
|
-cleanup {
|
|
rename tdbcodbc-9.22 {}
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-result 5
|
|
}
|
|
|
|
test tdbc::odbc-9.23 {stmt foreach / return out of the loop} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
proc tdbcodbc-9.23 {stmt} {
|
|
$stmt foreach -as lists -- row {
|
|
if {[lindex $row 1] eq {betty}} {
|
|
return [lindex $row 0]
|
|
}
|
|
}
|
|
return failed
|
|
}
|
|
}
|
|
-body {
|
|
tdbcodbc-9.23 $stmt
|
|
}
|
|
-cleanup {
|
|
rename tdbcodbc-9.23 {}
|
|
rename $stmt {}
|
|
}
|
|
-result 5
|
|
}
|
|
|
|
test tdbc::odbc-9.24 {db foreach / return out of the loop} {*}{
|
|
-setup {
|
|
proc tdbcodbc-9.24 {stmt} {
|
|
db foreach -as lists -- row {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
} {
|
|
if {[lindex $row 1] eq {betty}} {
|
|
return [lindex $row 0]
|
|
}
|
|
}
|
|
return failed
|
|
}
|
|
}
|
|
-body {
|
|
tdbcodbc-9.24 $stmt
|
|
}
|
|
-cleanup {
|
|
rename tdbcodbc-9.24 {}
|
|
}
|
|
-result 5
|
|
}
|
|
|
|
test tdbc::odbc-9.25 {rs foreach / error out of the loop} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
set rs [$stmt execute]
|
|
proc tdbcodbc-9.25 {rs} {
|
|
$rs foreach -as lists -- row {
|
|
if {[lindex $row 1] eq {betty}} {
|
|
error [lindex $row 0]
|
|
}
|
|
}
|
|
return failed
|
|
}
|
|
}
|
|
-body {
|
|
tdbcodbc-9.25 $rs
|
|
}
|
|
-cleanup {
|
|
rename tdbcodbc-9.25 {}
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-returnCodes error
|
|
-result 5
|
|
}
|
|
|
|
test tdbc::odbc-9.26 {stmt foreach - error out of the loop} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
proc tdbcodbc-9.26 {stmt} {
|
|
$stmt foreach -as lists -- row {
|
|
if {[lindex $row 1] eq {betty}} {
|
|
error [lindex $row 0]
|
|
}
|
|
}
|
|
return failed
|
|
}
|
|
}
|
|
-body {
|
|
tdbcodbc-9.26 $stmt
|
|
}
|
|
-cleanup {
|
|
rename tdbcodbc-9.26 {}
|
|
rename $stmt {}
|
|
}
|
|
-returnCodes error
|
|
-result 5
|
|
}
|
|
|
|
test tdbc::odbc-9.27 {db foreach / error out of the loop} {*}{
|
|
-setup {
|
|
proc tdbcodbc-9.27 {} {
|
|
db foreach -as lists -- row {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
} {
|
|
if {[lindex $row 1] eq {betty}} {
|
|
error [lindex $row 0]
|
|
}
|
|
}
|
|
return failed
|
|
}
|
|
}
|
|
-body {
|
|
tdbcodbc-9.27
|
|
}
|
|
-cleanup {
|
|
rename tdbcodbc-9.27 {}
|
|
}
|
|
-returnCodes error
|
|
-result 5
|
|
}
|
|
|
|
test tdbc::odbc-9.28 {rs foreach / unknown status from the loop} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
set rs [$stmt execute]
|
|
proc tdbcodbc-9.28 {rs} {
|
|
$rs foreach -as lists -- row {
|
|
if {[lindex $row 1] eq {betty}} {
|
|
return -code 666 -level 0 [lindex $row 0]
|
|
}
|
|
}
|
|
return failed
|
|
}
|
|
}
|
|
-body {
|
|
tdbcodbc-9.28 $rs
|
|
}
|
|
-cleanup {
|
|
rename tdbcodbc-9.28 {}
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-returnCodes 666
|
|
-result 5
|
|
}
|
|
|
|
test tdbc::odbc-9.29 {stmt foreach / unknown status from the loop} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
proc tdbcodbc-9.29 {stmt} {
|
|
$stmt foreach -as lists -- row {
|
|
if {[lindex $row 1] eq {betty}} {
|
|
return -code 666 -level 0 [lindex $row 0]
|
|
}
|
|
}
|
|
return failed
|
|
}
|
|
}
|
|
-body {
|
|
tdbcodbc-9.29 $stmt
|
|
}
|
|
-cleanup {
|
|
rename tdbcodbc-9.29 {}
|
|
rename $stmt {}
|
|
}
|
|
-returnCodes 666
|
|
-result 5
|
|
}
|
|
|
|
test tdbc::odbc-9.30 {db foreach / unknown status from the loop} {*}{
|
|
-setup {
|
|
proc tdbcodbc-9.30 {stmt} {
|
|
db foreach -as lists -- row {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
} {
|
|
if {[lindex $row 1] eq {betty}} {
|
|
return -code 666 -level 0 [lindex $row 0]
|
|
}
|
|
}
|
|
return failed
|
|
}
|
|
}
|
|
-body {
|
|
tdbcodbc-9.30 $stmt
|
|
}
|
|
-cleanup {
|
|
rename tdbcodbc-9.30 {}
|
|
}
|
|
-returnCodes 666
|
|
-result 5
|
|
}
|
|
|
|
test tdbc::odbc-9.31 {stmt foreach / params in variables} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE :thePattern
|
|
}]
|
|
$stmt paramtype thePattern varchar 40
|
|
}
|
|
-body {
|
|
set result {}
|
|
set thePattern b%
|
|
$stmt foreach row {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-9.32 {db foreach / params in variables} {*}{
|
|
-body {
|
|
set result {}
|
|
set thePattern b%
|
|
db foreach row {
|
|
SELECT idnum, name FROM people WHERE name LIKE :thePattern
|
|
} {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-9.33 {stmt foreach / parameters in a dictionary} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE :thePattern
|
|
}]
|
|
$stmt paramtype thePattern varchar 40
|
|
}
|
|
-body {
|
|
set result {}
|
|
$stmt foreach row {thePattern b%} {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-9.34 {db foreach / parameters in a dictionary} {*}{
|
|
-body {
|
|
set result {}
|
|
db foreach row {
|
|
SELECT idnum, name FROM people WHERE name LIKE :thePattern
|
|
} {thePattern b%} {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-9.35 {stmt foreach - variable not found} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE :thePattern
|
|
}]
|
|
$stmt paramtype thePattern varchar 40
|
|
catch {unset thePattern}
|
|
}
|
|
-body {
|
|
set result {}
|
|
set thePattern(bogosity) {}
|
|
$stmt foreach row {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
unset thePattern
|
|
$stmt close
|
|
}
|
|
-result {}
|
|
}
|
|
|
|
test tdbc::odbc-9.36 {db foreach - variable not found} {*}{
|
|
-setup {
|
|
catch {unset thePattern}
|
|
}
|
|
-body {
|
|
set result {}
|
|
set thePattern(bogosity) {}
|
|
db foreach row {
|
|
SELECT idnum, name FROM people WHERE name LIKE :thePattern
|
|
} {
|
|
lappend result $row
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
unset thePattern
|
|
}
|
|
-result {}
|
|
}
|
|
|
|
test tdbc::odbc-9.37 {rs foreach - too few args} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
$rs foreach row
|
|
}
|
|
-cleanup {
|
|
$rs close
|
|
$stmt close
|
|
}
|
|
-returnCodes error
|
|
-result {wrong # args*}
|
|
-match glob
|
|
}
|
|
|
|
test tdbc::odbc-9.38 {stmt foreach - too few args} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people
|
|
}]
|
|
}
|
|
-body {
|
|
$stmt foreach row
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-returnCodes error
|
|
-result {wrong # args*}
|
|
-match glob
|
|
}
|
|
|
|
test tdbc::odbc-9.39 {db foreach - too few args} {*}{
|
|
-body {
|
|
db foreach row {
|
|
SELECT idnum, name FROM people
|
|
}
|
|
}
|
|
-returnCodes error
|
|
-result {wrong # args*}
|
|
-match glob
|
|
}
|
|
|
|
test tdbc::odbc-9.40 {rs foreach - too many args} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
$rs foreach row do something
|
|
}
|
|
-cleanup {
|
|
$rs close
|
|
$stmt close
|
|
}
|
|
-returnCodes error
|
|
-result {wrong # args*}
|
|
-match glob
|
|
}
|
|
|
|
test tdbc::odbc-9.41 {stmt foreach - too many args} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people
|
|
}]
|
|
}
|
|
-body {
|
|
$stmt foreach row do something else
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-returnCodes error
|
|
-result {wrong # args*}
|
|
-match glob
|
|
}
|
|
|
|
test tdbc::odbc-9.42 {db foreach - too many args} {*}{
|
|
-body {
|
|
db foreach row {
|
|
SELECT idnum, name FROM people
|
|
} {} do something
|
|
}
|
|
-returnCodes error
|
|
-result {wrong # args*}
|
|
-match glob
|
|
}
|
|
|
|
test tdbc::odbc-10.1 {allrows - no args} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
$rs allrows
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-10.2 {allrows - no args} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
}
|
|
-body {
|
|
$stmt allrows
|
|
}
|
|
-cleanup {
|
|
rename $stmt {}
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-10.3 {allrows - no args} {*}{
|
|
-body {
|
|
db allrows {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-10.4 {allrows --} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
$rs allrows --
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-10.5 {allrows --} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
}
|
|
-body {
|
|
$stmt allrows --
|
|
}
|
|
-cleanup {
|
|
rename $stmt {}
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-10.6 {allrows --} {*}{
|
|
-body {
|
|
db allrows -- {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-10.7 {allrows -as lists} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
$rs allrows -as lists
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-result {{4 barney} {5 betty} {6 bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-10.8 {allrows -as lists} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
}
|
|
-body {
|
|
$stmt allrows -as lists
|
|
}
|
|
-cleanup {
|
|
rename $stmt {}
|
|
}
|
|
-result {{4 barney} {5 betty} {6 bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-10.9 {allrows -as lists} {*}{
|
|
-body {
|
|
db allrows -as lists {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}
|
|
}
|
|
-result {{4 barney} {5 betty} {6 bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-10.10 {allrows -as lists --} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
$rs allrows -as lists --
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-result {{4 barney} {5 betty} {6 bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-10.11 {allrows -as lists --} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
}
|
|
-body {
|
|
$stmt allrows -as lists --
|
|
}
|
|
-cleanup {
|
|
rename $stmt {}
|
|
}
|
|
-result {{4 barney} {5 betty} {6 bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-10.12 {allrows -as lists --} {*}{
|
|
-body {
|
|
db allrows -as lists -- {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}
|
|
}
|
|
-result {{4 barney} {5 betty} {6 bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-10.13 {allrows -as lists -columnsvar c} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
set result [$rs allrows -as lists -columnsvar c]
|
|
list $c $result
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-result {{idnum name} {{4 barney} {5 betty} {6 bam-bam}}}
|
|
}
|
|
|
|
test tdbc::odbc-10.14 {allrows -as lists -columnsvar c} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
}
|
|
-body {
|
|
set result [$stmt allrows -as lists -columnsvar c]
|
|
list $c $result
|
|
}
|
|
-cleanup {
|
|
rename $stmt {}
|
|
}
|
|
-result {{idnum name} {{4 barney} {5 betty} {6 bam-bam}}}
|
|
}
|
|
|
|
test tdbc::odbc-10.15 {allrows -as lists -columnsvar c} {*}{
|
|
-body {
|
|
set result [db allrows -as lists -columnsvar c {
|
|
SELECT idnum, name FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
list $c $result
|
|
}
|
|
-result {{idnum name} {{4 barney} {5 betty} {6 bam-bam}}}
|
|
}
|
|
|
|
test tdbc::odbc-10.16 {allrows - correct lexical scoping of variables} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE :thePattern
|
|
}]
|
|
$stmt paramtype thePattern varchar 40
|
|
}
|
|
-body {
|
|
set thePattern b%
|
|
$stmt allrows
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-10.17 {allrows - parameters in a dictionary} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people WHERE name LIKE :thePattern
|
|
}]
|
|
$stmt paramtype thePattern varchar 40
|
|
}
|
|
-body {
|
|
$stmt allrows {thePattern b%}
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-10.18 {allrows - parameters in a dictionary} {*}{
|
|
-body {
|
|
db allrows {
|
|
SELECT idnum, name FROM people WHERE name LIKE :thePattern
|
|
} {thePattern b%}
|
|
}
|
|
-result {{idnum 4 name barney} {idnum 5 name betty} {idnum 6 name bam-bam}}
|
|
}
|
|
|
|
test tdbc::odbc-10.19 {allrows - variable not found} {*}{
|
|
-setup {
|
|
catch {unset thePattern}
|
|
}
|
|
-body {
|
|
set thePattern(bogosity) {}
|
|
db allrows {
|
|
SELECT idnum, name FROM people WHERE name LIKE :thePattern
|
|
}
|
|
}
|
|
-cleanup {
|
|
unset thePattern
|
|
}
|
|
-result {}
|
|
}
|
|
|
|
test tdbc::odbc-10.20 {allrows - too many args} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT idnum, name FROM people
|
|
}]
|
|
}
|
|
-body {
|
|
$stmt allrows {} rubbish
|
|
}
|
|
-cleanup {
|
|
$stmt close
|
|
}
|
|
-returnCodes error
|
|
-result {wrong # args*}
|
|
-match glob
|
|
}
|
|
|
|
test tdbc::odbc-10.21 {bad -as} {*}{
|
|
-body {
|
|
db allrows -as trash {
|
|
SELECT idnum, name FROM people
|
|
}
|
|
}
|
|
-returnCodes error
|
|
-result {bad variable type "trash": must be lists or dicts}
|
|
}
|
|
|
|
test tdbc::odbc-11.1 {update - no rows} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
UPDATE people SET info = 1 WHERE idnum > 6
|
|
}]
|
|
set rs [$stmt execute]
|
|
}
|
|
-body {
|
|
$rs rowcount
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-result 0
|
|
}
|
|
|
|
test tdbc::odbc-11.2 {update - unique row} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
UPDATE people SET info = 1 WHERE name = 'fred'
|
|
}]
|
|
}
|
|
-body {
|
|
set rs [$stmt execute]
|
|
$rs rowcount
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-result 1
|
|
}
|
|
|
|
test tdbc::odbc-11.3 {update - multiple rows} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
UPDATE people SET info = 1 WHERE name LIKE 'b%'
|
|
}]
|
|
}
|
|
-body {
|
|
set rs [$stmt execute]
|
|
$rs rowcount
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-result 3
|
|
}
|
|
|
|
test tdbc::odbc-12.1 {delete - no rows} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
DELETE FROM people WHERE name = 'nobody'
|
|
}]
|
|
}
|
|
-body {
|
|
set rs [$stmt execute]
|
|
$rs rowcount
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-result 0
|
|
}
|
|
|
|
test tdbc::odbc-12.2 {delete - unique row} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
DELETE FROM people WHERE name = 'fred'
|
|
}]
|
|
}
|
|
-body {
|
|
set rs [$stmt execute]
|
|
$rs rowcount
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-result 1
|
|
}
|
|
|
|
test tdbc::odbc-12.3 {delete - multiple rows} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
DELETE FROM people WHERE name LIKE 'b%'
|
|
}]
|
|
}
|
|
-body {
|
|
set rs [$stmt execute]
|
|
$rs rowcount
|
|
}
|
|
-cleanup {
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
}
|
|
-result 3
|
|
}
|
|
|
|
test tdbc::odbc-13.1 {resultsets - no results} {*}{
|
|
-setup {
|
|
set stmt [::db prepare {
|
|
SELECT name FROM people WHERE idnum = $idnum
|
|
}]
|
|
}
|
|
-body {
|
|
list \
|
|
[llength [$stmt resultsets]] \
|
|
[llength [::db resultsets]]
|
|
}
|
|
-cleanup {
|
|
rename $stmt {}
|
|
}
|
|
-result {0 0}
|
|
}
|
|
|
|
# SQL Native Client does not allow more than one concurrent statement
|
|
# per connection. It might be possible to make tdbc::odbc to work around
|
|
# this problem by replicating the connection, but that really has the feel
|
|
# of working around a bug in the underlying infrastructure. Let's just
|
|
# document it instead.
|
|
|
|
test tdbc::odbc-13.2 {resultsets - various statements and results} {*}{
|
|
-constraints !sqlserver
|
|
-setup {
|
|
for {set i 0} {$i < 6} {incr i} {
|
|
set stmts($i) [::db prepare {
|
|
SELECT name FROM people WHERE idnum = :idnum
|
|
}]
|
|
$stmts($i) paramtype idnum integer
|
|
for {set j 0} {$j < $i} {incr j} {
|
|
set resultsets($i,$j) [$stmts($i) execute [list idnum $j]]
|
|
}
|
|
for {set j 1} {$j < $i} {incr j 2} {
|
|
$resultsets($i,$j) close
|
|
unset resultsets($i,$j)
|
|
}
|
|
}
|
|
}
|
|
-body {
|
|
set x [list [llength [::db resultsets]]]
|
|
for {set i 0} {$i < 6} {incr i} {
|
|
lappend x [llength [$stmts($i) resultsets]]
|
|
}
|
|
set x
|
|
}
|
|
-cleanup {
|
|
for {set i 0} {$i < 6} {incr i} {
|
|
$stmts($i) close
|
|
}
|
|
}
|
|
-result {9 0 1 1 2 2 3}
|
|
}
|
|
|
|
#-------------------------------------------------------------------------------
|
|
#
|
|
# next tests require a fresh database connection. Close the existing one down
|
|
|
|
catch {
|
|
set stmt [db prepare {
|
|
DELETE FROM people
|
|
}]
|
|
$stmt execute
|
|
}
|
|
catch {
|
|
rename ::db {}
|
|
}
|
|
|
|
tdbc::odbc::connection create ::db $::connStr
|
|
catch {
|
|
set stmt [db prepare {
|
|
INSERT INTO people(idnum, name, info) VALUES(:idnum, :name, NULL)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set idnum 1
|
|
foreach name {fred wilma pebbles barney betty bam-bam} {
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
incr idnum
|
|
}
|
|
rename $stmt {}
|
|
}
|
|
|
|
test tdbc::odbc-14.1 {begin transaction - wrong # args} {*}{
|
|
-body {
|
|
::db begintransaction junk
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {wrong # args*}
|
|
}
|
|
|
|
test tdbc::odbc-14.2 {commit - wrong # args} {*}{
|
|
-body {
|
|
::db commit junk
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {wrong # args*}
|
|
}
|
|
|
|
test tdbc::odbc-14.3 {rollback - wrong # args} {*}{
|
|
-body {
|
|
::db rollback junk
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {wrong # args*}
|
|
}
|
|
|
|
test tdbc::odbc-14.4 {commit - not in transaction} {*}{
|
|
-body {
|
|
list [catch {::db commit} result] $result $::errorCode
|
|
}
|
|
-match glob
|
|
-result {1 {no transaction is in progress} {TDBC GENERAL_ERROR HY* ODBC *}}
|
|
}
|
|
|
|
test tdbc::odbc-14.5 {rollback - not in transaction} {*}{
|
|
-body {
|
|
list [catch {::db rollback} result] $result $::errorCode
|
|
}
|
|
-match glob
|
|
-result {1 {no transaction is in progress} {TDBC GENERAL_ERROR HY* ODBC *}}
|
|
}
|
|
|
|
test tdbc::odbc-14.6 {empty transaction} {*}{
|
|
-body {
|
|
::db begintransaction
|
|
::db commit
|
|
}
|
|
-result {}
|
|
}
|
|
|
|
test tdbc::odbc-14.7 {empty rolled-back transaction} {*}{
|
|
-body {
|
|
::db begintransaction
|
|
::db rollback
|
|
}
|
|
-result {}
|
|
}
|
|
|
|
test tdbcobdc-14.8 {rollback does not change database} {*}{
|
|
-body {
|
|
::db begintransaction
|
|
set stmt [::db prepare {DELETE FROM people WHERE name = 'fred'}]
|
|
set rs [$stmt execute]
|
|
while {[$rs nextrow trash]} {}
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
::db rollback
|
|
set stmt [::db prepare {SELECT idnum FROM people WHERE name = 'fred'}]
|
|
set id {changes still visible after rollback}
|
|
set rs [$stmt execute]
|
|
while {[$rs nextrow -as lists row]} {
|
|
set id [lindex $row 0]
|
|
}
|
|
rename $rs {}
|
|
rename $stmt {}
|
|
set id
|
|
}
|
|
-result 1
|
|
}
|
|
|
|
test tdbc::odbc-14.9 {commit does change database} {*}{
|
|
-setup {
|
|
set stmt1 [db prepare {
|
|
INSERT INTO people(idnum, name, info)
|
|
VALUES(7, 'mr. gravel', 0)
|
|
}]
|
|
set stmt2 [db prepare {
|
|
SELECT idnum FROM people WHERE name = 'mr. gravel'
|
|
}]
|
|
}
|
|
-body {
|
|
::db begintransaction
|
|
set rs [$stmt1 execute]
|
|
rename $rs {}
|
|
::db commit
|
|
set rs [$stmt2 execute]
|
|
while {[$rs nextrow -as lists row]} {
|
|
set id [lindex $row 0]
|
|
}
|
|
rename $rs {}
|
|
set id
|
|
}
|
|
-cleanup {
|
|
rename $stmt1 {}
|
|
rename $stmt2 {}
|
|
}
|
|
-result 7
|
|
}
|
|
|
|
test tdbc::odbc-14.10 {nested transactions} {*}{
|
|
-body {
|
|
::db begintransaction
|
|
list [catch {::db begintransaction} result] $result $::errorCode
|
|
}
|
|
-cleanup {
|
|
catch {::db rollback}
|
|
}
|
|
-match glob
|
|
-result {1 {ODBC does not support nested transactions} {TDBC GENERAL_ERROR HYC00 ODBC *}}
|
|
}
|
|
|
|
#------------------------------------------------------------------------------
|
|
#
|
|
# Clean up database again for the next round.
|
|
|
|
catch {
|
|
set stmt [db prepare {
|
|
DELETE FROM people
|
|
}]
|
|
$stmt execute
|
|
}
|
|
catch {
|
|
rename ::db {}
|
|
}
|
|
|
|
tdbc::odbc::connection create ::db $::connStr
|
|
catch {
|
|
set stmt [db prepare {
|
|
INSERT INTO people(idnum, name, info) VALUES(:idnum, :name, NULL)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set idnum 1
|
|
foreach name {fred wilma pebbles barney betty bam-bam} {
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
incr idnum
|
|
}
|
|
rename $stmt {}
|
|
}
|
|
|
|
test tdbc::odbc-15.1 {successful (empty) transaction} {*}{
|
|
-body {
|
|
db transaction {
|
|
concat ok
|
|
}
|
|
}
|
|
-result ok
|
|
}
|
|
|
|
test tdbc::odbc-15.2 {failing transaction does not get committed} {*}{
|
|
-setup {
|
|
set stmt1 [db prepare {
|
|
DELETE FROM people WHERE name = 'fred'
|
|
}]
|
|
set stmt2 [db prepare {
|
|
SELECT idnum FROM people WHERE name = 'fred'
|
|
}]
|
|
}
|
|
-body {
|
|
catch {
|
|
::db transaction {
|
|
set rs [$stmt1 execute]
|
|
rename $rs {}
|
|
error "abort the transaction"
|
|
}
|
|
} result
|
|
set id {failed transaction got committed}
|
|
set rs [$stmt2 execute]
|
|
while {[$rs nextrow -as lists row]} {
|
|
set id [lindex $row 0]
|
|
}
|
|
rename $rs {}
|
|
list $result $id
|
|
}
|
|
-cleanup {
|
|
rename $stmt1 {}
|
|
rename $stmt2 {}
|
|
}
|
|
-result {{abort the transaction} 1}
|
|
}
|
|
|
|
test tdbc::odbc-15.3 {successful transaction gets committed} {*}{
|
|
-setup {
|
|
set stmt1 [db prepare {
|
|
INSERT INTO people(idnum, name, info)
|
|
VALUES(7, 'mr. gravel', 0)
|
|
}]
|
|
set stmt2 [db prepare {
|
|
SELECT idnum FROM people WHERE name = 'mr. gravel'
|
|
}]
|
|
}
|
|
-body {
|
|
::db transaction {
|
|
set rs [$stmt1 execute]
|
|
rename $rs {}
|
|
}
|
|
set rs [$stmt2 execute]
|
|
while {[$rs nextrow -as lists row]} {
|
|
set id [lindex $row 0]
|
|
}
|
|
rename $rs {}
|
|
set id
|
|
}
|
|
-cleanup {
|
|
rename $stmt1 {}
|
|
rename $stmt2 {}
|
|
}
|
|
-result 7
|
|
}
|
|
|
|
test tdbc::odbc-15.4 {break out of transaction commits it} {*}{
|
|
-setup {
|
|
set stmt1 [db prepare {
|
|
INSERT INTO people(idnum, name, info)
|
|
VALUES(8, 'gary granite', 0)
|
|
}]
|
|
set stmt2 [db prepare {
|
|
SELECT idnum FROM people WHERE name = 'gary granite'
|
|
}]
|
|
}
|
|
-body {
|
|
while {1} {
|
|
::db transaction {
|
|
set rs [$stmt1 execute]
|
|
rename $rs {}
|
|
break
|
|
}
|
|
}
|
|
set rs [$stmt2 execute]
|
|
while {[$rs nextrow -as lists row]} {
|
|
set id [lindex $row 0]
|
|
}
|
|
rename $rs {}
|
|
set id
|
|
}
|
|
-cleanup {
|
|
rename $stmt1 {}
|
|
rename $stmt2 {}
|
|
}
|
|
-result 8
|
|
}
|
|
|
|
test tdbc::odbc-15.5 {continue in transaction commits it} {*}{
|
|
-setup {
|
|
set stmt1 [db prepare {
|
|
INSERT INTO people(idnum, name, info)
|
|
VALUES(9, 'hud rockstone', 0)
|
|
}]
|
|
set stmt2 [db prepare {
|
|
SELECT idnum FROM people WHERE name = 'hud rockstone'
|
|
}]
|
|
}
|
|
-body {
|
|
for {set i 0} {$i < 1} {incr i} {
|
|
::db transaction {
|
|
set rs [$stmt1 execute]
|
|
rename $rs {}
|
|
continue
|
|
}
|
|
}
|
|
set rs [$stmt2 execute]
|
|
while {[$rs nextrow -as lists row]} {
|
|
set id [lindex $row 0]
|
|
}
|
|
rename $rs {}
|
|
set id
|
|
}
|
|
-cleanup {
|
|
rename $stmt1 {}
|
|
rename $stmt2 {}
|
|
}
|
|
-result 9
|
|
}
|
|
|
|
test tdbc::odbc-15.6 {return in transaction commits it} {*}{
|
|
-setup {
|
|
set stmt1 [db prepare {
|
|
INSERT INTO people(idnum, name, info)
|
|
VALUES(10, 'nelson stoneyfeller', 0)
|
|
}]
|
|
set stmt2 [db prepare {
|
|
SELECT idnum FROM people WHERE name = 'nelson stoneyfeller'
|
|
}]
|
|
proc tdbcodbc-15.6 {stmt1} {
|
|
::db transaction {
|
|
set rs [$stmt1 execute]
|
|
rename $rs {}
|
|
return
|
|
}
|
|
}
|
|
}
|
|
-body {
|
|
tdbcodbc-15.6 $stmt1
|
|
set rs [$stmt2 execute]
|
|
while {[$rs nextrow -as lists row]} {
|
|
set id [lindex $row 0]
|
|
}
|
|
rename $rs {}
|
|
set id
|
|
}
|
|
-cleanup {
|
|
rename $stmt1 {}
|
|
rename $stmt2 {}
|
|
rename tdbcodbc-15.6 {}
|
|
}
|
|
-result 10
|
|
}
|
|
|
|
test tdbc::odbc-16.1 {database tables, wrong # args} {
|
|
-body {
|
|
set dict [::db tables % rubbish]
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {wrong # args*}
|
|
}
|
|
|
|
test tdbc::odbc-16.2 {database tables - empty set} {
|
|
-body {
|
|
::db tables q%
|
|
}
|
|
-result {}
|
|
}
|
|
|
|
test tdbc::odbc-16.3 {enumerate database tables} {*}{
|
|
-body {
|
|
set dict [::db tables]
|
|
list [dict exists $dict people] [dict exists $dict property]
|
|
}
|
|
-result {1 0}
|
|
}
|
|
|
|
test tdbc::odbc-16.4 {enumerate database tables} {*}{
|
|
-body {
|
|
set dict [::db tables p%]
|
|
list [dict exists $dict people] [dict exists $dict property]
|
|
}
|
|
-result {1 0}
|
|
}
|
|
|
|
test tdbc::odbc-17.1 {database columns - wrong # args} {*}{
|
|
-body {
|
|
set dict [::db columns people % rubbish]
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {wrong # args*}
|
|
}
|
|
|
|
# sqlite driver appears to report "Function sequence error" if asked for
|
|
# columns on a nonexistent table
|
|
test tdbc::odbc-17.2 {database columns - no such table} {*}{
|
|
-constraints jet||sqlserver
|
|
-body {
|
|
::db columns rubbish
|
|
}
|
|
-result {}
|
|
}
|
|
|
|
# Jet driver promotes varchar to wvarchar
|
|
test tdbc::odbc-17.3 {database columns - no match pattern} {*}{
|
|
-body {
|
|
set result {}
|
|
dict for {colname attrs} [::db columns people] {
|
|
lappend result $colname \
|
|
[dict get $attrs type] \
|
|
[expr {[dict exists $attrs precision] ?
|
|
[dict get $attrs precision] : {NULL}}] \
|
|
[expr {[dict exists $attrs scale] ?
|
|
[dict get $attrs scale] : {NULL}}] \
|
|
[dict get $attrs nullable]
|
|
}
|
|
set result
|
|
}
|
|
-match glob
|
|
-result {idnum integer * * * name *varchar 40 * * info integer * * 1}
|
|
}
|
|
|
|
# sqlite driver appears not to implement pattern matching for SQLGetColumns
|
|
test tdbc::odbc-17.4 {database columns - match pattern} {*}{
|
|
-constraints jet||sqlserver
|
|
-body {
|
|
set result {}
|
|
dict for {colname attrs} [::db columns people i%] {
|
|
lappend result $colname \
|
|
[dict get $attrs type] \
|
|
[expr {[dict exists $attrs precision] ?
|
|
[dict get $attrs precision] : {NULL}}] \
|
|
[expr {[dict exists $attrs scale] ?
|
|
[dict get $attrs scale] : {NULL}}] \
|
|
[dict get $attrs nullable]
|
|
}
|
|
set result
|
|
}
|
|
-match glob
|
|
-result {idnum integer 10 0 * info integer 10 0 1}
|
|
}
|
|
|
|
test tdbc::odbc-18.1 {$statement params - excess arg} {*}{
|
|
-setup {
|
|
set s [::db prepare {
|
|
SELECT name FROM people
|
|
WHERE name LIKE :pattern
|
|
AND idnum >= :minid
|
|
}]
|
|
$s paramtype minid numeric 10 0
|
|
$s paramtype pattern varchar 40
|
|
}
|
|
-body {
|
|
$s params excess
|
|
}
|
|
-cleanup {
|
|
rename $s {}
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {wrong # args*}
|
|
}
|
|
|
|
test tdbc::odbc-18.2 {$statement params - no params} {*}{
|
|
-setup {
|
|
set s [::db prepare {
|
|
SELECT name FROM people
|
|
}]
|
|
}
|
|
-body {
|
|
$s params
|
|
}
|
|
-cleanup {
|
|
rename $s {}
|
|
}
|
|
-result {}
|
|
}
|
|
|
|
test tdbc::odbc-18.3 {$statement params - excess arg} {*}{
|
|
-setup {
|
|
set s [::db prepare {
|
|
SELECT name FROM people
|
|
WHERE name LIKE :pattern
|
|
AND idnum >= :minid
|
|
}]
|
|
$s paramtype minid numeric 10 0
|
|
$s paramtype pattern varchar 40
|
|
}
|
|
-body {
|
|
set d [$s params]
|
|
list \
|
|
[dict get $d minid direction] \
|
|
[dict get $d minid type] \
|
|
[dict get $d minid precision] \
|
|
[dict get $d minid scale] \
|
|
[dict get $d pattern direction] \
|
|
[dict get $d pattern type] \
|
|
[dict get $d pattern precision]
|
|
}
|
|
-cleanup {
|
|
rename $s {}
|
|
}
|
|
-result {in numeric 10 0 in varchar 40}
|
|
}
|
|
|
|
test tdbc::odbc-19.1 {$connection configure - no args} \
|
|
-body {
|
|
::db configure
|
|
} \
|
|
-match glob \
|
|
-result [list -encoding [encoding system] \
|
|
-isolation * \
|
|
-readonly 0 \
|
|
-timeout 0]
|
|
|
|
test tdbc::odbc-19.2 {$connection configure - unknown arg} {*}{
|
|
-body {
|
|
::db configure -junk
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result "bad option *"
|
|
}
|
|
|
|
test tdbc::odbc-19.3 {$connection configure - inappropriate arg} {*}{
|
|
-body {
|
|
list [catch {::db configure -parent} result] $::errorCode
|
|
}
|
|
-match glob
|
|
-result {1 {TDBC GENERAL_ERROR HY* ODBC -1}}
|
|
}
|
|
|
|
test tdbc::odbc-19.4 {$connection configure - set unknown arg} {*}{
|
|
-body {
|
|
::db configure -junk morejunk
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result "bad option *"
|
|
}
|
|
|
|
test tdbc::odbc-19.5 {$connection configure - set inappropriate arg} {*}{
|
|
-body {
|
|
list [catch {::db configure -parent .} result] $::errorCode
|
|
}
|
|
-match glob
|
|
-result {1 {TDBC GENERAL_ERROR HY* ODBC -1}}
|
|
}
|
|
|
|
test tdbc::odbc-19.6 {$connection configure - wrong # args} {*}{
|
|
-body {
|
|
::db configure -parent . -junk
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result "wrong # args*"
|
|
}
|
|
|
|
test tdbc::odbc-19.7 {$connection configure - -encoding} {*}{
|
|
-body {
|
|
::db configure -encoding junk
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {unknown encoding *}
|
|
}
|
|
|
|
test tdbc::odbc-19.8 {$connection configure - -encoding} {*}{
|
|
-body {
|
|
list [catch {::db configure -encoding ebcdic} result] \
|
|
[set result] \
|
|
[set errorCode]
|
|
}
|
|
-match glob
|
|
-result {1 {optional function not implemented} {TDBC GENERAL_ERROR HYC00 ODBC *}}
|
|
}
|
|
|
|
test tdbc::odbc-19.9 {$connection configure - -encoding} \
|
|
-body {
|
|
list [::db configure -encoding [encoding system]] \
|
|
[::db configure -encoding]
|
|
} \
|
|
-result [list {} [encoding system]]
|
|
|
|
|
|
test tdbc::odbc-19.10 {$connection configure - -isolation} {*}{
|
|
-body {
|
|
::db configure -isolation junk
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {bad isolation level "junk"*}
|
|
}
|
|
|
|
test tdbc::odbc-19.11a {$connection configure - -isolation} {*}{
|
|
-constraints !sqlite
|
|
-body {
|
|
list [::db configure -isolation readcommitted] \
|
|
[::db configure -isolation]
|
|
}
|
|
-result {{} readcommitted}
|
|
}
|
|
test tdbc::odbc-19.11b {$connection configure - -isolation} {*}{
|
|
-constraints sqlite
|
|
-body {
|
|
list [::db configure -isolation readcommitted] \
|
|
[::db configure -isolation]
|
|
}
|
|
-result {{} serializable}
|
|
}
|
|
|
|
test tdbc::odbc-19.12 {$connection configure - -readonly} {*}{
|
|
-body {
|
|
::db configure -readonly junk
|
|
}
|
|
-returnCodes error
|
|
-result {expected boolean value but got "junk"}
|
|
}
|
|
|
|
# sqlite doesn't allow change to the readonly status
|
|
test tdbc::odbc-19.13 {$connection configure - -readonly} {*}{
|
|
-constraints !sqlite
|
|
-body {
|
|
list [::db configure -readonly 1] \
|
|
[::db configure -readonly] \
|
|
[::db configure -readonly 0] \
|
|
[::db configure -readonly]
|
|
}
|
|
-result {{} 1 {} 0}
|
|
}
|
|
|
|
test tdbc::odbc-19.14 {$connection configure - -timeout} {*}{
|
|
-body {
|
|
::db configure -timeout junk
|
|
}
|
|
-returnCodes error
|
|
-result {expected integer but got "junk"}
|
|
}
|
|
|
|
test tdbc::odbc-19.15 {$connection configure - -timeout} {*}{
|
|
-body {
|
|
catch {::db configure -timeout 5000} result
|
|
list [::db configure -timeout 0] [::db configure -timeout]
|
|
}
|
|
-result {{} 0}
|
|
}
|
|
|
|
test tdbc::odbc-20.1a {direct value transfers} {*}{
|
|
-constraints jet||sqlite
|
|
-setup {
|
|
db allrows {
|
|
CREATE TABLE typetest (
|
|
xint1 INTEGER,
|
|
xsmall1 SMALLINT,
|
|
xbit1 BIT,
|
|
xdouble1 DOUBLE,
|
|
xreal1 REAL
|
|
)
|
|
}
|
|
set stmt [db prepare {
|
|
INSERT INTO typetest(xint1, xsmall1, xbit1, xdouble1, xreal1)
|
|
VALUES (:i1, :s1, :b1, :d1, :r1)
|
|
}]
|
|
$stmt paramtype i1 integer
|
|
$stmt paramtype s1 smallint
|
|
$stmt paramtype b1 bit
|
|
$stmt paramtype d1 double
|
|
$stmt paramtype r1 real
|
|
}
|
|
-body {
|
|
set i1 0xbc614e
|
|
set s1 0x3039
|
|
set b1 1
|
|
set d1 1.125
|
|
set r1 1.125
|
|
$stmt allrows
|
|
db allrows -as lists {select * from typetest}
|
|
}
|
|
-result {{12345678 12345 1 1.125 1.125}}
|
|
-cleanup {
|
|
$stmt close
|
|
db allrows {
|
|
DROP TABLE typetest
|
|
}
|
|
}
|
|
}
|
|
|
|
test tdbc::odbc-20.1b {direct value transfers} {*}{
|
|
-constraints sqlserver
|
|
-setup {
|
|
db allrows {
|
|
CREATE TABLE typetest (
|
|
xbigint1 BIGINT,
|
|
xint1 INT,
|
|
xsmallint1 SMALLINT,
|
|
xtinyint1 TINYINT,
|
|
xbit1 BIT,
|
|
xdecimal1 DECIMAL(12,6),
|
|
xmoney1 MONEY,
|
|
xsmallmoney1 SMALLMONEY,
|
|
xfloat1 FLOAT,
|
|
xreal1 REAL
|
|
)
|
|
}
|
|
set stmt [db prepare {
|
|
INSERT INTO typetest(xbigint1, xint1, xsmallint1, xtinyint1, xbit1,
|
|
xdecimal1, xmoney1, xsmallmoney1, xfloat1,
|
|
xreal1)
|
|
VALUES (:bi1, :i1, :si1, :ti1, :b1, :d1, :m1, :sm1, :f1, :r1)
|
|
}]
|
|
$stmt paramtype bi1 bigint
|
|
$stmt paramtype i1 integer
|
|
$stmt paramtype si1 smallint
|
|
$stmt paramtype ti1 tinyint
|
|
$stmt paramtype b1 bit
|
|
$stmt paramtype d1 decimal 12 6
|
|
$stmt paramtype m1 decimal 16 4
|
|
$stmt paramtype sm1 decimal 9 2
|
|
$stmt paramtype f1 float
|
|
$stmt paramtype r1 real
|
|
}
|
|
-body {
|
|
set bi1 0x7048860ddf79
|
|
set i1 0xbc614e
|
|
set si1 0x3039
|
|
set ti1 0x7b
|
|
set b1 1
|
|
set d1 12345.678901
|
|
set m1 12345.6789
|
|
set sm1 123.45
|
|
set f1 1.0000000149011612
|
|
set r1 1.125
|
|
$stmt allrows
|
|
db allrows -as lists {select * from typetest}
|
|
}
|
|
-result {{123456789012345 12345678 12345 123 1 12345.678901 12345.6789 123.45 1.0000000149011612 1.125}}
|
|
-cleanup {
|
|
$stmt close
|
|
db allrows {
|
|
DROP TABLE typetest
|
|
}
|
|
}
|
|
}
|
|
|
|
test tdbc::odbc-21.2 {transfers of binary data} {*}{
|
|
-setup {
|
|
db allrows {
|
|
CREATE TABLE bintest (
|
|
xint1 INTEGER PRIMARY KEY,
|
|
xbin VARBINARY(256)
|
|
)
|
|
}
|
|
set stmt1 [db prepare {
|
|
INSERT INTO bintest (xint1, xbin)
|
|
VALUES(:i1, :b1)
|
|
}]
|
|
$stmt1 paramtype i1 integer
|
|
$stmt1 paramtype b1 varbinary 256
|
|
set stmt2 [db prepare {
|
|
SELECT xbin FROM bintest WHERE xint1 = :i1
|
|
}]
|
|
$stmt2 paramtype i1 integer
|
|
}
|
|
-body {
|
|
set listdata {}
|
|
for {set i 0} {$i < 256} {incr i} {
|
|
lappend listdata $i
|
|
}
|
|
set b1 [binary format c* $listdata]
|
|
set i1 123
|
|
$stmt1 allrows
|
|
$stmt2 foreach -as lists row { set b2 [lindex $row 0] }
|
|
list [string length $b2] [string compare $b1 $b2]
|
|
}
|
|
-result {256 0}
|
|
-cleanup {
|
|
$stmt1 close
|
|
$stmt2 close
|
|
db allrows {DROP TABLE bintest}
|
|
}
|
|
}
|
|
|
|
test tdbc::odbc-22.1 {datasources, wrong # args} {*}{
|
|
-body {
|
|
tdbc::odbc::datasources two args
|
|
}
|
|
-returnCodes error
|
|
-result {wrong # args*}
|
|
-match glob
|
|
}
|
|
|
|
test tdbc::odbc-22.2 {datasources, bad arg} {*}{
|
|
-body {
|
|
tdbc::odbc::datasources -rubbish
|
|
}
|
|
-returnCodes error
|
|
-result {bad option "-rubbish"*}
|
|
-match glob
|
|
}
|
|
|
|
test tdbc::odbc-22.3 {datasources, sys + user = all} {*}{
|
|
-body {
|
|
set d1 [tdbc::odbc::datasources -user]
|
|
set d2 [tdbc::odbc::datasources -system]
|
|
set d3 [tdbc::odbc::datasources]
|
|
set d4 $d1
|
|
lappend d4 {*}$d2
|
|
list [expr {[llength $d1] % 2}] [expr {[llength $d2] % 2}] \
|
|
[expr {[llength $d3] == [llength $d1] + [llength $d2]}] \
|
|
[string equal $d4 $d3]
|
|
}
|
|
-result {0 0 1 1}
|
|
}
|
|
|
|
test tdbc::odbc-23.1 {drivers, wrong # args} {*}{
|
|
-body {
|
|
tdbc::odbc::drivers rubbish
|
|
}
|
|
-returnCodes error
|
|
-result {wrong # args*}
|
|
-match glob
|
|
}
|
|
|
|
test tdbc::odbc-23.2 {drivers} {*}{
|
|
-body {
|
|
expr {[llength [tdbc::odbc::drivers]] % 2}
|
|
}
|
|
-result 0
|
|
}
|
|
|
|
test tdbc::odbc-24.1 {datasource - wrong # args} {*}{
|
|
-constraints {odbcinst}
|
|
-body {
|
|
tdbc::odbc::datasource
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {wrong # args*}
|
|
}
|
|
|
|
test tdbc::odbc-24.2 {datasource - bad operation} {*}{
|
|
-constraints {odbcinst}
|
|
-body {
|
|
tdbc::odbc::datasource rubbish rubbish rubbish=rubbish
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {bad operation "rubbish"*}
|
|
}
|
|
|
|
test tdbc::odbc-24.3 {datasource - bad driver} {*}{
|
|
-constraints {odbcinst}
|
|
-body {
|
|
list [catch {
|
|
tdbc::odbc::datasource add rubbish rubbish=rubbish
|
|
} result] \
|
|
$::errorCode
|
|
}
|
|
-match glob
|
|
-result {1 {TDBC ODBC *}}
|
|
}
|
|
|
|
test tdbc::odbc-24.4 {datasource - add/remove} {*}{
|
|
-constraints odbcinst&&jet
|
|
-body {
|
|
list \
|
|
[tdbc::odbc::datasource add \
|
|
{Microsoft Access Driver (*.mdb)} \
|
|
DSN=TdbcOdbcTestDB \
|
|
DBQ=$testDBQ] \
|
|
[dict exists [tdbc::odbc::datasources] TdbcOdbcTestDB] \
|
|
[tdbc::odbc::datasource remove \
|
|
{Microsoft Access Driver (*.mdb)} \
|
|
DSN=TdbcOdbcTestDB] \
|
|
[dict exists [tdbc::odbc::datasources] TdbcOdbcTestDB]
|
|
}
|
|
-result {{} 1 {} 0}
|
|
}
|
|
|
|
test tdbc::odbc-25.1a {error code} {*}{
|
|
-constraints sqlite
|
|
-setup {
|
|
db allrows {DELETE FROM people}
|
|
db allrows {INSERT INTO people(idnum, name) VALUES(1, 'fred')}
|
|
}
|
|
-body {
|
|
list [catch {
|
|
db allrows {INSERT INTO people(idnum, name) VALUES(1, 'fred')}
|
|
} result] $result $::errorCode
|
|
}
|
|
-match glob
|
|
-result {1 * {TDBC GENERAL_ERROR HY* ODBC *}}
|
|
}
|
|
|
|
test tbdc::odbc-25.1b {error code} {*}{
|
|
-constraints jet||sqlserver
|
|
-setup {
|
|
db allrows {DELETE FROM people}
|
|
db allrows {INSERT INTO people(idnum, name) VALUES(1, 'fred')}
|
|
}
|
|
-body {
|
|
list [catch {
|
|
db allrows {INSERT INTO people(idnum, name) VALUES(1, 'fred')}
|
|
} result] $result $::errorCode
|
|
}
|
|
-match glob
|
|
-result {1 * {TDBC CONSTRAINT_VIOLATION 23000 ODBC *}}
|
|
}
|
|
|
|
test tdbc::odbc-26.1 {parameters in native form} {*}{
|
|
-constraints jet||sqlserver
|
|
-body {
|
|
list [catch {
|
|
db allrows {SELECT * from people where name = ?}
|
|
} result] $result $::errorCode
|
|
}
|
|
-match glob
|
|
-result {1 * {TDBC DYNAMIC_SQL_ERROR 07002 ODBC -1}}
|
|
}
|
|
|
|
test tdbc::odbc-27.1a {blobs} {*}{
|
|
-constraints sqlite
|
|
-setup {
|
|
db allrows {
|
|
create table blobtest (
|
|
id integer primary key,
|
|
stuff blob
|
|
)
|
|
}
|
|
set testblob [string repeat 0123456789abx 200]
|
|
db allrows {
|
|
insert into blobtest(id, stuff) values (1, :testblob)
|
|
}
|
|
}
|
|
-body {
|
|
set trouble {}
|
|
db foreach row {select id, stuff from blobtest} {
|
|
if {[dict get $row stuff] ne $testblob} {
|
|
set trouble "blob is \"[dict get $row stuff]\""
|
|
append trouble \n "should be \"" $testblob "\""
|
|
append trouble \n "length is [string length \
|
|
[dict get $row stuff]]"
|
|
append trouble \n "should be [string length $testblob]"
|
|
}
|
|
}
|
|
set trouble
|
|
}
|
|
-cleanup {
|
|
db allrows {
|
|
drop table blobtest
|
|
}
|
|
}
|
|
-result {}
|
|
}
|
|
|
|
test tdbc::odbc-27.1b {blobs} {*}{
|
|
-constraints sqlserver
|
|
-setup {
|
|
db allrows {
|
|
create table blobtest (
|
|
id integer primary key,
|
|
stuff image
|
|
)
|
|
}
|
|
set testblob [string repeat 0123456789abx 200]
|
|
db allrows {
|
|
insert into blobtest(id, stuff) values (1, :testblob)
|
|
}
|
|
}
|
|
-body {
|
|
set trouble {}
|
|
db foreach row {select id, stuff from blobtest} {
|
|
if {[dict get $row stuff] ne $testblob} {
|
|
set trouble "blob is \"[dict get $row stuff]\""
|
|
append trouble \n "should be \"" $testblob "\""
|
|
append trouble \n "length is [string length \
|
|
[dict get $row stuff]]"
|
|
append trouble \n "should be [string length $testblob]"
|
|
}
|
|
}
|
|
set trouble
|
|
}
|
|
-cleanup {
|
|
db allrows {
|
|
drop table blobtest
|
|
}
|
|
}
|
|
-result {}
|
|
}
|
|
|
|
test tdbc::odbc-27.2a {memos} {*}{
|
|
-constraints jet
|
|
-setup {
|
|
db allrows {
|
|
create table blobtest (
|
|
id integer primary key,
|
|
stuff memo
|
|
)
|
|
}
|
|
set testblob [string repeat 0123456789abs 200]
|
|
set stmt [db prepare {
|
|
insert into blobtest(id, stuff) values (1, :testblob)
|
|
}]
|
|
$stmt paramtype testblob longvarchar 65535
|
|
$stmt allrows
|
|
$stmt close
|
|
}
|
|
-body {
|
|
set trouble {}
|
|
set count 0
|
|
db foreach row {select id, stuff from blobtest} {
|
|
incr count
|
|
if {[dict get $row stuff] ne $testblob} {
|
|
set trouble "blob is \"[dict get $row stuff]\""
|
|
append trouble \n "should be \"" $testblob "\""
|
|
append trouble \n "length is [string length \
|
|
[dict get $row stuff]]"
|
|
append trouble \n "should be [string length $testblob]"
|
|
}
|
|
}
|
|
if {$count != 1} {
|
|
append trouble \n "$count rows returned, should have been 1"
|
|
}
|
|
set trouble
|
|
}
|
|
-cleanup {
|
|
db allrows {
|
|
drop table blobtest
|
|
}
|
|
}
|
|
-result {}
|
|
}
|
|
|
|
test tdbc::odbc-27.2b {clobs} {*}{
|
|
-constraints sqlite
|
|
-setup {
|
|
db allrows {
|
|
create table blobtest (
|
|
id integer primary key,
|
|
stuff varchar(10240)
|
|
)
|
|
}
|
|
set testblob [string repeat 0123456789abc 200]
|
|
db allrows {
|
|
insert into blobtest(id, stuff) values (1, :testblob)
|
|
}
|
|
}
|
|
-body {
|
|
set trouble {}
|
|
db foreach row {select id, stuff from blobtest} {
|
|
if {[dict get $row stuff] ne $testblob} {
|
|
set trouble "blob is \"[dict get $row stuff]\""
|
|
append trouble \n "should be \"" $testblob "\""
|
|
append trouble \n "length is [string length \
|
|
[dict get $row stuff]]"
|
|
append trouble \n "should be [string length $testblob]"
|
|
}
|
|
}
|
|
set trouble
|
|
}
|
|
-cleanup {
|
|
db allrows {
|
|
drop table blobtest
|
|
}
|
|
}
|
|
-result {}
|
|
}
|
|
|
|
test tdbc::odbc-27.2c {clobs} {*}{
|
|
-constraints sqlserver
|
|
-setup {
|
|
db allrows {
|
|
create table blobtest (
|
|
id integer primary key,
|
|
stuff nvarchar(max)
|
|
)
|
|
}
|
|
set testblob [string repeat 0123456789abc 200]
|
|
db allrows {
|
|
insert into blobtest(id, stuff) values (1, :testblob)
|
|
}
|
|
}
|
|
-body {
|
|
set trouble {}
|
|
db foreach row {select id, stuff from blobtest} {
|
|
if {[dict get $row stuff] ne $testblob} {
|
|
set trouble "blob is \"[dict get $row stuff]\""
|
|
append trouble \n "should be \"" $testblob "\""
|
|
append trouble \n "length is [string length \
|
|
[dict get $row stuff]]"
|
|
append trouble \n "should be [string length $testblob]"
|
|
}
|
|
}
|
|
set trouble
|
|
}
|
|
-cleanup {
|
|
db allrows {
|
|
drop table blobtest
|
|
}
|
|
}
|
|
-result {}
|
|
}
|
|
|
|
test tdbc::odbc-27.4 {blobs} {*}{
|
|
-constraints sqlserver
|
|
-setup {
|
|
db allrows {
|
|
create table blobtest (
|
|
id integer primary key,
|
|
stuff nvarchar(max)
|
|
)
|
|
}
|
|
set testblob [string repeat 0123456789abc 200]
|
|
db allrows {
|
|
insert into blobtest(id, stuff) values (1, :testblob)
|
|
}
|
|
}
|
|
-body {
|
|
set trouble {}
|
|
db foreach row {select id, stuff from blobtest} {
|
|
if {[dict get $row stuff] ne $testblob} {
|
|
set trouble "blob is \"[dict get $row stuff]\""
|
|
append trouble \n "should be \"" $testblob "\""
|
|
append trouble \n "length is [string length \
|
|
[dict get $row stuff]]"
|
|
append trouble \n "should be [string length $testblob]"
|
|
}
|
|
}
|
|
set trouble
|
|
}
|
|
-cleanup {
|
|
db allrows {
|
|
drop table blobtest
|
|
}
|
|
}
|
|
-result {}
|
|
}
|
|
|
|
# Information schema tests require additional tables in the database.
|
|
# Create them now.
|
|
|
|
catch {::db allrows {DROP TABLE d}}
|
|
catch {::db allrows {DROP TABLE c}}
|
|
catch {::db allrows {DROP TABLE b}}
|
|
catch {::db allrows {DROP TABLE a}}
|
|
|
|
# Create some tables with foreign key relationships to test querying
|
|
# foreign keys
|
|
|
|
::db allrows {
|
|
CREATE TABLE a (
|
|
k1 INTEGER,
|
|
CONSTRAINT pk_a PRIMARY KEY(k1)
|
|
)
|
|
}
|
|
|
|
::db allrows {
|
|
CREATE TABLE b (
|
|
k1 INTEGER,
|
|
k2 INTEGER,
|
|
CONSTRAINT pk_b PRIMARY KEY(k1, k2),
|
|
CONSTRAINT fk_b1 FOREIGN KEY (k1) REFERENCES a(k1),
|
|
CONSTRAINT fk_b2 FOREIGN KEY (k2) REFERENCES a(k1)
|
|
)
|
|
}
|
|
|
|
::db allrows {
|
|
CREATE TABLE c (
|
|
p1 INTEGER,
|
|
p2 INTEGER,
|
|
CONSTRAINT pk_c PRIMARY KEY(p1, p2),
|
|
CONSTRAINT fk_c1 FOREIGN KEY (p1) REFERENCES a(k1),
|
|
CONSTRAINT fk_c2 FOREIGN KEY (p2) REFERENCES a(k1),
|
|
CONSTRAINT fk_cpair FOREIGN KEY (p2,p1) REFERENCES b(k1,k2)
|
|
)
|
|
}
|
|
|
|
::db allrows {
|
|
CREATE TABLE d (
|
|
dtext VARCHAR(40)
|
|
)
|
|
}
|
|
|
|
test tdbc::odbc-28.1 {Primary keys - no arg} {*}{
|
|
-body {
|
|
::db primarykeys
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {wrong # args*}
|
|
}
|
|
test tdbc::odbc-28.2 {Primary keys - no primary key} {*}{
|
|
-constraints !jet
|
|
-body {
|
|
::db primarykeys d
|
|
}
|
|
-result {}
|
|
}
|
|
test tdbc::odbc-28.3 {Primary keys - simple primary key} {*}{
|
|
-constraints !jet
|
|
-body {
|
|
set result {}
|
|
foreach row [::db primarykeys a] {
|
|
lappend result [dict get $row columnName] [dict get $row ordinalPosition]
|
|
}
|
|
set result
|
|
}
|
|
-result {k1 1}
|
|
}
|
|
# next test uses unimplemented functionality in Jet, tickles a bug in
|
|
# the Win32 SQLite ODBC driver
|
|
test tdbc::odbc-28.4 {Primary keys - compound primary key} {*}{
|
|
-constraints !jet&&!(windows&&sqlite)
|
|
-body {
|
|
set result {}
|
|
foreach row [::db primarykeys b] {
|
|
lappend result [dict get $row columnName] [dict get $row ordinalPosition]
|
|
}
|
|
set result
|
|
}
|
|
-result {k1 1 k2 2}
|
|
}
|
|
|
|
test tdbc::odbc-29.1 {Foreign keys - wrong # args} {*}{
|
|
-body {
|
|
::db foreignkeys -wrong
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {wrong # args*}
|
|
}
|
|
|
|
test tdbc::odbc-29.2 {Foreign keys - bad arg} {*}{
|
|
-body {
|
|
::db foreignkeys -primary a -rubbish b
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {bad option "-rubbish"*}
|
|
}
|
|
|
|
test tdbc::odbc-29.3 {Foreign keys - redundant arg} {*}{
|
|
-body {
|
|
::db foreignkeys -primary a -primary b
|
|
}
|
|
-returnCodes error
|
|
-match glob
|
|
-result {duplicate option "-primary"*}
|
|
}
|
|
|
|
test tdbc::odbc-29.4 {Foreign keys - list all} \
|
|
-constraints knownBug \
|
|
-body {
|
|
set result {}
|
|
set wanted {a {} b {} c {} d {} people {}}
|
|
foreach row [::db foreignkeys] {
|
|
if {[dict exists $wanted [dict get $row foreignTable]]} {
|
|
dict set result [dict get $row foreignConstraintName] \
|
|
[dict get $row ordinalPosition] \
|
|
[list [dict get $row foreignTable] \
|
|
[dict get $row foreignColumn] \
|
|
[dict get $row primaryTable] \
|
|
[dict get $row primaryColumn]]
|
|
}
|
|
}
|
|
lsort [dict values $result]
|
|
} \
|
|
-result [list \
|
|
{1 {b k1 a k1}} \
|
|
{1 {b k2 a k1}} \
|
|
{1 {c p1 a k1}} \
|
|
{1 {c p1 b k2} 2 {c p2 b k1}} \
|
|
{1 {c p2 a k1}} \
|
|
]
|
|
|
|
|
|
test tdbc::odbc-29.5 {Foreign keys - -foreign} \
|
|
-constraints !jet \
|
|
-body {
|
|
set result {}
|
|
set wanted {a {} b {} c {} d {} people {}}
|
|
foreach row [::db foreignkeys -foreign c] {
|
|
if {[dict exists $wanted [dict get $row foreignTable]]} {
|
|
dict set result [dict get $row foreignConstraintName] \
|
|
[dict get $row ordinalPosition] \
|
|
[list [dict get $row foreignTable] \
|
|
[dict get $row foreignColumn] \
|
|
[dict get $row primaryTable] \
|
|
[dict get $row primaryColumn]]
|
|
}
|
|
}
|
|
lsort [dict values $result]
|
|
} \
|
|
-result [list \
|
|
{1 {c p1 a k1}} \
|
|
{1 {c p2 a k1}} \
|
|
{1 {c p2 b k1} 2 {c p1 b k2}} \
|
|
]
|
|
|
|
test tdbc::odbc-29.6 {Foreign keys - -primary} \
|
|
-constraints !jet \
|
|
-body {
|
|
set result {}
|
|
set wanted {a {} b {} c {} d {} people {}}
|
|
foreach row [::db foreignkeys -primary a] {
|
|
if {[dict exists $wanted [dict get $row foreignTable]]} {
|
|
dict set result [dict get $row foreignConstraintName] \
|
|
[dict get $row ordinalPosition] \
|
|
[list [dict get $row foreignTable] \
|
|
[dict get $row foreignColumn] \
|
|
[dict get $row primaryTable] \
|
|
[dict get $row primaryColumn]]
|
|
}
|
|
}
|
|
lsort [dict values $result]
|
|
} \
|
|
-result [list \
|
|
{1 {b k1 a k1}} \
|
|
{1 {b k2 a k1}} \
|
|
{1 {c p1 a k1}} \
|
|
{1 {c p2 a k1}}]
|
|
|
|
test tdbc::odbc-29.7 {Foreign keys - -foreign and -primary} \
|
|
-constraints !jet \
|
|
-body {
|
|
set result {}
|
|
set wanted {a {} b {} c {} d {} people {}}
|
|
foreach row [::db foreignkeys -foreign c -primary b] {
|
|
if {[dict exists $wanted [dict get $row foreignTable]]} {
|
|
dict set result [dict get $row foreignConstraintName] \
|
|
[dict get $row ordinalPosition] \
|
|
[list [dict get $row foreignTable] \
|
|
[dict get $row foreignColumn] \
|
|
[dict get $row primaryTable] \
|
|
[dict get $row primaryColumn]]
|
|
}
|
|
}
|
|
lsort [dict values $result]
|
|
} \
|
|
-result [list {1 {c p2 b k1} 2 {c p1 b k2}}]
|
|
|
|
# In next test, JET throws an error because there is no statement.
|
|
# SQLite and SQL Server both return a single empty result set
|
|
|
|
test tdbc::odbc-30.0 {Multiple result sets} {*}{
|
|
-constraints !jet
|
|
-body {
|
|
set stmt [::db prepare { }]
|
|
catch {
|
|
set resultset [$stmt execute {}]
|
|
catch {
|
|
set rowsets {}
|
|
while {1} {
|
|
set rows {}
|
|
while {[$resultset nextrow row]} {
|
|
lappend rows $row
|
|
}
|
|
lappend rowsets $rows
|
|
if {[$resultset nextresults] == 0} break
|
|
}
|
|
set rowsets
|
|
} results
|
|
rename $resultset {}
|
|
set results
|
|
} results
|
|
rename $stmt {}
|
|
set results
|
|
}
|
|
-result {{}}
|
|
}
|
|
|
|
test tdbc::odbc-30.1 {Multiple result sets - but in reality only one} {*}{
|
|
-setup {
|
|
::db allrows {delete from people}
|
|
set stmt [db prepare {
|
|
INSERT INTO people(idnum, name, info) VALUES(:idnum, :name, NULL)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set idnum 1
|
|
foreach name {fred wilma pebbles barney betty bam-bam} {
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
incr idnum
|
|
}
|
|
rename $stmt {}
|
|
}
|
|
-body {
|
|
set stmt [::db prepare {
|
|
select idnum, name from people where name = :a;
|
|
}]
|
|
catch {
|
|
set resultset [$stmt execute {a wilma}]
|
|
catch {
|
|
set rowsets {}
|
|
while {1} {
|
|
set rows {}
|
|
while {[$resultset nextrow row]} {
|
|
lappend rows $row
|
|
}
|
|
lappend rowsets $rows
|
|
if {[$resultset nextresults] == 0} break
|
|
}
|
|
set rowsets
|
|
} results
|
|
rename $resultset {}
|
|
set results
|
|
} results
|
|
rename $stmt {}
|
|
set results
|
|
}
|
|
-result {{{idnum 2 name wilma}}}
|
|
}
|
|
|
|
# sqlite and jet drivers don't support multiple statements
|
|
test tdbc::odbc-30.2 {Multiple result sets - actually multiple} {*}{
|
|
-constraints !jet&&!sqlite
|
|
-setup {
|
|
::db allrows {delete from people}
|
|
set stmt [db prepare {
|
|
INSERT INTO people(idnum, name, info) VALUES(:idnum, :name, NULL)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set idnum 1
|
|
foreach name {fred wilma pebbles barney betty bam-bam} {
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
incr idnum
|
|
}
|
|
rename $stmt {}
|
|
}
|
|
-body {
|
|
set stmt [::db prepare {
|
|
select idnum, name from people where name = :a;
|
|
select idnum, name, 1 as something from people where name = :b;
|
|
}]
|
|
catch {
|
|
set resultset [$stmt execute {a wilma b pebbles}]
|
|
catch {
|
|
set rowsets {}
|
|
while {1} {
|
|
set rows {}
|
|
while {[$resultset nextrow row]} {
|
|
lappend rows $row
|
|
}
|
|
lappend rowsets $rows
|
|
if {[$resultset nextresults] == 0} break
|
|
}
|
|
set rowsets
|
|
} results
|
|
rename $resultset {}
|
|
set results
|
|
} results
|
|
rename $stmt {}
|
|
set results
|
|
}
|
|
-result {{{idnum 2 name wilma}} {{idnum 3 name pebbles something 1}}}
|
|
}
|
|
|
|
test tdbc::odbc-30.3 {Multiple result sets - try to read past end} {*}{
|
|
-setup {
|
|
::db allrows {delete from people}
|
|
set stmt [db prepare {
|
|
INSERT INTO people(idnum, name, info) VALUES(:idnum, :name, NULL)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set idnum 1
|
|
foreach name {fred wilma pebbles barney betty bam-bam} {
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
incr idnum
|
|
}
|
|
rename $stmt {}
|
|
}
|
|
-body {
|
|
set stmt [::db prepare {
|
|
select idnum, name from people where name = :a;
|
|
}]
|
|
catch {
|
|
set resultset [$stmt execute {a wilma}]
|
|
catch {
|
|
set rowsets {}
|
|
while {1} {
|
|
set rows {}
|
|
while {[$resultset nextrow row]} {
|
|
lappend rows $row
|
|
}
|
|
lappend rowsets $rows
|
|
if {[$resultset nextresults] == 0} break
|
|
}
|
|
lappend rowsets [catch {$resultset nextresults} msg] $msg
|
|
set rowsets
|
|
} results
|
|
rename $resultset {}
|
|
set results
|
|
} results
|
|
rename $stmt {}
|
|
set results
|
|
}
|
|
-match glob
|
|
-result {{{idnum 2 name wilma}} 0 0}
|
|
}
|
|
|
|
test tdbc::odbc-30.4 {Multiple result sets - foreach} {*}{
|
|
-constraints !jet&&!sqlite
|
|
-setup {
|
|
::db allrows {delete from people}
|
|
set stmt [db prepare {
|
|
INSERT INTO people(idnum, name, info) VALUES(:idnum, :name, NULL)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set idnum 1
|
|
foreach name {fred wilma pebbles barney betty bam-bam} {
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
incr idnum
|
|
}
|
|
rename $stmt {}
|
|
}
|
|
-body {
|
|
set rows {}
|
|
::db foreach -columnsvar c -- row {
|
|
select idnum, name from people where name = :a;
|
|
select idnum, name, 1 as something from people where name = :b
|
|
} {a wilma b pebbles} {
|
|
lappend rows $c $row
|
|
}
|
|
set rows
|
|
}
|
|
-result {{idnum name} {idnum 2 name wilma} {idnum name something} {idnum 3 name pebbles something 1}}
|
|
}
|
|
|
|
test tdbc::odbc-30.5 {Multiple result sets - allrows} {*}{
|
|
-constraints !jet&&!sqlite
|
|
-setup {
|
|
::db allrows {delete from people}
|
|
set stmt [db prepare {
|
|
INSERT INTO people(idnum, name, info) VALUES(:idnum, :name, NULL)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set idnum 1
|
|
foreach name {fred wilma pebbles barney betty bam-bam} {
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
incr idnum
|
|
}
|
|
rename $stmt {}
|
|
}
|
|
-body {
|
|
::db allrows -as dicts {
|
|
select idnum, name from people where name = :a;
|
|
select idnum, name, 1 as something from people where name = :b;
|
|
} {a wilma b pebbles}
|
|
}
|
|
-result {{idnum 2 name wilma} {idnum 3 name pebbles something 1}}
|
|
}
|
|
|
|
test tdbc::odbc-30.6 {rowcount in multiple result sets} {*}{
|
|
-constraints !jet&&!sqlite
|
|
-setup {
|
|
::db allrows {delete from people}
|
|
set stmt [db prepare {
|
|
INSERT INTO people(idnum, name, info) VALUES(:idnum, :name, NULL)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set idnum 1
|
|
foreach name {fred wilma pebbles barney betty bam-bam} {
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
incr idnum
|
|
}
|
|
rename $stmt {}
|
|
unset stmt
|
|
}
|
|
-body {
|
|
set stmt [db prepare {
|
|
INSERT INTO PEOPLE(idnum, name, info)
|
|
SELECT idnum+10, name+'2', info
|
|
FROM PEOPLE
|
|
WHERE name LIKE 'b%';
|
|
INSERT INTO PEOPLE(idnum, name, info)
|
|
SELECT idnum+20, name+'3', info
|
|
FROM PEOPLE
|
|
WHERE name LIKE 'f%'
|
|
}]
|
|
set rs [$stmt execute]
|
|
set result {}
|
|
while {1} {
|
|
lappend result [$rs rowcount]
|
|
if {![$rs nextresults]} break
|
|
}
|
|
set result
|
|
}
|
|
-cleanup {
|
|
catch {rename $rs {}}
|
|
catch {rename $stmt {}}
|
|
::db allrows {delete from people}
|
|
}
|
|
-result {3 1}
|
|
}
|
|
|
|
test tdbc::odbc-31.1 {stored procedure - invoke with default config} {*}{
|
|
-constraints sqlserver
|
|
-setup {
|
|
::db allrows {delete from people}
|
|
set stmt [db prepare {
|
|
INSERT INTO people(idnum, name, info) VALUES(:idnum, :name, NULL)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set idnum 1
|
|
foreach name {fred wilma pebbles barney betty bam-bam} {
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
incr idnum
|
|
}
|
|
rename $stmt {}
|
|
db allrows {
|
|
IF EXISTS(SELECT name FROM sysobjects
|
|
WHERE name = 'find_person' AND type = 'P')
|
|
DROP PROCEDURE find_person
|
|
}
|
|
db allrows {
|
|
CREATE PROCEDURE find_person
|
|
@name VARCHAR(40),
|
|
@idnum INTEGER OUTPUT
|
|
AS
|
|
SELECT @idnum = idnum FROM people WHERE name = @name
|
|
}
|
|
catch {unset stmt}
|
|
}
|
|
-body {
|
|
set stmt [::db prepare {
|
|
DECLARE @x AS INTEGER;
|
|
EXECUTE find_person :name, @x OUTPUT;
|
|
SELECT @x AS result
|
|
}]
|
|
$stmt allrows {name barney}
|
|
}
|
|
-cleanup {
|
|
if {[info exists stmt]} {
|
|
rename $stmt {}
|
|
}
|
|
db allrows {
|
|
DROP PROCEDURE find_person
|
|
}
|
|
}
|
|
-result {{result 4}}
|
|
}
|
|
|
|
test tdbc::odbc-31.2 {stored procedure - invoke with escapes} {*}{
|
|
-constraints sqlserver&&knownBug
|
|
-setup {
|
|
::db allrows {delete from people}
|
|
set stmt [db prepare {
|
|
INSERT INTO people(idnum, name, info) VALUES(:idnum, :name, NULL)
|
|
}]
|
|
$stmt paramtype idnum integer
|
|
$stmt paramtype name varchar 40
|
|
set idnum 1
|
|
foreach name {fred wilma pebbles barney betty bam-bam} {
|
|
set rs [$stmt execute]
|
|
rename $rs {}
|
|
incr idnum
|
|
}
|
|
rename $stmt {}
|
|
db allrows {
|
|
IF EXISTS(SELECT name FROM sysobjects
|
|
WHERE name = 'find_person' AND type = 'P')
|
|
DROP PROCEDURE find_person
|
|
}
|
|
db allrows -outputparams x {
|
|
CREATE PROCEDURE find_person
|
|
@name VARCHAR(40),
|
|
@idnum INTEGER OUTPUT
|
|
AS
|
|
SELECT @idnum = idnum FROM people WHERE name = @name
|
|
}
|
|
catch {unset stmt}
|
|
}
|
|
-body {
|
|
set stmt [::db prepare {{CALL find_person(:name, :x)}}]
|
|
$stmt paramtype x out integer 10
|
|
puts [$stmt params]
|
|
$stmt allrows {name barney}
|
|
}
|
|
-cleanup {
|
|
if {[info exists stmt]} {
|
|
rename $stmt {}
|
|
}
|
|
db allrows {
|
|
DROP PROCEDURE find_person
|
|
}
|
|
}
|
|
-result {x 4}
|
|
}
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Test cleanup. Drop tables and get rid of the test database.
|
|
|
|
|
|
catch {::db allrows {DROP TABLE d}}
|
|
catch {::db allrows {DROP TABLE c}}
|
|
catch {::db allrows {DROP TABLE b}}
|
|
catch {::db allrows {DROP TABLE a}}
|
|
catch {::db allrows {DROP TABLE people}}
|
|
|
|
catch {rename ::db {}}
|
|
|
|
puts [info class instances tdbc::connection]
|
|
puts [info class instances tdbc::statement]
|
|
puts [info class instances tdbc::resultset]
|
|
|
|
|
|
if {[info exists testFileName]} {
|
|
catch {removeFile $testFileName $testdir}
|
|
}
|
|
removeDirectory tdbctest
|
|
|
|
cleanupTests
|
|
return
|
|
|
|
# Local Variables:
|
|
# mode: tcl
|
|
# End:
|