kexi

kexidbconnection.cpp

00001 /***************************************************************************
00002  * kexidbconnection.cpp
00003  * This file is part of the KDE project
00004  * copyright (C)2004-2005 by Sebastian Sauer (mail@dipe.org)
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  * You should have received a copy of the GNU Library General Public License
00015  * along with this program; see the file COPYING.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  ***************************************************************************/
00019 
00020 #include "kexidbconnection.h"
00021 #include "kexidbconnectiondata.h"
00022 #include "kexidbdrivermanager.h"
00023 #include "kexidbdriver.h"
00024 #include "kexidbcursor.h"
00025 #include "kexidbfieldlist.h"
00026 #include "kexidbschema.h"
00027 #include "kexidbtransaction.h"
00028 #include "kexidbparser.h"
00029 
00030 #include <api/exception.h>
00031 
00032 #include <kdebug.h>
00033 
00034 #include <kexidb/transaction.h>
00035 
00036 using namespace Kross::KexiDB;
00037 
00038 KexiDBConnection::KexiDBConnection(::KexiDB::Connection* connection, KexiDBDriver* driver, KexiDBConnectionData* connectiondata)
00039     : Kross::Api::Class<KexiDBConnection>("KexiDBConnection", driver ? driver : new KexiDBDriver(connection->driver()))
00040     , m_connection(connection)
00041     , m_connectiondata(connectiondata ? connectiondata : new KexiDBConnectionData(connection->data()))
00042 {
00043     addFunction("hadError", &KexiDBConnection::hadError);
00044     addFunction("lastError", &KexiDBConnection::lastError);
00045 
00046     addFunction("data", &KexiDBConnection::data);
00047     addFunction("driver", &KexiDBConnection::driver);
00048 
00049     addFunction("connect", &KexiDBConnection::connect);
00050     addFunction("isConnected", &KexiDBConnection::isConnected);
00051     addFunction("disconnect", &KexiDBConnection::disconnect);
00052 
00053     addFunction("databaseExists", &KexiDBConnection::databaseExists,
00054         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::Api::Variant::String"));
00055     addFunction("currentDatabase", &KexiDBConnection::currentDatabase);
00056     addFunction("databaseNames", &KexiDBConnection::databaseNames);
00057     addFunction("isDatabaseUsed", &KexiDBConnection::isDatabaseUsed);
00058     addFunction("isReadOnly", &KexiDBConnection::isReadOnly);
00059 
00060     addFunction("useDatabase", &KexiDBConnection::useDatabase,
00061         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::Api::Variant::String"));
00062     addFunction("closeDatabase", &KexiDBConnection::closeDatabase);
00063 
00064     addFunction("tableNames", &KexiDBConnection::tableNames);
00065     addFunction("queryNames", &KexiDBConnection::queryNames);
00066 
00067     addFunction("executeQueryString", &KexiDBConnection::executeQueryString,
00068         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::Api::Variant::String"));
00069     addFunction("executeQuerySchema", &KexiDBConnection::executeQuerySchema,
00070         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::KexiDB::KexiDBQuerySchema"));
00071     addFunction("querySingleString", &KexiDBConnection::querySingleString,
00072         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::Api::Variant::String"));
00073     addFunction("queryStringList", &KexiDBConnection::queryStringList,
00074         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::Api::Variant::String"));
00075     addFunction("querySingleRecord", &KexiDBConnection::querySingleRecord,
00076         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::Api::Variant::String"));
00077 
00078     addFunction("insertRecord", &KexiDBConnection::insertRecord,
00079         Kross::Api::ArgumentList()
00080             << Kross::Api::Argument("Kross::KexiDB::KexiDBTableSchema")
00081             << Kross::Api::Argument("Kross::Api::List"));
00082 
00083     addFunction("createDatabase", &KexiDBConnection::createDatabase,
00084         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::Api::Variant::String"));
00085     addFunction("dropDatabase", &KexiDBConnection::dropDatabase,
00086         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::Api::Variant::String"));
00087 
00088     addFunction("createTable", &KexiDBConnection::createTable,
00089         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::KexiDB::KexiDBTableSchema"));
00090     addFunction("dropTable", &KexiDBConnection::dropTable,
00091         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::Api::Variant::String"));
00092     addFunction("alterTable", &KexiDBConnection::alterTable,
00093         Kross::Api::ArgumentList()
00094             << Kross::Api::Argument("Kross::KexiDB::KexiDBTableSchema")
00095             << Kross::Api::Argument("Kross::KexiDB::KexiDBTableSchema"));
00096     addFunction("alterTableName", &KexiDBConnection::alterTableName,
00097         Kross::Api::ArgumentList()
00098             << Kross::Api::Argument("Kross::KexiDB::KexiDBTableSchema")
00099             << Kross::Api::Argument("Kross::Api::Variant::String"));
00100     addFunction("tableSchema", &KexiDBConnection::tableSchema,
00101         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::Api::Variant::String"));
00102     addFunction("isEmptyTable", &KexiDBConnection::isEmptyTable,
00103         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::KexiDB::KexiDBTableSchema"));
00104 
00105     addFunction("querySchema", &KexiDBConnection::querySchema,
00106         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::Api::Variant::String"));
00107 
00108     addFunction("autoCommit", &KexiDBConnection::autoCommit);
00109     addFunction("setAutoCommit", &KexiDBConnection::setAutoCommit,
00110         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::Api::Variant::Bool"));
00111     addFunction("beginTransaction", &KexiDBConnection::beginTransaction);
00112     addFunction("commitTransaction", &KexiDBConnection::commitTransaction,
00113         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::KexiDB::KexiDBTransaction"));
00114     addFunction("rollbackTransaction", &KexiDBConnection::rollbackTransaction,
00115         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::KexiDB::KexiDBTransaction"));
00116     addFunction("defaultTransaction", &KexiDBConnection::defaultTransaction);
00117     addFunction("setDefaultTransaction", &KexiDBConnection::setDefaultTransaction,
00118         Kross::Api::ArgumentList() << Kross::Api::Argument("Kross::KexiDB::KexiDBTransaction"));
00119     addFunction("transactions", &KexiDBConnection::transactions);
00120 
00121     addFunction("parser", &KexiDBConnection::parser);
00122 }
00123 
00124 KexiDBConnection::~KexiDBConnection()
00125 {
00126 }
00127 
00128 const QString KexiDBConnection::getClassName() const
00129 {
00130     return "Kross::KexiDB::KexiDBConnection";
00131 }
00132 
00133 ::KexiDB::Connection* KexiDBConnection::connection()
00134 {
00135     if(! m_connection)
00136         throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("KexiDB::Connection is NULL.")) );
00137     //if(m_connection->error())
00138     //    throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("KexiDB::Connection error: %1").arg(m_connection->errorMsg())) );
00139     return m_connection;
00140 }
00141 
00142 Kross::Api::Object::Ptr KexiDBConnection::hadError(Kross::Api::List::Ptr)
00143 {
00144     return new Kross::Api::Variant(QVariant(connection()->error(),0));
00145 }
00146 
00147 Kross::Api::Object::Ptr KexiDBConnection::lastError(Kross::Api::List::Ptr)
00148 {
00149     return new Kross::Api::Variant(connection()->errorMsg());
00150 }
00151 
00152 Kross::Api::Object::Ptr KexiDBConnection::data(Kross::Api::List::Ptr)
00153 {
00154     return m_connectiondata;
00155 }
00156 
00157 Kross::Api::Object::Ptr KexiDBConnection::driver(Kross::Api::List::Ptr)
00158 {
00159     if(! getParent()) // We don't check getParent()->driver() here!
00160         throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("Invalid driver - KexiDBConnection::driver() is NULL.")) );
00161     return getParent(); // the parent object is our KexiDBDriver* instance
00162 }
00163 
00164 Kross::Api::Object::Ptr KexiDBConnection::connect(Kross::Api::List::Ptr)
00165 {
00166     return new Kross::Api::Variant(QVariant(connection()->connect(),0));
00167 }
00168 
00169 Kross::Api::Object::Ptr KexiDBConnection::isConnected(Kross::Api::List::Ptr)
00170 {
00171     return new Kross::Api::Variant(QVariant(connection()->isConnected(),0));
00172 }
00173 
00174 Kross::Api::Object::Ptr KexiDBConnection::disconnect(Kross::Api::List::Ptr)
00175 {
00176     return new Kross::Api::Variant(QVariant(connection()->disconnect(),0));
00177 }
00178 
00179 Kross::Api::Object::Ptr KexiDBConnection::databaseExists(Kross::Api::List::Ptr args)
00180 {
00181     return new Kross::Api::Variant(
00182            QVariant(connection()->databaseExists(Kross::Api::Variant::toString(args->item(0))),0));
00183 }
00184 
00185 Kross::Api::Object::Ptr KexiDBConnection::currentDatabase(Kross::Api::List::Ptr)
00186 {
00187     return new Kross::Api::Variant(connection()->currentDatabase());
00188 }
00189 
00190 Kross::Api::Object::Ptr KexiDBConnection::databaseNames(Kross::Api::List::Ptr)
00191 {
00192     return new Kross::Api::Variant(connection()->databaseNames());
00193 }
00194 
00195 Kross::Api::Object::Ptr KexiDBConnection::isDatabaseUsed(Kross::Api::List::Ptr)
00196 {
00197     return new Kross::Api::Variant(QVariant(connection()->isDatabaseUsed(),0));
00198 }
00199 
00200 Kross::Api::Object::Ptr KexiDBConnection::isReadOnly(Kross::Api::List::Ptr)
00201 {
00202     return new Kross::Api::Variant(QVariant(connection()->isReadOnly(),0));
00203 }
00204 
00205 Kross::Api::Object::Ptr KexiDBConnection::useDatabase(Kross::Api::List::Ptr args)
00206 {
00207     QString dbname = Kross::Api::Variant::toString(args->item(0));
00208     bool ok = connection()->databaseExists(dbname);
00209     if(ok) ok = m_connection->useDatabase(dbname);
00210     return new Kross::Api::Variant(QVariant(ok,0));
00211 }
00212 
00213 Kross::Api::Object::Ptr KexiDBConnection::closeDatabase(Kross::Api::List::Ptr)
00214 {
00215     return new Kross::Api::Variant(QVariant(connection()->closeDatabase(),0));
00216 }
00217 
00218 Kross::Api::Object::Ptr KexiDBConnection::tableNames(Kross::Api::List::Ptr args)
00219 {
00220     bool systables = args->count() > 0 ? Kross::Api::Variant::toBool(args->item(0)) : false;
00221     return new Kross::Api::Variant(connection()->tableNames(systables));
00222 }
00223 
00224 Kross::Api::Object::Ptr KexiDBConnection::queryNames(Kross::Api::List::Ptr)
00225 {
00226     bool ok = true;
00227     QStringList queries = connection()->objectNames(::KexiDB::QueryObjectType, &ok);
00228     if(! ok)
00229         throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("Failed to determinate querynames.")) );
00230     return new Kross::Api::Variant(queries);
00231 }
00232 
00233 Kross::Api::Object::Ptr KexiDBConnection::executeQueryString(Kross::Api::List::Ptr args)
00234 {
00235     QString querystatement = Kross::Api::Variant::toString(args->item(0));
00236 
00237     // The ::KexiDB::Connection::executeQuery() method does not check if we pass
00238     // a valid SELECT-statement or e.g. a DROP TABLE operation. So, let's check
00239     // for such dangerous operations right now.
00240     ::KexiDB::Parser parser( connection() );
00241     if(! parser.parse(querystatement))
00242         throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("Failed to parse query: %1 %2").arg(parser.error().type()).arg(parser.error().error())) );
00243     if( parser.query() == 0 || parser.operation() != ::KexiDB::Parser::OP_Select )
00244         throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("Invalid query operation \"%1\"").arg(parser.operationString()) ) );
00245 
00246     ::KexiDB::Cursor* cursor = connection()->executeQuery(querystatement);
00247     if(! cursor)
00248         throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("Failed to execute querystring.")) );
00249     return new KexiDBCursor(this, cursor);
00250 }
00251 
00252 Kross::Api::Object::Ptr KexiDBConnection::executeQuerySchema(Kross::Api::List::Ptr args)
00253 {
00254     ::KexiDB::Cursor* cursor = connection()->executeQuery(
00255         *Kross::Api::Object::fromObject<KexiDBQuerySchema>(args->item(0))->queryschema()
00256     );
00257     if(! cursor)
00258         throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("Failed to execute queryschema.")) );
00259     return new KexiDBCursor(this, cursor);
00260 }
00261 
00262 Kross::Api::Object::Ptr KexiDBConnection::querySingleString(Kross::Api::List::Ptr args)
00263 {
00264     QString sql = Kross::Api::Variant::toString(args->item(0));
00265     uint column = args->count() > 1 ? Kross::Api::Variant::toUInt(args->item(1)) : 0;
00266     QString value;
00267     if(connection()->querySingleString(sql, value, column))
00268         return new Kross::Api::Variant(value);
00269     throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("The string query failed.")) );
00270 }
00271 
00272 Kross::Api::Object::Ptr KexiDBConnection::queryStringList(Kross::Api::List::Ptr args)
00273 {
00274     QString sql = Kross::Api::Variant::toString(args->item(0));
00275     uint column = args->count() > 1 ? Kross::Api::Variant::toUInt(args->item(1)) : 0;
00276     QStringList valuelist;
00277     if(connection()->queryStringList(sql, valuelist, column))
00278         return new Kross::Api::Variant(valuelist);
00279     throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("Failed to query stringlist.")) );
00280 }
00281 
00282 Kross::Api::Object::Ptr KexiDBConnection::querySingleRecord(Kross::Api::List::Ptr args)
00283 {
00284     QValueVector<QVariant> list;
00285     if(connection()->querySingleRecord(Kross::Api::Variant::toString(args->item(0)), list)) {
00286         QValueList<QVariant> l; //FIXME isn't there a better/faster way to deal with QValueVector<QVariant> => QVariant ?!
00287         for(QValueVector<QVariant>::Iterator it = list.begin(); it != list.end(); ++it)
00288             l.append(*it);
00289         return new Kross::Api::Variant(l);
00290     }
00291     throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("Failed to query single record.")) );
00292 }
00293 
00294 Kross::Api::Object::Ptr KexiDBConnection::insertRecord(Kross::Api::List::Ptr args)
00295 {
00296     QValueList<QVariant> values = Kross::Api::Variant::toList(args->item(1));
00297     /*
00298     kdDebug()<<"Kross::KexiDB::KexiDBConnection::insertRecord()"<<endl;
00299     for(QValueList<QVariant>::Iterator it = values.begin(); it != values.end(); ++it)
00300         kdDebug()<<"  value="<< (*it).toString() << " type=" << (*it).typeName() << endl;
00301     */
00302 
00303     Kross::Api::Object::Ptr obj = args->item(0);
00304     if(obj->getClassName() == "Kross::KexiDB::KexiDBFieldList") {
00305         return new Kross::Api::Variant(
00306                    QVariant(connection()->insertRecord(
00307                        *Kross::Api::Object::fromObject<KexiDBFieldList>(obj)->fieldlist(),
00308                        values
00309                    ), 0));
00310     }
00311     return new Kross::Api::Variant(
00312                QVariant(connection()->insertRecord(
00313                    *Kross::Api::Object::fromObject<KexiDBTableSchema>(obj)->tableschema(),
00314                    values
00315                ), 0));
00316 }
00317 
00318 Kross::Api::Object::Ptr KexiDBConnection::createDatabase(Kross::Api::List::Ptr args)
00319 {
00320     return new Kross::Api::Variant(
00321            QVariant(connection()->createDatabase(Kross::Api::Variant::toString(args->item(0))),0));
00322 }
00323 
00324 Kross::Api::Object::Ptr KexiDBConnection::dropDatabase(Kross::Api::List::Ptr args)
00325 {
00326     return new Kross::Api::Variant(
00327            QVariant(connection()->dropDatabase(Kross::Api::Variant::toString(args->item(0))),0));
00328 }
00329 
00330 Kross::Api::Object::Ptr KexiDBConnection::createTable(Kross::Api::List::Ptr args)
00331 {
00332     bool replace = args->count() > 1 ? Kross::Api::Variant::toBool(args->item(1)) : false;
00333     return new Kross::Api::Variant(QVariant(
00334                connection()->createTable(
00335                     Kross::Api::Object::fromObject<KexiDBTableSchema>(args->item(0))->tableschema(),
00336                     replace) // replace existing tables
00337                ,0));
00338 }
00339 
00340 Kross::Api::Object::Ptr KexiDBConnection::dropTable(Kross::Api::List::Ptr args)
00341 {
00342     return new Kross::Api::Variant(QVariant(
00343                    connection()->dropTable(Kross::Api::Variant::toString(args->item(0)))
00344                ,0));
00345 }
00346 
00347 Kross::Api::Object::Ptr KexiDBConnection::alterTable(Kross::Api::List::Ptr args)
00348 {
00349     return new Kross::Api::Variant(QVariant(
00350                connection()->alterTable(
00351                    *Kross::Api::Object::fromObject<KexiDBTableSchema>(args->item(0))->tableschema(),
00352                    *Kross::Api::Object::fromObject<KexiDBTableSchema>(args->item(1))->tableschema() )
00353                ,0));
00354 }
00355 
00356 Kross::Api::Object::Ptr KexiDBConnection::alterTableName(Kross::Api::List::Ptr args)
00357 {
00358     return new Kross::Api::Variant(QVariant(
00359            connection()->alterTableName(
00360                *Kross::Api::Object::fromObject<KexiDBTableSchema>(args->item(0))->tableschema(),
00361                Kross::Api::Variant::toString(args->item(1)) )
00362            ,0));
00363 }
00364 
00365 Kross::Api::Object::Ptr KexiDBConnection::tableSchema(Kross::Api::List::Ptr args)
00366 {
00367     ::KexiDB::TableSchema* tableschema = connection()->tableSchema( Kross::Api::Variant::toString(args->item(0)) );
00368     if(! tableschema)
00369         return 0; //throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("No such tableschema.")) );
00370     return new KexiDBTableSchema(tableschema);
00371 }
00372 
00373 Kross::Api::Object::Ptr KexiDBConnection::isEmptyTable(Kross::Api::List::Ptr args)
00374 {
00375     bool success;
00376     bool notempty =
00377         connection()->isEmpty(
00378             *Kross::Api::Object::fromObject<KexiDBTableSchema>(args->item(0))->tableschema(),
00379             success);
00380     return new Kross::Api::Variant(QVariant(! (success && notempty), 0));
00381 }
00382 
00383 Kross::Api::Object::Ptr KexiDBConnection::querySchema(Kross::Api::List::Ptr args)
00384 {
00385     ::KexiDB::QuerySchema* queryschema = connection()->querySchema( Kross::Api::Variant::toString(args->item(0)) );
00386     if(! queryschema)
00387         throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("No such queryschema.")) );
00388     return new KexiDBQuerySchema(queryschema);
00389 }
00390 
00391 Kross::Api::Object::Ptr KexiDBConnection::autoCommit(Kross::Api::List::Ptr)
00392 {
00393     return new Kross::Api::Variant(QVariant(connection()->autoCommit(), 0));
00394 }
00395 
00396 Kross::Api::Object::Ptr KexiDBConnection::setAutoCommit(Kross::Api::List::Ptr args)
00397 {
00398     return new Kross::Api::Variant(
00399            QVariant(connection()->setAutoCommit(Kross::Api::Variant::toBool(args->item(0))), 0) );
00400 }
00401 
00402 Kross::Api::Object::Ptr KexiDBConnection::beginTransaction(Kross::Api::List::Ptr)
00403 {
00404     ::KexiDB::Transaction t = connection()->beginTransaction();
00405     return new KexiDBTransaction(this, t);
00406 }
00407 
00408 Kross::Api::Object::Ptr KexiDBConnection::commitTransaction(Kross::Api::List::Ptr args)
00409 {
00410     return new Kross::Api::Variant(QVariant(
00411            connection()->commitTransaction(
00412                Kross::Api::Object::fromObject<KexiDBTransaction>(args->item(0))->transaction() )
00413            , 0));
00414 }
00415 
00416 Kross::Api::Object::Ptr KexiDBConnection::rollbackTransaction(Kross::Api::List::Ptr args)
00417 {
00418     return new Kross::Api::Variant(QVariant(
00419            connection()->rollbackTransaction(
00420                Kross::Api::Object::fromObject<KexiDBTransaction>(args->item(0))->transaction() )
00421            , 0));
00422 }
00423 
00424 Kross::Api::Object::Ptr KexiDBConnection::defaultTransaction(Kross::Api::List::Ptr)
00425 {
00426     return new KexiDBTransaction(this, connection()->defaultTransaction());
00427 }
00428 
00429 Kross::Api::Object::Ptr KexiDBConnection::setDefaultTransaction(Kross::Api::List::Ptr args)
00430 {
00431     connection()->setDefaultTransaction(
00432         Kross::Api::Object::fromObject<KexiDBTransaction>(args->item(0))->transaction()
00433     );
00434     return 0; // no returnvalue
00435 }
00436 
00437 Kross::Api::Object::Ptr KexiDBConnection::transactions(Kross::Api::List::Ptr)
00438 {
00439     QValueList<Kross::Api::Object::Ptr> l;
00440     QValueList< ::KexiDB::Transaction > list = connection()->transactions();
00441     for(QValueList< ::KexiDB::Transaction >::Iterator it = list.begin(); it != list.end(); ++it)
00442         l.append( new KexiDBTransaction(this, *it) );
00443     return new Kross::Api::List(l);
00444 }
00445 
00446 Kross::Api::Object::Ptr KexiDBConnection::parser(Kross::Api::List::Ptr)
00447 {
00448     return new KexiDBParser(this, new ::KexiDB::Parser(connection()));
00449 }
00450 
KDE Home | KDE Accessibility Home | Description of Access Keys