/************************* * * * * * * * * * * * * *************************** 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 "arcplugin.h" #include "qhacc.h" #include "qhaccext.h" #include "qhaccutils.h" #include "qhacctable.h" // plugin factory calls extern "C" { QHaccPlugin * create(){ return new ARCImpExporter; } void destroy( ARCImpExporter * p ){ delete p; } } const ARCInfo ARCImpExporter::pinfo; ARCImpExporter::ARCImpExporter() : QHaccIOPlugin() {} ARCImpExporter::~ARCImpExporter(){} bool ARCImpExporter::connect( QHacc * e, const QString& h, QString& ){ engine=e; home=h; return true; } const PluginInfo& ARCImpExporter::info() const { return pinfo; } bool ARCImpExporter::load( QString& err ){ QHaccPlugin * texports=0; QString thome=engine->getPluginFor( QHacc::PIIMPORTER, home, texports ); QHaccIOPlugin * restorer=( QHaccIOPlugin * )texports; bool ret=restorer->connect( engine, thome, err ); engine->destroyPlugin( QHacc::PIIMPORTER, texports ); return ret; } bool ARCImpExporter::exprt( QHaccResultSet * ){ QHaccPlugin * texports=0; QString thome=engine->getPluginFor( QHacc::PIIMPORTER, home, texports ); QHaccIOPlugin * restorer=( QHaccIOPlugin * )texports; QString err; bool b=( restorer->connect( engine, thome, err ) && restorer->load( err ) ); if( b ) QHaccExt( engine ).restore( restorer ); engine->destroyPlugin( QHacc::PIIMPORTER, texports ); return b; } bool ARCImpExporter::imprt( QHaccResultSet * data ){ std::ostream * str=0; // first things first: parse the home string for date and target home int finder=home.find( ":" ); if( finder==-1 ){ if( Utils::error( Utils::ERROPER, str ) ) *str<<"no target location"<getA( dater ); QDate date; bool bydate=false; if( acct.isNull() ) { bydate=true; date=Utils::dateFromString( dater, engine->getSP( "DATESEPARATOR" ), engine->getIP( "DATEFORMAT" ) ); if( !date.isValid() ){ if( Utils::error( Utils::ERROPER, str ) ){ *str<<"no account or date: "< trans; // we really want to operate on tables, not resultsets QHaccTable * tbls=new QHaccTable[QC::NUMTABLES]; for( int i=0; i tra=engine->getWhere( TRANSACTIONS, vector( 1, TableSelect( QC::TDATE, TableCol( date ), TableSelect::LT ) ), rr ); trans=tra; } else{ uint r=0; vector v; auto_ptr tras=engine->getXTForA( acct, TableGet(), v, r ); trans.reset( ( new QHaccResultSet( QC::TCOLS, QC::TCOLTYPES, r ) ) ); trans->startLoad(); for( uint i=0; isplitXTrans( tras->at( i ), tr, sp ); trans->add( tr ); } trans->stopLoad(); } // load the tables we won't be filling with our own data int pops[]={ QC::ACCTT, QC::JRNLT, QC::PREFT }; for( int i=0; i<3; i++ ) tbls[pops[i]]+=data[pops[i]]; // we now have a resultset that includes all the transactions // we want to archive, so start the archiving! // basically, keep all the stuff that would get removed during an // engine->remA() on the account, which means: // 1: keep transactions and splits that reference this account // 2: keep named trans that include kept transactions // 3: keep scheduled trans that reference the namedtrans // 4: keep the account itself (there's nothing to do for this step) // notice that we actually keep all the accounts in the archive // because during import, we don't really know what we'll need // why are we re-selecting data from the engine if we already // have that same data in the data array? Because the engine // could be using an external database for its QHACC_HOME, in // which case all these selections will be much faster than the // native QHaccTable. If it's not using a plugin db, we're not // really adding too much overhead, and for the ease of use, // it can't be beat. // step 1: uint r=trans->rows(); for( uint i=0; iat( i ); tbls[QC::TRANT]+=row; // keep transactions // keep splits tbls[QC::SPLTT]+=engine->getTSplits( row[QC::TID].getu() ); // step 2: uint rr=0; TableSelect tt( QC::NTID, row[QC::TID] ); auto_ptr names=tbls[QC::NAMET].getWhere( tt, rr ); for( uint j=0; jat( j ); tbls[QC::NAMET]+=nt; // step 3: uint rrr=0; TableSelect ttt( QC::JWHAT, nt[QC::NNAME] ); auto_ptr jbs=tbls[QC::JOBST].getWhere( ttt, rrr ); tbls[QC::JOBST]+=*jbs; } } // at this point, we should have all the data we need in the tbls array // we'll do our save by getting an ExportPlugin from the engine and // forcing that plugin to do the save for us. QHaccPlugin * texports=0; QString thome=engine->getPluginFor( QHacc::PIEXPORTER, target, texports ); QHaccIOPlugin * exports=( QHaccIOPlugin * )texports; QString err; bool good=exports->connect( engine, thome, err ); if( good ){ QHaccExt ext( engine ); QHaccResultSet * rslts=ext.getRSSet(); for( int i=0; iimprt( rslts ); good=exports->save( err ); if( good ){ if( bydate ) ext.archive( date ); else ext.archive( acct ); } delete [] rslts; } engine->destroyPlugin( QHacc::PIEXPORTER, exports ); delete [] tbls; return good; } bool ARCImpExporter::save( QString& ){ return false; } ARCInfo::ARCInfo(){ raw=false; guisel=false; description="Archive/Restore"; stubby="ARC"; targ=ANY; }