22#include "keximigrate.h"
25#include <kinputdialog.h>
26#include <tdeapplication.h>
28#include <kexiutils/identifier.h>
30#include <core/kexiproject.h>
31#include <kexidb/drivermanager.h>
38 : TQObject( parent, name )
42 m_kexiDBCompatibleTableSchemasToRemoveFromMemoryAfterImport.setAutoDelete(
true);
47#define NUM_OF_ROWS_PER_CREATE_TABLE 20
59KexiMigrate::~KexiMigrate()
65 bool& acceptingNeeded)
67 acceptingNeeded =
false;
69 result->clearStatus();
75 result->setStatus(&drvManager,
76 i18n(
"Could not create database \"%1\".")
87 if (!tmpConn || destDriver->
error() || !tmpConn->
connect()) {
92 acceptingNeeded =
true;
104 sourcedata && destinationdata &&
119 result->clearStatus();
125 result->setStatus(&drvManager,
126 i18n(
"Could not create database \"%1\".")
134 kdDebug() <<
"KexiMigrate::performImport() CONNECTING..." << endl;
136 kdDebug() <<
"Couldnt connect to database server" << endl;
138 result->setStatus(i18n(
"Could not connect to data source \"%1\".")
144 kdDebug() <<
"KexiMigrate::performImport() GETTING TABLENAMES..." << endl;
145 if (!tableNames(tables)) {
146 kdDebug() <<
"Couldnt get list of tables" << endl;
149 i18n(
"Could not get a list of table names for data source \"%1\".")
155 if (tables.isEmpty()) {
156 kdDebug() <<
"There were no tables to import" << endl;
159 i18n(
"No tables to import found in data source \"%1\".")
166 m_tableSchemas.clear();
168 result->setStatus(&drvManager);
171 const bool kexi__objects_exists = tables.find(
"kexi__objects")!=tables.end();
172 TQStringList kexiDBTables;
173 if (kexi__objects_exists) {
175 TQString::fromLatin1(
"SELECT o_name FROM kexi__objects WHERE o_type=%1")
176 .arg((
int)KexiDB::TableObjectType), 0, kexiDBTables, -1);
181 foreach(TQStringList::ConstIterator, it, kexiDBTables)
182 tables.remove( *it );
190 foreach (TQStringList::ConstIterator, it, tables) {
192 || (*it).lower().startsWith(
"kexi__"))
197 tableSchema->setCaption( *it );
203 i18n(
"Could not import project from data source \"%1\". Error reading table \"%2\".")
204 .arg(
m_migrateData->source->serverInfoString()).arg(tableName),
"");
209 m_tableSchemas.append(tableSchema);
218 bool ok =
true == m_destPrj->create(
true );
223 ok = (destConn = m_destPrj->dbConnection());
231 result->setStatus(destConn,
232 i18n(
"Could not create database \"%1\".")
241 if (drv_progressSupported())
242 progressInitialise();
245 m_kexiDBCompatibleTableSchemasToRemoveFromMemoryAfterImport.clear();
246 foreach (TQStringList::ConstIterator, it, kexiDBTables) {
250 bool firstRecord =
true;
252 TQString(
"SELECT o_id, o_type, o_name, o_caption, o_desc FROM kexi__objects "
253 "WHERE o_name='%1' AND o_type=%1").arg(*it).arg((
int)KexiDB::TableObjectType),
261 TQString::fromLatin1(
"SELECT t_id, f_type, f_name, f_length, f_precision, f_constraints, "
262 "f_options, f_default, f_order, f_caption, f_help"
263 " FROM kexi__fields WHERE t_id=%1 ORDER BY f_order").arg(t->id()) );
280 m_kexiDBCompatibleTableSchemasToRemoveFromMemoryAfterImport.append(t);
289 if (kexi__objects_exists)
296 for (TQPtrListIterator<TableSchema> it (m_tableSchemas); (ts = it.current()); ++it) {
299 kdDebug() <<
"Failed to create a table " << ts->name() << endl;
302 result->setStatus(destConn,
303 i18n(
"Could not create database \"%1\".")
305 m_tableSchemas.remove(ts);
308 updateProgress((TQ_ULLONG)NUM_OF_ROWS_PER_CREATE_TABLE);
318 for(TQPtrListIterator<TableSchema> it (m_kexiDBCompatibleTableSchemasToRemoveFromMemoryAfterImport);
321 m_tableSchemas.append(it.current());
325 m_tableSchemas.clear();
329 if (m_destPrj->error()) {
332 result->setStatus(m_destPrj,
333 i18n(
"Could not import project from data source \"%1\".")
347 if (tables.find(
"kexi__objectdata")!=tables.end())
348 m_tableSchemas.append(destConn->
tableSchema(
"kexi__objectdata"));
350 if (tables.find(
"kexi__blobs")!=tables.end())
351 m_tableSchemas.append(destConn->
tableSchema(
"kexi__blobs"));
353 if (tables.find(
"kexi__fields")!=tables.end())
354 m_tableSchemas.append(destConn->
tableSchema(
"kexi__fields"));
357 for(TQPtrListIterator<TableSchema> ts(m_tableSchemas); ok && ts.current() != 0 ; ++ts)
359 const TQString tname( ts.current()->name().lower() );
363 && tname!=
"kexi__objectdata"
364 && tname!=
"kexi__blobs"
365 && tname!=
"kexi__fields"
368 kdDebug() <<
"Do not copy data for system table: " << tname << endl;
372 kdDebug() <<
"Copying data for table: " << tname << endl;
373 TQString originalTableName;
374 if (kexiDBTables.find(tname)==kexiDBTables.end())
376 originalTableName = ts.current()->caption().isEmpty() ? tname : ts.current()->caption();
378 originalTableName = tname;
379 ok =
drv_copyTable(originalTableName, destConn, ts.current());
381 kdDebug() <<
"Failed to copy table " << tname << endl;
383 result->setStatus(destConn,
384 i18n(
"Could not copy table \"%1\" to destination database.").arg(tname));
397 m_kexiDBCompatibleTableSchemasToRemoveFromMemoryAfterImport.clear();
406 if (result && result->error())
407 result->setStatus(destConn,
408 i18n(
"Could not import data from data source \"%1\".")
426 result->clearStatus();
435bool KexiMigrate::tableNames(TQStringList & tn)
438 kdDebug() <<
"Reading list of tables..." << endl;
444bool KexiMigrate::progressInitialise() {
445 TQ_ULLONG sum = 0, size;
446 emit progressPercent(0);
450 if(!tableNames(tables))
455 for(TQStringList::Iterator it = tables.begin();
456 it != tables.end(); ++it, tableNumber++)
459 kdDebug() <<
"KexiMigrate::progressInitialise() - table: " << *it
460 <<
"size: " << (ulong)size << endl;
462 emit progressPercent(tableNumber * 5 / tables.count());
468 kdDebug() <<
"KexiMigrate::progressInitialise() - job size: " << (ulong)sum << endl;
469 m_progressTotal = sum;
470 m_progressTotal += tables.count() * NUM_OF_ROWS_PER_CREATE_TABLE;
471 m_progressTotal = m_progressTotal * 105 / 100;
472 m_progressNextReport = sum / 100;
473 m_progressDone = m_progressTotal * 5 / 100;
478void KexiMigrate::updateProgress(TQ_ULLONG step) {
479 m_progressDone += step;
480 if (m_progressDone >= m_progressNextReport) {
481 int percent = (m_progressDone+1) * 100 / m_progressTotal;
482 m_progressNextReport = ((percent + 1) * m_progressTotal) / 100;
483 kdDebug() <<
"KexiMigrate::updateProgress(): " << (ulong)m_progressDone <<
"/"
484 << (ulong)m_progressTotal <<
" (" << percent <<
"%) next report at "
485 << (ulong)m_progressNextReport << endl;
486 emit progressPercent(percent);
498 types <<
"Short Integer";
500 types <<
"Big Integer";
503 types <<
"Date Time";
508 types <<
"Long Text";
509 types <<
"Binary Large Object";
511 res = KInputDialog::getItem( i18n(
"Field Type"),
512 i18n(
"The data type for %1 could not be determined. "
513 "Please select one of the following data "
518 if (res == *types.at(0))
520 else if (res == *types.at(1))
522 else if (res == *types.at(2))
524 else if (res == *types.at(3))
526 else if (res == *types.at(4))
528 else if (res == *types.at(5))
529 return KexiDB::Field::Date;
530 else if (res == *types.at(6))
531 return KexiDB::Field::DateTime;
532 else if (res == *types.at(7))
533 return KexiDB::Field::Time;
534 else if (res == *types.at(8))
536 else if (res == *types.at(9))
538 else if (res == *types.at(10))
540 else if (res == *types.at(11))
542 else if (res == *types.at(12))
575 setError(ERR_INCOMPAT_DRIVER_VERSION,
576 i18n(
"Incompatible migration driver's \"%1\" version: found version %2, expected version %3.")
586 const TQString& columnName,
int& result)
590 TQString::fromLatin1(
"SELECT MAX(%1) FROM %2").arg(drv_escapeIdentifier(columnName))
591 .arg(drv_escapeIdentifier(tableName)), 0,
string);
599 int tmpResult =
string.toInt(&ok);
606 const TQString& sqlStatement, uint columnNumber, TQString&
string)
608 TQStringList stringList;
611 string = stringList.first();
615#include "keximigrate.moc"
TQString driverName
the name of the driver that should be used to create a connection
TQString hostName
Host name used for the remote connection.
Database specific connection data, e.g. host, port.
TQString fileName() const
Get the filename used by the connection.
TQString dbFileName() const
The file name (without path) of the database file.
TQString dbPath() const
The directory the database file is in.
Provides database connection, allowing queries and data modification.
bool commitTransaction(Transaction trans=Transaction::null, bool ignore_inactive=false)
TableSchema * tableSchema(int tableId)
bool rollbackTransaction(Transaction trans=Transaction::null, bool ignore_inactive=false)
virtual bool drv_createTable(const TableSchema &tableSchema)
bool createTable(TableSchema *tableSchema, bool replaceExisting=false)
Creates a table according to the given schema.
bool dropDatabase(const TQString &dbName=TQString())
Drops database with name dbName.
bool disconnect()
Disconnects from driver with given parameters.
bool databaseExists(const TQString &dbName, bool ignoreErrors=true)
bool setupObjectSchemaData(const RowData &data, SchemaData &sdata)
Transaction beginTransaction()
Creates new transaction handle and starts a new transaction.
KexiDB::Field * setupField(const RowData &data)
bool connect()
Connects to driver with given parameters.
Database driver management, e.g. finding and loading drivers.
Driver * driver(const TQString &name)
Generic database abstraction.
bool isFileDriver() const
Connection * createConnection(ConnectionData &conn_data, int options=0)
virtual bool isSystemObjectName(const TQString &n) const
FieldList & addField(Field *field)
virtual void setError(int code=ERR_OTHER, const TQString &msg=TQString())
This class encapsulates transaction handle.
bool performExport(Kexi::ObjectStatus *result=0)
Perform an export operation.
bool performImport(Kexi::ObjectStatus *result=0)
Perform an import operation.
virtual tristate drv_fetchRecordFromSQL(const TQString &sqlStatement, KexiDB::RowData &data, bool &firstRecord)
KexiMigrate(TQObject *parent, const char *name, const TQStringList &args=TQStringList())
Used by MigrateManager.
virtual bool drv_tableNames(TQStringList &tablenames)=0
Get table names in source database (driver specific).
virtual bool drv_readTableSchema(const TQString &originalName, KexiDB::TableSchema &tableSchema)=0
Read schema for a given table (driver specific).
virtual TQVariant propertyValue(const TQCString &propName)
bool isSourceAndDestinationDataSourceTheSame() const
bool checkIfDestinationDatabaseOverwritingNeedsAccepting(Kexi::ObjectStatus *result, bool &acceptingNeeded)
virtual bool drv_connect()=0
Connect to source database (driver specific).
void setData(KexiMigration::Data *migrateData)
Data Setup. Requires two connection objects, a name and a bool.
virtual bool drv_queryMaxNumber(const TQString &tableName, const TQString &columnName, int &result)
virtual tristate drv_queryStringListFromSQL(const TQString &sqlStatement, uint columnNumber, TQStringList &stringList, int numRecords=-1)
virtual bool drv_getTableSize(const TQString &, TQ_ULLONG &)
TQString propertyCaption(const TQCString &propName) const
void setPropertyValue(const TQCString &propName, const TQVariant &value)
KexiMigration::Data * data() const
KexiDB::Field::Type userType(const TQString &fname)
Prompt user to select a field type for unrecognized fields.
TQMap< TQCString, TQString > m_propertyCaptions
virtual bool drv_copyTable(const TQString &srcTable, KexiDB::Connection *destConn, KexiDB::TableSchema *dstTable)=0
TQValueList< TQCString > propertyNames() const
TQMap< TQCString, TQVariant > m_properties
virtual bool drv_disconnect()=0
Disconnect from source database (driver specific).
KexiMigration::Data * m_migrateData
Migrate Options.
virtual tristate drv_querySingleStringFromSQL(const TQString &sqlStatement, uint columnNumber, TQString &string)
A project's main controller.
3-state logical type with three values: true, false and cancelled and convenient operators.
High-level database connectivity library with database backend drivers.
TQValueVector< TQVariant > RowData
structure for storing single record with type information
Framework for importing databases into native KexiDB databases.
KEXIMIGR_EXPORT int versionMajor()
KEXIMIGR_EXPORT int versionMinor()
KEXIUTILS_EXPORT TQString string2Identifier(const TQString &s)