From c601b5a27f74b16158adafe429faefbe573e64a2 Mon Sep 17 00:00:00 2001 From: Szymon Tomasz Stefanek Date: Sat, 1 Jan 2011 20:19:56 +0000 Subject: The big rename for modules. Still some details remaining. git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@5284 17fca916-40b9-46aa-a4ea-0a15b648b75c --- src/modules/objects/KvsObject_sql.cpp | 603 ++++++++++++++++++++++++++++++++++ 1 file changed, 603 insertions(+) create mode 100644 src/modules/objects/KvsObject_sql.cpp (limited to 'src/modules/objects/KvsObject_sql.cpp') diff --git a/src/modules/objects/KvsObject_sql.cpp b/src/modules/objects/KvsObject_sql.cpp new file mode 100644 index 000000000..2c7b32438 --- /dev/null +++ b/src/modules/objects/KvsObject_sql.cpp @@ -0,0 +1,603 @@ +//============================================================================= +// +// File : KvsObject_sql.cpp +// Creation date : Wed Gen 28 2009 21:07:55 by Alessandro Carbone +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program 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 GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================ + +#include "kvi_debug.h" +#include "KviMemory.h" +#include "KviLocale.h" +#include "KvsObject_sql.h" +#include +#include "KvsObject_memoryBuffer.h" +#include +#include + +static KviPointerList sql_instances; + +static bool checkDuplicatedConnection(QString &szConnectionName) +{ + if(!sql_instances.count()) return false; + bool bFound=false; + for(KvsObject_sql *i = sql_instances.first(); i; i = sql_instances.next()) + { + QSqlQuery *q=i->getQueryConnectionsDict().value(szConnectionName); + if (q) + { + i->closeQueryConnection(q); + bFound=true; + break; + } + } + return bFound; +} +static void KviKvsSqlInstanceRegister(KvsObject_sql *instance) +{ + sql_instances.setAutoDelete(false); + sql_instances.append(instance); +} +static void KviKvsSqlInstanceUnregister(KvsObject_sql *instance) +{ + int idx=sql_instances.findRef(instance); + sql_instances.remove(idx); +} + +#define CHECK_QUERY_IS_INIT if (!m_pCurrentSQlQuery)\ + {\ + c->error("No query has been initialized!");\ + return false;} + + +/* + @doc: sql + @keyterms: + Sql database. + @title: + sql class + @type: + class + @short: + A sql database interface. + @inherits: + [class]object[/class] + @description: + This class permits KVIrc to have an interface with a SQL database supported by Qt library drivers. + @functions: + !fn: $setConnection(,,[,,,]) + Connects to the DBMS using the connection and selecting the database .[br] + If the optional parameter is passed, it will be used the corresponding driver (if present), otherwise Sqlite will be used. + Returns true if the operation is successful, false otherwise. + !fn:: $connectionNames([:'s']) + Returns as array or, if the flag 's' is passed, as a comma separate string all the database active connection's names. + !fn: $tablesList() + Returns as array the database tables list. + !fn: $queryInit() + Initialize the query for the database which has to be already connected. + !fn: $transaction() + Begin a transaction. + !fn: $commit() + Commit the transaction. + !fn: $setCurrentQuery() + Sets the query for the database connection , which has to be already connected, as current query. + !fn: $currentQuery() + Returns the name of the database connection for the current query, or an empty string if there aren't any initialized queries. + !fn: $closeConnection() + Closes the connection . + !fn: $queryResultsSize() + Returns the query size in rows or -1 if the query is empty or the database driver doesn' support the function. + !fn: $lastError() + Returns last error occurred. Use the more_details flag for more info about the error. + !fn: $queryExec([]) + Execs the current query . The string must follow the right syntax against the database in use. + If there are no parameters, it will exec the query previously done. + After the execution, the query will positioned on the first resulting record. + Returns true if the operation is successful, false otherwise. + See also [classfnc]$queryPrepare[/classfnc]() + !fn: $queryPrepare() + Prepare the query to execute. The string must follow the right syntax against the database in use. + It's possible to use the placeholders. It's supported either the identifier ':' and '?' but it's not possible to use them together. + Returns true if the operation is successful, false otherwise. + See also [classfnc]$queryExec[/classfnc]and[classfnc]$queryBindValue[/classfnc. + !fn: $queryBindValue() + Sets the placeholder to be bound to the value in the prepared statement. + Note that the placeholder mark (e.g :) must be included when specifing the placeholder name. + !fn: $queryPrevious() + Sets the current query position to the previous resulting record. + Returns true if the operation is successful, false otherwise. + !fn: $queryNext() + Sets the current query position to the next resulting record. + Returns true if the operation is successful, false otherwise. + !fn: $queryLast() + Sets the current query position to the last resulting record. + Returns true if the operation is successful, false otherwise. + !fn: $queryFirst() + Sets the current query position to the first resulting record. + Returns true if the operation is successful, false otherwise. + !fn: $queryRecord() + Returns a hash containing the current query's record fields. + !fn: $queryFinish() + Sets the current query to inactive. +*/ + + + +KVSO_BEGIN_REGISTERCLASS(KvsObject_sql,"sql","object") + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryLastInsertId) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,commit) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,beginTransaction) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,setConnection) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,connectionNames) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,setCurrentQuery) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,tablesList) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,currentQuery) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,closeConnection) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryInit) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryFinish) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryResultsSize) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryExec) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryPrepare) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryBindValue) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryPrevious) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryNext) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryLast) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryFirst) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,queryRecord) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,lastError) + KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_sql,features) +KVSO_END_REGISTERCLASS(KvsObject_sql) + + +KVSO_BEGIN_CONSTRUCTOR(KvsObject_sql,KviKvsObject) +m_pCurrentSQlQuery=0; +KviKvsSqlInstanceRegister(this); +KVSO_END_CONSTRUCTOR(KvsObject_sql) + + +KVSO_BEGIN_DESTRUCTOR(KvsObject_sql) +QHashIterator t(queryConnectionsDict); +while (t.hasNext()) +{ + t.next(); + QString szConnectionName=t.key(); + queryConnectionsDict.value(szConnectionName)->finish(); + delete queryConnectionsDict.value(szConnectionName); + QSqlDatabase::removeDatabase(szConnectionName); +} +KviKvsSqlInstanceUnregister(this); +queryConnectionsDict.clear(); + +KVSO_END_DESTRUCTOR(KvsObject_sql) + +KVSO_CLASS_FUNCTION(sql,setConnection) +{ + QString szConnectionName,szDbName,szDbDriver,szUserName,szHostName,szPassword; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connection_name",KVS_PT_STRING,0,szConnectionName) + KVSO_PARAMETER("database_name",KVS_PT_STRING,0,szDbName) + KVSO_PARAMETER("user_name",KVS_PT_STRING,KVS_PF_OPTIONAL,szUserName) + KVSO_PARAMETER("host_name",KVS_PT_STRING,KVS_PF_OPTIONAL,szHostName) + KVSO_PARAMETER("password",KVS_PT_STRING,KVS_PF_OPTIONAL,szPassword) + KVSO_PARAMETER("database_type",KVS_PT_STRING,KVS_PF_OPTIONAL,szDbDriver) + KVSO_PARAMETERS_END(c) + if(!szDbDriver.isEmpty()) + { + QStringList drivers = QSqlDatabase::drivers(); + if (!drivers.contains(szDbDriver)) + { + c->error(__tr2qs_ctx("Missing Qt plugin for database %Q","objects"),&szDbDriver); + return false; + } + } + else szDbDriver="QSQLITE"; + if (checkDuplicatedConnection(szConnectionName)) + { + c->warning(__tr2qs_ctx("Duplicate connection name '%Q', old query connection removed","objects"),&szConnectionName); + } + QSqlDatabase db=QSqlDatabase::addDatabase(szDbDriver,szConnectionName); + db.setDatabaseName(szDbName); + db.setHostName(szHostName); + db.setUserName(szUserName); + db.setPassword(szPassword); + + c->returnValue()->setBoolean(db.open()); + return true; +} + +KVSO_CLASS_FUNCTION(sql,connectionNames) +{ + + QString szFlag; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("stringreturnflag",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlag) + KVSO_PARAMETERS_END(c) + QStringList szConnectionsList=QSqlDatabase::connectionNames(); + if(szFlag.indexOf('s',0,Qt::CaseInsensitive) != -1) + { + QString szConnections=szConnectionsList.join(","); + c->returnValue()->setString(szConnections); + } + else + { + KviKvsArray *pArray=new KviKvsArray(); + for(int i=0;iset(i,new KviKvsVariant(szConnectionsList.at(i))); + } + c->returnValue()->setArray(pArray); + } + return true; +} + +KVSO_CLASS_FUNCTION(sql,queryLastInsertId) +{ + CHECK_QUERY_IS_INIT + QVariant value=m_pCurrentSQlQuery->lastInsertId(); + if (value.type()==QVariant::LongLong){ + c->returnValue()->setInteger((kvs_int_t) value.toLongLong()); + } + return true; + } +KVSO_CLASS_FUNCTION(sql,features) +{ + QString szConnectionName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connectionName",KVS_PT_STRING,0,szConnectionName) + KVSO_PARAMETERS_END(c) + + QStringList connections = QSqlDatabase::connectionNames(); + if (!connections.contains(szConnectionName)) + { + c->warning(__tr2qs_ctx("Connection %Q does not exists","objects"),&szConnectionName); + return true; + } + QSqlDatabase db=QSqlDatabase::database(szConnectionName); + QSqlDriver *sqlDriver=db.driver(); + QStringList features; + if (sqlDriver->hasFeature(QSqlDriver::Transactions)) features.append("transactions"); + if (sqlDriver->hasFeature(QSqlDriver::QuerySize)) features.append("querysize"); + if (sqlDriver->hasFeature(QSqlDriver::BLOB)) features.append("blob"); + if (sqlDriver->hasFeature(QSqlDriver::PreparedQueries)) features.append("preparedqueries"); + if (sqlDriver->hasFeature(QSqlDriver::NamedPlaceholders)) features.append("namedplaceholders"); + if (sqlDriver->hasFeature(QSqlDriver::PositionalPlaceholders)) features.append("positionaplaceholders"); + if (sqlDriver->hasFeature(QSqlDriver::LastInsertId)) features.append("lastinsertid"); + if (sqlDriver->hasFeature(QSqlDriver::BatchOperations)) features.append("batchoperations"); + if (sqlDriver->hasFeature(QSqlDriver::SimpleLocking)) features.append("simplelocking"); + if (sqlDriver->hasFeature(QSqlDriver::LowPrecisionNumbers)) features.append("lowprecisionnumbers"); + if (sqlDriver->hasFeature(QSqlDriver::EventNotifications)) features.append("eventnotifications"); + if (sqlDriver->hasFeature(QSqlDriver::FinishQuery)) features.append("finishquery"); + if (sqlDriver->hasFeature(QSqlDriver::MultipleResultSets)) features.append("multipleresults"); + c->returnValue()->setString(features.join(",")); + return true; +} + +KVSO_CLASS_FUNCTION(sql,beginTransaction) +{ + QString szConnectionName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connectionName",KVS_PT_STRING,0,szConnectionName) + KVSO_PARAMETERS_END(c) + + QStringList connections = QSqlDatabase::connectionNames(); + if (!connections.contains(szConnectionName)) + { + c->warning(__tr2qs_ctx("Connection %Q does not exists","objects"),&szConnectionName); + return true; + } + QSqlDatabase db=QSqlDatabase::database(szConnectionName); + db.transaction(); + return true; +} +KVSO_CLASS_FUNCTION(sql,commit) +{ + QString szConnectionName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connectionName",KVS_PT_STRING,0,szConnectionName) + KVSO_PARAMETERS_END(c) + + QStringList connections = QSqlDatabase::connectionNames(); + if (!connections.contains(szConnectionName)) + { + c->warning(__tr2qs_ctx("Connection %Q does not exists","objects"),&szConnectionName); + return true; + } + QSqlDatabase db=QSqlDatabase::database(szConnectionName); + db.commit(); + return true; +} +KVSO_CLASS_FUNCTION(sql,closeConnection) +{ + QString szConnectionName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connectionName",KVS_PT_STRING,0,szConnectionName) + KVSO_PARAMETERS_END(c) + + QStringList connections = QSqlDatabase::connectionNames(); + if (!connections.contains(szConnectionName)) + { + c->warning(__tr2qs_ctx("Connection %Q does not exists","objects"),&szConnectionName); + return true; + } + QSqlQuery *q=queryConnectionsDict.value(szConnectionName); + if (q) closeQueryConnection(q); + QSqlDatabase::removeDatabase(szConnectionName); + return true; +} +KVSO_CLASS_FUNCTION(sql,tablesList) +{ + QString szConnectionName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connectionName",KVS_PT_STRING,0,szConnectionName) + KVSO_PARAMETERS_END(c) + QStringList connections = QSqlDatabase::connectionNames(); + if (!connections.contains(szConnectionName)) + { + c->warning(__tr2qs_ctx("Connection %Q does not exists","objects"),&szConnectionName); + return true; + } + QSqlDatabase db=QSqlDatabase::database(szConnectionName); + QStringList tables=db.tables(); + KviKvsArray *pArray=new KviKvsArray(); + for(int i=0;iset(i,new KviKvsVariant(tables.at(i))); + } + c->returnValue()->setArray(pArray); + return true; +} +KVSO_CLASS_FUNCTION(sql,setCurrentQuery) +{ + QString szConnectionName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connection_name",KVS_PT_STRING,0,szConnectionName) + KVSO_PARAMETERS_END(c) + QSqlQuery *q=queryConnectionsDict.value(szConnectionName); + if(!q) + { + c->warning(__tr2qs_ctx("Connection query %Q does not exists","objects"),&szConnectionName); + return true; + } + m_pCurrentSQlQuery=q; + return true; +} +KVSO_CLASS_FUNCTION(sql,queryFinish) +{ + QString szConnectionName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connection_name",KVS_PT_STRING,KVS_PF_OPTIONAL,szConnectionName) + KVSO_PARAMETERS_END(c) + QSqlQuery *q; + if(szConnectionName.isEmpty()) + { + q=m_pCurrentSQlQuery; + if (!q) + { + c->warning(__tr2qs_ctx("No query connection is open","objects")); + return true; + } + } + else + { + q=queryConnectionsDict.value(szConnectionName); + if(!q) + { + c->warning(__tr2qs_ctx("Query for connection %Q does not exists","objects"),&szConnectionName); + return true; + } + } + q->finish(); + return true; +} +KVSO_CLASS_FUNCTION(sql,currentQuery) +{ + if (!m_pCurrentSQlQuery) c->returnValue()->setString(QString()); + else + { + QString szKey=queryConnectionsDict.key(m_pCurrentSQlQuery); + c->returnValue()->setString(szKey); + } + return true; +} +KVSO_CLASS_FUNCTION(sql,queryInit) +{ + QString szConnectionName; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("connection_name",KVS_PT_STRING,0,szConnectionName) + KVSO_PARAMETERS_END(c) + if (queryConnectionsDict.value(szConnectionName)) + { + c->warning(__tr2qs_ctx("Query %Q already initialized","objects"),&szConnectionName); + return true; + } + if(!QSqlDatabase::connectionNames().contains(szConnectionName)) + { + c->error(__tr2qs_ctx("Connection %Q is not open!","objects"),&szConnectionName); + return false; + } + m_pCurrentSQlQuery=new QSqlQuery(QSqlDatabase::database(szConnectionName)); + queryConnectionsDict[szConnectionName]=m_pCurrentSQlQuery; + return true; +} + + +KVSO_CLASS_FUNCTION(sql,queryPrepare) +{ + CHECK_QUERY_IS_INIT + QString szQuery; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("query",KVS_PT_STRING,0,szQuery) + KVSO_PARAMETERS_END(c) + c->returnValue()->setBoolean(m_pCurrentSQlQuery->prepare(szQuery)); + return true; +} +KVSO_CLASS_FUNCTION(sql,queryBindValue) +{ + CHECK_QUERY_IS_INIT + QString szFieldName; + KviKvsVariant *v; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("bindName",KVS_PT_STRING,0,szFieldName) + KVSO_PARAMETER("value",KVS_PT_VARIANT,0,v) + KVSO_PARAMETERS_END(c) + QString szType; + v->getTypeName(szType); + if (v->isString()|| v->isNothing()) + { + QString szText; + v->asString(szText); + m_pCurrentSQlQuery->bindValue(szFieldName,QVariant(szText)); + } + else if (v->isReal()) + { + kvs_real_t i; + v->asReal(i); + m_pCurrentSQlQuery->bindValue(szFieldName,QVariant((double)i)); + } + else if (v->isInteger()) + { + kvs_int_t i; + v->asInteger(i); + m_pCurrentSQlQuery->bindValue(szFieldName,QVariant((int)i)); + } + else if (v->isBoolean()) + { + bool b=v->asBoolean(); + m_pCurrentSQlQuery->bindValue(szFieldName,QVariant(b)); + } + else if (v->isHObject()) + { + kvs_hobject_t hOb; + v->asHObject(hOb); + KviKvsObject *pObject; + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hOb); + if (pObject->inheritsClass("memorybuffer")) + m_pCurrentSQlQuery->bindValue(szFieldName,QVariant(*((KvsObject_memoryBuffer *)pObject)->pBuffer())); + else c->warning(__tr2qs_ctx("Only memorybuffer class object is supported","objects")); + } + else + { + QString szTypeName; + v->getTypeName(szTypeName); + c->warning(__tr2qs_ctx("Type value %Q not supported","objects"),&szTypeName); + } + return true; +} + +KVSO_CLASS_FUNCTION(sql,queryExec) +{ + CHECK_QUERY_IS_INIT + QString szQuery; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("query",KVS_PT_STRING,KVS_PF_OPTIONAL,szQuery) + KVSO_PARAMETERS_END(c) + bool bOk; + if (szQuery.isEmpty()) bOk=m_pCurrentSQlQuery->exec(); + else bOk=m_pCurrentSQlQuery->exec(szQuery.toLatin1()); + c->returnValue()->setBoolean(bOk); + return true; +} +KVSO_CLASS_FUNCTION(sql,queryNext) +{ + CHECK_QUERY_IS_INIT + if (m_pCurrentSQlQuery->isActive() && m_pCurrentSQlQuery->isSelect()) c->returnValue()->setBoolean(m_pCurrentSQlQuery->next()); + else c->returnValue()->setNothing(); + return true; +} +KVSO_CLASS_FUNCTION(sql,queryPrevious) +{ + CHECK_QUERY_IS_INIT + if (m_pCurrentSQlQuery->isActive() && m_pCurrentSQlQuery->isSelect()) c->returnValue()->setBoolean(m_pCurrentSQlQuery->previous()); + else c->returnValue()->setNothing(); + return true; +} +KVSO_CLASS_FUNCTION(sql,queryResultsSize) +{ + CHECK_QUERY_IS_INIT + c->returnValue()->setInteger(m_pCurrentSQlQuery->size()); + return true; +} +KVSO_CLASS_FUNCTION(sql,queryFirst) +{ + CHECK_QUERY_IS_INIT + if (m_pCurrentSQlQuery->isActive() && m_pCurrentSQlQuery->isSelect()) c->returnValue()->setBoolean(m_pCurrentSQlQuery->first()); + return true; +} +KVSO_CLASS_FUNCTION(sql,queryLast) +{ + CHECK_QUERY_IS_INIT + if (m_pCurrentSQlQuery->isActive() && m_pCurrentSQlQuery->isSelect()) c->returnValue()->setBoolean(m_pCurrentSQlQuery->last()); + return true; +} +KVSO_CLASS_FUNCTION(sql,queryRecord) +{ + CHECK_QUERY_IS_INIT + KviKvsHash *pHash=new KviKvsHash(); + QSqlRecord record=m_pCurrentSQlQuery->record(); + for(int i=0;iobjectController()->lookupClass("memoryBuffer"); + KviKvsVariantList params(new KviKvsVariant(QString())); + KviKvsObject * pObject = pClass->allocateInstance(0,"",c->context(),¶ms); + *((KvsObject_memoryBuffer *)pObject)->pBuffer()=value.toByteArray(); + pValue=new KviKvsVariant(pObject->handle()); + } + else pValue=new KviKvsVariant(QString()); + pHash->set(record.fieldName(i),pValue); + KviKvsVariant *value2=pHash->get(record.fieldName(i)); + value2->type(); + } + c->returnValue()->setHash(pHash); + return true; +} + +KVSO_CLASS_FUNCTION(sql,lastError) +{ + CHECK_QUERY_IS_INIT + bool bMoreErrorDetails; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("more",KVS_PT_BOOLEAN,KVS_PF_OPTIONAL,bMoreErrorDetails) + KVSO_PARAMETERS_END(c) + QString szError; + QSqlError error=m_pCurrentSQlQuery->lastError(); + if (bMoreErrorDetails) szError=error.text(); + else + { + if (error.type()==QSqlError::StatementError) szError="SyntaxError"; + else if (error.type()==QSqlError::ConnectionError) szError="ConnectionError"; + else if (error.type()==QSqlError::TransactionError) szError="TransactionError"; + else szError="UnkonwnError"; + } + c->returnValue()->setString(szError); + return true; +} +void KvsObject_sql::closeQueryConnection(QSqlQuery * query) +{ + if (query==m_pCurrentSQlQuery) m_pCurrentSQlQuery=0; + query->finish(); + queryConnectionsDict.remove(queryConnectionsDict.key(query)); + delete query; + } + -- cgit v1.3.1-10-gc9f91