diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
commit | 8362bf63dea22bbf6736609b0f49c152f975eb63 (patch) | |
tree | 0eea3928e39e50fae91d4e68b21b1e6cbae25604 /kexi/kexidb/drivers/pqxx | |
download | koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip |
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kexi/kexidb/drivers/pqxx')
-rw-r--r-- | kexi/kexidb/drivers/pqxx/Makefile.am | 22 | ||||
-rw-r--r-- | kexi/kexidb/drivers/pqxx/README | 18 | ||||
-rw-r--r-- | kexi/kexidb/drivers/pqxx/kexidb_pqxxsqldriver.desktop | 11 | ||||
-rw-r--r-- | kexi/kexidb/drivers/pqxx/pqxxconnection.cpp | 448 | ||||
-rw-r--r-- | kexi/kexidb/drivers/pqxx/pqxxconnection.h | 104 | ||||
-rw-r--r-- | kexi/kexidb/drivers/pqxx/pqxxconnection_p.cpp | 51 | ||||
-rw-r--r-- | kexi/kexidb/drivers/pqxx/pqxxconnection_p.h | 63 | ||||
-rw-r--r-- | kexi/kexidb/drivers/pqxx/pqxxcursor.cpp | 339 | ||||
-rw-r--r-- | kexi/kexidb/drivers/pqxx/pqxxcursor.h | 110 | ||||
-rw-r--r-- | kexi/kexidb/drivers/pqxx/pqxxdriver.cpp | 181 | ||||
-rw-r--r-- | kexi/kexidb/drivers/pqxx/pqxxdriver.h | 71 | ||||
-rw-r--r-- | kexi/kexidb/drivers/pqxx/pqxxkeywords.cpp | 244 | ||||
-rw-r--r-- | kexi/kexidb/drivers/pqxx/pqxxpreparedstatement.cpp | 56 | ||||
-rw-r--r-- | kexi/kexidb/drivers/pqxx/pqxxpreparedstatement.h | 49 |
14 files changed, 1767 insertions, 0 deletions
diff --git a/kexi/kexidb/drivers/pqxx/Makefile.am b/kexi/kexidb/drivers/pqxx/Makefile.am new file mode 100644 index 00000000..5129c84f --- /dev/null +++ b/kexi/kexidb/drivers/pqxx/Makefile.am @@ -0,0 +1,22 @@ +include $(top_srcdir)/kexi/Makefile.global + +kde_module_LTLIBRARIES = kexidb_pqxxsqldriver.la + +INCLUDES = -I$(srcdir)/../../.. $(all_includes) -I$(PG_INCDIR) -I$(PQXX_INCDIR) + +kexidb_pqxxsqldriver_la_METASOURCES = AUTO + +kexidb_pqxxsqldriver_la_SOURCES = pqxxdriver.cpp pqxxcursor.cpp pqxxconnection.cpp \ + pqxxkeywords.cpp pqxxconnection_p.cpp pqxxpreparedstatement.cpp + +kexidb_pqxxsqldriver_la_LIBADD = $(LIB_KPARTS) $(LIB_QT) -lpqxx ../../libkexidb.la + +kexidb_pqxxsqldriver_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) \ + -L$(PQXX_LIBDIR) -L$(PG_LIBDIR) $(VER_INFO) -no-undefined + +kde_services_DATA = kexidb_pqxxsqldriver.desktop + +noinst_HEADERS = pqxxconnection.h pqxxconnection_p.h + +KDE_CXXFLAGS += -DKEXIDB_PGSQL_DRIVER_EXPORT= -D__KEXIDB__= \ + -include $(top_srcdir)/kexi/kexidb/global.h diff --git a/kexi/kexidb/drivers/pqxx/README b/kexi/kexidb/drivers/pqxx/README new file mode 100644 index 00000000..6a1e6c3e --- /dev/null +++ b/kexi/kexidb/drivers/pqxx/README @@ -0,0 +1,18 @@ +ReadMe For Kexi pqkexidb_pqxxslqdriver.desktop~xx PostgreSQL Driver + +This driver requires libpqxx available from pqxx.tk or gborg.postgresql.org. + +Currently the driver builds against 1.9.4 of libpqxx, but it should always work with the latest version. +When 2.0.0 comes out then that will be the version to use. + +The driver may require PostgreSQL >=7.4. Using the old api this was a requirement, but the rewrite +isnt far enough in to get into those kinds of details, so at the mement it should be happy with earlier versions. +Im using PostgreSQL from CVS so i cant say for sure. + +To build the driver you may need to add 'pqxx' to the list of subdirs in Makefile.am in kexi/drivers/ + +Thats it for now + +Adam Pigg +adam@piggz.fsnet.co.uk +adampigg.9p.org.uk
\ No newline at end of file diff --git a/kexi/kexidb/drivers/pqxx/kexidb_pqxxsqldriver.desktop b/kexi/kexidb/drivers/pqxx/kexidb_pqxxsqldriver.desktop new file mode 100644 index 00000000..1f38241b --- /dev/null +++ b/kexi/kexidb/drivers/pqxx/kexidb_pqxxsqldriver.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=PostgreSQL +Name[hi]=पोस्टग्रे-एसक्यूएल +Name[ne]=पोस्ट ग्रे एसक्यूएल +X-KDE-Library=kexidb_pqxxsqldriver +ServiceTypes=Kexi/DBDriver +Type=Service +InitialPreference=8 +X-Kexi-DriverName=PostgreSQL +X-Kexi-DriverType=Network +X-Kexi-KexiDBVersion=1.8 diff --git a/kexi/kexidb/drivers/pqxx/pqxxconnection.cpp b/kexi/kexidb/drivers/pqxx/pqxxconnection.cpp new file mode 100644 index 00000000..8465bcf4 --- /dev/null +++ b/kexi/kexidb/drivers/pqxx/pqxxconnection.cpp @@ -0,0 +1,448 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Adam Pigg <adam@piggz.co.uk> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "pqxxconnection.h" +#include <qvariant.h> +#include <qfile.h> +#include <kdebug.h> +#include <kexidb/error.h> +#include <kexidb/global.h> +#include <klocale.h> +#include <string> +#include "pqxxpreparedstatement.h" +#include "pqxxconnection_p.h" +using namespace KexiDB; + +pqxxTransactionData::pqxxTransactionData(Connection *conn, bool nontransaction) + : TransactionData(conn) +{ + if (nontransaction) + data = new pqxx::nontransaction(*static_cast<pqxxSqlConnection*>(conn)->d->pqxxsql /* todo: add name? */); + else + data = new pqxx::transaction<>(*static_cast<pqxxSqlConnection*>(conn)->d->pqxxsql /* todo: add name? */); + if (!static_cast<pqxxSqlConnection*>(conn)->m_trans) { + static_cast<pqxxSqlConnection*>(conn)->m_trans = this; + } +} + +pqxxTransactionData::~pqxxTransactionData() +{ + if (static_cast<pqxxSqlConnection*>(m_conn)->m_trans == this) { + static_cast<pqxxSqlConnection*>(m_conn)->m_trans = 0; + } + delete data; + data = 0; +} + +//================================================================================== + +pqxxSqlConnection::pqxxSqlConnection(Driver *driver, ConnectionData &conn_data) + : Connection(driver,conn_data) + , d( new pqxxSqlConnectionInternal(this) ) + , m_trans(0) +{ +} + +//================================================================================== +//Do any tidying up before the object is deleted +pqxxSqlConnection::~pqxxSqlConnection() +{ + //delete m_trans; + destroy(); + delete d; +} + +//================================================================================== +//Return a new query based on a query statment +Cursor* pqxxSqlConnection::prepareQuery( const QString& statement, uint cursor_options) +{ + Q_UNUSED(cursor_options); + return new pqxxSqlCursor(this, statement, 1); //Always used buffered cursor +} + +//================================================================================== +//Return a new query based on a query object +Cursor* pqxxSqlConnection::prepareQuery( QuerySchema& query, uint cursor_options) +{ + Q_UNUSED(cursor_options); + return new pqxxSqlCursor(this, query, 1);//Always used buffered cursor +} + +//================================================================================== +//Properly escaped a database object name +QString pqxxSqlConnection::escapeName(const QString &name) const +{ + return QString("\"" + name + "\""); +} + +//================================================================================== +//Made this a noop +//We tell kexi we are connected, but we wont actually connect until we use a database! +bool pqxxSqlConnection::drv_connect(KexiDB::ServerVersionInfo& version) +{ + KexiDBDrvDbg << "pqxxSqlConnection::drv_connect" << endl; + version.clear(); + d->version = &version; //remember for later... +#ifdef __GNUC__ +#warning pqxxSqlConnection::drv_connect implement setting version info when we drop libpqxx for libpq +#endif + return true; +} + +//================================================================================== +//Made this a noop +//We tell kexi wehave disconnected, but it is actually handled by closeDatabse +bool pqxxSqlConnection::drv_disconnect() +{ + KexiDBDrvDbg << "pqxxSqlConnection::drv_disconnect: " << endl; + return true; +} + +//================================================================================== +//Return a list of database names +bool pqxxSqlConnection::drv_getDatabasesList( QStringList &list ) +{ +// KexiDBDrvDbg << "pqxxSqlConnection::drv_getDatabaseList" << endl; + + if (executeSQL("SELECT datname FROM pg_database WHERE datallowconn = TRUE")) + { + std::string N; + for (pqxx::result::const_iterator c = d->res->begin(); c != d->res->end(); ++c) + { + // Read value of column 0 into a string N + c[0].to(N); + // Copy the result into the return list + list << QString::fromLatin1 (N.c_str()); + } + return true; + } + + return false; +} + +//================================================================================== +//Create a new database +bool pqxxSqlConnection::drv_createDatabase( const QString &dbName ) +{ + KexiDBDrvDbg << "pqxxSqlConnection::drv_createDatabase: " << dbName << endl; + + if (executeSQL("CREATE DATABASE " + escapeName(dbName))) + return true; + + return false; +} + +//================================================================================== +//Use this as our connection instead of connect +bool pqxxSqlConnection::drv_useDatabase( const QString &dbName, bool *cancelled, + MessageHandler* msgHandler ) +{ + Q_UNUSED(cancelled); + Q_UNUSED(msgHandler); + KexiDBDrvDbg << "pqxxSqlConnection::drv_useDatabase: " << dbName << endl; + + QString conninfo; + QString socket; + QStringList sockets; + + if (data()->hostName.isEmpty() || data()->hostName == "localhost") + { + if (data()->localSocketFileName.isEmpty()) + { + sockets.append("/tmp/.s.PGSQL.5432"); + + for(QStringList::ConstIterator it = sockets.constBegin(); it != sockets.constEnd(); it++) + { + if(QFile(*it).exists()) + { + socket = (*it); + break; + } + } + } + else + { + socket=data()->localSocketFileName; //data()->fileName(); + } + } + else + { + conninfo = "host='" + data()->hostName + "'"; + } + + //Build up the connection string + if (data()->port == 0) + data()->port = 5432; + + conninfo += QString::fromLatin1(" port='%1'").arg(data()->port); + + conninfo += QString::fromLatin1(" dbname='%1'").arg(dbName); + + if (!data()->userName.isNull()) + conninfo += QString::fromLatin1(" user='%1'").arg(data()->userName); + + if (!data()->password.isNull()) + conninfo += QString::fromLatin1(" password='%1'").arg(data()->password); + + try + { + d->pqxxsql = new pqxx::connection( conninfo.latin1() ); + drv_executeSQL( "SET DEFAULT_WITH_OIDS TO ON" ); //Postgres 8.1 changed the default to no oids but we need them + + if (d->version) { +//! @todo set version using the connection pointer when we drop libpqxx for libpq + } + return true; + } + catch(const std::exception &e) + { + KexiDBDrvDbg << "pqxxSqlConnection::drv_useDatabase:exception - " << e.what() << endl; + d->errmsg = QString::fromUtf8( e.what() ); + + } + catch(...) + { + d->errmsg = i18n("Unknown error."); + } + return false; +} + +//================================================================================== +//Here we close the database connection +bool pqxxSqlConnection::drv_closeDatabase() +{ + KexiDBDrvDbg << "pqxxSqlConnection::drv_closeDatabase" << endl; +// if (isConnected()) +// { + delete d->pqxxsql; + return true; +// } +/* js: not needed, right? + else + { + d->errmsg = "Not connected to database backend"; + d->res = ERR_NO_CONNECTION; + } + return false;*/ +} + +//================================================================================== +//Drops the given database +bool pqxxSqlConnection::drv_dropDatabase( const QString &dbName ) +{ + KexiDBDrvDbg << "pqxxSqlConnection::drv_dropDatabase: " << dbName << endl; + + //FIXME Maybe should check that dbname is no the currentdb + if (executeSQL("DROP DATABASE " + escapeName(dbName))) + return true; + + return false; +} + +//================================================================================== +//Execute an SQL statement +bool pqxxSqlConnection::drv_executeSQL( const QString& statement ) +{ +// KexiDBDrvDbg << "pqxxSqlConnection::drv_executeSQL: " << statement << endl; + bool ok = false; + + // Clear the last result information... + delete d->res; + d->res = 0; + +// KexiDBDrvDbg << "About to try" << endl; + try + { + //Create a transaction + const bool implicityStarted = !m_trans; + if (implicityStarted) + (void)new pqxxTransactionData(this, true); + + // m_trans = new pqxx::nontransaction(*m_pqxxsql); +// KexiDBDrvDbg << "About to execute" << endl; + //Create a result object through the transaction + d->res = new pqxx::result(m_trans->data->exec(std::string(statement.utf8()))); +// KexiDBDrvDbg << "Executed" << endl; + //Commit the transaction + if (implicityStarted) { + pqxxTransactionData *t = m_trans; + drv_commitTransaction(t); + delete t; +// m_trans = 0; + } + + //If all went well then return true, errors picked up by the catch block + ok = true; + } + catch(const pqxx::sql_error& sqlerr) { + KexiDBDrvDbg << "pqxxSqlConnection::drv_executeSQL: sql_error exception - " << sqlerr.query().c_str() << endl; + } + catch (const pqxx::broken_connection& bcerr) { + KexiDBDrvDbg << "pqxxSqlConnection::drv_executeSQL: broken_connection exception" << endl; + } + catch (const std::exception &e) + { + //If an error ocurred then put the error description into _dbError + d->errmsg = QString::fromUtf8( e.what() ); + KexiDBDrvDbg << "pqxxSqlConnection::drv_executeSQL:exception - " << e.what() << endl; + } + catch(...) + { + d->errmsg = i18n("Unknown error."); + } + //KexiDBDrvDbg << "EXECUTE SQL OK: OID was " << (d->res ? d->res->inserted_oid() : 0) << endl; + return ok; +} + +//================================================================================== +//Return true if currently connected to a database, ignoring the m_is_connected falg. +bool pqxxSqlConnection::drv_isDatabaseUsed() const +{ + if (d->pqxxsql->is_open()) + { + return true; + } + return false; +} + +//================================================================================== +//Return the oid of the last insert - only works if sql was insert of 1 row +Q_ULLONG pqxxSqlConnection::drv_lastInsertRowID() +{ + if (d->res) + { + pqxx::oid theOid = d->res->inserted_oid(); + + if (theOid != pqxx::oid_none) + { + return (Q_ULLONG)theOid; + } + else + { + return 0; + } + } + return 0; +} + +//<queries taken from pqxxMigrate> +bool pqxxSqlConnection::drv_containsTable( const QString &tableName ) +{ + bool success; + return resultExists(QString("select 1 from pg_class where relkind='r' and relname LIKE %1") + .arg(driver()->escapeString(tableName)), success) && success; +} + +bool pqxxSqlConnection::drv_getTablesList( QStringList &list ) +{ + KexiDB::Cursor *cursor; + m_sql = "select lower(relname) from pg_class where relkind='r'"; + if (!(cursor = executeQuery( m_sql ))) { + KexiDBDrvWarn << "pqxxSqlConnection::drv_getTablesList(): !executeQuery()" << endl; + return false; + } + list.clear(); + cursor->moveFirst(); + while (!cursor->eof() && !cursor->error()) { + list += cursor->value(0).toString(); + cursor->moveNext(); + } + if (cursor->error()) { + deleteCursor(cursor); + return false; + } + return deleteCursor(cursor); +} +//</taken from pqxxMigrate> + +TransactionData* pqxxSqlConnection::drv_beginTransaction() +{ + return new pqxxTransactionData(this, false); +} + +bool pqxxSqlConnection::drv_commitTransaction(TransactionData *tdata) +{ + bool result = true; + try { + static_cast<pqxxTransactionData*>(tdata)->data->commit(); + } + catch (const std::exception &e) + { + //If an error ocurred then put the error description into _dbError + d->errmsg = QString::fromUtf8( e.what() ); + result = false; + } + catch (...) { + //! @todo + setError(); + result = false; + } + if (m_trans == tdata) + m_trans = 0; + return result; +} + +bool pqxxSqlConnection::drv_rollbackTransaction(TransactionData *tdata) +{ + bool result = true; + try { + static_cast<pqxxTransactionData*>(tdata)->data->abort(); + } + catch (const std::exception &e) + { + //If an error ocurred then put the error description into _dbError + d->errmsg = QString::fromUtf8( e.what() ); + + result = false; + } + catch (...) { + d->errmsg = i18n("Unknown error."); + result = false; + } + if (m_trans == tdata) + m_trans = 0; + return result; +} + +int pqxxSqlConnection::serverResult() +{ + return d->resultCode; +} + +QString pqxxSqlConnection::serverResultName() +{ + return QString::null; +} + +void pqxxSqlConnection::drv_clearServerResult() +{ + d->resultCode = 0; +} + +QString pqxxSqlConnection::serverErrorMsg() +{ + return d->errmsg; +} + +PreparedStatement::Ptr pqxxSqlConnection::prepareStatement(PreparedStatement::StatementType type, + FieldList& fields) +{ + return new pqxxPreparedStatement(type, *d, fields); +} +#include "pqxxconnection.moc" diff --git a/kexi/kexidb/drivers/pqxx/pqxxconnection.h b/kexi/kexidb/drivers/pqxx/pqxxconnection.h new file mode 100644 index 00000000..85bed42a --- /dev/null +++ b/kexi/kexidb/drivers/pqxx/pqxxconnection.h @@ -0,0 +1,104 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Adam Pigg <adam@piggz.co.uk> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef PQXXCONNECTION_H +#define PQXXCONNECTION_H + +#include <qstringlist.h> + +#include <kexidb/connection.h> +#include "pqxxcursor.h" + + + + +namespace KexiDB +{ + +class pqxxSqlConnectionInternal; + +//! @internal +class pqxxTransactionData : public TransactionData +{ + public: + pqxxTransactionData(Connection *conn, bool nontransaction); + ~pqxxTransactionData(); + pqxx::transaction_base *data; +}; + +/** +@author Adam Pigg +*/ +class pqxxSqlConnection : public Connection +{ + Q_OBJECT + + public: + virtual ~pqxxSqlConnection(); + + virtual Cursor* prepareQuery( const QString& statement = QString::null, uint cursor_options = 0 ); + virtual Cursor* prepareQuery( QuerySchema& query, uint cursor_options = 0 ); + virtual PreparedStatement::Ptr prepareStatement(PreparedStatement::StatementType type, + FieldList& fields); + protected: + + pqxxSqlConnection( Driver *driver, ConnectionData &conn_data ); + + virtual bool drv_isDatabaseUsed() const; + virtual bool drv_connect(KexiDB::ServerVersionInfo& version); + virtual bool drv_disconnect(); + virtual bool drv_getDatabasesList( QStringList &list ); + virtual bool drv_createDatabase( const QString &dbName = QString::null ); + virtual bool drv_useDatabase( const QString &dbName = QString::null, bool *cancelled = 0, + MessageHandler* msgHandler = 0 ); + virtual bool drv_closeDatabase(); + virtual bool drv_dropDatabase( const QString &dbName = QString::null ); + virtual bool drv_executeSQL( const QString& statement ); + virtual Q_ULLONG drv_lastInsertRowID(); + +//TODO: move this somewhere to low level class (MIGRATION?) + virtual bool drv_getTablesList( QStringList &list ); +//TODO: move this somewhere to low level class (MIGRATION?) + virtual bool drv_containsTable( const QString &tableName ); + + virtual TransactionData* drv_beginTransaction(); + virtual bool drv_commitTransaction(TransactionData *); + virtual bool drv_rollbackTransaction(TransactionData *); + + //Error reporting + virtual int serverResult(); + virtual QString serverResultName(); + virtual void drv_clearServerResult(); + virtual QString serverErrorMsg(); + + pqxxSqlConnectionInternal *d; + private: + QString escapeName(const QString &tn) const; + // pqxx::transaction_base* m_trans; + //! temporary solution for executeSQL()... + pqxxTransactionData *m_trans; + + + + friend class pqxxSqlDriver; + friend class pqxxSqlCursor; + friend class pqxxTransactionData; +}; +} +#endif diff --git a/kexi/kexidb/drivers/pqxx/pqxxconnection_p.cpp b/kexi/kexidb/drivers/pqxx/pqxxconnection_p.cpp new file mode 100644 index 00000000..b4bc266a --- /dev/null +++ b/kexi/kexidb/drivers/pqxx/pqxxconnection_p.cpp @@ -0,0 +1,51 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Adam Pigg <adam@piggz.co.uk> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ +// +// C++ Implementation: pqxxsqlconnectioninternal +// +// Description: +// +// +// Author: Adam Pigg <adam@piggz.co.uk>, (C) 2005 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "pqxxconnection_p.h" +#include <kdebug.h> + +using namespace KexiDB; +pqxxSqlConnectionInternal::pqxxSqlConnectionInternal(Connection *conn) + : ConnectionInternal(conn) + , pqxxsql(0) + , res(0) + , version(0) +{ +} + + +pqxxSqlConnectionInternal::~pqxxSqlConnectionInternal() +{ + +} + +void pqxxSqlConnectionInternal::storeResult() +{ + errmsg = ""; +} diff --git a/kexi/kexidb/drivers/pqxx/pqxxconnection_p.h b/kexi/kexidb/drivers/pqxx/pqxxconnection_p.h new file mode 100644 index 00000000..0c78e583 --- /dev/null +++ b/kexi/kexidb/drivers/pqxx/pqxxconnection_p.h @@ -0,0 +1,63 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Adam Pigg <adam@piggz.co.uk> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ +// +// C++ Interface: pqxxsqlconnectioninternal +// +// Description: +// +// +// Author: Adam Pigg <adam@piggz.co.uk>, (C) 2005 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef PQXXSQLCONNECTIONINTERNAL_H +#define PQXXSQLCONNECTIONINTERNAL_H + +#include <kexidb/connection_p.h> +#include <pqxx/pqxx> + +namespace KexiDB +{ + +/** + @internal + @author Adam Pigg <adam@piggz.co.uk> +*/ +class pqxxSqlConnectionInternal : public ConnectionInternal +{ + public: + pqxxSqlConnectionInternal(Connection *conn); + + virtual ~pqxxSqlConnectionInternal(); + + //! stores last result's message + virtual void storeResult(); + + pqxx::connection* pqxxsql; + pqxx::result* res; + + KexiDB::ServerVersionInfo *version; //!< this is set in drv_connect(), so we can use it in drv_useDatabase() + //!< because pgsql really connects after "USE". + + QString errmsg; //!< server-specific message of last operation + int resultCode; //!< result code of last operation on server +}; +} +#endif diff --git a/kexi/kexidb/drivers/pqxx/pqxxcursor.cpp b/kexi/kexidb/drivers/pqxx/pqxxcursor.cpp new file mode 100644 index 00000000..0004cf92 --- /dev/null +++ b/kexi/kexidb/drivers/pqxx/pqxxcursor.cpp @@ -0,0 +1,339 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Adam Pigg <adam@piggz.co.uk> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "pqxxcursor.h" +#include "pqxxconnection.h" +#include "pqxxconnection_p.h" + +#include <kexidb/error.h> +#include <kexidb/global.h> + +#include <klocale.h> +#include <kdebug.h> + +#include <cstdlib> + +using namespace KexiDB; + + +unsigned int pqxxSqlCursor_trans_num=0; //!< debug helper + +static QByteArray pgsqlByteaToByteArray(const pqxx::result::field& r) +{ + return KexiDB::pgsqlByteaToByteArray(r.c_str(), r.size()); +} + +//================================================================================== +//Constructor based on query statement +pqxxSqlCursor::pqxxSqlCursor(KexiDB::Connection* conn, const QString& statement, uint options): + Cursor(conn,statement, options) +{ +// KexiDBDrvDbg << "PQXXSQLCURSOR: constructor for query statement" << endl; + my_conn = static_cast<pqxxSqlConnection*>(conn)->d->pqxxsql; + m_options = Buffered; + m_res = 0; +// m_tran = 0; + m_implicityStarted = false; +} + +//================================================================================== +//Constructor base on query object +pqxxSqlCursor::pqxxSqlCursor(Connection* conn, QuerySchema& query, uint options ) + : Cursor( conn, query, options ) +{ +// KexiDBDrvDbg << "PQXXSQLCURSOR: constructor for query schema" << endl; + my_conn = static_cast<pqxxSqlConnection*>(conn)->d->pqxxsql; + m_options = Buffered; + m_res = 0; +// m_tran = 0; + m_implicityStarted = false; +} + +//================================================================================== +//Destructor +pqxxSqlCursor::~pqxxSqlCursor() +{ + close(); +} + +//================================================================================== +//Create a cursor result set +bool pqxxSqlCursor::drv_open() +{ +// KexiDBDrvDbg << "pqxxSqlCursor::drv_open:" << m_sql << endl; + + if (!my_conn->is_open()) + { +//! @todo this check should be moved to Connection! when drv_prepareQuery() arrive + //should never happen, but who knows + setError(ERR_NO_CONNECTION,i18n("No connection for cursor open operation specified")); + return false; + } + + QCString cur_name; + //Set up a transaction + try + { + //m_tran = new pqxx::work(*my_conn, "cursor_open"); + cur_name.sprintf("cursor_transaction%d", pqxxSqlCursor_trans_num++); + +// m_tran = new pqxx::nontransaction(*my_conn, (const char*)cur_name); + if (!((pqxxSqlConnection*)connection())->m_trans) { +// my_conn->drv_beginTransaction(); +// if (implicityStarted) + (void)new pqxxTransactionData((pqxxSqlConnection*)connection(), true); + m_implicityStarted = true; + } + + m_res = new pqxx::result(((pqxxSqlConnection*)connection())->m_trans->data->exec(std::string(m_sql.utf8()))); + ((pqxxSqlConnection*)connection()) + ->drv_commitTransaction(((pqxxSqlConnection*)connection())->m_trans); +// my_conn->m_trans->commit(); +// KexiDBDrvDbg << "pqxxSqlCursor::drv_open: trans. committed: " << cur_name <<endl; + + //We should now be placed before the first row, if any + m_fieldCount = m_res->columns() - (m_containsROWIDInfo ? 1 : 0); +//js m_opened=true; + m_afterLast=false; + m_records_in_buf = m_res->size(); + m_buffering_completed = true; + return true; + } + catch (const std::exception &e) + { + setError(ERR_DB_SPECIFIC, QString::fromUtf8( e.what()) ); + KexiDBDrvWarn << "pqxxSqlCursor::drv_open:exception - " << QString::fromUtf8( e.what() ) << endl; + } + catch(...) + { + setError(); + } +// delete m_tran; +// m_tran = 0; + if (m_implicityStarted) { + delete ((pqxxSqlConnection*)connection())->m_trans; + m_implicityStarted = false; + } +// KexiDBDrvDbg << "pqxxSqlCursor::drv_open: trans. rolled back! - " << cur_name <<endl; + return false; +} + +//================================================================================== +//Delete objects +bool pqxxSqlCursor::drv_close() +{ +//js m_opened=false; + + delete m_res; + m_res = 0; + +// if (m_implicityStarted) { +// delete m_tran; +// m_tran = 0; +// m_implicityStarted = false; +// } + + return true; +} + +//================================================================================== +//Gets the next record...does not need to do much, just return fetchend if at end of result set +void pqxxSqlCursor::drv_getNextRecord() +{ +// KexiDBDrvDbg << "pqxxSqlCursor::drv_getNextRecord, size is " <<m_res->size() << " Current Position is " << (long)at() << endl; + if(at() < m_res->size() && at() >=0) + { + m_result = FetchOK; + } + else if (at() >= m_res->size()) + { + m_result = FetchEnd; + } + else + { + m_result = FetchError; + } +} + +//================================================================================== +//Check the current position is within boundaries +void pqxxSqlCursor::drv_getPrevRecord() +{ +// KexiDBDrvDbg << "pqxxSqlCursor::drv_getPrevRecord" << endl; + + if(at() < m_res->size() && at() >=0) + { + m_result = FetchOK; + } + else if (at() >= m_res->size()) + { + m_result = FetchEnd; + } + else + { + m_result = FetchError; + } +} + +//================================================================================== +//Return the value for a given column for the current record +QVariant pqxxSqlCursor::value(uint pos) +{ + if (pos < m_fieldCount) + return pValue(pos); + else + return QVariant(); +} + +//================================================================================== +//Return the value for a given column for the current record - Private const version +QVariant pqxxSqlCursor::pValue(uint pos)const +{ + if (m_res->size() <= 0) + { + KexiDBDrvWarn << "pqxxSqlCursor::value - ERROR: result size not greater than 0" << endl; + return QVariant(); + } + + if (pos>=(m_fieldCount+(m_containsROWIDInfo ? 1 : 0))) + { +// KexiDBDrvWarn << "pqxxSqlCursor::value - ERROR: requested position is greater than the number of fields" << endl; + return QVariant(); + } + + KexiDB::Field *f = (m_fieldsExpanded && pos<QMIN(m_fieldsExpanded->count(), m_fieldCount)) + ? m_fieldsExpanded->at(pos)->field : 0; + +// KexiDBDrvDbg << "pqxxSqlCursor::value(" << pos << ")" << endl; + + //from most to least frequently used types: + if (f) //We probably have a schema type query so can use kexi to determin the row type + { + if ((f->isIntegerType()) || (/*ROWID*/!f && m_containsROWIDInfo && pos==m_fieldCount)) + { + return (*m_res)[at()][pos].as(int()); + } + else if (f->isTextType()) + { + return QString::fromUtf8((*m_res)[at()][pos].c_str()); //utf8? + } + else if (f->isFPNumericType()) + { + return (*m_res)[at()][pos].as(double()); + } + else if (f->typeGroup() == Field::BLOBGroup) + { +// pqxx::result::field r = (*m_res)[at()][pos]; +// kdDebug() << r.name() << ", " << r.c_str() << ", " << r.type() << ", " << r.size() << endl; + return ::pgsqlByteaToByteArray((*m_res)[at()][pos]); + } + } + else // We probably have a raw type query so use pqxx to determin the column type + { + return pgsqlCStrToVariant((*m_res)[at()][pos]); + } + + return QString::fromUtf8((*m_res)[at()][pos].c_str(), (*m_res)[at()][pos].size()); //utf8? +} + +//================================================================================== +//Return the current record as a char** +//who'd have thought we'd be using char** in this day and age :o) +const char** pqxxSqlCursor::rowData() const +{ +// KexiDBDrvDbg << "pqxxSqlCursor::recordData" << endl; + + const char** row; + + row = (const char**)malloc(m_res->columns()+1); + row[m_res->columns()] = NULL; + if (at() >= 0 && at() < m_res->size()) + { + for(int i = 0; i < (int)m_res->columns(); i++) + { + row[i] = (char*)malloc(strlen((*m_res)[at()][i].c_str())+1); + strcpy((char*)(*m_res)[at()][i].c_str(), row[i]); +// KexiDBDrvDbg << row[i] << endl; + } + } + else + { + KexiDBDrvWarn << "pqxxSqlCursor::recordData: m_at is invalid" << endl; + } + return row; +} + +//================================================================================== +//Store the current record in [data] +void pqxxSqlCursor::storeCurrentRow(RowData &data) const +{ +// KexiDBDrvDbg << "pqxxSqlCursor::storeCurrentRow: POSITION IS " << (long)m_at<< endl; + + if (m_res->size()<=0) + return; + + const uint realCount = m_fieldCount + (m_containsROWIDInfo ? 1 : 0); + data.resize(realCount); + + for( uint i=0; i<realCount; i++) + { + data[i] = pValue(i); + } +} + +//================================================================================== +// +void pqxxSqlCursor::drv_clearServerResult() +{ +//! @todo pqxxSqlCursor: stuff with server results +} + +//================================================================================== +//Add the current record to the internal buffer +//Implementation required but no need in this driver +//Result set is a buffer so do not need another +void pqxxSqlCursor::drv_appendCurrentRecordToBuffer() +{ + +} + +//================================================================================== +//Move internal pointer to internal buffer +1 +//Implementation required but no need in this driver +void pqxxSqlCursor::drv_bufferMovePointerNext() +{ + +} + +//================================================================================== +//Move internal pointer to internal buffer -1 +//Implementation required but no need in this driver +void pqxxSqlCursor::drv_bufferMovePointerPrev() +{ + +} + +//================================================================================== +//Move internal pointer to internal buffer to N +//Implementation required but no need in this driver +void pqxxSqlCursor::drv_bufferMovePointerTo(Q_LLONG to) +{ + Q_UNUSED(to); +} + diff --git a/kexi/kexidb/drivers/pqxx/pqxxcursor.h b/kexi/kexidb/drivers/pqxx/pqxxcursor.h new file mode 100644 index 00000000..d596acca --- /dev/null +++ b/kexi/kexidb/drivers/pqxx/pqxxcursor.h @@ -0,0 +1,110 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Adam Pigg <adam@piggz.co.uk> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KEXIDB_CURSOR_PQXX_H +#define KEXIDB_CURSOR_PQXX_H + +#include <kexidb/cursor.h> +#include <kexidb/connection.h> +#include <kexidb/utils.h> + +#if 0 +#include <pqxx/all.h> +#else +#include <pqxx/pqxx> +#endif + +#include <pqxx/binarystring> +#include <migration/pqxx/pg_type.h> + +namespace KexiDB { + +class pqxxSqlCursor: public Cursor { +public: + virtual ~pqxxSqlCursor(); + + virtual QVariant value(uint i); + virtual const char** rowData() const; + virtual void storeCurrentRow(RowData &data) const; + +//TODO virtual const char *** bufferData() + +//TODO virtual int serverResult() const; + +//TODO virtual QString serverResultName() const; + +//TODO virtual QString serverErrorMsg() const; + +protected: + pqxxSqlCursor(Connection* conn, const QString& statement = QString::null, uint options = NoOptions ); + pqxxSqlCursor(Connection* conn, QuerySchema& query, uint options = NoOptions ); + virtual void drv_clearServerResult(); + virtual void drv_appendCurrentRecordToBuffer(); + virtual void drv_bufferMovePointerNext(); + virtual void drv_bufferMovePointerPrev(); + virtual void drv_bufferMovePointerTo(Q_LLONG to); + virtual bool drv_open(); + virtual bool drv_close(); + virtual void drv_getNextRecord(); + virtual void drv_getPrevRecord(); + +private: + pqxx::result* m_res; +// pqxx::nontransaction* m_tran; + pqxx::connection* my_conn; + QVariant pValue(uint pos)const; + bool m_implicityStarted : 1; + //QByteArray processBinaryData(pqxx::binarystring*) const; + friend class pqxxSqlConnection; +}; + +inline QVariant pgsqlCStrToVariant(const pqxx::result::field& r) +{ + switch(r.type()) + { + case BOOLOID: + return QString::fromLatin1(r.c_str(), r.size())=="true"; //TODO check formatting + case INT2OID: + case INT4OID: + case INT8OID: + return r.as(int()); + case FLOAT4OID: + case FLOAT8OID: + case NUMERICOID: + return r.as(double()); + case DATEOID: + return QString::fromUtf8(r.c_str(), r.size()); //TODO check formatting + case TIMEOID: + return QString::fromUtf8(r.c_str(), r.size()); //TODO check formatting + case TIMESTAMPOID: + return QString::fromUtf8(r.c_str(), r.size()); //TODO check formatting + case BYTEAOID: + return KexiDB::pgsqlByteaToByteArray(r.c_str(), r.size()); + case BPCHAROID: + case VARCHAROID: + case TEXTOID: + return QString::fromUtf8(r.c_str(), r.size()); //utf8? + default: + return QString::fromUtf8(r.c_str(), r.size()); //utf8? + } +} + +} + +#endif diff --git a/kexi/kexidb/drivers/pqxx/pqxxdriver.cpp b/kexi/kexidb/drivers/pqxx/pqxxdriver.cpp new file mode 100644 index 00000000..d8e6216d --- /dev/null +++ b/kexi/kexidb/drivers/pqxx/pqxxdriver.cpp @@ -0,0 +1,181 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Adam Pigg <adam@piggz.co.uk> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include <kexidb/connection.h> +#include <kexidb/drivermanager.h> +#include <kexidb/driver_p.h> +#include <kexidb/utils.h> +#include "pqxxdriver.h" +#include "pqxxconnection.h" +#include <string> + +#include <kdebug.h> + +using namespace KexiDB; + +KEXIDB_DRIVER_INFO( pqxxSqlDriver, pqxxsql ) + +//================================================================================== +// +pqxxSqlDriver::pqxxSqlDriver( QObject *parent, const char *name, const QStringList &args ) + : Driver( parent, name, args ) +{ + d->isFileDriver = false; + d->features = SingleTransactions | CursorForward | CursorBackward; +//! @todo enable this when kexidb supports multiple: d->features = MultipleTransactions | CursorForward | CursorBackward; + + beh->UNSIGNED_TYPE_KEYWORD = ""; + beh->ROW_ID_FIELD_NAME = "oid"; + beh->SPECIAL_AUTO_INCREMENT_DEF = false; + beh->AUTO_INCREMENT_TYPE = "SERIAL"; + beh->AUTO_INCREMENT_FIELD_OPTION = ""; + beh->AUTO_INCREMENT_PK_FIELD_OPTION = "PRIMARY KEY"; + beh->ALWAYS_AVAILABLE_DATABASE_NAME = "template1"; + beh->QUOTATION_MARKS_FOR_IDENTIFIER = '"'; + beh->SQL_KEYWORDS = keywords; + initSQLKeywords(233); + + //predefined properties + d->properties["client_library_version"] = "";//TODO + d->properties["default_server_encoding"] = ""; //TODO + + d->typeNames[Field::Byte]="SMALLINT"; + d->typeNames[Field::ShortInteger]="SMALLINT"; + d->typeNames[Field::Integer]="INTEGER"; + d->typeNames[Field::BigInteger]="BIGINT"; + d->typeNames[Field::Boolean]="BOOLEAN"; + d->typeNames[Field::Date]="DATE"; + d->typeNames[Field::DateTime]="TIMESTAMP"; + d->typeNames[Field::Time]="TIME"; + d->typeNames[Field::Float]="REAL"; + d->typeNames[Field::Double]="DOUBLE PRECISION"; + d->typeNames[Field::Text]="CHARACTER VARYING"; + d->typeNames[Field::LongText]="TEXT"; + d->typeNames[Field::BLOB]="BYTEA"; +} + +//================================================================================== +//Override the default implementation to allow for NUMERIC type natively +QString pqxxSqlDriver::sqlTypeName(int id_t, int p) const +{ + if (id_t==Field::Null) + return "NULL"; + if (id_t==Field::Float || id_t==Field::Double) + { + if (p>0) + { + return "NUMERIC"; + } + else + { + return d->typeNames[id_t]; + } + } + else + { + return d->typeNames[id_t]; + } +} + +//================================================================================== +// +pqxxSqlDriver::~pqxxSqlDriver() +{ +// delete d; +} + +//================================================================================== +// +KexiDB::Connection* +pqxxSqlDriver::drv_createConnection( ConnectionData &conn_data ) +{ + return new pqxxSqlConnection( this, conn_data ); +} + +//================================================================================== +// +bool pqxxSqlDriver::isSystemObjectName( const QString& n ) const +{ + return Driver::isSystemObjectName(n); +} + +//================================================================================== +// +bool pqxxSqlDriver::drv_isSystemFieldName( const QString& ) const +{ + return false; +} + +//================================================================================== +// +bool pqxxSqlDriver::isSystemDatabaseName( const QString& n ) const +{ + return n.lower()=="template1" || n.lower()=="template0"; +} + +//================================================================================== +// +QString pqxxSqlDriver::escapeString( const QString& str) const +{ + return QString::fromLatin1("'") + + QString::fromAscii( pqxx::sqlesc(std::string(str.utf8())).c_str() ) + + QString::fromLatin1("'"); +} + +//================================================================================== +// +QCString pqxxSqlDriver::escapeString( const QCString& str) const +{ + return QCString("'") + + QCString( pqxx::sqlesc(QString(str).ascii()).c_str() ) + + QCString("'"); +} + +//================================================================================== +// +QString pqxxSqlDriver::drv_escapeIdentifier( const QString& str) const { + return QString(str).replace( '"', "\"\"" ); +} + +//================================================================================== +// +QCString pqxxSqlDriver::drv_escapeIdentifier( const QCString& str) const { + return QCString(str).replace( '"', "\"\"" ); +} + +//================================================================================== +// +QString pqxxSqlDriver::escapeBLOB(const QByteArray& array) const +{ + return KexiDB::escapeBLOB(array, KexiDB::BLOBEscapeOctal); +} + +QString pqxxSqlDriver::valueToSQL( uint ftype, const QVariant& v ) const +{ + if (ftype==Field::Boolean) { + // use SQL compliant TRUE or FALSE as described here + // http://www.postgresql.org/docs/8.0/interactive/datatype-boolean.html + // 1 or 0 does not work + return v.toInt()==0 ? QString::fromLatin1("FALSE") : QString::fromLatin1("TRUE"); + } + return Driver::valueToSQL(ftype, v); +} + + +#include "pqxxdriver.moc" diff --git a/kexi/kexidb/drivers/pqxx/pqxxdriver.h b/kexi/kexidb/drivers/pqxx/pqxxdriver.h new file mode 100644 index 00000000..bbfdddc3 --- /dev/null +++ b/kexi/kexidb/drivers/pqxx/pqxxdriver.h @@ -0,0 +1,71 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Adam Pigg <adam@piggz.co.uk> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KEXIDB_DRIVER_PQXX_H +#define KEXIDB_DRIVER_PQXX_H + +#include <qstringlist.h> + +#include <kexidb/driver.h> + +namespace KexiDB +{ + +class Connection; +class DriverManager; + +//! PostgreSQL database driver. +class pqxxSqlDriver : public Driver +{ + Q_OBJECT + KEXIDB_DRIVER + + public: + pqxxSqlDriver( QObject *parent, const char *name, const QStringList &args = QStringList() ); + ~pqxxSqlDriver(); + + virtual bool isSystemObjectName( const QString& n )const; + virtual bool isSystemDatabaseName( const QString& n )const; + + //! Escape a string for use as a value + virtual QString escapeString( const QString& str) const; + virtual QCString escapeString( const QCString& str) const; + virtual QString sqlTypeName(int id_t, int p=0) const; + + //! Escape BLOB value \a array + virtual QString escapeBLOB(const QByteArray& array) const; + + /*! Escapes and converts value \a v (for type \a ftype) + to string representation required by SQL commands. + Reimplemented for boolean type only to use SQL compliant TRUE or FALSE */ + virtual QString valueToSQL( uint ftype, const QVariant& v ) const; + + protected: + virtual QString drv_escapeIdentifier( const QString& str) const; + virtual QCString drv_escapeIdentifier( const QCString& str) const; + virtual Connection *drv_createConnection( ConnectionData &conn_data ); + virtual bool drv_isSystemFieldName( const QString& n )const; + + private: + static const char *keywords[]; +}; + +}; + +#endif diff --git a/kexi/kexidb/drivers/pqxx/pqxxkeywords.cpp b/kexi/kexidb/drivers/pqxx/pqxxkeywords.cpp new file mode 100644 index 00000000..cc1a9f6e --- /dev/null +++ b/kexi/kexidb/drivers/pqxx/pqxxkeywords.cpp @@ -0,0 +1,244 @@ + /* + * This file has been automatically generated from + * koffice/kexi/tools/sql_keywords/sql_keywords.sh and + * postgresql-7.4.6/src/backend/parser/keywords.c. + * + * Please edit the sql_keywords.sh, not this file! + */ +#include <pqxxdriver.h> + +namespace KexiDB { + const char* pqxxSqlDriver::keywords[] = { + "ABORT", + "ABSOLUTE", + "ACCESS", + "ACTION", + "ADD", + "AGGREGATE", + "ALTER", + "ANALYSE", + "ANALYZE", + "ANY", + "ARRAY", + "ASSERTION", + "ASSIGNMENT", + "AT", + "AUTHORIZATION", + "BACKWARD", + "BIGINT", + "BINARY", + "BIT", + "BOOLEAN", + "BOTH", + "CACHE", + "CALLED", + "CAST", + "CHAIN", + "CHAR", + "CHARACTER", + "CHARACTERISTICS", + "CHECKPOINT", + "CLASS", + "CLOSE", + "CLUSTER", + "COALESCE", + "COLUMN", + "COMMENT", + "COMMITTED", + "CONSTRAINTS", + "CONVERSION", + "CONVERT", + "COPY", + "CREATEDB", + "CREATEUSER", + "CURRENT_DATE", + "CURRENT_TIME", + "CURRENT_TIMESTAMP", + "CURRENT_USER", + "CURSOR", + "CYCLE", + "DAY", + "DEALLOCATE", + "DEC", + "DECIMAL", + "DECLARE", + "DEFAULTS", + "DEFERRABLE", + "DEFERRED", + "DEFINER", + "DELIMITER", + "DELIMITERS", + "DO", + "DOMAIN", + "DOUBLE", + "EACH", + "ENCODING", + "ENCRYPTED", + "ESCAPE", + "EXCEPT", + "EXCLUDING", + "EXCLUSIVE", + "EXECUTE", + "EXISTS", + "EXTERNAL", + "EXTRACT", + "FALSE", + "FETCH", + "FIRST", + "FLOAT", + "FORCE", + "FORWARD", + "FREEZE", + "FUNCTION", + "GLOBAL", + "GRANT", + "HANDLER", + "HOLD", + "HOUR", + "ILIKE", + "IMMEDIATE", + "IMMUTABLE", + "IMPLICIT", + "INCLUDING", + "INCREMENT", + "INHERITS", + "INITIALLY", + "INOUT", + "INPUT", + "INSENSITIVE", + "INSTEAD", + "INT", + "INTERSECT", + "INTERVAL", + "INVOKER", + "ISNULL", + "ISOLATION", + "LANCOMPILER", + "LANGUAGE", + "LAST", + "LEADING", + "LEVEL", + "LISTEN", + "LOAD", + "LOCAL", + "LOCALTIME", + "LOCALTIMESTAMP", + "LOCATION", + "LOCK", + "MAXVALUE", + "MINUTE", + "MINVALUE", + "MODE", + "MONTH", + "MOVE", + "NAMES", + "NATIONAL", + "NCHAR", + "NEW", + "NEXT", + "NO", + "NOCREATEDB", + "NOCREATEUSER", + "NONE", + "NOTHING", + "NOTIFY", + "NOTNULL", + "NULLIF", + "NUMERIC", + "OF", + "OFF", + "OIDS", + "OLD", + "ONLY", + "OPERATOR", + "OPTION", + "OUT", + "OVERLAPS", + "OVERLAY", + "OWNER", + "PARTIAL", + "PASSWORD", + "PATH", + "PENDANT", + "PLACING", + "POSITION", + "PRECISION", + "PREPARE", + "PRESERVE", + "PRIOR", + "PRIVILEGES", + "PROCEDURAL", + "PROCEDURE", + "READ", + "REAL", + "RECHECK", + "REINDEX", + "RELATIVE", + "RENAME", + "RESET", + "RESTART", + "RETURNS", + "REVOKE", + "ROWS", + "RULE", + "SCHEMA", + "SCROLL", + "SECOND", + "SECURITY", + "SEQUENCE", + "SERIALIZABLE", + "SESSION", + "SESSION_USER", + "SETOF", + "SHARE", + "SHOW", + "SIMPLE", + "SMALLINT", + "SOME", + "STABLE", + "START", + "STATEMENT", + "STATISTICS", + "STDIN", + "STDOUT", + "STORAGE", + "STRICT", + "SUBSTRING", + "SYSID", + "TEMP", + "TEMPLATE", + "TIME", + "TIMESTAMP", + "TOAST", + "TRAILING", + "TREAT", + "TRIGGER", + "TRIM", + "TRUE", + "TRUNCATE", + "TRUSTED", + "TYPE", + "UNENCRYPTED", + "UNKNOWN", + "UNLISTEN", + "UNTIL", + "USAGE", + "USER", + "VACUUM", + "VALID", + "VALIDATOR", + "VARCHAR", + "VARYING", + "VERBOSE", + "VERSION", + "VIEW", + "VOLATILE", + "WITH", + "WITHOUT", + "WORK", + "WRITE", + "YEAR", + "ZONE", + 0 + }; +} diff --git a/kexi/kexidb/drivers/pqxx/pqxxpreparedstatement.cpp b/kexi/kexidb/drivers/pqxx/pqxxpreparedstatement.cpp new file mode 100644 index 00000000..5c87f78a --- /dev/null +++ b/kexi/kexidb/drivers/pqxx/pqxxpreparedstatement.cpp @@ -0,0 +1,56 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Adam Pigg <adam@piggz.co.uk> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ +// +// C++ Implementation: pqxxpreparedstatement +// +// Description: +// +// +// Author: Adam Pigg <adam@piggz.co.uk>, (C) 2005 +// +// Copyright: See COPYING file that comes with this distribution +// +#include "pqxxpreparedstatement.h" +#include <kdebug.h> +using namespace KexiDB; + +pqxxPreparedStatement::pqxxPreparedStatement( + StatementType type, ConnectionInternal& conn, FieldList& fields) + : KexiDB::PreparedStatement(type, conn, fields) + , m_conn(conn.connection) +{ +// KexiDBDrvDbg << "pqxxPreparedStatement: Construction" << endl; +} + + +pqxxPreparedStatement::~pqxxPreparedStatement() +{ +} + +bool pqxxPreparedStatement::execute() +{ +// KexiDBDrvDbg << "pqxxPreparedStatement::execute()" << endl; + m_resetRequired = true; + if (m_conn->insertRecord(*m_fields, m_args)) { + return true; + } + return false; +} + + diff --git a/kexi/kexidb/drivers/pqxx/pqxxpreparedstatement.h b/kexi/kexidb/drivers/pqxx/pqxxpreparedstatement.h new file mode 100644 index 00000000..232454d3 --- /dev/null +++ b/kexi/kexidb/drivers/pqxx/pqxxpreparedstatement.h @@ -0,0 +1,49 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Adam Pigg <adam@piggz.co.uk> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ +// +// C++ Interface: pqxxpreparedstatement +// +// Description: +// +// +#ifndef PQXXPREPAREDSTATEMENT_H +#define PQXXPREPAREDSTATEMENT_H +#include <kexidb/preparedstatement.h> +#include <kexidb/connection_p.h> + +namespace KexiDB +{ +/** + @author Adam Pigg <adam@piggz.co.uk> +*/ +class pqxxPreparedStatement : public PreparedStatement +{ + public: + pqxxPreparedStatement(StatementType type, ConnectionInternal& conn, FieldList& fields); + + virtual ~pqxxPreparedStatement(); + + virtual bool execute(); + bool m_resetRequired : 1; + + private: + Connection* m_conn; +}; +} +#endif |