21#include "pqxxmigrate.h"
26#include <tqstringlist.h>
32#include <kexidb/cursor.h>
33#include <kexidb/utils.h>
34#include <kexidb/drivermanager.h>
35#include <kexiutils/identifier.h>
36#include <kexidb/drivers/pqxx/pqxxcursor.h>
48KEXIMIGRATE_DRIVER_INFO( PqxxMigrate, pqxx )
60PqxxMigrate::PqxxMigrate(TQObject *parent,
const char *name,
const TQStringList &args)
67 m_kexiDBDriver = manager.
driver(
"pqxx");
71PqxxMigrate::~PqxxMigrate()
80bool PqxxMigrate::drv_readTableSchema(
81 const TQString& originalName, KexiDB::TableSchema& tableSchema)
89 if (query(
"select * from \"" + originalName +
"\" limit 1"))
92 for (uint i = 0; i < (uint)m_res->columns(); i++)
94 TQString fldName(m_res->column_name(i));
95#if PQXX_VERSION_MAJOR < 7
101 const pqxx::oid toid = tableOid(originalName);
104 KexiDB::Field *f =
new KexiDB::Field(fldID, fldType);
118 kdDebug() <<
"Added field [" << f->name() <<
"] type [" << f->
typeName()
131bool PqxxMigrate::drv_tableNames(TQStringList& tableNames)
137 if (query(
"SELECT relname FROM pg_class WHERE ((relkind = 'r') AND ((relname !~ '^pg_') AND (relname !~ '^pga_') AND (relname !~ '^sql_')))"))
139 for (pqxx::result::const_iterator c = m_res->begin(); c != m_res->end(); ++c)
142 tableNames << TQString::fromLatin1 (c[0].c_str());
175 return KexiDB::Field::Date;
177 return KexiDB::Field::Time;
179 return KexiDB::Field::DateTime;
198 kdDebug() <<
"drv_connect: " <<
m_migrateData->sourceName << endl;
208 socket=
"/tmp/.s.PGSQL.5432";
224 conninfo += TQString::fromLatin1(
" port='%1'").arg(
m_migrateData->source->port);
226 conninfo += TQString::fromLatin1(
" dbname='%1'").arg(
m_migrateData->sourceName);
229 conninfo += TQString::fromLatin1(
" user='%1'").arg(
m_migrateData->source->userName);
232 conninfo += TQString::fromLatin1(
" password='%1'").arg(
m_migrateData->source->password);
236 m_conn =
new pqxx::connection( conninfo.latin1() );
239 catch(
const std::exception &e)
241 kdDebug() <<
"PqxxMigrate::drv_connect:exception - " << e.what() << endl;
245 kdDebug() <<
"PqxxMigrate::drv_connect:exception(...)??" << endl;
256#if PQXX_VERSION_MAJOR < 7
257 m_conn->disconnect();
266bool PqxxMigrate::query(
const TQString& statement)
268 kdDebug() <<
"query: " << statement.latin1() << endl;
278 m_trans =
new pqxx::nontransaction(*m_conn);
280 m_res =
new pqxx::result(m_trans->exec(statement.latin1()));
286 catch (
const std::exception &e)
289 kdDebug() <<
"pqxxImport::query:exception - " << e.what() << endl;
294 kdDebug() <<
"PqxxMigrate::query:exception(...)??" << endl;
301void PqxxMigrate::clearResultInfo()
312pqxx::oid PqxxMigrate::tableOid(
const TQString& table)
315 static TQString otable;
316 static pqxx::oid toid;
318 pqxx::nontransaction* tran = 0;
319 pqxx::result* tmpres = 0;
324 kdDebug() <<
"Returning table OID from cache..." << endl;
334 statement =
"SELECT relfilenode FROM pg_class WHERE (relname = '";
338 tran =
new pqxx::nontransaction(*m_conn,
"find_t_oid");
339 tmpres =
new pqxx::result(tran->exec(statement.latin1()));
342 if (tmpres->size() > 0)
345 tmpres->at(0).at(0).to(toid);
352 catch(
const std::exception &e)
354 kdDebug() <<
"pqxxSqlDB::tableOid:exception - " << e.what() << endl;
355 kdDebug() <<
"pqxxSqlDB::tableOid:failed statement - " << statement << endl;
360 kdDebug() <<
"PqxxMigrate::tableOid:exception(...)??" << endl;
368 kdDebug() <<
"OID for table [" << table <<
"] is [" << toid <<
"]" << endl;
375bool PqxxMigrate::primaryKey(pqxx::oid table_uid,
int col)
const
381 pqxx::nontransaction* tran = 0;
382 pqxx::result* tmpres = 0;
386 statement = TQString(
"SELECT indkey FROM pg_index WHERE ((indisprimary = true) AND (indrelid = %1))").arg(table_uid);
388 tran =
new pqxx::nontransaction(*m_conn,
"find_pkey");
389 tmpres =
new pqxx::result(tran->exec(statement.latin1()));
392 if (tmpres->size() > 0)
395 tmpres->at(0).at(0).to(keyf);
399 kdDebug() <<
"Field is pkey" << endl;
404 kdDebug() <<
"Field is NOT pkey" << endl;
410 kdDebug() <<
"Field is NOT pkey" << endl;
413 catch(
const std::exception &e)
415 kdDebug() <<
"pqxxSqlDB::primaryKey:exception - " << e.what() << endl;
416 kdDebug() <<
"pqxxSqlDB::primaryKey:failed statement - " << statement << endl;
433tristate PqxxMigrate::drv_queryStringListFromSQL(
434 const TQString& sqlStatement, uint columnNumber, TQStringList& stringList,
int numRecords)
438 if (query(sqlStatement))
440 for (pqxx::result::const_iterator it = m_res->begin();
441 it != m_res->end() && (numRecords == -1 || i < numRecords); ++it, i++)
443 if (it.size() > 0 && it.size() > columnNumber) {
444 it.at(columnNumber).to(result);
445 stringList.append( TQString::fromUtf8(result.c_str()) );
500tristate PqxxMigrate::drv_fetchRecordFromSQL(
const TQString& sqlStatement,
503 if (firstRecord || !m_res) {
506 if (!query(sqlStatement))
508 m_fetchRecordFromSQL_iter = m_res->begin();
512 ++m_fetchRecordFromSQL_iter;
514 if (m_fetchRecordFromSQL_iter == m_res->end()) {
520 const int numFields = m_fetchRecordFromSQL_iter.size();
521 data.resize(numFields);
522 for (
int i=0; i < numFields; i++)
523 data[i] = KexiDB::pgsqlCStrToVariant(m_fetchRecordFromSQL_iter.at(i));
529bool PqxxMigrate::drv_copyTable(
const TQString& srcTable, KexiDB::Connection *destConn,
530 KexiDB::TableSchema* dstTable)
532 if (query(TQString(
"SELECT * FROM ") + srcTable.latin1()))
534 pqxx::work T(*m_conn,
"PqxxMigrate::drv_copyTable");
537 const KexiDB::QueryColumnInfo::Vector fieldsExpanded( dstTable->
query()->
fieldsExpanded() );
538 for (pqxx::result::const_iterator rowIt = m_res->begin(); rowIt != m_res->end(); ++rowIt)
540 TQValueList<TQVariant> vals;
542 for (
int i = 0; i < rowIt.size(); ++i, index++)
551 vals.append(TQString(rowIt.at(i).c_str()).lower() ==
"t" ? TQVariant(
true) : TQVariant(
false));
558 if (!destConn->insertRecord(*dstTable, vals))
572bool PqxxMigrate::uniqueKey(pqxx::oid table_uid,
int col)
const
578 pqxx::nontransaction* tran = 0;
579 pqxx::result* tmpres = 0;
583 statement = TQString(
"SELECT indkey FROM pg_index WHERE ((indisunique = true) AND (indrelid = %1))").arg(table_uid);
585 tran =
new pqxx::nontransaction(*m_conn,
"find_ukey");
586 tmpres =
new pqxx::result(tran->exec(statement.latin1()));
589 if (tmpres->size() > 0)
592 tmpres->at(0).at(0).to(keyf);
596 kdDebug() <<
"Field is unique" << endl;
601 kdDebug() <<
"Field is NOT unique" << endl;
607 kdDebug() <<
"Field is NOT unique" << endl;
610 catch(
const std::exception &e)
612 kdDebug() <<
"uniqueKey:exception - " << e.what() << endl;
613 kdDebug() <<
"uniqueKey:failed statement - " << statement << endl;
628bool PqxxMigrate::autoInc(pqxx::oid ,
int )
const
635bool PqxxMigrate::notNull(pqxx::oid ,
int )
const
642bool PqxxMigrate::notEmpty(pqxx::oid ,
int )
const
671#include "pqxxmigrate.moc"
Database driver management, e.g. finding and loading drivers.
Driver * driver(const TQString &name)
FieldList & addField(Field *field)
void setCaption(const TQString &caption)
void setPrimaryKey(bool p)
void setUniqueKey(bool u)
void setAutoIncrement(bool a)
static TQString typeName(uint type)
QueryColumnInfo::Vector fieldsExpanded(FieldsExpandedOptions options=Default)
Imports non-native databases into Kexi projects.
virtual bool drv_connect()=0
Connect to source database (driver specific).
KexiMigration::Data * data() const
KexiDB::Field::Type userType(const TQString &fname)
Prompt user to select a field type for unrecognized fields.
virtual bool drv_disconnect()=0
Disconnect from source database (driver specific).
KexiMigration::Data * m_migrateData
Migrate Options.
High-level database connectivity library with database backend drivers.
TQVariant cstringToVariant(const char *data, KexiDB::Field *f, int length=-1)
TQValueVector< TQVariant > RowData
structure for storing single record with type information
KEXI_DB_EXPORT TQByteArray pgsqlByteaToByteArray(const char *data, int length)
Framework for importing databases into native KexiDB databases.
KEXIUTILS_EXPORT TQString string2Identifier(const TQString &s)