Keximigrate extension

View: New views
2 Messages — Rating Filter:   Alert me  

Keximigrate extension

by Adam Pigg :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Lo

Attached is 3 patches to kexi.

1. Extend the keximigrate api to add a cursor style api - fix the txt plugin
to use this api

2. A kspread plugin implementing the api

3. Updated reportspgz plugin to allow using keximigrate as a datasource for
reporting (also some misc cleanups)

The idea behind this is that it allows integration with other koffice apps, as
a driver could be written for kplato also.  We could also extend the existing
plugins with the cursor api, to allow reading directly from a mysql or
postgresql datasource etc.

Please comment on the theory, im not saying the impl is perfect yet, more of a
'just enough to work'!

More ideas very welcome.

Cheers

Adam


[keximigrate_and_txt_driver.patch]

Index: txt/txtmigrate.cpp
===================================================================
--- txt/txtmigrate.cpp (revision 985390)
+++ txt/txtmigrate.cpp (working copy)
@@ -14,8 +14,12 @@
 namespace KexiMigration
 {
 
-TxtMigrate::TxtMigrate()
-        : KexiMigrate()
+KEXIMIGRATE_DRIVER_INFO(TxtMigrate, txt)
+
+
+
+TxtMigrate::TxtMigrate(QObject *parent, const QStringList &args)
+        : KexiMigrate(parent, args)
 {
 }
 
@@ -24,5 +28,85 @@
 {
 }
 
+bool TxtMigrate::drv_connect()
+{
+  mfolder = m_migrateData->source->dbPath();
+  return true;
+}
 
+bool TxtMigrate::drv_disconnect()
+{
+  return true;
+}
+
+bool TxtMigrate::drv_tableNames(QStringList& tablenames)
+{
+  tablenames << "Table1";
+  return true;
+}
+
+bool TxtMigrate::drv_readTableSchema(const QString& originalName, KexiDB::TableSchema& tableSchema)
+{
+  if (drv_readFromTable(originalName))
+  {
+    for (unsigned int i = 0; i < mFieldNames.count(); ++i)
+    {
+      tableSchema.addField( new KexiDB::Field(mFieldNames[i], KexiDB::Field::Text) );
+    }
+    return true;
+  }
+  return false;
+}
+
+bool TxtMigrate::drv_readFromTable(const QString & tableName)
+{
+  mDataFile = new QFile(mfolder + "/" + tableName);
+
+  kDebug() << mDataFile->fileName();
+  mRow = -1;
+  fileRow = -1;
+
+  if (!mDataFile->open(QIODevice::ReadOnly | QIODevice::Text))
+         return false;
+
+  mLastLine = mDataFile->readLine();
+  mFieldNames = mLastLine.split("\t");
+
+  return true;
+}
+
+bool TxtMigrate::drv_moveNext()
+{
+  if (mRow < fileRow)
+  {
+   mRow++;
+  }
+  else
+  {
+    if (mDataFile->atEnd())
+      return false;
+
+    mLastLine = mDataFile->readLine();
+    mFieldValues.push_back(mLastLine.split("\t"));
+    mRow++;
+    fileRow++;
+  }
+  return true;
+}
+
+bool TxtMigrate::drv_movePrevious()
+{
+  if (mRow > 0)
+  {
+    mRow--;
+    return true;
+  }
+  return false;
+}
+
+QVariant TxtMigrate::drv_value(uint i)
+{
+  return QVariant(mFieldValues[mRow][i]);
+}
+
 };
Index: txt/CMakeLists.txt
===================================================================
--- txt/CMakeLists.txt (revision 985390)
+++ txt/CMakeLists.txt (working copy)
@@ -8,40 +8,20 @@
 set(keximigrate_txtmigrate_PART_SRCS txtmigrate.cpp )
 
 
-kde4_add_plugin(keximigrate_txtmigrate ${keximigrate_txtmigrate_PART_SRCS})
+kde4_add_plugin(keximigrate_txt ${keximigrate_txtmigrate_PART_SRCS})
 
 
 
-target_link_libraries(keximigrate_txtmigrate  ${KDE4_KPARTS_LIBS} keximigrate )
+target_link_libraries(keximigrate_txt  
+    ${KDE4_KPARTS_LIBS}
+    keximigrate
+    kexidb
+    kexiutils
+)
 
-install(TARGETS keximigrate_txtmigrate  DESTINATION ${PLUGIN_INSTALL_DIR})
+install(TARGETS keximigrate_txt  DESTINATION ${PLUGIN_INSTALL_DIR})
 
 
 ########### install files ###############
 
-install( FILES  keximigrate_txtmigrate.desktop  DESTINATION ${SERVICES_INSTALL_DIR})
-
-
-
-
-
-#original Makefile.am contents follow:
-
-#include $(top_srcdir)/kexi/Makefile.global
-#
-#kde_module_LTLIBRARIES = keximigrate_txtmigrate.la
-#
-#INCLUDES = -I$(srcdir)/../../.. -I$(top_srcdir)/kexi $(all_includes)
-#
-#keximigrate_txtmigrate_la_METASOURCES = AUTO
-#
-#keximigrate_txtmigrate_la_SOURCES = txtmigrate.cpp
-#
-#keximigrate_txtmigrate_la_LIBADD = $(LIB_KPARTS) $(LIB_QT) ../libkeximigrate.la
-#
-#keximigrate_txtmigrate_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(VER_INFO) -no-undefined
-#
-#kde_services_DATA = keximigrate_txtmigrate.desktop
-#
-#noinst_HEADERS =  txtmigrate.h
-#
+install( FILES  keximigrate_txt.desktop  DESTINATION ${SERVICES_INSTALL_DIR})
Index: txt/txtmigrate.h
===================================================================
--- txt/txtmigrate.h (revision 985390)
+++ txt/txtmigrate.h (working copy)
@@ -12,7 +12,8 @@
 #ifndef KEXIMIGRATIONTXTMIGRATE_H
 #define KEXIMIGRATIONTXTMIGRATE_H
 
-#include <keximigrate.h>
+#include <migration/keximigrate.h>
+#include <QFile>
 
 namespace KexiMigration
 {
@@ -22,11 +23,56 @@
 */
 class TxtMigrate : public KexiMigrate
 {
+    Q_OBJECT
+    KEXIMIGRATION_DRIVER
 public:
-    TxtMigrate();
+    TxtMigrate(QObject *parent, const QStringList &args = QStringList());
 
-    ~TxtMigrate();
+    virtual ~TxtMigrate();
 
+  protected:
+    //! Connect to source
+    virtual bool drv_connect();
+
+    //! Disconnect from source
+    virtual bool drv_disconnect();
+
+    //! Get table names in source
+    virtual bool drv_tableNames(QStringList& tablenames);
+
+    virtual bool drv_copyTable(const QString&, KexiDB::Connection*, KexiDB::TableSchema*){return false;};
+
+    //! Read schema for a given table
+    virtual bool drv_readTableSchema(const QString& originalName, KexiDB::TableSchema& tableSchema);
+
+    //!Position the source dataset at the start of a table
+    virtual bool drv_readFromTable(const QString & tableName);
+
+    //!Move to the next row
+    virtual bool drv_moveNext();
+
+    //!Move to the previous row
+    virtual bool drv_movePrevious();
+
+    //!Read the data at the given row/field
+    virtual QVariant drv_value(uint i);
+
+  private:
+    QString mfolder;
+
+    QString mFileName;
+
+    QString mLastLine;
+
+    QFile *mDataFile;
+
+    QStringList mFieldNames;
+    QVector<QStringList> mFieldValues;
+
+    int mRow;
+    
+    int fileRow;
+
 };
 
 };
Index: keximigrate.cpp
===================================================================
--- keximigrate.cpp (revision 985390)
+++ keximigrate.cpp (working copy)
@@ -429,15 +429,6 @@
 }
 
 //=============================================================================
-// Functions for getting table data
-bool KexiMigrate::tableNames(QStringList & tn)
-{
-    //! @todo Cache list of table names
-    kDebug() << "Reading list of tables...";
-    return drv_tableNames(tn);
-}
-
-//=============================================================================
 // Progress functions
 bool KexiMigrate::progressInitialise()
 {
@@ -573,4 +564,53 @@
     return res;
 }
 
+//=============================================================================
+//Extended API for access to external data
+bool KexiMigrate::connectSource()
+{
+  return drv_connect();
+}
+
+bool KexiMigrate::readTableSchema(const QString& originalName, KexiDB::TableSchema& tableSchema)
+{
+  return drv_readTableSchema(originalName, tableSchema);
+}
+
+bool KexiMigrate::tableNames(QStringList & tn)
+{
+    //! @todo Cache list of table names
+    kDebug() << "Reading list of tables...";
+    return drv_tableNames(tn);
+}
+
+bool KexiMigrate::readFromTable(const QString & tableName)
+{
+  return drv_readFromTable(tableName);
+}
+    
+bool KexiMigrate::moveNext()
+{
+  return drv_moveNext();
+}
+
+bool KexiMigrate::movePrevious()
+{
+  return drv_movePrevious();
+}
+
+bool KexiMigrate::moveFirst()
+{
+  return drv_moveFirst();
+}
+
+bool KexiMigrate::moveLast()
+{
+  return drv_moveLast();
+}
+  
+QVariant KexiMigrate::value(uint i)
+{
+  return drv_value(i);
+}
+
 #include "keximigrate.moc"
Index: keximigrate.h
===================================================================
--- keximigrate.h (revision 985390)
+++ keximigrate.h (working copy)
@@ -114,7 +114,7 @@
 
     //! Perform an export operation
     bool performExport(Kexi::ObjectStatus* result = 0);
-
+    
     //! Returns true if the migration driver supports progress updates.
     inline bool progressSupported() {
         return drv_progressSupported();
@@ -144,7 +144,35 @@
      and KexiMigrate::versionMinor() are matching.
      You can reimplement this but always call KexiMigrate::isValid() implementation. */
     virtual bool isValid();
+    
+    //Extension of existing api to provide generic row access to external data.
+    //!Connect to the source data
+    bool connectSource();
+    
+    //! Get table names in source database (driver specific)
+    bool tableNames(QStringList& tablenames);
 
+    //! Read schema for a given table (driver specific)
+    bool readTableSchema(const QString& originalName, KexiDB::TableSchema& tableSchema);
+    
+    //!Position the source dataset at the start of a table    
+    bool readFromTable(const QString& tableName);
+    
+    //!Move to the next row
+    bool moveNext();
+    
+    //!Move to the previous row
+    bool movePrevious();
+    
+    //!Move to the next row
+    bool moveFirst();
+    
+    //!Move to the previous row
+    bool moveLast();
+    
+    //!Read the data at the given row/field
+    QVariant value(uint i);
+
 signals:
     void progressPercent(int percent);
 
@@ -275,10 +303,27 @@
 
     //! KexiDB driver. For instance, it is used for escaping identifiers
     QPointer<KexiDB::Driver> m_kexiDBDriver;
-
+    
+    //Extended API
+    //!Position the source dataset at the start of a table
+    virtual bool drv_readFromTable(const QString & tableName){ return false; };
+    
+    //!Move to the next row
+    virtual bool drv_moveNext() { return false; };
+    
+    //!Move to the previous row
+    virtual bool drv_movePrevious() { return false; };
+    
+    //!Move to the next row
+    virtual bool drv_moveFirst() { return false; };
+    
+    //!Move to the previous row
+    virtual bool drv_moveLast() { return false; };
+    
+    //!Read the data at the given row/field
+    virtual QVariant drv_value(uint i){ return QVariant(); };
+    
 private:
-    //! Get the list of tables
-    bool tableNames(QStringList& tablenames);
 
     //! Create the target database project
 //  KexiProject* createProject(Kexi::ObjectStatus* result);
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt (revision 985390)
+++ CMakeLists.txt (working copy)
@@ -6,6 +6,10 @@
 
 add_definitions(-DKDE_DEFAULT_DEBUG_AREA=44000)
 
+add_subdirectory(txt)
+
+add_subdirectory(kspread)
+
 macro_optional_find_package(MySQL)
 macro_log_feature(MYSQL_FOUND "libmysqlclient" "MySQL Client Library" "http://www.mysql.com" FALSE "" "Required by Kexi MySQL Migration driver")
 IF (MYSQL_FOUND)
@@ -74,7 +78,14 @@
 
 target_link_libraries(keximigratetest  ${KDE4_KDECORE_LIBS} keximigrate kexicore kexidb kexiextendedwidgets keximain )
 
+########### next target ###############
 
+set(readertest_SRCS readertest.cpp )
+
+kde4_add_executable(readertest ${readertest_SRCS})
+
+target_link_libraries(readertest  ${KDE4_KDECORE_LIBS} keximigrate kexicore kexidb keximain )
+
 ########### install files ###############
 
 install( FILES  keximigrate.h keximigratedata.h migratemanager.h  DESTINATION ${INCLUDE_INSTALL_DIR}/kexidb COMPONENT Devel)


[keximigrate_kspread_plugin.patch]

Index: kspreadmigrate.cpp
===================================================================
--- kspreadmigrate.cpp (revision 0)
+++ kspreadmigrate.cpp (revision 0)
@@ -0,0 +1,150 @@
+//
+// C++ Implementation: txtmigrate
+//
+// Description:
+//
+//
+// Author: Adam Pigg <adam@...>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "kspreadmigrate.h"
+
+namespace KexiMigration
+{
+
+KEXIMIGRATE_DRIVER_INFO(KSpreadMigrate, kspread)
+
+KSpreadMigrate::KSpreadMigrate(QObject *parent, const QStringList &args)
+        : KexiMigrate(parent, args)
+{
+  mCurSheet = 0;
+}
+
+KSpreadMigrate::~KSpreadMigrate()
+{
+}
+
+bool KSpreadMigrate::drv_connect()
+{
+  mFileName = m_migrateData->source->dbPath() + "/" + m_migrateData->source->dbFileName();
+  mKSDoc = new KSpread::Doc();
+  return mKSDoc->openUrl(mFileName);
+}
+
+bool KSpreadMigrate::drv_disconnect()
+{
+  delete mKSDoc;
+  return true;
+}
+
+bool KSpreadMigrate::drv_tableNames(QStringList& tablenames)
+{
+  QList<KSpread::Sheet*> sheets = mKSDoc->map()->sheetList();
+  
+  kDebug() << sheets.size() << "sheets" << mKSDoc->map()->sheetList().size();
+  
+  for (unsigned int i = 0; i < sheets.size(); ++i)
+  {
+    tablenames << sheets[i]->sheetName();
+  }
+  
+  return true;
+}
+
+bool KSpreadMigrate::drv_readTableSchema(const QString& originalName, KexiDB::TableSchema& tableSchema)
+{
+  KSpread::Sheet *sheet = mKSDoc->map()->findSheet(originalName);
+  
+  if (!sheet)
+  {
+      kDebug() << "unable to find sheet" << originalName;
+      return false;
+  }
+  
+  int row=1, col = 1;
+  QString fieldname;
+  
+  KSpread::Cell *cell;
+  do
+  {
+      cell = new KSpread::Cell(sheet, col, row);
+
+      fieldname = cell->displayText();
+      col++;
+      if (!cell->isEmpty())
+      {
+ tableSchema.addField( new KexiDB::Field(fieldname, KexiDB::Field::Text) );
+ kDebug() << fieldname;
+      }
+  }while(!cell->isEmpty());
+  
+  return true;
+}
+
+bool KSpreadMigrate::drv_readFromTable(const QString & tableName)
+{
+  mCurSheet = mKSDoc->map()->findSheet(tableName);
+  
+  mRow = 1;
+  
+  return mCurSheet;
+}
+
+bool KSpreadMigrate::drv_moveNext()
+{
+  if (!mCurSheet)
+    return false;
+  
+  KSpread::Cell cell = KSpread::Cell(mCurSheet, 1, mRow + 1);
+  
+  if (!cell.isEmpty())
+  {
+    mRow++;
+    return true;
+  }
+  
+  return false;
+}
+
+bool KSpreadMigrate::drv_movePrevious()
+{
+  if (!mCurSheet)
+    return false;
+  
+  if (mRow > 1)
+  {
+    mRow--;
+    return true;
+  }
+  return false;
+}
+
+bool KSpreadMigrate::drv_moveFirst()
+{
+  if (!mCurSheet)
+    return false;
+  
+  mRow = 1;
+  return drv_moveNext();
+}
+
+bool KSpreadMigrate::drv_moveLast()
+{
+  if (!mCurSheet)
+    return false;
+  
+  while(drv_moveNext()){}
+  
+  return true;
+}
+
+QVariant KSpreadMigrate::drv_value(uint i)
+{
+  QString str = KSpread::Cell(mCurSheet, i+1, mRow).displayText();
+  
+  return str;
+}
+
+};

Property changes on: kspreadmigrate.cpp
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:eol-style
   + native

Index: kspreadmigrate.h
===================================================================
--- kspreadmigrate.h (revision 0)
+++ kspreadmigrate.h (revision 0)
@@ -0,0 +1,87 @@
+//
+// C++ Interface: kspreadmigrate
+//
+// Description:
+//
+//
+// Author: Adam Pigg <adam@...>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef KEXIMIGRATIONTXTMIGRATE_H
+#define KEXIMIGRATIONTXTMIGRATE_H
+
+#include <migration/keximigrate.h>
+#include <QFile>
+#include <kspread/part/Doc.h>
+#include <kspread/Map.h>
+#include <kspread/Sheet.h>
+#include <KoStore.h>
+#include <KoOdfWriteStore.h>
+#include <KoEmbeddedDocumentSaver.h>
+#include <KoDocument.h>
+
+namespace KexiMigration
+{
+
+/**
+@author Adam Pigg
+*/
+class KSpreadMigrate : public KexiMigrate
+{
+    Q_OBJECT
+    KEXIMIGRATION_DRIVER
+public:
+    KSpreadMigrate(QObject *parent, const QStringList &args = QStringList());
+
+    virtual ~KSpreadMigrate();
+
+  protected:
+    //! Connect to source
+    virtual bool drv_connect();
+
+    //! Disconnect from source
+    virtual bool drv_disconnect();
+
+    //! Get table names in source
+    virtual bool drv_tableNames(QStringList& tablenames);
+
+    virtual bool drv_copyTable(const QString&, KexiDB::Connection*, KexiDB::TableSchema*){return false;};
+
+    //! Read schema for a given table
+    virtual bool drv_readTableSchema(const QString& originalName, KexiDB::TableSchema& tableSchema);
+
+    //!Position the source dataset at the start of a table
+    virtual bool drv_readFromTable(const QString & tableName);
+
+    //!Move to the next row
+    virtual bool drv_moveNext();
+
+    //!Move to the previous row
+    virtual bool drv_movePrevious();
+    
+    //!Move to the next row
+    virtual bool drv_moveFirst();
+
+    //!Move to the previous row
+    virtual bool drv_moveLast();
+    
+    //!Read the data at the given row/field
+    virtual QVariant drv_value(uint i);
+
+  private:
+    QString mFileName;
+    KSpread::Sheet *mCurSheet;
+    
+    KSpread::Doc *mKSDoc;
+
+    QStringList mFieldNames;
+
+    unsigned int mRow;
+
+};
+
+};
+
+#endif

Property changes on: kspreadmigrate.h
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:eol-style
   + native

Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt (revision 980386)
+++ CMakeLists.txt (working copy)
@@ -5,43 +5,24 @@
 
 ########### next target ###############
 
-set(keximigrate_txtmigrate_PART_SRCS txtmigrate.cpp )
+set(keximigrate_kspread_PART_SRCS kspreadmigrate.cpp )
 
 
-kde4_add_plugin(keximigrate_txtmigrate ${keximigrate_txtmigrate_PART_SRCS})
+kde4_add_plugin(keximigrate_kspread ${keximigrate_kspread_PART_SRCS})
 
 
 
-target_link_libraries(keximigrate_txtmigrate  ${KDE4_KPARTS_LIBS} keximigrate )
+target_link_libraries(keximigrate_kspread
+    ${KDE4_KPARTS_LIBS}
+    keximigrate
+    kexidb
+    kexiutils
+    kspreadcommon
+)
 
-install(TARGETS keximigrate_txtmigrate  DESTINATION ${PLUGIN_INSTALL_DIR})
+install(TARGETS keximigrate_kspread DESTINATION ${PLUGIN_INSTALL_DIR})
 
 
 ########### install files ###############
 
-install( FILES  keximigrate_txtmigrate.desktop  DESTINATION ${SERVICES_INSTALL_DIR})
-
-
-
-
-
-#original Makefile.am contents follow:
-
-#include $(top_srcdir)/kexi/Makefile.global
-#
-#kde_module_LTLIBRARIES = keximigrate_txtmigrate.la
-#
-#INCLUDES = -I$(srcdir)/../../.. -I$(top_srcdir)/kexi $(all_includes)
-#
-#keximigrate_txtmigrate_la_METASOURCES = AUTO
-#
-#keximigrate_txtmigrate_la_SOURCES = txtmigrate.cpp
-#
-#keximigrate_txtmigrate_la_LIBADD = $(LIB_KPARTS) $(LIB_QT) ../libkeximigrate.la
-#
-#keximigrate_txtmigrate_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(VER_INFO) -no-undefined
-#
-#kde_services_DATA = keximigrate_txtmigrate.desktop
-#
-#noinst_HEADERS =  txtmigrate.h
-#
+install( FILES  keximigrate_kspread.desktop  DESTINATION ${SERVICES_INSTALL_DIR})


[reportspgz_use_keximigrate_and_cleanup.patch]

Index: backend/renderer/orutils.cpp
===================================================================
--- backend/renderer/orutils.cpp (revision 985390)
+++ backend/renderer/orutils.cpp (working copy)
@@ -25,44 +25,79 @@
 //
 // Class orQuery implementations
 //
-orQuery::orQuery()
-{
-    m_cursor = 0;
-    m_connection = 0;
-}
 
-orQuery::orQuery(const QString &qstrPName, const QString &qstrSQL,
-                 bool doexec, KexiDB::Connection * pDb)
+orQuery::orQuery(const QString &qstrSQL,
+                 KexiDB::Connection * pDb)
 {
     QString qstrParsedSQL(qstrSQL);
     QString qstrParam;
     int     intParamNum;
     int     intStartIndex = 0;
 
+    m_externalData = false;
     m_cursor = 0;
     m_connection = pDb;
     m_schema = 0;
     //  Initialize some privates
-    m_qstrName  = qstrPName;
     m_qstrQuery = qstrSQL;
 
     kDebug() << m_qstrName << ":" << m_qstrQuery;
 
-    //For now, lets assume we only support simple tables or queries
-    if (doexec) {
-        execute();
+    m_valid = executeInternal();
+}
+
+//!Connect to an external data source
+//!connStr is in the form driver|connection_string|table
+orQuery::orQuery(const QString & connStr)
+{
+  m_externalData = true;
+  m_cursor = 0;
+  
+  QStringList extConn = connStr.split("|");
+  
+  if (extConn.size() == 3)
+  {
+    KexiMigration::MigrateManager mm;
+    
+    m_km = mm.driver(extConn[0]);
+    KexiDB::ConnectionData cd;
+    KexiMigration::Data dat;
+    cd.setFileName(extConn[1]);
+    dat.source = &cd;
+    m_km->setData(&dat);
+    m_valid = m_km->connectSource();
+    QStringList names;
+    
+    if (m_valid) {  
+      m_valid = m_km->readTableSchema(extConn[2], ts);
     }
-
+    if (m_valid) {
+      m_schema = new KexiDB::TableOrQuerySchema(ts);
+    }
+    m_valid = m_km->tableNames(names);
+    if (m_valid && names.contains(extConn[2])){
+       m_valid = m_km->readFromTable(extConn[2]);
+    }
+  }
 }
 
 orQuery::~orQuery()
 {
-    m_cursor->close();
-    delete m_cursor;
-    m_cursor = 0;
+  if (m_externalData)
+  {
+    delete m_km;
+  }
+  else
+  {
+    if (m_cursor) {
+      m_cursor->close();
+      delete m_cursor;
+      m_cursor = 0;
+    }
+  }
 }
 
-bool orQuery::execute()
+bool orQuery::executeInternal()
 {
     if (m_connection && m_cursor == 0) {
         //NOTE we can use the variation of executeQuery to pass in parameters
@@ -92,19 +127,29 @@
 
 uint orQuery::fieldNumber(const QString &fld)
 {
+  KexiDB::QueryColumnInfo::Vector flds;
+  
     uint x = -1;
-    if (m_cursor->query()) {
-        KexiDB::QueryColumnInfo::Vector flds = m_cursor->query()->fieldsExpanded();
-        for (int i = 0; i < flds.size() ; ++i) {
-            if (fld.toLower() == flds[i]->aliasOrName()) {
-                x = i;
-            }
-        }
+    if (m_externalData) {
+      flds = schema().columns();
     }
+    else {
+      if (m_cursor->query()) {
+  flds = m_cursor->query()->fieldsExpanded();
+  
+      }
+    }
+    for (int i = 0; i < flds.size() ; ++i) {
+  if (fld.toLower() == flds[i]->aliasOrName().toLower()) {
+    x = i;
+  }
+    
+    }
+  
     return x;
 }
 
-KexiDB::TableOrQuerySchema &orQuery::schema()
+KexiDB::TableOrQuerySchema &orQuery::schema() const
 {
     if (m_schema)
         return *m_schema;
@@ -115,43 +160,102 @@
     }
 }
 
-//
-// Class orData
-//
-orData::orData()
+QVariant orQuery::value(unsigned int i)
 {
-    m_valid = false;
-    m_query = 0;
+  if(!m_valid)
+    return QVariant();
+  
+  if (m_externalData) {
+    return m_km->value(i);
+  } else {
+    return m_cursor->value(i);
+  }
 }
 
-void orData::setQuery(orQuery *qryPassed)
+QVariant orQuery::value(const QString &fld)
 {
-    m_query = qryPassed;
-    m_valid = (m_query != 0 && m_field.length());
+  if(!m_valid)
+    return QVariant();
+  
+  int i = fieldNumber(fld);
+  
+  if (m_externalData) {
+    return m_km->value(i);
+  } else {
+    return m_cursor->value(i);
+  }
 }
 
-void orData::setField(const QString &qstrPPassed)
+bool orQuery::moveNext()
 {
-    m_field = qstrPPassed;
-    m_valid = (m_query != 0 && m_field.length());
+  if (!m_valid)
+    return false;
+  
+  if (m_externalData) {
+    return m_km->moveNext();
+  } else {
+    return m_cursor->moveNext();
+  }
 }
 
-const QString &orData::getValue()
+bool orQuery::movePrevious()
 {
-    if (m_valid && m_query->getQuery()) {
-        m_value = m_query->getQuery()->value(m_query->fieldNumber(m_field)).toString();
-    } else {
-        kDebug() << "Not Valid";
-    }
-    return m_value;
+  if(!m_valid)
+    return false;
+  
+  if (m_externalData) {
+    return m_km->movePrevious();
+  } else {
+    if (m_cursor) return m_cursor->movePrev();
+  }
 }
 
-const QByteArray &orData::getRawValue()
+bool orQuery::moveFirst()
 {
-    if (m_valid && m_query->getQuery()) {
-        m_rawValue = m_query->getQuery()->value(m_query->fieldNumber(m_field)).toByteArray();
-    }
+  if(!m_valid)
+    return false;
+  
+  if (m_externalData) {
+    return m_km->moveFirst();
+  } else {
+    if (m_cursor) return m_cursor->moveFirst();
+  }
+}
 
-    return m_rawValue;
+bool orQuery::moveLast()
+{
+  if(!m_valid)
+    return false;
+  
+  if (m_externalData) {
+    return m_km->moveLast();
+  } else {
+    if (m_cursor) return m_cursor->moveLast();
+  }
 }
 
+long orQuery::at() const
+{
+  if(!m_valid)
+    return 0;
+  
+  if (m_externalData) {
+    return 0;
+  } else {
+    return m_cursor->at();
+  }
+}
+
+long orQuery::recordCount()
+{
+  if (m_externalData) {
+    return 1;
+  }
+  else {
+    if (schema().table() || schema().query()) {
+      return KexiDB::rowCount(schema());
+    } else {
+      return 1;
+    }
+  }
+}
Index: backend/renderer/orutils.h
===================================================================
--- backend/renderer/orutils.h (revision 985390)
+++ backend/renderer/orutils.h (working copy)
@@ -23,10 +23,13 @@
 
 #include <QString>
 #include <QStringList>
-#include <QSqlDatabase>
 
 #include <kexidb/cursor.h>
 #include <kexidb/utils.h>
+
+#include <migration/migratemanager.h>
+#include <migration/keximigrate.h>
+
 //
 // These classes are used by the original orRender class and the new
 // ORPreRenderer class as internal structures for processing. There is
@@ -50,56 +53,48 @@
 
     KexiDB::Connection   *m_connection;
     KexiDB::TableOrQuerySchema *m_schema;
+    
+    KexiMigration::KexiMigrate *m_km;
+    
+    bool executeInternal();
+    
+    bool m_externalData;
 
+    bool m_valid;
+    KexiDB::TableSchema ts;
+    
 public:
-    orQuery();
-    orQuery(const QString &, const QString &, bool doexec, KexiDB::Connection *conn = 0);
-
+    orQuery(const QString &, KexiDB::Connection *conn); //Internal Data
+    orQuery(const QString &); //External data
+    
     virtual ~orQuery();
-
-    inline bool queryExecuted() const {
-        return (m_cursor != 0);
+    
+    inline KexiDB::Connection *connection() const {
+      if (!m_externalData)
+ return m_connection;
+
+      return 0;
     }
-    bool execute();
 
-    inline KexiDB::Cursor *getQuery() {
-        return m_cursor;
-    }
     inline const QString &getSql() const {
         return m_qstrQuery;
     }
-    inline const QString &getName() const {
-        return m_qstrName;
-    }
 
     uint fieldNumber(const QString &fld);
-    KexiDB::TableOrQuerySchema &schema();
+    KexiDB::TableOrQuerySchema &schema() const;
+    
+    QVariant value(unsigned int);
+    QVariant value(const QString &);
+    
+    bool moveNext();
+    bool movePrevious();
+    bool moveFirst();
+    bool moveLast();
+    
+    long at() const;
+    
+    long recordCount();
 };
 
-
-// Data class
-class orData
-{
-private:
-    orQuery *m_query;
-    QString m_field;
-    QString m_value;
-    bool    m_valid;
-    QByteArray m_rawValue;
-
-public:
-    orData();
-
-    void  setQuery(orQuery *qryPassed);
-    void  setField(const QString &qstrPPassed);
-
-    inline bool  isValid() const {
-        return m_valid;
-    }
-
-    const QString &getValue();
-    const QByteArray &getRawValue();
-};
-
 #endif // __ORUTILS_H__
 
Index: backend/renderer/scripting/krscripthandler.cpp
===================================================================
--- backend/renderer/scripting/krscripthandler.cpp (revision 985390)
+++ backend/renderer/scripting/krscripthandler.cpp (working copy)
@@ -44,9 +44,9 @@
 #include <renderobjects.h>
 #include "krscriptdraw.h"
 
-KRScriptHandler::KRScriptHandler(const KexiDB::Cursor* cu, KRReportData* d)
+KRScriptHandler::KRScriptHandler(const orQuery *cu, KRReportData* d)
 {
-    m_connection = cu->connection();
+    //m_connection = cu->connection();
     m_reportData = d;
     m_cursor = cu;
 
Index: backend/renderer/scripting/krscriptfunctions.h
===================================================================
--- backend/renderer/scripting/krscriptfunctions.h (revision 985390)
+++ backend/renderer/scripting/krscriptfunctions.h (working copy)
@@ -24,6 +24,7 @@
 #include <QString>
 #include <kexidb/connection.h>
 #include <kexidb/cursor.h>
+#include "orutils.h"
 
 /**
  @author
@@ -32,14 +33,14 @@
 {
     Q_OBJECT
 public:
-    KRScriptFunctions(const KexiDB::Cursor*);
+    KRScriptFunctions(const orQuery*);
 
     ~KRScriptFunctions();
     void setWhere(const QString&);
     void setSource(const QString&);
 private:
     KexiDB::Connection *m_connection;
-    const KexiDB::Cursor *m_cursor;
+    const orQuery *m_cursor;
     QString m_source;
     qreal math(const QString &, const QString &);
 
Index: backend/renderer/scripting/krscripthandler.h
===================================================================
--- backend/renderer/scripting/krscripthandler.h (revision 985390)
+++ backend/renderer/scripting/krscripthandler.h (working copy)
@@ -26,6 +26,7 @@
 #include <kross/core/action.h>
 #include "krscriptconstants.h"
 #include <kdeversion.h>
+#include "orutils.h"
 
 class KRScriptFunctions;
 class KRScriptDebug;
@@ -42,7 +43,7 @@
 {
     Q_OBJECT
 public:
-    KRScriptHandler(const KexiDB::Cursor *, KRReportData*);
+    KRScriptHandler(const orQuery */*KexiDB::Cursor **/, KRReportData*);
     ~KRScriptHandler();
     void setSource(const QString &s);
     QVariant evaluate(const QString&);
@@ -74,9 +75,11 @@
     
     QString scriptCode();
     
-    KexiDB::Connection *m_connection;
-    const KexiDB::Cursor *m_cursor;
+    //KexiDB::Connection *m_connection;
+    //const KexiDB::Cursor *m_cursor;
 
+    const orQuery *m_cursor;
+    
     QString m_source;
     KRReportData  *m_reportData;
 
Index: backend/renderer/scripting/krscriptfunctions.cpp
===================================================================
--- backend/renderer/scripting/krscriptfunctions.cpp (revision 985390)
+++ backend/renderer/scripting/krscriptfunctions.cpp (working copy)
@@ -21,9 +21,10 @@
 #include <kexidb/cursor.h>
 #include <kdebug.h>
 
-KRScriptFunctions::KRScriptFunctions(const KexiDB::Cursor *c)
+KRScriptFunctions::KRScriptFunctions(const orQuery *c)
 {
     m_cursor = c;
+    
     m_connection = m_cursor->connection();;
 }
 
@@ -99,11 +100,11 @@
     }
 
 
-    KexiDB::QueryColumnInfo::Vector flds = m_cursor->query()->fieldsExpanded();
+    KexiDB::QueryColumnInfo::Vector flds = m_cursor->schema().columns();
     for (int i = 0; i < flds.size() ; ++i) {
 
         if (flds[i]->aliasOrName().toLower() == field.toLower()) {
-            val = const_cast<KexiDB::Cursor*>(m_cursor)->value(i);
+            val = const_cast<orQuery*>(m_cursor)->value(i);
         }
     }
 
Index: backend/renderer/orprerender.cpp
===================================================================
--- backend/renderer/orprerender.cpp (revision 985390)
+++ backend/renderer/orprerender.cpp (working copy)
@@ -91,13 +91,6 @@
     orQuery* _query;
     QList<OROTextBox*> _postProcText;
 
-    QMap<ORDataData, qreal> _subtotPageCheckPoints;
-    QMap<ORDataData, qreal> * _subtotContextMap;
-    KRDetailSectionData * _subtotContextDetail;
-    bool _subtotContextPageFooter;
-
-    bool populateData(const ORDataData &, orData &);
-
     void createNewPage();
     qreal finishCurPage(bool = false);
     qreal finishCurPageSize(bool = false);
@@ -130,11 +123,6 @@
     _pageCounter = 0;
     _maxHeight = _maxWidth = 0.0;
     _query = 0;
-    _subtotContextMap = 0;
-// _subtotContextDetail = 0;
-    _subtotContextPageFooter = false;
-
-
 }
 
 ORPreRenderPrivate::~ORPreRenderPrivate()
@@ -147,35 +135,11 @@
     _postProcText.clear();
 }
 
-bool ORPreRenderPrivate::populateData(const ORDataData & dataSource, orData &dataTarget)
-{
-
-    dataTarget.setQuery(_query);
-    dataTarget.setField(dataSource.column);
-    return true;
-
-}
-
 void ORPreRenderPrivate::createNewPage()
 {
     if (_pageCounter > 0)
         finishCurPage();
 
-#if 0
-    //TODO Totals
-    // get the checkpoints for the page footers
-    QMapIterator<ORDataData, qreal> it(_subtotPageCheckPoints);
-    while (it.hasNext()) {
-        it.next();
-//  qreal d = 0.0;
-        ORDataData data = it.key();
-//  XSqlQuery * xqry = getQuerySource ( data.query )->getQuery();
-//  if ( xqry )
-//   d = xqry->getFieldTotal ( data.column );
-//  _subtotPageCheckPoints.insert ( it.key(), d );
-    }
-#endif
-
     _pageCounter++;
 
     //Update the page count script value
@@ -185,6 +149,7 @@
     _page = new OROPage(0);
     _document->addPage(_page);
 
+    //TODO calculate past page
     bool lastPage = false;
 
     _yOffset = _topMargin;
@@ -205,7 +170,6 @@
 {
     qreal retval = 0.0;
 
-    _subtotContextPageFooter = true;
     if (lastPage && _reportData->pgfoot_last != 0)
         retval = renderSectionSize(* (_reportData->pgfoot_last));
     else if (_pageCounter == 1 && _reportData->pgfoot_first)
@@ -216,7 +180,6 @@
         retval = renderSectionSize(* (_reportData->pgfoot_even));
     else if (_reportData->pgfoot_any != 0)
         retval = renderSectionSize(* (_reportData->pgfoot_any));
-    _subtotContextPageFooter = false;
 
     kDebug() << retval;
     return retval;
@@ -229,7 +192,7 @@
     qreal retval = 0.0;
 
     kDebug() << offset;
-    _subtotContextPageFooter = true;
+
     if (lastPage && _reportData->pgfoot_last != 0) {
         kDebug() << "Last Footer";
         _yOffset = offset - renderSectionSize(* (_reportData->pgfoot_last));
@@ -251,7 +214,6 @@
         _yOffset = offset - renderSectionSize(* (_reportData->pgfoot_any));
         retval = renderSection(* (_reportData->pgfoot_any));
     }
-    _subtotContextPageFooter = false;
 
     return retval;
 }
@@ -261,27 +223,19 @@
     kDebug();
 
     if (detailData.m_detailSection != 0) {
-        KexiDB::Cursor *curs = 0;
-        _subtotContextDetail = &detailData;
-
         if (_query) {
-            curs = _query->getQuery();
-//    //TODO init the engine earlier?
+    //TODO init the engine earlier?
             _handler->setSource(_query->getSql());
         }
-        if (curs && !curs->eof()) {
+        if (_query/* && !curs->eof()*/) {
             QStringList keys;
             QStringList keyValues;
             bool    status;
             int i = 0, pos = 0, cnt = 0;
             ORDetailGroupSectionData * grp = 0;
 
-            curs->moveFirst();
-            if (_query->schema().table() || _query->schema().query()) {
-                _recordCount = KexiDB::rowCount(_query->schema());
-            } else {
-                _recordCount = 1;
-            }
+            _query->moveFirst();
+            _recordCount = _query->recordCount();
 
             kDebug() << "Record Count:" << _recordCount;
 
@@ -295,42 +249,46 @@
                 }
                 keys.append(grp->column);
                 if (!keys[i].isEmpty())
-                    keyValues.append(curs->value(_query->fieldNumber(keys[i])).toString());
+                    keyValues.append(_query->value(_query->fieldNumber(keys[i])).toString());
                 else
                     keyValues.append(QString());
-
-                _subtotContextMap = & (grp->_subtotCheckPoints);
-
+      
                 //Tell interested parties we're about to render a header
                 kDebug() << "EMIT1";
                 emit(enteredGroup(keys[i], keyValues[i]));
 
                 if (grp->head)
                     renderSection(* (grp->head));
-                _subtotContextMap = 0;
             }
 
             do {
-                int l = curs->at();
+ kDebug() << "...getting pos";
+                long l = _query->at();
 
                 kDebug() << "At:" << l << "Y:" << _yOffset;
 
                 if (renderSectionSize(* (detailData.m_detailSection)) + finishCurPageSize((l + 1 == _recordCount)) + _bottomMargin + _yOffset >= _maxHeight) {
-                    if (l > 0)
-                        curs->movePrev();
-                    createNewPage();
-                    if (l > 0)
-                        curs->moveNext();
+                    if (l > 0) {
+ kDebug() << "...moving prev";
+                        _query->movePrevious();
+ kDebug() << "...creating new page";
+ createNewPage();
+ kDebug() << "...moving next";
+                        _query->moveNext();
+    }
                 }
 
                 renderSection(* (detailData.m_detailSection));
-
-                status = curs->moveNext();
+ kDebug() << "...moving next";
+ if (_query)
+  status = _query->moveNext();
+ kDebug() << "...done";
+
                 if (status == true && keys.count() > 0) {
                     // check to see where it is we need to start
                     pos = -1; // if it's still -1 by the time we are done then no keyValues changed
                     for (i = 0; i < keys.count(); i++) {
-                        if (keyValues[i] != curs->value(_query->fieldNumber(keys[i])).toString()) {
+                        if (keyValues[i] != _query->value(_query->fieldNumber(keys[i])).toString()) {
                             pos = i;
                             break;
                         }
@@ -339,7 +297,7 @@
                     // don't bother if nothing has changed
                     if (pos != -1) {
                         // roll back the query and go ahead if all is good
-                        status = curs->movePrev();
+                        status = _query->movePrevious();
                         if (status == true) {
                             // print the footers as needed
                             // any changes made in this for loop need to be duplicated
@@ -350,50 +308,38 @@
                                     createNewPage();
                                 do_break = false;
                                 grp = detailData.m_groupList[i];
-                                _subtotContextMap = & (grp->_subtotCheckPoints);
+                              
                                 if (grp->foot) {
                                     if (renderSectionSize(* (grp->foot)) + finishCurPageSize() + _bottomMargin + _yOffset >= _maxHeight)
                                         createNewPage();
                                     renderSection(* (grp->foot));
                                 }
-                                _subtotContextMap = 0;
-                                // reset the sub-total values for this group
-                                QMapIterator<ORDataData, qreal> it(grp->_subtotCheckPoints);
-                                while (it.hasNext()) {
-                                    it.next();
-                                    qreal d = 0.0;
-                                    ORDataData data = it.key();
-                                    KexiDB::Cursor * xqry = _query->getQuery();
-                                    if (xqry) {
-//TODO field totals        d = xqry->getFieldTotal ( data.column );
-                                    }
-                                    grp->_subtotCheckPoints.insert(it.key(), d);
-                                }
+
                                 if (ORDetailGroupSectionData::BreakAfterGroupFoot == grp->pagebreak)
                                     do_break = true;
                             }
                             // step ahead to where we should be and print the needed headers
                             // if all is good
-                            status = curs->moveNext();
+                            status = _query->moveNext();
                             if (do_break)
                                 createNewPage();
                             if (status == true) {
                                 for (i = pos; i < cnt; i++) {
                                     grp = detailData.m_groupList[i];
-                                    _subtotContextMap = & (grp->_subtotCheckPoints);
+                            
                                     if (grp->head) {
                                         if (renderSectionSize(* (grp->head)) + finishCurPageSize() + _bottomMargin + _yOffset >= _maxHeight) {
-                                            curs->movePrev();
+                                            _query->movePrevious();
                                             createNewPage();
-                                            curs->moveNext();
+                                            _query->moveNext();
                                         }
 
 
                                         renderSection(* (grp->head));
                                     }
-                                    _subtotContextMap = 0;
+                              
                                     if (!keys[i].isEmpty())
-                                        keyValues[i] = curs->value(_query->fieldNumber(keys[i])).toString();
+                                        keyValues[i] = _query->value(_query->fieldNumber(keys[i])).toString();
 
                                     //Tell interested parties thak key values changed
                                     kDebug() << "EMIT2";
@@ -405,35 +351,21 @@
                 }
             } while (status == true);
 
-            if (keys.size() > 0 && curs->movePrev()) {
+            if (keys.size() > 0 && _query->movePrevious()) {
                 // finish footers
                 // duplicated changes from above here
                 for (i = cnt - 1; i >= 0; i--) {
                     grp = detailData.m_groupList[i];
-                    _subtotContextMap = & (grp->_subtotCheckPoints);
+
                     if (grp->foot) {
                         if (renderSectionSize(* (grp->foot)) + finishCurPageSize() + _bottomMargin + _yOffset >= _maxHeight)
                             createNewPage();
                         renderSection(* (grp->foot));
                         emit(exitedGroup(keys[i], keyValues[i]));
                     }
-                    _subtotContextMap = 0;
-                    // reset the sub-total values for this group
-                    QMapIterator<ORDataData, qreal> it(grp->_subtotCheckPoints);
-                    while (it.hasNext()) {
-                        it.next();
-                        qreal d = 0.0;
-                        ORDataData data = it.key();
-                        KexiDB::Cursor * xqry = _query->getQuery();
-                        if (xqry) {
-//TODO field totals       d = xqry->getFieldTotal ( data.column );
-                        }
-                        grp->_subtotCheckPoints.insert(it.key(), d);
-                    }
                 }
             }
         }
-        _subtotContextDetail = 0;
         if (KRDetailSectionData::BreakAtEnd == detailData.m_pageBreak)
             createNewPage();
     }
@@ -454,13 +386,8 @@
         // TODO: See if this can be simplified anymore than it already is.
         //       All we need to know is how much stretch we are going to get.
         if (elemThis->type() == KRObjectData::EntityText) {
-            orData       dataThis;
             KRTextData * t = elemThis->toText();
 
-            populateData(t->data(), dataThis);
-
-            //dataThis.setQuery();
-            dataThis.setField(t->m_controlSource->value().toString());
             QPointF pos = t->m_pos.toScene();
             QSizeF size = t->m_size.toScene();
             pos += QPointF(_leftMargin, _yOffset);
@@ -473,7 +400,7 @@
 
             QFont f = t->m_font->value().value<QFont>();
 
-            qstrValue = dataThis.getValue();
+            qstrValue = _query->value(t->m_controlSource->value().toString()).toString();
             if (qstrValue.length()) {
                 int pos = 0;
                 int idx;
@@ -524,7 +451,7 @@
     qreal intHeight = POINT_TO_INCH(sectionData.height()) * KoGlobal::dpiY();
     kDebug() << "Name: " << sectionData.name() << " Height: " << intHeight << "Objects: " << sectionData.objects().count();
 
-    _handler->populateEngineParameters(_query->getQuery());
+    //_handler->populateEngineParameters(_query->getQuery());
 
     emit(renderingSection(const_cast<KRSectionData*>(§ionData), _page, QPointF(_leftMargin, _yOffset)));
 
@@ -569,7 +496,6 @@
             tb2->setPosition(l->m_pos.toPoint());
             sec->addPrimitive(tb2);
         } else if (elemThis->type() == KRObjectData::EntityField) {
-            orData       dataThis;
             KRFieldData* f = elemThis->toField();
 
             QPointF pos = f->m_pos.toScene();
@@ -607,11 +533,12 @@
             } else if (cs.left(1) == "$") { //Everything past $ is treated as a string
                 str = cs.mid(1);
             } else {
-                QString qry = "Data Source";
+                //QString qry = "Data Source";
                 QString clm = f->m_controlSource->value().toString();
 
-                populateData(f->data(), dataThis);
-                str = dataThis.getValue();
+                //populateData(f->data(), dataThis);
+                //str = dataThis.getValue();
+ str = _query->value(clm).toString();
             }
             tb->setText(str);
             _page->addPrimitive(tb);
@@ -623,7 +550,6 @@
 
         } else if (elemThis->type() == KRObjectData::EntityText) {
     QString qstrValue;
-    orData       dataThis;
             KRTextData * t = elemThis->toText();
     
     QString cs = t->m_controlSource->value().toString();
@@ -633,8 +559,7 @@
     if (cs.left(1) == "$") { //Everything past $ is treated as a string
       qstrValue = cs.mid(1);
     } else {
-      populateData(t->data(), dataThis);
-      qstrValue = dataThis.getValue();
+      qstrValue = _query->value(t->m_controlSource->value().toString()).toString();
     }
     
             QPointF pos = t->m_pos.toScene();
@@ -748,7 +673,6 @@
             sec->addPrimitive(l2);
         } else if (elemThis->type() == KRObjectData::EntityBarcode) {
             KRBarcodeData * bc = elemThis->toBarcode();
-            orData       dataThis;
 
             QPointF pos = bc->m_pos.toScene();
             QSizeF size = bc->m_size.toScene();
@@ -756,24 +680,23 @@
 
             QRectF rect = QRectF(pos, size);
 
-            populateData(bc->data(), dataThis);
-
+    QString val = _query->value(bc->m_controlSource->value().toString()).toString();
             QString fmt = bc->m_format->value().toString();
             int align = bc->alignment();
             if (fmt == "3of9")
-                render3of9(_page, rect, dataThis.getValue(), align);
+                render3of9(_page, rect, val, align);
             else if (fmt == "3of9+")
-                renderExtended3of9(_page, rect, dataThis.getValue(), align);
+                renderExtended3of9(_page, rect, val, align);
             else if (fmt == "128")
-                renderCode128(_page, rect, dataThis.getValue(), align);
+                renderCode128(_page, rect, val, align);
             else if (fmt == "ean13")
-                renderCodeEAN13(_page, rect, dataThis.getValue(), align);
+                renderCodeEAN13(_page, rect, val, align);
             else if (fmt == "ean8")
-                renderCodeEAN8(_page, rect, dataThis.getValue(), align);
+                renderCodeEAN8(_page, rect, val, align);
             else if (fmt == "upc-a")
-                renderCodeUPCA(_page, rect, dataThis.getValue(), align);
+                renderCodeUPCA(_page, rect, val, align);
             else if (fmt == "upc-e")
-                renderCodeUPCE(_page, rect, dataThis.getValue(), align);
+                renderCodeUPCE(_page, rect, val, align);
             else {
                 //logMessage("Encountered unknown barcode format: %s",(const char*)bc->format);
             }
@@ -782,9 +705,9 @@
             QString uudata;
             QByteArray imgdata;
             if (!im->isInline()) {
-                orData dataThis;
-                populateData(im->data(), dataThis);
-                imgdata = dataThis.getRawValue();
+//TODO                orData dataThis;
+//                populateData(im->data(), dataThis);
+//                imgdata = dataThis.getRawValue();
             } else {
                 uudata = im->inlineImageData();
                 imgdata = KCodecs::base64Decode(uudata.toLatin1());
@@ -818,7 +741,7 @@
             QStringList masterFields = ch->masterFields();
             for (int i = 0; i < masterFields.size(); ++i){
                 if (!masterFields[i].simplified().isEmpty()){
-                    ch->setLinkData(masterFields[i], _query->getQuery()->value(_query->fieldNumber(masterFields[i])));
+        //            ch->setLinkData(masterFields[i], _query->getQuery()->value(_query->fieldNumber(masterFields[i])));
                 }
             }
             ch->populateData();
@@ -844,7 +767,6 @@
                 sec->addPrimitive(p2);
             }
         } else if (elemThis->type() == KRObjectData::EntityCheck) {
-            orData dataThis;
             KRCheckData *cd = elemThis->toCheck();
             OROCheck *chk = new OROCheck();
 
@@ -871,11 +793,8 @@
       str = _handler->evaluate(cd->entityName()).toString();
 #endif  
             } else {
-                QString qry = "Data Source";
                 QString clm = cd->m_controlSource->value().toString();
-
-                populateData(cd->data(), dataThis);
-                str = dataThis.getValue();
+                str = _query->value(clm).toString();
             }
 
             bool v = false;
@@ -899,59 +818,13 @@
 
     _yOffset += intHeight;
 
+    kDebug() << _yOffset;
     return intHeight;
 }
 
-qreal ORPreRenderPrivate::getNearestSubTotalCheckPoint(const ORDataData & d)
-{
-    // use the various contexts setup to determine what we should be
-    // doing and try and locate the nearest subtotal check point value
-    // and return that value... if we are unable to locate one then we
-    // will just return 0.0 which will case the final value to be a
-    // running total
-
-    if (_subtotContextPageFooter) {
-        // first check to see if it's a page footer context
-        // as that can happen from anywhere at any time.
-
-        // TODO Totals
-        if (_subtotPageCheckPoints.contains(d))
-            return _subtotPageCheckPoints[d];
-
-    } else if (_subtotContextMap != 0) {
-        // next if an explicit map is set then we are probably
-        // rendering a group head/foot now so we will use the
-        // available their.. if it's not then we made a mistake
-
-        if (_subtotContextMap->contains(d))
-            return (*_subtotContextMap)[d];
-
-    } else if (_subtotContextDetail != 0) {
-        // finally if we are in a detail section then we will simply
-        // traverse that details sections groups from the most inner
-        // to the most outer and use the first check point we find
-
-        // in actuallity we search from the outer most group to the
-        // inner most group and just take the last value found which
-        // would be the inner most group
-
-        qreal dbl = 0.0;
-        ORDetailGroupSectionData * grp = 0;
-        for (int i = 0; i < (int) _subtotContextDetail->m_groupList.count(); i++) {
-            grp = _subtotContextDetail->m_groupList[i];
-            if (grp->_subtotCheckPoints.contains(d))
-                dbl = grp->_subtotCheckPoints[d];
-        }
-        return dbl;
-
-    }
-
-    return 0.0;
-}
-
 void ORPreRenderPrivate::initEngine()
 {
-    _handler = new KRScriptHandler(_query->getQuery(), _reportData);
+    _handler = new KRScriptHandler(_query, _reportData);
 
     connect(this, SIGNAL(enteredGroup(const QString&, const QVariant&)), _handler, SLOT(slotEnteredGroup(const QString&, const QVariant&)));
 
@@ -1058,20 +931,13 @@
 
     d->_document->setPageOptions(rpo);
 
-// QuerySource * qs = 0;
-
-    d->_query = (new orQuery("Data Source", d->_reportData->query(), true, d->_conn));
-
-//TODO field totals
-// _internal->_subtotPageCheckPoints.clear();
-// for ( int i = 0; i < _internal->_reportData->trackTotal.count(); i++ )
-// {
-//  _internal->_subtotPageCheckPoints.insert ( _internal->_reportData->trackTotal[i], 0 );
-//  XSqlQuery * xqry = _internal->getQuerySource ( _internal->_reportData->trackTotal[i].query )->getQuery();
-//  if ( xqry )
-//   xqry->trackFieldTotal ( _internal->_reportData->trackTotal[i].column );
-// }
-
+    if (!d->_reportData->externalData())  {
+      d->_query = (new orQuery(d->_reportData->query(), d->_conn));
+    }
+    else {
+     d->_query = new orQuery( d->_reportData->query() );
+    }
+    
     d->initEngine();
     d->createNewPage();
     if (!label.isNull()) {
@@ -1106,10 +972,10 @@
         KRDetailSectionData * detailData = d->_reportData->detailsection;
         if (detailData->m_detailSection != 0) {
             orQuery *orqThis = d->_query;
-            KexiDB::Cursor *query;
+            //KexiDB::Cursor *query;
 
-            if ((orqThis != 0) && !((query = orqThis->getQuery())->eof())) {
-                query->moveFirst();
+            if ((orqThis != 0))/* && !((query = orqThis->getQuery())->eof()))*/ {
+                //orqThis->moveFirst();
                 do {
                     tmp = d->_yOffset; // store the value as renderSection changes it
                     d->renderSection(* (detailData->m_detailSection));
@@ -1128,7 +994,7 @@
                             d->createNewPage();
                         }
                     }
-                } while (query->moveNext());
+                } while (orqThis->moveNext());
             }
         }
 
Index: backend/common/krreportdata.h
===================================================================
--- backend/common/krreportdata.h (revision 985390)
+++ backend/common/krreportdata.h (working copy)
@@ -81,6 +81,11 @@
     QString interpreter() {
         return m_interpreter;
     }
+    
+    bool externalData() {
+      return m_externalData;
+    }
+    
     KRDetailSectionData* detail() {
         return detailsection;
     }
@@ -94,6 +99,7 @@
     QString m_query;
     QString m_script;
     QString m_interpreter;
+    bool m_externalData;
 
     ReportPageOptions page;
 
Index: backend/common/krbarcodedata.h
===================================================================
--- backend/common/krbarcodedata.h (revision 985390)
+++ backend/common/krbarcodedata.h (working copy)
@@ -53,10 +53,6 @@
     QString format();
     void setFormat(const QString&);
 
-    ORDataData data() {
-        return ORDataData("Data Source", m_controlSource->value().toString());
-    }
-
 protected:
     QRect _rect();
     KRSize m_size;
Index: backend/common/krreportdata.cpp
===================================================================
--- backend/common/krreportdata.cpp (revision 985390)
+++ backend/common/krreportdata.cpp (working copy)
@@ -59,9 +59,10 @@
         QDomElement elemThis = section.item(nodeCounter).toElement();
         if (elemThis.tagName() == "title")
             m_title = elemThis.text();
-        else if (elemThis.tagName() == "datasource")
+        else if (elemThis.tagName() == "datasource") {
             m_query = elemThis.text();
-        else if (elemThis.tagName() == "script") {
+    m_externalData = elemThis.attribute("external").toInt();
+ } else if (elemThis.tagName() == "script") {
             m_script = elemThis.text();
             m_interpreter = elemThis.attribute("interpreter");
         } else if (elemThis.tagName() == "size") {
Index: backend/wrtembed/reportdesigner.h
===================================================================
--- backend/wrtembed/reportdesigner.h (revision 985390)
+++ backend/wrtembed/reportdesigner.h (working copy)
@@ -29,8 +29,6 @@
 #include <QVBoxLayout>
 #include <QCloseEvent>
 
-//#include "parsexmlutils.h"
-
 #include <krreportdata.h>
 #include <kexidb/connection.h>
 #include <koproperty/Set.h>
@@ -38,6 +36,9 @@
 #include <kdebug.h>
 #include <krobjectdata.h>
 
+#include <migration/keximigrate.h>
+#include <migration/migratemanager.h>
+
 class ReportGridOptions;
 class QDomDocument;
 class QGraphicsScene;
@@ -62,8 +63,7 @@
 {
     Q_OBJECT
 public:
-
-
+  
     ReportDesigner(QWidget *, KexiDB::Connection *);
     ReportDesigner(QWidget *, KexiDB::Connection *, const QString&);
     ~ReportDesigner();
@@ -185,6 +185,9 @@
     void init();
     bool m_modified; // true if this document has been modified, false otherwise
     KexiDB::Connection *m_conn;
+    KexiMigration::KexiMigrate *m_external;
+    QString m_externalTableName;
+    
     QStringList pageFormats();
 
     virtual void resizeEvent(QResizeEvent * event);
@@ -195,6 +198,7 @@
     KoProperty::Set* m_itmset;
     KoProperty::Property* m_title;
     KoProperty::Property* m_dataSource;
+    KoProperty::Property* m_externalData;
     KoProperty::Property* m_pageSize;
     KoProperty::Property* m_orientation;
     KoProperty::Property* m_unit;
Index: backend/wrtembed/reportdesigner.cpp
===================================================================
--- backend/wrtembed/reportdesigner.cpp (revision 985390)
+++ backend/wrtembed/reportdesigner.cpp (working copy)
@@ -63,6 +63,7 @@
 #include <QSplitter>
 
 #include <kexidb/connection.h>
+#include <kexidb/connectiondata.h>
 #include <kexidb/utils.h>
 #include <kexidb/schemadata.h>
 #include <kexiutils/tristate.h>
@@ -144,6 +145,7 @@
         : QWidget(parent), d(new Private())
 {
     m_conn = cn;
+    m_external = 0;
     init();
 }
 void ReportDesigner::init()
@@ -161,7 +163,6 @@
     pageHeadFirst = pageHeadOdd = pageHeadEven = pageHeadLast = pageHeadAny = 0;
     pageFootFirst = pageFootOdd = pageFootEven = pageFootLast = pageFootAny = 0;
 
-
     d->grid = new QGridLayout(this);
     d->grid->setSpacing(0);
     d->grid->setMargin(0);
@@ -234,6 +235,7 @@
                 setReportTitle(it.firstChild().nodeValue());
             } else if (n == "datasource") {
                 setReportDataSource(it.firstChild().nodeValue());
+ m_externalData->setValue(it.toElement().attribute("external"));
             } else if (n == "script") {
                 m_interpreter->setValue(it.toElement().attribute("interpreter"));
                 m_script->setValue(it.firstChild().nodeValue());
@@ -605,6 +607,7 @@
     root.appendChild(title);
 
     QDomElement rds = doc.createElement("datasource");
+    rds.setAttribute("external", m_externalData->value().toBool());
     rds.appendChild(doc.createTextNode(reportDataSource()));
     root.appendChild(rds);
 
@@ -822,18 +825,34 @@
     QStringList qs;
     qs << "";
 
-    if (isConnected()) {
-        //Get the list of fields in the selected query
-        KexiDB::TableOrQuerySchema *flds = new KexiDB::TableOrQuerySchema(m_conn, m_dataSource->value().toString().toLocal8Bit());
+    if (!m_externalData->value().toBool()) {
+      if (isConnected()) {
+  //Get the list of fields in the selected query
+  KexiDB::TableOrQuerySchema *flds = new KexiDB::TableOrQuerySchema(m_conn, m_dataSource->value().toString().toLocal8Bit());
 
-        KexiDB::QueryColumnInfo::Vector cs = flds->columns();
+  KexiDB::QueryColumnInfo::Vector cs = flds->columns();
 
-        for (int i = 0 ; i < cs.count(); ++i) {
-            qs << cs[i]->field->name();
-        }
-    } else {
+  for (int i = 0 ; i < cs.count(); ++i) {
+      qs << cs[i]->field->name();
+  }
+      }
+      else {
         kDebug() << "Cannot return field list";
+      }
     }
+    else
+    {
+      if (!m_externalTableName.isEmpty()) {
+ KexiDB::TableSchema ts;
+ m_external->readTableSchema(m_externalTableName, ts);
+      
+ for (unsigned int i = 0; i < ts.fieldCount(); ++i) {
+  qs << ts.field(i)->name();
+ }
+      }
+      
+    }
+    kDebug() << qs;
     return qs;
 }
 
@@ -893,7 +912,10 @@
 
     keys = queryList();
     m_dataSource = new KoProperty::Property("DataSource", keys, keys, "", "Data Source");
-
+    m_dataSource->setOption("extraValueAllowed", "true");
+    
+    m_externalData = new KoProperty::Property("ExternalData", QVariant(false), "External Data", "External Data");
+    
     keys.clear();
     keys = pageFormats();
     m_pageSize = new KoProperty::Property("PageSize", keys, keys, "A4", "Page Size");
@@ -930,6 +952,7 @@
     m_script = new KoProperty::Property("Script", keys, keys, "", "Object Script");
     
     m_set->addProperty(m_title);
+    m_set->addProperty(m_externalData);
     m_set->addProperty(m_dataSource);
     m_set->addProperty(m_pageSize);
     m_set->addProperty(m_orientation);
@@ -966,6 +989,22 @@
         m_set->property("TopMargin").setOption("unit", newstr);
         m_set->property("BottomMargin").setOption("unit", newstr);
     }
+    if ((p.name() == "DataSource" || p.name() == "ExternalData") && m_externalData->value().toBool())
+    {
+      KexiMigration::MigrateManager mm;
+      QStringList md = m_dataSource->value().toString().split("|");
+      if (md.size() == 3) { //Need 3 paramters
+ m_external = mm.driver(md[0]);
+ KexiDB::ConnectionData cd;
+ cd.setFileName(md[1]);
+ m_externalTableName = md[2];
+ KexiMigration::Data dat;
+ dat.source = &cd;
+ m_external->setData(&dat);
+ m_external->connectSource();
+    }
+    
+  }
 }
 
 /**
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt (revision 985390)
+++ CMakeLists.txt (working copy)
@@ -104,7 +104,7 @@
 
 target_link_libraries(pgzkexireportpart2 ${KDE4_KDEUI_LIBS} ${QT_QTGUI_LIBRARY}
   ${QT_QTSCRIPT_LIBRARY} ${KDE4_KPARTS_LIBS} kexidb kexicore keximain ${KOPROPERTY_LIBS}  ${QT_QT3SUPPORT_LIBRARY} kexiguiutils
-    kexiextendedwidgets kdchart ${KDE4_KROSSCORE_LIBS})
+    kexiextendedwidgets kdchart keximigrate ${KDE4_KROSSCORE_LIBS})
 if (SHOULD_BUILD_KSPREAD)
   target_link_libraries(pgzkexireportpart2 kspreadcommon)
 endif (SHOULD_BUILD_KSPREAD)


_______________________________________________
Kexi mailing list
Kexi@...
https://mail.kde.org/mailman/listinfo/kexi

Re: Keximigrate extension

by Jaroslaw Staniek :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2009/6/22 Adam Pigg <piggz1@...>:
> Lo
>
> Attached is 3 patches to kexi.
>
> 1. Extend the keximigrate api to add a cursor style api - fix the txt plugin
> to use this api

Thanks!

Missing readertest.cpp?
And I suggest to move to test/ subdir.

keximigrate.h:
- please add space after //!
- please remove ; after }

bool TxtMigrate::drv_connect():
- check if m_migrateData->source->dbPath() an existing dir, otherwise
return false and dont set mFolder
- similarly in KSpreadMigrate::drv_connect()

bool TxtMigrate::drv_disconnect():
- clear mFolder
- delete(mDataFile) here
TxtMigrate::TxtMigrate
- init mDataFile to 0
bool TxtMigrate::drv_readFromTable(const QString & tableName):
- possible MEMORY LEAK? first delete(mDataFile) here (yes, and in
TxtMigrate::drv_disconnect() too)
^^ and file lock on Windows because it's not closed afterwards
bool KSpreadMigrate::drv_disconnect()
- for sanity add mKSDoc = 0
bool KSpreadMigrate::drv_tableNames(QStringList& tablenames)
- use foreach()
kspreadmigrate.cpp, kspreadmigrate.h
- unset the executable bit
kspreadmigrate.h
- add standard file header that we use in KDE, update year

backend/renderer/orutils: use more meaningful names for these members:
- KexiMigration::KexiMigrate *m_km
- KexiDB::TableSchema ts

backend/common/krreportdata.h
- add const to: bool externalData()

General:
- please use m_ prefix for member variables

PS: I don't discuss the API now - before predicate we have no place
for bigger refactorings...

--
regards / pozdrawiam, Jaroslaw Staniek
 Kexi & KOffice (http://www.kexi-project.org, http://www.koffice.org)
 KDE Libraries for MS Windows (http://windows.kde.org)
 http://www.linkedin.com/in/jstaniek
_______________________________________________
Kexi mailing list
Kexi@...
https://mail.kde.org/mailman/listinfo/kexi