summaryrefslogtreecommitdiffstats
path: root/kexi/kexidb/drivers/pqxx
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
commit8362bf63dea22bbf6736609b0f49c152f975eb63 (patch)
tree0eea3928e39e50fae91d4e68b21b1e6cbae25604 /kexi/kexidb/drivers/pqxx
downloadkoffice-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.am22
-rw-r--r--kexi/kexidb/drivers/pqxx/README18
-rw-r--r--kexi/kexidb/drivers/pqxx/kexidb_pqxxsqldriver.desktop11
-rw-r--r--kexi/kexidb/drivers/pqxx/pqxxconnection.cpp448
-rw-r--r--kexi/kexidb/drivers/pqxx/pqxxconnection.h104
-rw-r--r--kexi/kexidb/drivers/pqxx/pqxxconnection_p.cpp51
-rw-r--r--kexi/kexidb/drivers/pqxx/pqxxconnection_p.h63
-rw-r--r--kexi/kexidb/drivers/pqxx/pqxxcursor.cpp339
-rw-r--r--kexi/kexidb/drivers/pqxx/pqxxcursor.h110
-rw-r--r--kexi/kexidb/drivers/pqxx/pqxxdriver.cpp181
-rw-r--r--kexi/kexidb/drivers/pqxx/pqxxdriver.h71
-rw-r--r--kexi/kexidb/drivers/pqxx/pqxxkeywords.cpp244
-rw-r--r--kexi/kexidb/drivers/pqxx/pqxxpreparedstatement.cpp56
-rw-r--r--kexi/kexidb/drivers/pqxx/pqxxpreparedstatement.h49
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