|
|
|
/***************************************************************************
|
|
|
|
mymoneystoragesql.h
|
|
|
|
-------------------
|
|
|
|
begin : 11 November 2005
|
|
|
|
copyright : (C) 2005 by Tony Bloomfield
|
|
|
|
email : tonybloom@users.sourceforge.net
|
|
|
|
: Fernando Vilas <fvilas@iname.com>
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#ifndef MYMONEYSTORAGESQL_H
|
|
|
|
#define MYMONEYSTORAGESQL_H
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// QT Includes
|
|
|
|
|
|
|
|
#include <tqsqldatabase.h>
|
|
|
|
#include <tqsqlquery.h>
|
|
|
|
#include <tqsqlerror.h>
|
|
|
|
#include <tqvaluestack.h>
|
|
|
|
|
|
|
|
class TQIODevice;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// KDE Includes
|
|
|
|
|
|
|
|
#include <kurl.h>
|
|
|
|
#include <ksharedptr.h>
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Project Includes
|
|
|
|
|
|
|
|
#include <kmymoney/imymoneystorageformat.h>
|
|
|
|
#include <kmymoney/mymoneyaccount.h>
|
|
|
|
#include <kmymoney/mymoneybudget.h>
|
|
|
|
#include <kmymoney/mymoneyfile.h>
|
|
|
|
#include <kmymoney/mymoneyinstitution.h>
|
|
|
|
#include <kmymoney/mymoneykeyvaluecontainer.h>
|
|
|
|
#include <kmymoney/mymoneymoney.h>
|
|
|
|
#include <kmymoney/mymoneypayee.h>
|
|
|
|
#include <kmymoney/mymoneyprice.h>
|
|
|
|
#include <kmymoney/mymoneyreport.h>
|
|
|
|
#include <kmymoney/mymoneysplit.h>
|
|
|
|
#include <kmymoney/mymoneyscheduled.h>
|
|
|
|
#include <kmymoney/mymoneysecurity.h>
|
|
|
|
#include <kmymoney/mymoneytransaction.h>
|
|
|
|
#include <kmymoney/mymoneytransactionfilter.h>
|
|
|
|
|
|
|
|
// This is a convenience functor to make it easier to use STL algorithms
|
|
|
|
// It will return false if the MyMoneyTransaction DOES match the filter.
|
|
|
|
// This functor may disappear when all filtering can be handled in SQL.
|
|
|
|
class FilterFail {
|
|
|
|
public:
|
|
|
|
FilterFail (const MyMoneyTransactionFilter& filter,
|
|
|
|
IMyMoneyStorage* storage)
|
|
|
|
: m_filter (filter),
|
|
|
|
m_storage (storage)
|
|
|
|
{}
|
|
|
|
|
|
|
|
inline bool operator() (const TQPair<TQString, MyMoneyTransaction>& transactionPair)
|
|
|
|
{ return (*this) (transactionPair.second); }
|
|
|
|
|
|
|
|
inline bool operator() (const MyMoneyTransaction& transaction)
|
|
|
|
{
|
|
|
|
return (! m_filter.match(transaction)) && (m_filter.matchingSplits().count() == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
MyMoneyTransactionFilter m_filter;
|
|
|
|
IMyMoneyStorage *m_storage;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
@author Tony Bloomfield
|
|
|
|
*/
|
|
|
|
typedef enum databaseTypeE { // database (driver) type
|
|
|
|
Db2 = 0, //
|
|
|
|
Interbase, //
|
|
|
|
Mysql, //
|
|
|
|
Oracle8, //
|
|
|
|
ODBC3, //
|
|
|
|
Postgresql, //
|
|
|
|
Sqlite, //
|
|
|
|
Sybase, //
|
|
|
|
Sqlite3 //
|
|
|
|
} _databaseType;
|
|
|
|
|
|
|
|
class MyMoneyStorageSql;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The MyMoneySqlQuery class is derived from TQSqlQuery to provide
|
|
|
|
* a way to adjust some queries based on databaseTypeE and make
|
|
|
|
* debugging easier by providing a place to put debug statements.
|
|
|
|
*/
|
|
|
|
class MyMoneySqlQuery : public TQSqlQuery {
|
|
|
|
public:
|
|
|
|
MyMoneySqlQuery (MyMoneyStorageSql* db = 0);
|
|
|
|
virtual ~MyMoneySqlQuery() {}
|
|
|
|
bool exec ();
|
|
|
|
bool prepare ( const TQString & query );
|
|
|
|
private:
|
|
|
|
const MyMoneyStorageSql* m_db;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The MyMoneyDbDrivers class is a map from string to enum of db types.
|
|
|
|
*/
|
|
|
|
class MyMoneyDbDrivers {
|
|
|
|
public:
|
|
|
|
MyMoneyDbDrivers ();
|
|
|
|
/**
|
|
|
|
* @return a list ofsupported TQt database driver types, their qt names and useful names
|
|
|
|
**/
|
|
|
|
const TQMap<TQString, TQString> driverMap() const {return (m_driverMap);};
|
|
|
|
databaseTypeE driverToType (const TQString& driver) const;
|
|
|
|
bool isTested (databaseTypeE dbType) const;
|
|
|
|
private:
|
|
|
|
TQMap<TQString, TQString> m_driverMap;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The MyMoneyDbColumn class is a base type for generic db columns.
|
|
|
|
* Derived types exist for several common column types.
|
|
|
|
*/
|
|
|
|
class MyMoneyDbColumn : public TDEShared {
|
|
|
|
public:
|
|
|
|
MyMoneyDbColumn (const TQString& iname,
|
|
|
|
const TQString& itype = TQString(),
|
|
|
|
const bool iprimary = false,
|
|
|
|
const bool inotnull = false,
|
|
|
|
const TQString &initVersion = "0.1"):
|
|
|
|
m_name(iname),
|
|
|
|
m_type(itype),
|
|
|
|
m_isPrimary(iprimary),
|
|
|
|
m_isNotNull(inotnull),
|
|
|
|
m_initVersion(initVersion) {}
|
|
|
|
MyMoneyDbColumn (void) {}
|
|
|
|
virtual ~MyMoneyDbColumn () {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method is used to copy column objects. Because there are several derived types,
|
|
|
|
* clone() is more appropriate than a copy ctor in most cases.
|
|
|
|
*/
|
|
|
|
virtual MyMoneyDbColumn* clone () const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method generates the DDL (Database Design Language) string for the column.
|
|
|
|
*
|
|
|
|
* @param dbType Database driver type
|
|
|
|
*
|
|
|
|
* @return TQString of the DDL for the column, tailored for what the driver supports.
|
|
|
|
*/
|
|
|
|
virtual const TQString generateDDL (databaseTypeE dbType) const;
|
|
|
|
|
|
|
|
const TQString& name(void) const {return (m_name);}
|
|
|
|
const TQString& type(void) const {return (m_type);}
|
|
|
|
bool isPrimaryKey(void) const {return (m_isPrimary);}
|
|
|
|
bool isNotNull(void) const {return (m_isNotNull);}
|
|
|
|
private:
|
|
|
|
TQString m_name;
|
|
|
|
TQString m_type;
|
|
|
|
bool m_isPrimary;
|
|
|
|
bool m_isNotNull;
|
|
|
|
TQString m_initVersion;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The MyMoneyDbDatetimeColumn class is a representation of datetime columns.
|
|
|
|
*/
|
|
|
|
class MyMoneyDbDatetimeColumn : public MyMoneyDbColumn {
|
|
|
|
public:
|
|
|
|
MyMoneyDbDatetimeColumn (const TQString& iname,
|
|
|
|
const bool iprimary = false,
|
|
|
|
const bool inotnull = false,
|
|
|
|
const TQString &initVersion = "0.1"):
|
|
|
|
MyMoneyDbColumn (iname, "", iprimary, inotnull, initVersion)
|
|
|
|
{}
|
|
|
|
virtual ~MyMoneyDbDatetimeColumn() {}
|
|
|
|
virtual const TQString generateDDL (databaseTypeE dbType) const;
|
|
|
|
virtual MyMoneyDbDatetimeColumn* clone () const;
|
|
|
|
private:
|
|
|
|
static const TQString calcType(void);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The MyMoneyDbColumn class is a representation of integer db columns.
|
|
|
|
*/
|
|
|
|
class MyMoneyDbIntColumn : public MyMoneyDbColumn {
|
|
|
|
public:
|
|
|
|
enum size {TINY, SMALL, MEDIUM, BIG};
|
|
|
|
MyMoneyDbIntColumn (const TQString& iname,
|
|
|
|
const size type = MEDIUM,
|
|
|
|
const bool isigned = true,
|
|
|
|
const bool iprimary = false,
|
|
|
|
const bool inotnull = false,
|
|
|
|
const TQString &initVersion = "0.1"):
|
|
|
|
MyMoneyDbColumn (iname, "", iprimary, inotnull, initVersion),
|
|
|
|
m_type (type),
|
|
|
|
m_isSigned (isigned) {}
|
|
|
|
virtual ~MyMoneyDbIntColumn() {}
|
|
|
|
virtual const TQString generateDDL (databaseTypeE dbType) const;
|
|
|
|
virtual MyMoneyDbIntColumn* clone () const;
|
|
|
|
private:
|
|
|
|
size m_type;
|
|
|
|
bool m_isSigned;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The MyMoneyDbTextColumn class is a representation of text db columns,
|
|
|
|
* for drivers that support it. If the driver does not support it, it is
|
|
|
|
* usually some sort of really large varchar or varchar2.
|
|
|
|
*/
|
|
|
|
class MyMoneyDbTextColumn : public MyMoneyDbColumn {
|
|
|
|
public:
|
|
|
|
enum size {TINY, NORMAL, MEDIUM, LONG};
|
|
|
|
MyMoneyDbTextColumn (const TQString& iname,
|
|
|
|
const size type = MEDIUM,
|
|
|
|
const bool iprimary = false,
|
|
|
|
const bool inotnull = false,
|
|
|
|
const TQString &initVersion = "0.1"):
|
|
|
|
MyMoneyDbColumn (iname, "", iprimary, inotnull, initVersion),
|
|
|
|
m_type (type) {}
|
|
|
|
virtual ~MyMoneyDbTextColumn() {}
|
|
|
|
virtual const TQString generateDDL (databaseTypeE dbType) const;
|
|
|
|
virtual MyMoneyDbTextColumn* clone () const;
|
|
|
|
private:
|
|
|
|
size m_type;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The MyMoneyDbIndex class is a representation of a db index.
|
|
|
|
* To provide generic support for most databases, the table name,
|
|
|
|
* name of the index, and list of columns for the index are required.
|
|
|
|
* Additionally, the user can specify whether the index is unique or not.
|
|
|
|
*
|
|
|
|
* At this time, different types of index are not supported, since the portability
|
|
|
|
* is fairly limited.
|
|
|
|
*/
|
|
|
|
class MyMoneyDbIndex {
|
|
|
|
public:
|
|
|
|
MyMoneyDbIndex (const TQString& table,
|
|
|
|
const TQString& name,
|
|
|
|
const TQStringList& columns,
|
|
|
|
bool unique = false):
|
|
|
|
m_table(table),
|
|
|
|
m_unique(unique),
|
|
|
|
m_name(name),
|
|
|
|
m_columns(columns)
|
|
|
|
{}
|
|
|
|
MyMoneyDbIndex () {}
|
|
|
|
inline const TQString table () const {return m_table;}
|
|
|
|
inline bool isUnique () const {return m_unique;}
|
|
|
|
inline const TQString name () const {return m_name;}
|
|
|
|
inline const TQStringList columns () const {return m_columns;}
|
|
|
|
const TQString generateDDL (databaseTypeE dbType) const;
|
|
|
|
private:
|
|
|
|
TQString m_table;
|
|
|
|
bool m_unique;
|
|
|
|
TQString m_name;
|
|
|
|
TQStringList m_columns;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The MyMoneyDbTable class is a representation of a db table.
|
|
|
|
* It has a list of the columns (pointers to MyMoneyDbColumn types) and a
|
|
|
|
* list of any indices that may be on the table.
|
|
|
|
* Additionally, a string for a parameterized query for each of some common
|
|
|
|
* tasks on a table is created by the ctor.
|
|
|
|
*
|
|
|
|
* Const iterators over the list of columns are provided as a convenience.
|
|
|
|
*/
|
|
|
|
class MyMoneyDbTable {
|
|
|
|
public:
|
|
|
|
MyMoneyDbTable (const TQString& iname,
|
|
|
|
const TQValueList<TDESharedPtr <MyMoneyDbColumn> >& ifields,
|
|
|
|
const TQString& initVersion = "1.0"):
|
|
|
|
m_name(iname),
|
|
|
|
m_fields(ifields),
|
|
|
|
m_initVersion(initVersion) {}
|
|
|
|
MyMoneyDbTable (void) {}
|
|
|
|
|
|
|
|
inline const TQString& name(void) const {return (m_name);}
|
|
|
|
inline const TQString& insertString(void) const {return (m_insertString);};
|
|
|
|
inline const TQString selectAllString(bool terminate = true) const
|
|
|
|
{return (terminate ? TQString(m_selectAllString + ";") : m_selectAllString);};
|
|
|
|
inline const TQString& updateString(void) const {return (m_updateString);};
|
|
|
|
inline const TQString& deleteString(void) const {return (m_deleteString);};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method determines the string required to drop the primary key for the table
|
|
|
|
* based on the db specific syntax.
|
|
|
|
*
|
|
|
|
* @param dbType The driver type of the database.
|
|
|
|
*
|
|
|
|
* @return TQString for the syntax to drop the primary key.
|
|
|
|
*/
|
|
|
|
const TQString dropPrimaryKeyString(databaseTypeE dbType) const;
|
|
|
|
/**
|
|
|
|
* This method returns a comma-separated list of all column names in the table
|
|
|
|
*
|
|
|
|
* @return TQString column list.
|
|
|
|
*/
|
|
|
|
const TQString columnList() const;
|
|
|
|
/**
|
|
|
|
* This method returns the string for changing a column's definition. It covers statements
|
|
|
|
* like ALTER TABLE..CHANGE COLUMN, MODIFY COLUMN, etc.
|
|
|
|
*
|
|
|
|
* @param dbType The driver type of the database.
|
|
|
|
* @param columnName The name of the column to be modified.
|
|
|
|
* @param newDef The MyMoneyColumn object of the new column definition.
|
|
|
|
*
|
|
|
|
* @return TQString containing DDL to change the column.
|
|
|
|
*/
|
|
|
|
const TQString modifyColumnString(databaseTypeE dbType, const TQString& columnName, const MyMoneyDbColumn& newDef) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method builds all of the SQL strings for common operations.
|
|
|
|
*/
|
|
|
|
void buildSQLStrings(void);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method generates the DDL required to create the table.
|
|
|
|
*
|
|
|
|
* @param dbType The driver type of the database.
|
|
|
|
*
|
|
|
|
* @return TQString of the DDL.
|
|
|
|
*/
|
|
|
|
const TQString generateCreateSQL (databaseTypeE dbType) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method creates a MyMoneyDbIndex object and adds it to the list of indices for the table.
|
|
|
|
*
|
|
|
|
* @param name The name of the index.
|
|
|
|
* @param columns The list of the columns affected.
|
|
|
|
* @param unique Whether or not this should be a unique index.
|
|
|
|
*/
|
|
|
|
void addIndex(const TQString& name, const TQStringList& columns, bool unique = false);
|
|
|
|
|
|
|
|
typedef TQValueList<TDESharedPtr <MyMoneyDbColumn> >::const_iterator field_iterator;
|
|
|
|
inline field_iterator begin(void) const {return m_fields.constBegin();}
|
|
|
|
inline field_iterator end(void) const {return m_fields.constEnd(); }
|
|
|
|
private:
|
|
|
|
TQString m_name;
|
|
|
|
TQValueList<TDESharedPtr <MyMoneyDbColumn> > m_fields;
|
|
|
|
|
|
|
|
typedef TQValueList<MyMoneyDbIndex>::const_iterator index_iterator;
|
|
|
|
TQValueList<MyMoneyDbIndex> m_indices;
|
|
|
|
TQString m_initVersion;
|
|
|
|
TQString m_insertString; // string to insert a record
|
|
|
|
TQString m_selectAllString; // to select all fields
|
|
|
|
TQString m_updateString; // normal string for record update
|
|
|
|
TQString m_deleteString; // string to delete 1 record
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The MyMoneyDbView class is a representation of a db view.
|
|
|
|
*
|
|
|
|
* Views will be dropped and recreated on upgrade, so there is no need
|
|
|
|
* to do anything more complex than storing the name of the view and
|
|
|
|
* the CREATE VIEW string.
|
|
|
|
*/
|
|
|
|
class MyMoneyDbView {
|
|
|
|
public:
|
|
|
|
MyMoneyDbView (const TQString& name,
|
|
|
|
const TQString& createString,
|
|
|
|
const TQString& initVersion = "0.1")
|
|
|
|
: m_name (name), m_createString (createString), m_initVersion (initVersion)
|
|
|
|
{}
|
|
|
|
|
|
|
|
MyMoneyDbView (void) {}
|
|
|
|
|
|
|
|
inline const TQString& name(void) const {return (m_name);}
|
|
|
|
inline const TQString createString(void) const {return (m_createString);};
|
|
|
|
|
|
|
|
private:
|
|
|
|
TQString m_name;
|
|
|
|
TQString m_createString;
|
|
|
|
TQString m_initVersion;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The MyMoneyDbDef class is
|
|
|
|
*/
|
|
|
|
class MyMoneyDbDef {
|
|
|
|
friend class MyMoneyStorageSql;
|
|
|
|
friend class MyMoneyDatabaseMgr;
|
|
|
|
public:
|
|
|
|
MyMoneyDbDef();
|
|
|
|
~MyMoneyDbDef() {}
|
|
|
|
|
|
|
|
const TQString generateSQL (const TQString& driver) const;
|
|
|
|
|
|
|
|
typedef TQMap<TQString, MyMoneyDbTable>::const_iterator table_iterator;
|
|
|
|
inline table_iterator tableBegin(void) const {return m_tables.constBegin();}
|
|
|
|
inline table_iterator tableEnd(void) const {return m_tables.constEnd();}
|
|
|
|
|
|
|
|
typedef TQMap<TQString, MyMoneyDbView>::const_iterator view_iterator;
|
|
|
|
inline view_iterator viewBegin(void) const {return m_views.constBegin();}
|
|
|
|
inline view_iterator viewEnd(void) const {return m_views.constEnd();}
|
|
|
|
|
|
|
|
inline unsigned int currentVersion() const {return (m_currentVersion);};
|
|
|
|
|
|
|
|
private:
|
|
|
|
const TQString enclose(const TQString& text) const
|
|
|
|
{return (TQString("'" + text + "'"));};
|
|
|
|
static unsigned int m_currentVersion; // The current version of the database layout
|
|
|
|
MyMoneyDbDrivers m_drivers;
|
|
|
|
#define TABLE(name) void name();
|
|
|
|
#define VIEW(name) void name();
|
|
|
|
TABLE(FileInfo);
|
|
|
|
TABLE(Institutions);
|
|
|
|
TABLE(Payees);
|
|
|
|
TABLE(Accounts);
|
|
|
|
TABLE(Transactions);
|
|
|
|
TABLE(Splits);
|
|
|
|
TABLE(KeyValuePairs);
|
|
|
|
TABLE(Schedules);
|
|
|
|
TABLE(SchedulePaymentHistory);
|
|
|
|
TABLE(Securities);
|
|
|
|
TABLE(Prices);
|
|
|
|
TABLE(Currencies);
|
|
|
|
TABLE(Reports);
|
|
|
|
TABLE(Budgets);
|
|
|
|
VIEW(Balances);
|
|
|
|
protected:
|
|
|
|
TQMap<TQString, MyMoneyDbTable> m_tables;
|
|
|
|
TQMap<TQString, MyMoneyDbView> m_views;
|
|
|
|
};
|
|
|
|
|
|
|
|
class IMyMoneySerialize;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The MyMoneyDbColumn class is a base type for generic db columns.
|
|
|
|
* Derived types exist for several common column types.
|
|
|
|
*/
|
|
|
|
class MyMoneyStorageSql : public IMyMoneyStorageFormat, public TQSqlDatabase, public TDEShared {
|
|
|
|
public:
|
|
|
|
|
|
|
|
MyMoneyStorageSql (IMyMoneySerialize *storage, const KURL& = KURL());
|
|
|
|
virtual ~MyMoneyStorageSql() {close(true);}
|
|
|
|
|
|
|
|
unsigned int currentVersion() const {return (m_db.currentVersion());};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* MyMoneyStorageSql - open database file
|
|
|
|
*
|
|
|
|
* @param url pseudo-URL of database to be opened
|
|
|
|
* @param openMode open mode, same as for TQFile::open
|
|
|
|
* @param clear whether existing data can be deleted
|
|
|
|
|
|
|
|
* @return 0 - database successfully opened
|
|
|
|
* @return 1 - database not opened, use lastError function for reason
|
|
|
|
* @return -1 - output database not opened, contains data, clean not specified
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
int open(const KURL& url, int openMode, bool clear = false);
|
|
|
|
/**
|
|
|
|
* MyMoneyStorageSql close the database
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
void close(bool logoff = true);
|
|
|
|
/**
|
|
|
|
* MyMoneyStorageSql read all the database into storage
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
bool readFile(void);
|
|
|
|
/**
|
|
|
|
* MyMoneyStorageSql write/update the database from storage
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
bool writeFile(void);
|
|
|
|
|
|
|
|
// check database type
|
|
|
|
bool isDb2() const { return (m_dbType == Db2);};
|
|
|
|
bool isInterbase() const { return (m_dbType == Interbase);};
|
|
|
|
bool isMysql() const { return (m_dbType == Mysql);};
|
|
|
|
bool isOracle8() const { return (m_dbType == Oracle8);};
|
|
|
|
bool isODBC3() const { return (m_dbType == ODBC3);};
|
|
|
|
bool isPostgresql() const { return (m_dbType == Postgresql);};
|
|
|
|
bool isSybase() const { return (m_dbType == Sybase);};
|
|
|
|
bool isSqlite3() const { return (m_dbType == Sqlite3);};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* MyMoneyStorageSql generalized error routine
|
|
|
|
*
|
|
|
|
* @return : error message to be displayed
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
const TQString& lastError() const {return (m_error);};
|
|
|
|
/**
|
|
|
|
* This method is used when a database file is open, and the data is to
|
|
|
|
* be saved in a different file or format. It will ensure that all data
|
|
|
|
* from the database is available in memory to enable it to be written.
|
|
|
|
*/
|
|
|
|
virtual void fillStorage();
|
|
|
|
/**
|
|
|
|
* The following functions correspond to the identically named (usually) functions
|
|
|
|
* within the Storage Manager, and are called to update the database
|
|
|
|
*/
|
|
|
|
void modifyUserInfo(const MyMoneyPayee& payee);
|
|
|
|
void addInstitution(const MyMoneyInstitution& inst);
|
|
|
|
void modifyInstitution(const MyMoneyInstitution& inst);
|
|
|
|
void removeInstitution(const MyMoneyInstitution& inst);
|
|
|
|
void addPayee(const MyMoneyPayee& payee);
|
|
|
|
void modifyPayee(const MyMoneyPayee& payee);
|
|
|
|
void removePayee(const MyMoneyPayee& payee);
|
|
|
|
void addAccount(const MyMoneyAccount& acc);
|
|
|
|
void modifyAccount(const MyMoneyAccount& acc);
|
|
|
|
void removeAccount(const MyMoneyAccount& acc);
|
|
|
|
void addTransaction(const MyMoneyTransaction& tx);
|
|
|
|
void modifyTransaction(const MyMoneyTransaction& tx);
|
|
|
|
void removeTransaction(const MyMoneyTransaction& tx);
|
|
|
|
void addSchedule(const MyMoneySchedule& sch);
|
|
|
|
void modifySchedule(const MyMoneySchedule& sch);
|
|
|
|
void removeSchedule(const MyMoneySchedule& sch);
|
|
|
|
void addSecurity(const MyMoneySecurity& sec);
|
|
|
|
void modifySecurity(const MyMoneySecurity& sec);
|
|
|
|
void removeSecurity(const MyMoneySecurity& sec);
|
|
|
|
void addPrice(const MyMoneyPrice& p);
|
|
|
|
void removePrice(const MyMoneyPrice& p);
|
|
|
|
void addCurrency(const MyMoneySecurity& sec);
|
|
|
|
void modifyCurrency(const MyMoneySecurity& sec);
|
|
|
|
void removeCurrency(const MyMoneySecurity& sec);
|
|
|
|
void addReport(const MyMoneyReport& rep);
|
|
|
|
void modifyReport(const MyMoneyReport& rep);
|
|
|
|
void removeReport(const MyMoneyReport& rep);
|
|
|
|
void addBudget(const MyMoneyBudget& bud);
|
|
|
|
void modifyBudget(const MyMoneyBudget& bud);
|
|
|
|
void removeBudget(const MyMoneyBudget& bud);
|
|
|
|
|
|
|
|
unsigned long transactionCount (const TQString& aid = TQString()) const;
|
|
|
|
inline const TQMap<TQString, unsigned long> transactionCountMap () const
|
|
|
|
{return (m_transactionCountMap);};
|
|
|
|
/**
|
|
|
|
* the storage manager also needs the following read entry points
|
|
|
|
*/
|
|
|
|
const TQMap<TQString, MyMoneyAccount> fetchAccounts (const TQStringList& idList = TQStringList (), bool forUpdate = false) const;
|
|
|
|
const TQMap<TQString, MyMoneyMoney> fetchBalance(const TQStringList& id, const TQDate& date) const;
|
|
|
|
const TQMap<TQString, MyMoneyBudget> fetchBudgets (const TQStringList& idList = TQStringList (), bool forUpdate = false) const;
|
|
|
|
const TQMap<TQString, MyMoneySecurity> fetchCurrencies (const TQStringList& idList = TQStringList (), bool forUpdate = false) const;
|
|
|
|
const TQMap<TQString, MyMoneyInstitution> fetchInstitutions (const TQStringList& idList = TQStringList (), bool forUpdate = false) const;
|
|
|
|
const TQMap<TQString, MyMoneyPayee> fetchPayees (const TQStringList& idList = TQStringList (), bool forUpdate = false) const;
|
|
|
|
const MyMoneyPriceList fetchPrices (const TQStringList& fromIdList = TQStringList (), const TQStringList& toIdList = TQStringList(), bool forUpdate = false) const;
|
|
|
|
const MyMoneyPrice fetchSinglePrice (const TQString& fromIdList, const TQString& toIdList, const TQDate& date, bool exactDate, bool forUpdate = false) const;
|
|
|
|
const TQMap<TQString, MyMoneyReport> fetchReports (const TQStringList& idList = TQStringList (), bool forUpdate = false) const;
|
|
|
|
const TQMap<TQString, MyMoneySchedule> fetchSchedules (const TQStringList& idList = TQStringList (), bool forUpdate = false) const;
|
|
|
|
const TQMap<TQString, MyMoneySecurity> fetchSecurities (const TQStringList& idList = TQStringList (), bool forUpdate = false) const;
|
|
|
|
const TQMap<TQString, MyMoneyTransaction> fetchTransactions (const TQString& tidList = TQString (), const TQString& dateClause = TQString(), bool forUpdate = false) const;
|
|
|
|
const TQMap<TQString, MyMoneyTransaction> fetchTransactions (const MyMoneyTransactionFilter& filter) const;
|
|
|
|
bool isReferencedByTransaction(const TQString& id) const;
|
|
|
|
|
|
|
|
void readPayees(const TQString&);
|
|
|
|
void readPayees(const TQValueList<TQString> payeeList = TQValueList<TQString>());
|
|
|
|
void readTransactions(const MyMoneyTransactionFilter& filter);
|
|
|
|
void setProgressCallback(void(*callback)(int, int, const TQString&));
|
|
|
|
|
|
|
|
virtual void readFile(TQIODevice* s, IMyMoneySerialize* storage) { Q_UNUSED(s); Q_UNUSED(storage) };
|
|
|
|
virtual void writeFile(TQIODevice* s, IMyMoneySerialize* storage){ Q_UNUSED(s); Q_UNUSED(storage) };
|
|
|
|
|
|
|
|
void startCommitUnit (const TQString& callingFunction);
|
|
|
|
bool endCommitUnit (const TQString& callingFunction);
|
|
|
|
void cancelCommitUnit (const TQString& callingFunction);
|
|
|
|
|
|
|
|
long unsigned getRecCount(const TQString& table) const;
|
|
|
|
long unsigned getNextBudgetId() const;
|
|
|
|
long unsigned getNextAccountId() const;
|
|
|
|
long unsigned getNextInstitutionId() const;
|
|
|
|
long unsigned getNextPayeeId() const;
|
|
|
|
long unsigned getNextReportId() const;
|
|
|
|
long unsigned getNextScheduleId() const;
|
|
|
|
long unsigned getNextSecurityId() const;
|
|
|
|
long unsigned getNextTransactionId() const;
|
|
|
|
|
|
|
|
long unsigned incrementBudgetId();
|
|
|
|
long unsigned incrementAccountId();
|
|
|
|
long unsigned incrementInstitutionId();
|
|
|
|
long unsigned incrementPayeeId();
|
|
|
|
long unsigned incrementReportId();
|
|
|
|
long unsigned incrementScheduleId();
|
|
|
|
long unsigned incrementSecurityId();
|
|
|
|
long unsigned incrementTransactionId();
|
|
|
|
|
|
|
|
void loadAccountId(const unsigned long& id);
|
|
|
|
void loadTransactionId(const unsigned long& id);
|
|
|
|
void loadPayeeId(const unsigned long& id);
|
|
|
|
void loadInstitutionId(const unsigned long& id);
|
|
|
|
void loadScheduleId(const unsigned long& id);
|
|
|
|
void loadSecurityId(const unsigned long& id);
|
|
|
|
void loadReportId(const unsigned long& id);
|
|
|
|
void loadBudgetId(const unsigned long& id);
|
|
|
|
|
|
|
|
private:
|
|
|
|
// a function to build a comprehensive error message
|
|
|
|
TQString& buildError (const TQSqlQuery& q, const TQString& function, const TQString& message) const;
|
|
|
|
// write routines
|
|
|
|
void writeUserInformation(void);
|
|
|
|
void writeInstitutions(void);
|
|
|
|
void writePayees(void);
|
|
|
|
void writeAccounts(void);
|
|
|
|
void writeTransactions(void);
|
|
|
|
void writeSchedules(void);
|
|
|
|
void writeSecurities(void);
|
|
|
|
void writePrices(void);
|
|
|
|
void writeCurrencies(void);
|
|
|
|
void writeFileInfo(void);
|
|
|
|
void writeReports(void);
|
|
|
|
void writeBudgets(void);
|
|
|
|
|
|
|
|
void writeInstitution(const MyMoneyInstitution& i, MyMoneySqlQuery& q);
|
|
|
|
void writePayee(const MyMoneyPayee& p, MyMoneySqlQuery& q, bool isUserInfo = false);
|
|
|
|
void writeAccount (const MyMoneyAccount& a, MyMoneySqlQuery& q);
|
|
|
|
void writeTransaction(const TQString& txId, const MyMoneyTransaction& tx, MyMoneySqlQuery& q, const TQString& type);
|
|
|
|
void writeSplits(const TQString& txId, const TQString& type, const TQValueList<MyMoneySplit>& splitList);
|
|
|
|
void writeSplit(const TQString& txId, const MyMoneySplit& split, const TQString& type, const int splitId, MyMoneySqlQuery& q);
|
|
|
|
void writeSchedule(const MyMoneySchedule& sch, MyMoneySqlQuery& q, bool insert);
|
|
|
|
void writeSecurity(const MyMoneySecurity& security, MyMoneySqlQuery& q);
|
|
|
|
void writePricePair ( const MyMoneyPriceEntries& p);
|
|
|
|
void writePrice (const MyMoneyPrice& p);
|
|
|
|
void writeCurrency(const MyMoneySecurity& currency, MyMoneySqlQuery& q);
|
|
|
|
void writeReport (const MyMoneyReport& rep, MyMoneySqlQuery& q);
|
|
|
|
void writeBudget (const MyMoneyBudget& bud, MyMoneySqlQuery& q);
|
|
|
|
void writeKeyValuePairs(const TQString& kvpType, const TQString& kvpId, const TQMap<TQString, TQString>& pairs);
|
|
|
|
void writeKeyValuePair(const TQString& kvpType, const TQString& kvpId,
|
|
|
|
const TQString& kvpKey, const TQString& kvpData);
|
|
|
|
// read routines
|
|
|
|
void readFileInfo(void);
|
|
|
|
void readLogonData(void);
|
|
|
|
void readUserInformation(void);
|
|
|
|
void readInstitutions(void);
|
|
|
|
void readAccounts(void);
|
|
|
|
void readTransaction(const TQString id);
|
|
|
|
void readTransactions(const TQString& tidList = TQString(), const TQString& dateClause = TQString());
|
|
|
|
void readTransaction(MyMoneyTransaction &tx, const TQString& tid);
|
|
|
|
void readSplit (MyMoneySplit& s, const MyMoneySqlQuery& q, const MyMoneyDbTable& t) const;
|
|
|
|
const MyMoneyKeyValueContainer readKeyValuePairs (const TQString& kvpType, const TQString& kvpId) const;
|
|
|
|
const TQMap<TQString, MyMoneyKeyValueContainer> readKeyValuePairs (const TQString& kvpType, const TQStringList& kvpIdList) const;
|
|
|
|
void readSchedules(void);
|
|
|
|
void readSecurities(void);
|
|
|
|
void readPrices(void);
|
|
|
|
void readCurrencies(void);
|
|
|
|
void readReports(void);
|
|
|
|
void readBudgets(void);
|
|
|
|
|
|
|
|
void deleteTransaction(const TQString& id);
|
|
|
|
void deleteSchedule(const TQString& id);
|
|
|
|
void deleteKeyValuePairs(const TQString& kvpType, const TQString& kvpId);
|
|
|
|
long unsigned calcHighId (const long unsigned&, const TQString&);
|
|
|
|
|
|
|
|
void setVersion (const TQString& version);
|
|
|
|
|
|
|
|
void signalProgress(int current, int total, const TQString& = "") const;
|
|
|
|
void (*m_progressCallback)(int, int, const TQString&);
|
|
|
|
|
|
|
|
//void startCommitUnit (const TQString& callingFunction);
|
|
|
|
//void endCommitUnit (const TQString& callingFunction);
|
|
|
|
//void cancelCommitUnit (const TQString& callingFunction);
|
|
|
|
int splitState(const MyMoneyTransactionFilter::stateOptionE& state) const;
|
|
|
|
|
|
|
|
inline const TQDate getDate (const TQString& date) const {
|
|
|
|
return (date.isNull() ? TQDate() : TQDate::fromString(date, Qt::ISODate));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline const TQDateTime getDateTime (const TQString& date) const {
|
|
|
|
return (date.isNull() ? TQDateTime() : TQDateTime::fromString(date, Qt::ISODate));
|
|
|
|
}
|
|
|
|
|
|
|
|
// open routines
|
|
|
|
/**
|
|
|
|
* MyMoneyStorageSql create database
|
|
|
|
*
|
|
|
|
* @param url pseudo-URL of database to be opened
|
|
|
|
*
|
|
|
|
* @return true - creation successful
|
|
|
|
* @return false - could not create
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
int createDatabase(const KURL& url);
|
|
|
|
int upgradeDb();
|
|
|
|
int upgradeToV1();
|
|
|
|
int upgradeToV2();
|
|
|
|
int upgradeToV3();
|
|
|
|
int upgradeToV4();
|
|
|
|
int upgradeToV5();
|
|
|
|
int upgradeToV6();
|
|
|
|
bool sqliteAlterTable(const MyMoneyDbTable& t);
|
|
|
|
bool addColumn(const MyMoneyDbTable& t,
|
|
|
|
const MyMoneyDbColumn& c,
|
|
|
|
const TQString& after = TQString());
|
|
|
|
bool addColumn(const TQString& table,
|
|
|
|
const TQString& column,
|
|
|
|
const TQString& after = TQString());
|
|
|
|
bool dropColumn(const MyMoneyDbTable& t,
|
|
|
|
const TQString& c);
|
|
|
|
bool dropColumn(const TQString& table,
|
|
|
|
const TQString& column);
|
|
|
|
|
|
|
|
// long long unsigned getRecCount(const TQString& table);
|
|
|
|
int createTables();
|
|
|
|
void createTable(const MyMoneyDbTable& t);
|
|
|
|
void clean ();
|
|
|
|
int isEmpty();
|
|
|
|
// data
|
|
|
|
MyMoneyDbDrivers m_drivers;
|
|
|
|
databaseTypeE m_dbType;
|
|
|
|
|
|
|
|
MyMoneyDbDef m_db;
|
|
|
|
unsigned int m_dbVersion;
|
|
|
|
IMyMoneySerialize *m_storage;
|
|
|
|
IMyMoneyStorage *m_storagePtr;
|
|
|
|
// input options
|
|
|
|
bool m_loadAll; // preload all data
|
|
|
|
bool m_override; // override open if already in use
|
|
|
|
// error message
|
|
|
|
TQString m_error;
|
|
|
|
// record counts
|
|
|
|
long unsigned m_institutions;
|
|
|
|
long unsigned m_accounts;
|
|
|
|
long unsigned m_payees;
|
|
|
|
long unsigned m_transactions;
|
|
|
|
long unsigned m_splits;
|
|
|
|
long unsigned m_securities;
|
|
|
|
long unsigned m_prices;
|
|
|
|
long unsigned m_currencies;
|
|
|
|
long unsigned m_schedules;
|
|
|
|
long unsigned m_reports;
|
|
|
|
long unsigned m_kvps;
|
|
|
|
long unsigned m_budgets;
|
|
|
|
// next id to use (for future archive)
|
|
|
|
long unsigned m_hiIdInstitutions;
|
|
|
|
long unsigned m_hiIdPayees;
|
|
|
|
long unsigned m_hiIdAccounts;
|
|
|
|
long unsigned m_hiIdTransactions;
|
|
|
|
long unsigned m_hiIdSchedules;
|
|
|
|
long unsigned m_hiIdSecurities;
|
|
|
|
long unsigned m_hiIdReports;
|
|
|
|
long unsigned m_hiIdBudgets;
|
|
|
|
// encrypt option - usage TBD
|
|
|
|
TQString m_encryptData;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This variable is used to suppress status messages except during
|
|
|
|
* initial data load and final write
|
|
|
|
|
|
|
|
*/
|
|
|
|
bool m_displayStatus;
|
|
|
|
/**
|
|
|
|
* On occasions, e.g. after a complex transaction search, or for populating a
|
|
|
|
* payee popup list, it becomes necessary to load all data into memory. The
|
|
|
|
* following flags will be set after such a load, to indicate that further
|
|
|
|
* retrievals are not needed.
|
|
|
|
*/
|
|
|
|
// bool m_transactionListRead;
|
|
|
|
// bool m_payeeListRead;
|
|
|
|
/**
|
|
|
|
* This member variable holds a list of those accounts for which all
|
|
|
|
* transactions are in memory, thus saving reading them again
|
|
|
|
*/
|
|
|
|
// TQValueList<TQString> m_accountsLoaded;
|
|
|
|
/**
|
|
|
|
* This member variable is used when loading transactions to list all
|
|
|
|
* referenced payees, which can then be read into memory (if not already there)
|
|
|
|
*/
|
|
|
|
// TQValueList<TQString> m_payeeList;
|
|
|
|
|
|
|
|
void alert(TQString s) const {tqDebug("%s", s.ascii());}; // FIXME: remove...
|
|
|
|
/** The following keeps track of commitment units (known as transactions in SQL
|
|
|
|
* though it would be confusing to use that term within KMM). It is implemented
|
|
|
|
* as a stack for debug purposes. Long term, probably a count would suffice
|
|
|
|
*/
|
|
|
|
TQValueStack<TQString> m_commitUnitStack;
|
|
|
|
/**
|
|
|
|
* This member variable is used to preload transactions for preferred accounts
|
|
|
|
*/
|
|
|
|
MyMoneyTransactionFilter m_preferred;
|
|
|
|
/**
|
|
|
|
* This member variable is used because reading prices from a file uses the 'add...' function rather than a
|
|
|
|
* 'load...' function which other objects use. Having this variable allows us to avoid needing to check the
|
|
|
|
* database to see if this really is a new or modified price
|
|
|
|
*/
|
|
|
|
bool m_readingPrices;
|
|
|
|
/**
|
|
|
|
* This member variable holds a map of transaction counts per account, indexed by
|
|
|
|
* the account id. It is used
|
|
|
|
* to avoid having to scan all transactions whenever a count is needed. It should
|
|
|
|
* probably be moved into the MyMoneyAccount object; maybe we will do that once
|
|
|
|
* the database code has been properly checked out
|
|
|
|
*/
|
|
|
|
TQMap<TQString, unsigned long> m_transactionCountMap;
|
|
|
|
/**
|
|
|
|
* These member variables hold the user name and date/time of logon
|
|
|
|
*/
|
|
|
|
TQString m_logonUser;
|
|
|
|
TQDateTime m_logonAt;
|
|
|
|
TQDateTime m_txPostDate; // FIXME: remove when Tom puts date into split object
|
|
|
|
|
|
|
|
//Disable copying
|
|
|
|
MyMoneyStorageSql (const MyMoneyStorageSql& rhs);
|
|
|
|
MyMoneyStorageSql& operator= (const MyMoneyStorageSql& rhs);
|
|
|
|
//
|
|
|
|
bool m_newDatabase;
|
|
|
|
};
|
|
|
|
#endif // MYMONEYSTORAGESQL_H
|