20#include "XbaseExport.h"
27#include "KDbRecordData.h"
29#include "KDbDriverManager.h"
31#include <migration/keximigratedata.h>
37class KDbxBaseExportPrivate {
39 xBaseExportPrivate() {
63 char xBaseType =
'\0';
68 xBaseType = XB_CHAR_FLD;
72 xBaseType = XB_LOGICAL_FLD;
77 xBaseType = XB_FLOAT_FLD;
82 xBaseType = XB_NUMERIC_FLD;
85 case KDbField::DateTime:
88 xBaseType = XB_DATE_FLD;
92 xBaseType = XB_MEMO_FLD;
102bool xBaseExportPrivate::appendRecord(
const QString& sourceTableName ,
KDbRecordData* recordData ) {
105 QString pathName = tableNamePathMap.value( sourceTableName );
107 xbDbf* table = xbase.GetDbfPtr( pathNameBa.
constData() );
110 table->BlankRecord();
111 for (
int i=0;i < recordData->size();++i) {
112 char fieldType = table->GetFieldType(i);
115 if (fieldType == XB_MEMO_FLD) {
116 #ifdef XB_MEMO_FIELDS
118 table->UpdateMemoData(i, stringData.
size()+1, stringData.
constData(), F_SETLKW );
120 xbaseDebug() <<
"XB_MEMO_FIELDS support disabled during compilation of XBase libraries";
123 if ((returnCode = table->PutField( i, stringData.
constData())) != XB_NO_ERROR ) {
125 case XB_INVALID_FIELDNO:
126 xbaseWarning() <<
"Invalid field number" << i;
128 case XB_INVALID_DATA:
129 xbaseWarning() <<
"Invalid data" << stringData;
132 xbaseWarning() <<
"Error number" << returnCode <<
"has occurred";
139 if((returnCode = table->AppendRecord()) != XB_NO_ERROR) {
140 xbaseWarning() <<
"xBase Error" << returnCode <<
"appending data record.";
152int xBaseExportPrivate::fieldLength(
KDbField* f)
154 const Field::Type t = f->
type();
203 QString pathName = tableNamePathMap.value( sourceTableName );
205 xbDbf* table = xbase.GetDbfPtr( pathNameBa.
constData() );
210 for (
int i=0; i< fieldCount ; ++i) {
217 QByteArray fieldNameBa = fieldName.toLatin1();
222 if ((returnCode = index.CreateIndex(indexNameBa.
constData(), fieldNameBa.
constData(), XB_UNIQUE, XB_OVERLAY)) != XB_NO_ERROR ) {
223 xbaseWarning() <<
"Couldn't create unique index for fieldName"
224 << fieldName <<
"on table" << sourceTableName <<
"Error Code" << returnCode;
231 if ((returnCode = index.CreateIndex(indexNameBa.
constData(), fieldNameBa.
constData(), XB_NOT_UNIQUE, XB_OVERLAY)) != XB_NO_ERROR ) {
232 xbaseWarning() <<
"Couldn't create index for fieldName" << fieldName <<
"on table"
233 << sourceTableName <<
"Error Code" << returnCode;
244xBaseExport::xBaseExport()
246d(new xBaseExportPrivate)
250void xBaseExport::setData(KexiMigration::Data* migrateData) {
251 m_migrateData = migrateData;
254bool xBaseExport::performExport(Kexi::ObjectStatus* result) {
257 result->clearStatus();
262 if (!m_migrateData) {
263 xbaseWarning() <<
"Migration Data not set yet";
264 result->setStatus(&drvManager, tr(
"Data not set for migration."));
268 KDbDriver *sourceDriver = drvManager.
driver(m_migrateData->source->driverId);
270 result->setStatus(&drvManager,
271 tr(
"Could not export back to destination database."));
276 if (!dest_connect()) {
277 xbaseWarning() <<
"Couldn't connect to destination database";
279 result->setStatus(tr(
"Could not connect to data source \"%1\".",
280 m_migrateData->destination->connectionData()->serverInfoString()),
"");
286 if (!sourceConn || sourceDriver->error()) {
287 xbaseWarning() <<
"Export failed";
291 xbaseWarning() <<
"Export failed.Could not connect";
295 if (!sourceConn->
useDatabase(m_migrateData->sourceName)) {
296 xbaseWarning() <<
"Couldn't use database "<<m_migrateData->sourceName;
304 xbaseDebug() <<
"There were no tables to export";
307 tr(
"No tables to export found in data source \"%1\".",
308 m_migrateData->source->serverInfoString()),
"");
315 foreach (
const QString& tableCaption, tables) {
316 if (dest_isSystemObjectName( tableCaption )) {
322 if (!dest_createTable(tableCaption, tableSchema)) {
324 result->setStatus(tr(
"Could not create table in destination \"%1\". Error reading table \"%2\".", m_migrateData->destination->connectionData()->serverInfoString(), tableCaption),
"");
328 if (m_migrateData->keepData) {
329 if (!dest_copyTable(tableCaption, sourceConn, tableSchema)) {
330 xbaseWarning() <<
"Failed to copy table " << tableCaption;
332 result->setStatus(sourceConn,
333 tr(
"Could not copy table \"%1\" to destination database.", tableCaption));
339 if (dest_disconnect()) {
347 if (result && result->error())
348 result->setStatus(sourceConn,
349 tr(
"Could not export data to \"%1\".",
350 m_migrateData->source->serverInfoString()));
358bool xBaseExport::dest_connect() {
362bool xBaseExport::dest_disconnect() {
364 foreach(
const QString& pathName, pathNameList) {
366 xbDbf* tablePtr = d->xbase.GetDbfPtr(ba.
constData());
367 tablePtr->CloseDatabase();
381 const int arrayLength = fieldCount + 1;
382 xbSchema xBaseTableSchema[arrayLength];
385 for (i = 0; i < fieldCount ; ++i) {
390 strcpy(xBaseTableSchema[i].FieldName, ba.
data());
391 xBaseTableSchema[i].Type = d->type(f->
type());
392 xBaseTableSchema[i].FieldLen = d->fieldLength( f );
393 xBaseTableSchema[i].NoOfDecs = ( xBaseTableSchema[i].Type != XB_CHAR_FLD )? f->
scale() : 0 ;
398 strcpy( xBaseTableSchema[i].FieldName ,
"" );
399 xBaseTableSchema[i].Type = 0;
400 xBaseTableSchema[i].FieldLen = 0;
401 xBaseTableSchema[i].NoOfDecs = 0;
403 const KDbConnectionData* connData = m_migrateData->destination->connectionData();
404 QString dirName = connData->fileName();
406 QString pathName = dirName + originalName +
".dbf";
407 d->tableNamePathMap[originalName] = pathName;
411 xbDbf* xBaseTable =
new xbDbf( &d->xbase );
412 xBaseTable->SetVersion( 4 );
414 if (( returnCode = xBaseTable->CreateDatabase( pathNameBa.
constData() , xBaseTableSchema, XB_OVERLAY )) != XB_NO_ERROR ) {
415 xbaseWarning() <<
"Error creating table" << originalName <<
"Error Code" << returnCode;
419 if (!d->createIndexes(originalName, tableSchema)) {
439 if (!cursor->
moveFirst() && cursor->error())
442 while (!cursor->
eof()) {
447 if (!d->appendRecord(srcTableName, record)) {
448 xbaseWarning() <<
"Couldn't append record";
452 if (!cursor->
moveNext() && cursor->error()) {
459bool xBaseExport::dest_isSystemObjectName(
const QString& ) {
Database specific connection data, e.g. host, port.
Provides database connection, allowing queries and data modification.
bool connect()
Connects to driver with given parameters.
KDbCursor * executeQuery(const KDbEscapedString &sql, KDbCursor::Options options=KDbCursor::Option::None)
QStringList tableNames(bool alsoSystemTables=false, bool *ok=nullptr)
bool disconnect()
Disconnects from driver with given parameters.
KDbTableSchema * tableSchema(int tableId)
bool useDatabase(const QString &dbName=QString(), bool kexiCompatible=true, bool *cancelled=nullptr, KDbMessageHandler *msgHandler=nullptr)
Opens an existing database specified by dbName.
Provides database cursor functionality.
KDbRecordData * storeCurrentRecord() const
A driver manager for finding and loading driver plugins.
KDbDriver * driver(const QString &id)
Database driver's abstraction.
KDbConnection * createConnection(const KDbConnectionData &connData, const KDbConnectionOptions &options)
Specialized string for escaping.
virtual KDbField * field(int id)
bool isPrimaryKey() const
Structure for storing single record with type information.
QVariant value(int i) const
Type type(const QSqlDatabase &db)
const char * constData() const const
qsizetype size() const const
QString toString(QStringView format, QCalendar cal) const const
QString path() const const
bool isEmpty() const const
QByteArray toLatin1() const const
QByteArray toUtf8() const const
void sort(Qt::CaseSensitivity cs)
bool toBool() const const
QByteArray toByteArray() const const
QDate toDate() const const
QString toString() const const