diff options
Diffstat (limited to 'kpilot/lib/pilotLocalDatabase.cc')
-rw-r--r-- | kpilot/lib/pilotLocalDatabase.cc | 762 |
1 files changed, 0 insertions, 762 deletions
diff --git a/kpilot/lib/pilotLocalDatabase.cc b/kpilot/lib/pilotLocalDatabase.cc deleted file mode 100644 index 735632de7..000000000 --- a/kpilot/lib/pilotLocalDatabase.cc +++ /dev/null @@ -1,762 +0,0 @@ -/* KPilot -** -** Copyright (C) 1998-2001 by Dan Pilone -** Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com> -** -** This defines an interface to Pilot databases on the local disk. -*/ - -/* -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU Lesser General Public License as published by -** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public License -** along with this program in a file called COPYING; if not, write to -** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -** MA 02110-1301, USA. -*/ - -/* -** Bug reports and questions can be sent to kde-pim@kde.org -*/ - - -#include "options.h" - -#include <stdio.h> -#include <unistd.h> -#include <assert.h> - -#include <iostream> - -#include <pi-file.h> - -#include <tqstring.h> -#include <tqfile.h> -#include <tqregexp.h> -#include <tqdatetime.h> -#include <tqvaluevector.h> - -#include <kdebug.h> -#include <kglobal.h> -#include <kstandarddirs.h> -#include <ksavefile.h> - -#include "pilotRecord.h" -#include "pilotLocalDatabase.h" - -typedef TQValueVector<PilotRecord *> Records; - -class PilotLocalDatabase::Private : public Records -{ -public: - static const int DEFAULT_SIZE = 128; - Private(int size=DEFAULT_SIZE) : Records(size) { resetIndex(); } - ~Private() { deleteRecords(); } - - void deleteRecords() - { - for (unsigned int i=0; i<size(); i++) - { - delete at(i); - } - clear(); - resetIndex(); - } - - void resetIndex() - { - current = 0; - pending = -1; - } - - unsigned int current; - int pending; -} ; - -PilotLocalDatabase::PilotLocalDatabase(const TQString & path, - const TQString & dbName, bool useDefaultPath) : - PilotDatabase(dbName), - fPathName(path), - fDBName(dbName), - fAppInfo(0L), - fAppLen(0), - d(0L) -{ - FUNCTIONSETUP; - fixupDBName(); - openDatabase(); - - if (!isOpen() && useDefaultPath) - { - if (fPathBase && !fPathBase->isEmpty()) - { - fPathName = *fPathBase; - } - else - { - fPathName = KGlobal::dirs()->saveLocation("data", - CSL1("kpilot/DBBackup/")); - } - fixupDBName(); - openDatabase(); - if (!isOpen()) - { - fPathName=path; - } - } - -} - -PilotLocalDatabase::PilotLocalDatabase(const TQString &dbName) : - PilotDatabase( TQString() ), - fPathName( TQString() ), - fDBName( TQString() ), - fAppInfo(0L), - fAppLen(0), - d(0L) -{ - FUNCTIONSETUP; - - int p = dbName.findRev( '/' ); - if (p<0) - { - // No slash - fPathName = CSL1("."); - fDBName = dbName; - } - else - { - fPathName = dbName.left(p); - fDBName = dbName.mid(p+1); - } - openDatabase(); -} - -PilotLocalDatabase::~PilotLocalDatabase() -{ - FUNCTIONSETUP; - - closeDatabase(); - delete[]fAppInfo; - delete d; -} - -// Changes any forward slashes to underscores -void PilotLocalDatabase::fixupDBName() -{ - FUNCTIONSETUP; - fDBName = fDBName.replace(CSL1("/"),CSL1("_")); -} - -bool PilotLocalDatabase::createDatabase(long creator, long type, int, int flags, int version) -{ - FUNCTIONSETUP; - - // if the database is already open, we cannot create it again. - // How about completely resetting it? (i.e. deleting it and then - // creating it again) - if (isOpen()) - { - DEBUGKPILOT << fname << ": Database " << fDBName - << " already open. Cannot recreate it." << endl; - return true; - } - - DEBUGKPILOT << fname << ": Creating database " << fDBName << endl; - - // Database names seem to be latin1. - Pilot::toPilot(fDBName, fDBInfo.name, sizeof(fDBInfo.name)); - fDBInfo.creator=creator; - fDBInfo.type=type; - fDBInfo.more=0; - fDBInfo.flags=flags; - fDBInfo.miscFlags=0; - fDBInfo.version=version; - fDBInfo.modnum=0; - fDBInfo.index=0; - fDBInfo.createDate=(TQDateTime::currentDateTime()).toTime_t(); - fDBInfo.modifyDate=(TQDateTime::currentDateTime()).toTime_t(); - fDBInfo.backupDate=(TQDateTime::currentDateTime()).toTime_t(); - - delete[] fAppInfo; - fAppInfo=0L; - fAppLen=0; - - d = new Private; - - // TODO: Do I have to open it explicitly??? - setDBOpen(true); - return true; -} - -int PilotLocalDatabase::deleteDatabase() -{ - FUNCTIONSETUP; - if (isOpen()) - { - closeDatabase(); - } - - TQString dbpath=dbPathName(); - TQFile fl(dbpath); - if (TQFile::remove(dbPathName())) - { - return 0; - } - else - { - return -1; - } -} - - - -// Reads the application block info -int PilotLocalDatabase::readAppBlock(unsigned char *buffer, int size) -{ - FUNCTIONSETUP; - - size_t m = kMin((size_t)size,(size_t)fAppLen); - - if (!isOpen()) - { - WARNINGKPILOT << "DB not open!" << endl; - memset(buffer,0,m); - return -1; - } - - memcpy((void *) buffer, fAppInfo, m); - return fAppLen; -} - -int PilotLocalDatabase::writeAppBlock(unsigned char *buffer, int len) -{ - FUNCTIONSETUP; - - if (!isOpen()) - { - WARNINGKPILOT << "DB not open!" << endl; - return -1; - } - delete[]fAppInfo; - fAppLen = len; - fAppInfo = new char[fAppLen]; - - memcpy(fAppInfo, (void *) buffer, fAppLen); - return 0; -} - - -// returns the number of records in the database -unsigned int PilotLocalDatabase::recordCount() const -{ - if (d && isOpen()) - { - return d->size(); - } - else - { - return 0; - } -} - - -// Returns a TQValueList of all record ids in the database. -TQValueList<recordid_t> PilotLocalDatabase::idList() -{ - int idlen=recordCount(); - TQValueList<recordid_t> idlist; - if (idlen<=0) - { - return idlist; - } - - // now create the QValue list from the idarr: - for (int i=0; i<idlen; i++) - { - idlist.append((*d)[i]->id()); - } - - return idlist; -} - -// Reads a record from database by id, returns record length -PilotRecord *PilotLocalDatabase::readRecordById(recordid_t id) -{ - FUNCTIONSETUP; - - if (!isOpen()) - { - WARNINGKPILOT << "Database '" << fDBName << " not open!" << endl; - return 0L; - } - - d->pending = -1; - - for (unsigned int i = 0; i < d->size(); i++) - { - if ((*d)[i]->id() == id) - { - PilotRecord *newRecord = new PilotRecord((*d)[i]); - d->current = i; - return newRecord; - } - } - return 0L; -} - -// Reads a record from database, returns the record -PilotRecord *PilotLocalDatabase::readRecordByIndex(int index) -{ - FUNCTIONSETUP; - - if (index < 0) - { - DEBUGKPILOT << fname << ": Index " << index << " is bogus." << endl; - return 0L; - } - - d->pending = -1; - if (!isOpen()) - { - WARNINGKPILOT << "DB not open!" << endl; - return 0L; - } - - DEBUGKPILOT << fname << ": Index=" << index << " Count=" << recordCount() << endl; - - if ( (unsigned int)index >= recordCount() ) - { - return 0L; - } - PilotRecord *newRecord = new PilotRecord((*d)[index]); - d->current = index; - - return newRecord; -} - -// Reads the next record from database in category 'category' -PilotRecord *PilotLocalDatabase::readNextRecInCategory(int category) -{ - FUNCTIONSETUP; - d->pending = -1; - if (!isOpen()) - { - WARNINGKPILOT << "DB not open!" << endl; - return 0L; - } - - while ((d->current < d->size()) - && ((*d)[d->current]->category() != category)) - { - d->current++; - } - - if (d->current >= d->size()) - return 0L; - PilotRecord *newRecord = new PilotRecord((*d)[d->current]); - - d->current++; // so we skip it next time - return newRecord; -} - -const PilotRecord *PilotLocalDatabase::findNextNewRecord() -{ - FUNCTIONSETUP; - - if (!isOpen()) - { - WARNINGKPILOT << "DB not open!" << endl; - return 0L; - } - DEBUGKPILOT << fname << ": looking for new record from " << d->current << endl; - // Should this also check for deleted? - while ((d->current < d->size()) - && ((*d)[d->current]->id() != 0 )) - { - d->current++; - } - - if (d->current >= d->size()) - return 0L; - - d->pending = d->current; // Record which one needs the new id - d->current++; // so we skip it next time - return (*d)[d->pending]; -} - -PilotRecord *PilotLocalDatabase::readNextModifiedRec(int *ind) -{ - FUNCTIONSETUP; - - if (!isOpen()) - { - WARNINGKPILOT << "DB not open!" << endl; - return 0L; - } - - d->pending = -1; - // Should this also check for deleted? - while ((d->current < d->size()) - && !((*d)[d->current]->isModified()) && ((*d)[d->current]->id()>0 )) - { - d->current++; - } - - if (d->current >= d->size()) - { - return 0L; - } - PilotRecord *newRecord = new PilotRecord((*d)[d->current]); - if (ind) - { - *ind=d->current; - } - - d->pending = d->current; // Record which one needs the new id - d->current++; // so we skip it next time - return newRecord; -} - -// Writes a new ID to the record specified the index. Not supported on Serial connections -recordid_t PilotLocalDatabase::updateID(recordid_t id) -{ - FUNCTIONSETUP; - - if (!isOpen()) - { - WARNINGKPILOT << "DB not open!" << endl; - return 0; - } - if (d->pending < 0) - { - WARNINGKPILOT << "Last call was NOT readNextModifiedRec()" << endl; - return 0; - } - (*d)[d->pending]->setID(id); - d->pending = -1; - return id; -} - -// Writes a new record to database (if 'id' == 0, it is assumed that this is a new record to be installed on pilot) -recordid_t PilotLocalDatabase::writeRecord(PilotRecord * newRecord) -{ - FUNCTIONSETUP; - - if (!isOpen()) - { - WARNINGKPILOT << "DB not open!" << endl; - return 0; - } - - d->pending = -1; - if (!newRecord) - { - WARNINGKPILOT << "Record to be written is invalid!" << endl; - return 0; - } - - // Instead of making the app do it, assume that whenever a record is - // written to the database it is dirty. (You can clean up the database with - // resetSyncFlags().) This will make things get copied twice during a hot-sync - // but shouldn't cause any other major headaches. - newRecord->setModified( true ); - - // First check to see if we have this record: - if (newRecord->id() != 0) - { - for (unsigned int i = 0; i < d->size(); i++) - if ((*d)[i]->id() == newRecord->id()) - { - delete (*d)[i]; - - (*d)[i] = new PilotRecord(newRecord); - return 0; - } - } - // Ok, we don't have it, so just tack it on. - d->append( new PilotRecord(newRecord) ); - return newRecord->id(); -} - -// Deletes a record with the given recordid_t from the database, or all records, if all is set to true. The recordid_t will be ignored in this case -int PilotLocalDatabase::deleteRecord(recordid_t id, bool all) -{ - FUNCTIONSETUP; - if (!isOpen()) - { - WARNINGKPILOT <<"DB not open"<<endl; - return -1; - } - d->resetIndex(); - if (all) - { - d->deleteRecords(); - d->clear(); - return 0; - } - else - { - Private::Iterator i; - for ( i=d->begin() ; i!=d->end(); ++i) - { - if ((*i) && (*i)->id() == id) break; - } - if ( (i!=d->end()) && (*i) && (*i)->id() == id) - { - d->erase(i); - } - else - { - // Record with this id does not exist! - return -1; - } - } - return 0; -} - - -// Resets all records in the database to not dirty. -int PilotLocalDatabase::resetSyncFlags() -{ - FUNCTIONSETUP; - - if (!isOpen()) - { - WARNINGKPILOT << "DB not open!" << endl; - return -1; - } - d->pending = -1; - for (unsigned int i = 0; i < d->size(); i++) - { - (*d)[i]->setModified( false ); - } - return 0; -} - -// Resets next record index to beginning -int PilotLocalDatabase::resetDBIndex() -{ - FUNCTIONSETUP; - if (!isOpen()) - { - WARNINGKPILOT << "DB not open!" << endl; - return -1; - } - d->resetIndex(); - return 0; -} - -// Purges all Archived/Deleted records from Palm Pilot database -int PilotLocalDatabase::cleanup() -{ - FUNCTIONSETUP; - if (!isOpen()) - { - WARNINGKPILOT << "DB not open!" << endl; - return -1; - } - d->resetIndex(); - - /* Not the for loop one might expect since when we erase() - * a record the iterator changes too. - */ - Private::Iterator i = d->begin(); - while ( i!=d->end() ) - { - if ( (*i)->isDeleted() || (*i)->isArchived() ) - { - delete (*i); - i = d->erase(i); - } - else - { - ++i; - } - } - - // Don't have to do anything. Will be taken care of by closeDatabase()... - // Changed! - return 0; -} - -TQString PilotLocalDatabase::dbPathName() const -{ - FUNCTIONSETUP; - TQString tempName(fPathName); - TQString slash = CSL1("/"); - - if (!tempName.endsWith(slash)) tempName += slash; - tempName += getDBName(); - tempName += CSL1(".pdb"); - return tempName; -} - -void PilotLocalDatabase::openDatabase() -{ - FUNCTIONSETUP; - - pi_file *dbFile; - - setDBOpen(false); - - dbFile = pi_file_open( TQFile::encodeName(dbPathName()) ); - if (dbFile == 0L) - { - TQString path = dbPathName(); - DEBUGKPILOT << fname << ": Failed to open " << path << endl; - return; - } - - - PI_SIZE_T size = 0; - void *tmpBuffer; - pi_file_get_info(dbFile, &fDBInfo); - pi_file_get_app_info(dbFile, &tmpBuffer, &size); - fAppLen = size; - fAppInfo = new char[fAppLen]; - memcpy(fAppInfo, tmpBuffer, fAppLen); - - int count; - pi_file_get_entries(dbFile, &count); - if (count >= 0) - { - KPILOT_DELETE(d); - d = new Private(count); - } - - int attr, cat; - recordid_t id; - unsigned int i = 0; - while (pi_file_read_record(dbFile, i, - &tmpBuffer, &size, &attr, &cat, &id) == 0) - { - pi_buffer_t *b = pi_buffer_new(size); - memcpy(b->data,tmpBuffer,size); - b->used = size; - (*d)[i] = new PilotRecord(b, attr, cat, id); - i++; - } - pi_file_close(dbFile); // We done with it once we've read it in. - - KSaveFile::backupFile( dbPathName() ); - - setDBOpen(true); -} - -void PilotLocalDatabase::closeDatabase() -{ - FUNCTIONSETUP; - pi_file *dbFile; - - if (!isOpen()) - { - DEBUGKPILOT << fname << ": Database " << fDBName - << " is not open. Cannot close and write it" - << endl; - return; - } - - TQString newName = dbPathName() + CSL1(".new"); - TQString path = dbPathName(); - DEBUGKPILOT << fname - << ": Creating temp file " << newName - << " for the database file " << path << endl; - - dbFile = pi_file_create(TQFile::encodeName(newName),&fDBInfo); - pi_file_set_app_info(dbFile, fAppInfo, fAppLen); - - for (unsigned int i = 0; i < d->size(); i++) - { - // How did a NULL pointer sneak in here? - if (!(*d)[i]) - { - continue; - } - - if (((*d)[i]->id() == 0) && ((*d)[i]->isDeleted())) - { - // Just ignore it - } - else - { - pi_file_append_record(dbFile, - (*d)[i]->data(), - (*d)[i]->size(), - (*d)[i]->attributes(), (*d)[i]->category(), - (*d)[i]->id()); - } - } - - pi_file_close(dbFile); - TQFile::remove(dbPathName()); - rename((const char *) TQFile::encodeName(newName), - (const char *) TQFile::encodeName(dbPathName())); - setDBOpen(false); -} - - -TQString *PilotLocalDatabase::fPathBase = 0L; - -void PilotLocalDatabase::setDBPath(const TQString &s) -{ - FUNCTIONSETUP; - - DEBUGKPILOT << fname - << ": Setting default DB path to " - << s - << endl; - - if (!fPathBase) - { - fPathBase = new TQString(s); - } - else - { - *fPathBase = s; - } -} - -/* virtual */ PilotDatabase::DBType PilotLocalDatabase::dbType() const -{ - return eLocalDB; -} - - -/* static */ bool PilotLocalDatabase::infoFromFile( const TQString &path, DBInfo *d ) -{ - FUNCTIONSETUP; - - pi_file *f = 0L; - - if (!d) - { - return false; - } - if (!TQFile::exists(path)) - { - return false; - } - - TQCString fileName = TQFile::encodeName( path ); - f = pi_file_open( fileName ); - if (!f) - { - WARNINGKPILOT << "Can't open " << path << endl; - return false; - } - - pi_file_get_info(f,d); - pi_file_close(f); - - return true; -} - |