// -*- mode:C++; tab-width:2; c-basic-offset:2; indent-tabs-mode:nil -*-
//
// Copyright (C) 2000-2005 by Roger Rene Kommer / artefaktur, Kassel, Germany.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public License (LGPL).
//
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// License ACDK-FreeLicense document enclosed in the distribution
// for more for more details.
// This file is part of the Artefaktur Component Development Kit:
// ACDK
//
// Please refer to
// - http://www.acdk.de
// - http://www.artefaktur.com
// - http://acdk.sourceforge.net
// for more information.
//
// $Header: /cvsroot/acdk/acdk/acdk_sql_odbc/src/acdk/tools/odbctests/dbconnect.cpp,v 1.10 2005/03/08 18:55:38 kommer Exp $
#include <acdk.h>
#include <acdk/lang/System.h>
#include <acdk/lang/Integer.h>
#include <acdk/lang/Long.h>
#include <acdk/lang/Double.h>
#include <acdk/lang/ClassNotFoundException.h>
#include <acdk/util/Date.h>
#include <acdk/sql/DriverManager.h>
#include <acdk/sql/SQLException.h>
#include <acdk/sql/Statement.h>
#include <acdk/sql/ResultSetMetaData.h>
#include <acdk/sql/odbc/ODBCDriver.h>
#include "dbconnect.h"
namespace acdk {
namespace tools {
namespace odbctests {
using namespace acdk::lang;
using namespace acdk::sql;
/**
* Class DBConnect:
**/
DBConnect::DBConnect()
{
_status = false;
_out = System::out;
_sizeOfTimeStamp = 8;
_url = Nil;
_driver = Nil;
_connection = Nil;
_connectionProperties = Nil;
_testTable = Nil;
_numberOfTestRecords = 0;
_testSuccessful = false;
_starttime = 0;
}
DBConnect::~DBConnect()
{
if (getStatus() && (_connection != Nil)){
_connection->close();
}
}
void
DBConnect::init(RString testTable, int numberOfTestRecords, RConnection connection,
::acdk::io::RPrintWriter out)
{
_connection = connection;
_testTable = testTable;
_numberOfTestRecords = numberOfTestRecords;
_out = out;
if (connection != Nil) {
setStatus(true);
} else {
setStatus(false);
}
}
/**
* connect(RString url)
* in: URL (Connection String to Database)
* out: bool (true if connection is ok, false if error occurs)
**/
bool DBConnect::connect(RString url)
{
SYNCTHIS(); // Paranoia setting ;-)
setURL(url); // Set new URL in member var
setStatus(false);
try {
System::out->println(url);
_driver = DriverManager::getDriver(url);
if (_driver == Nil){
return false;
}
_connectionProperties = new acdk::util::Properties();
_connection = RConnection(_driver->connect(url, Nil));
setStatus(true); // set connection flag to valid
} catch (RSQLException ex) {
// can't connect to Database
do {
_out->println(ex->getMessage());
//ex->printStackTrace(System::err);
ex = ex->getNextException();
} while (ex != Nil);
} // catch RSQLException
return getStatus();
}
void
DBConnect::print(RString message)
{
jlong now = ::acdk::util::Date().getTime();
RString time = String::valueOf((now - getStartTime()) / 1000);
RString timestamp;
if (time->length() > _sizeOfTimeStamp){
timestamp = time->substring(0,_sizeOfTimeStamp);
} else {
RStringBuffer buf = new StringBuffer("");
for (int i = time->length(); i < _sizeOfTimeStamp; i++){
buf->append("0");
}
buf->append(time);
timestamp = buf->toString();
}
_out->print(RString("[") + getTestTable() + "][" + timestamp + "]: " + message);
_out->flush();
}
void
DBConnect::println(RString message)
{
SYNCTHIS();
jlong now = ::acdk::util::Date().getTime();
RString time = String::valueOf((now - getStartTime()) / 1000);
RString timestamp;
if (time->length() > _sizeOfTimeStamp){
timestamp = time->substring(0,_sizeOfTimeStamp);
} else {
RStringBuffer buf = new StringBuffer("");
for (int i = time->length(); i < _sizeOfTimeStamp; i++){
buf->append("0");
}
buf->append(time);
timestamp = buf->toString();
}
_out->println(RString("[") + getTestTable() + "][" + timestamp + "]: " + message);
}
/**
* execute(RString sql) - Execute SQL Statement
* in: sql-Statement to process
* out: -
**/
void
DBConnect::execute(RString sql)
{
RStatement statement = (RStatement)_connection->createStatement();
statement->execute(sql);
statement->close();
//statement = Nil;
}
/**
* executeUpdate(RString sql) - Execute SQL Statement
* in: sql-Statement to process
* out: -
**/
void
DBConnect::executeUpdate(RString sql)
{
RStatement statement = (RStatement)_connection->createStatement();
statement->executeUpdate(sql);
statement->close();
//statement = Nil;
}
/**
* executeQuery(RString sql)
* in (sql-Statement to process
* out: ResultSet
**/
::acdk::sql::RResultSet
DBConnect::executeQuery(RString sql)
{
RStatement statement
= (RStatement)_connection->createStatement();
return statement->executeQuery(sql);
}
//static
void
DBConnect::loadDriver(RString driverClassName)
{
// This Statement is currently needed to load the ODBC-DLL.
// If no Class from acdk::sql::odbc is used, Class::forName will fail!
// So let's start with a dummy line ...
#if defined(ACDK_OS_WIN32)
RString dummy = ::acdk::sql::odbc::ODBCDriver::GetClass()->getName();
#endif //defined(ACDK_OS_WIN32)
try {
System::out->println(RString("LOAD DRIVER: ") + driverClassName);
acdk::lang::Object driver = ::acdk::lang::Class::forName(driverClassName)->newInstance();
DriverManager::registerDriver((RDriver)driver);
} catch (RClassNotFoundException ex) {
System::err->println(ex->getMessage());
}
}
// virtual
void
DBConnect::run()
{
if ((getStatus() == true) && ( getTestTable() != Nil)){
setStartTime(::acdk::util::Date().getTime());
setTestSuccessful(false);
println("Starting Test");
println("Timestamp-Precision is Milliseconds");
println("Connection-Autocommit is " + String::valueOf(_connection->getAutoCommit()));
println("Connection-ReadOnly is " + String::valueOf(_connection->isReadOnly()));
println(RString("Number of TestRecords is ") + getNumberOfTestRecords());
int i = 0;
// used to store the SQLStatements
RString clause;
// the Resultset for Queries ..
RResultSet query;
try {
clause = RString("drop table ") + getTestTable();
println(clause);
execute(clause);
} catch (RSQLException ex) {}
try {
// create testtable
clause = RString(RString("create table ") + getTestTable() +
"(" +
"intval int," +
"realval real," +
"stringval Varchar(100)" +
")");
println(clause);
execute(clause);
clause = RString(RString("create unique index ") + getTestTable() + "_idx on " +
getTestTable() + "(stringval)");
println(clause);
execute(clause);
// fill testtable
println(RString("doing ") + getNumberOfTestRecords() + " inserts:");
for(i = 0; i < getNumberOfTestRecords(); i++){
clause = "insert into " + getTestTable() + " values (" + i + "," + i + ",'" + i + "')";
executeUpdate(clause);
}
//execute("commit");
// lets see if everything stored / retrieved right ...
println(RString("checking ") + getNumberOfTestRecords() + " inserts:");
clause = "select * from " + getTestTable() + " order by intval asc";
RResultSet rset = executeQuery(clause);
RResultSetMetaData mdata = rset->getMetaData();
i = 0;
while(rset->next())
{
int int_val = rset->getInt(1);
double double_val = rset->getDouble(2);
RString string_val = rset->getString(3);
if ((int_val != i) || (double_val != i) || (string_val->equals(String::valueOf(i)) == false))
{
println("MISSMATCH WHILE READING RESULTSET (should be equal to rownum):");
println(RString("ResultSet rownum: ") + i);
println(RString("intval = ") + int_val + " (retrieved with getInt)" );
println(RString(" ResultSet ObjectName is ") + rset->getObject(1)->getName());
println(RString("realval = ") + double_val + " (retrieved with getDouble)");
println(RString(" ResultSet ObjectName is ") + rset->getObject(2)->getName());
println(RString("stringval = ") + string_val + RString(" (retrieved with getString)"));
println(RString(" ResultSet ObjectName is ") + rset->getObject(3)->getName());
setTestSuccessful(false);
return;
}
i++;
}
// there should be no more or less rows in the ResultSet ...
if (i < getNumberOfTestRecords()){
println("LESS ROWS IN RESULTSET THAN INSERTED!");
setTestSuccessful(false);
return;
}
//try {
// rset->next();
// println("MORE ROWS IN RESULTSET THAN INSERTED!");
// setTestSuccessful(false);
// return;
//} catch (RSQLException ex) {}
// update testtable
println(RString("doing ") + getNumberOfTestRecords() + " updates:");
for(i = 0; i < getNumberOfTestRecords(); i++){
clause = "update " + getTestTable() + " set " +
"intval = " + (i + getNumberOfTestRecords()) + ", " +
"realval = " + (i + getNumberOfTestRecords()) + ", " +
"stringval = 'new" + (i + getNumberOfTestRecords()) + "'" +
"where intval=" + i;
//if ((i == 0) || (i == getNumberOfTestRecords() - 1)){
// println(clause);
//}
executeUpdate(clause);
}
//execute("commit");
// delete testtable
println(RString("doing ") + getNumberOfTestRecords() + " deletes:");
for(i = 0; i < getNumberOfTestRecords(); i++){
clause = "delete from " + getTestTable() + " where " +
"stringval = 'new" + (i + getNumberOfTestRecords()) + "'";
//if ((i == 0) || (i == getNumberOfTestRecords() - 1)){
// println(clause);
//}
executeUpdate(clause);
}
//execute("commit");
// check the remaing number of rows
query = executeQuery(RString("select count(*) from ") + getTestTable());
println(RString("remaing records after delete ") + query->getInt(1));
if (query->getInt(1) != 0){
println(">>> TEST FAILED <<<");
return;
}
// drop testtable after use ..
//clause = RString("drop table ") + getTestTable();
//println(clause);
//execute(clause);
setTestSuccessful(true);
println(">>> TEST PASSED SUCCESSFUL! <<<");
} catch (RException ex) {
System::out->println(ex->getMessage());
} catch (RThrowable ex) {
System::out->println("Throwable caught: " + ex->getMessage());
}
} else {
println(" no connection has been established yet.");
}
}
} // odbctests
} // tools
} // acdk
|