/************************* * * * * * * * * * * * * *************************** Copyright (c) 1999-2005 Ryan Bobko ryan@ostrich-emulators.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ************************** * * * * * * * * * * * * **************************/ #include "qhacctable.h" #include "localfileplugin.h" #include "qhaccutils.h" #include "qhacc.h" #include #include #include #include #include using namespace std; #include // "factory" function calls extern "C" { QHaccPlugin * create(){ return new LocalFileDBPlugin; } void destroy( LocalFileDBPlugin * p ){ delete p; } } const LocalFileDBInfo LocalFileDBPlugin::pinfo; /* read and write local files */ LocalFileDBPlugin::LocalFileDBPlugin() : QHaccDBPlugin(){ needsave=false; transactions=accounts=journals=splits= preferences=namedtrans=procs=0; dbs=0; } LocalFileDBPlugin::~LocalFileDBPlugin(){ if( transactions!=0 ){ for( int i=0; igetBP( "KEEPFILEPERMS" ), e ); } bool LocalFileDBPlugin::savet( QHaccTable& t, const QString& f, bool perm, QString& e ){ std::ostream * str=0; bool ret=false; QFile file( f ); if( file.open( IO_WriteOnly ) ){ QTextStream out( &file ); uint rows=t.rows(); //int tpk=t.idcol(); //QHaccTableIndex index( &t, tpk, t.coltype( tpk ) ); //for( uint j=0; j1 ? "s" : "" )<<" from " <setPK( Utils::tpk( ( Table )i ) ); accounts->addIndexOn( QC::APID, QC::AID ); transactions->addIndexOn( QC::TDATE, QC::TID ); transactions->addIndexOn( QC::TPAYEE, QC::TDATE ); transactions->addIndexOn( QC::TTYPE ); transactions->addIndexOn( QC::TLID ); splits->addIndexOn( QC::SACCTID ); splits->addIndexOn( QC::STID ); namedtrans->addIndexOn( QC::NNAME ); namedtrans->addIndexOn( QC::NACCTID ); home=h; engine=e; return iconnect( e, h, r ); } bool LocalFileDBPlugin::load( QString& err ){ return iload( err ); } bool LocalFileDBPlugin::iload( QString& err ){ for( int i=0; iclear(); iloadt( *dbs[i], home+"/"+QC::TABLENAMES[i], err ); } return true; // no error should stop QHacc form proceeding } bool LocalFileDBPlugin::iloadt( QHaccTable& tbl, const QString& fn, QString& error ){ return loadt( tbl, fn, error ); } auto_ptr LocalFileDBPlugin::xtrans( vector mts ){ auto_ptr ret( new QHaccTable( QC::XCOLS, QC::XCOLTYPES ) ); ret->setName( "xtrans temp" ); // we need to prune the splits and transactions as much as possible before // joining them, or we'll end up always getting a huge table to manipulate vectorsplts; vectortrns; //cout<<"XTRANS: "< splitsgw=splits->getWhere( splts, srr ); //cout<<"XTRANS trans: "< transgw=transactions->getWhere( trns, trr ); // create the combined table // first optimization: if one of our tables is empty, just return if( srr==0 || trr==0 ) return ret; //cout<<"split rows="<rows()<rows(); } bool LocalFileDBPlugin::load( Table t, const QHaccResultSet * model ){ if( t==XTRANS ) return false; needsave=true; return table( t )->load( model ); } int LocalFileDBPlugin::add( Table t, const TableRow& r ){ if( t==XTRANS ) return 0; needsave=true; return table( t )->add( r ); } void LocalFileDBPlugin::updateWhere( Table t, const TableSelect& ts, const TableUpdate& tu ){ if( t==XTRANS ){ std::ostream * str=0; if( Utils::error( Utils::ERROPER, str ) ) *str<<"cannot update XTRANS"<updateWhere( ts, tu ); } void LocalFileDBPlugin::updateWhere( Table t, const TableSelect& ts, const TableRow& tr ){ if( t==XTRANS ){ std::ostream * str=0; if( Utils::error( Utils::ERROPER, str ) ) *str<<"cannot update XTRANS"<updateWhere( ts, tr ); } auto_ptr LocalFileDBPlugin::getWhere( Table t, const TableGet& tg, vector ts, uint& retrows ){ if( t==XTRANS ){ // the call to xtrans() automatically does the TableSelect filtering, // so it's a bad idea to do it again on the getWhere() vector v; return xtrans( ts )->getWhere( tg, v, retrows ); } else return table( t )->getWhere( tg, ts, retrows ); } auto_ptr LocalFileDBPlugin::getWhere( Table t, vector ts, uint& retrows ){ return getWhere( t, TableGet(), ts, retrows ); } auto_ptr LocalFileDBPlugin::getWhere( Table t, const TableSelect& s, uint& retrows ){ return getWhere( t, TableGet(), vector( 1, s ), retrows ); } void LocalFileDBPlugin::deleteWhere( Table t, const TableSelect& ts ){ if( t==XTRANS ) return; needsave=true; table( t )->deleteWhere( ts ); } TableCol LocalFileDBPlugin::max( Table t, int col ){ TableCol ret; if( t==XTRANS ){ vector v; ret=xtrans( v )->max( col ); } else ret=table( t )->max( col ); return ret; } TableCol LocalFileDBPlugin::min( Table t, int col ){ TableCol ret; if( t==XTRANS ){ vector v; ret=xtrans( v )->min( col ); } else ret=table( t )->min( col ); return ret; } void LocalFileDBPlugin::startLoad( Table t, uint i ){ if( t==XTRANS ) return; table( t )->startLoad( i ); } void LocalFileDBPlugin::stopLoad( Table t ){ if( t==XTRANS ) return; table( t )->stopLoad(); } bool LocalFileDBPlugin::dirty() const { return needsave; } bool LocalFileDBPlugin::imprt( QHaccResultSet * tbls ){ bool ret=true; for( int i=0; iload( &tbls[i] ); needsave=true; return ret; } bool LocalFileDBPlugin::exprt( QHaccResultSet * tbls ){ for( int i=0; iadd( row ); }