From fe7cdbcc7f635c14b4b0aa95e34fbef2d1ceb7f9 Mon Sep 17 00:00:00 2001 From: Chris Frey Date: Thu, 5 Apr 2012 16:13:44 -0400 Subject: [PATCH] Added workaround to Desktop for Tasks database corruption Also added KnownBugs file, to warn of this. Still need to add workarounds for the opensync plugins --- KnownBugs | 22 ++++++++++ desktop/src/Mode_Browse.cc | 101 ++++++++++++++++++++++++++++++++++++--------- desktop/src/Mode_Browse.h | 5 +++ 3 files changed, 108 insertions(+), 20 deletions(-) create mode 100644 KnownBugs diff --git a/KnownBugs b/KnownBugs new file mode 100644 index 00000000..3456e531 --- /dev/null +++ b/KnownBugs @@ -0,0 +1,22 @@ +Tasks database self-corrupts on many devices +-------------------------------------------- + If you extract a Tasks record, and then write it back via + SetRecordByIndex(), on many devices that I tested, it ends up + corrupting the record on the device, and the GUI on the device + appears messed up. (It shows the first few fields twice) + Such a corrupt record also loses the due date. + + This appears to be a bug in the device firmware. + + The workaround, when working with the Tasks database, is to + first DeleteByIndex() and then AddRecord() via the Desktop mode class, + using the same record ID. This works, but is unfortunately + cumbersome. + + See the Desktop GUI and the opensync plugins for examples of this + workaround. + + Ideally, we should test a Tasks sync on Windows, and see how + the Windows software handles this. There may be some protocol + changes that will be needed in future Barry versions. + diff --git a/desktop/src/Mode_Browse.cc b/desktop/src/Mode_Browse.cc index 38380840..8b4b0732 100644 --- a/desktop/src/Mode_Browse.cc +++ b/desktop/src/Mode_Browse.cc @@ -402,38 +402,99 @@ cout << m_state << endl; } } -bool DBCache::Edit(wxWindow *parent, - const Barry::TimeZones &zones, - iterator record) +bool DBCache::OverwriteRecord(wxWindow *parent, iterator record) { - if( record == end() ) + // see if this record has a builder + Barry::Builder *bp = dynamic_cast ((*record).get()); + if( !bp ) return false; - if( (*record)->Edit(parent, true, zones) && (*record)->IsBuildable() ) { - // see if this record has a builder - Barry::Builder *bp = dynamic_cast ((*record).get()); - if( !bp ) +cout << "Changing device record with index: 0x" << hex << (*record)->GetStateIndex() << endl; +cout << m_state << endl; + // update the device with new record data + DesktopInstancePtr dip = m_tdesktop.Get(); + Barry::Mode::Desktop &desktop = dip->Desktop(); +bool iv = Barry::IsVerbose(); +Barry::Verbose(true); + try { + desktop.SetRecord(m_dbid, (*record)->GetStateIndex(), *bp); + } catch( Barry::ReturnCodeError &rce ) { + if( rce.IsReadOnly() ) { + ShowReadOnlyMsg(parent, rce); return false; + } + + throw; + } +Barry::Verbose(iv); + + return true; +} + +bool DBCache::DeleteAndAddRecord(wxWindow *parent, iterator record) +{ + // see if this record has a builder + Barry::Builder *bp = dynamic_cast ((*record).get()); + if( !bp ) + return false; cout << "Changing device record with index: 0x" << hex << (*record)->GetStateIndex() << endl; cout << m_state << endl; - // update the device with new record data - DesktopInstancePtr dip = m_tdesktop.Get(); - Barry::Mode::Desktop &desktop = dip->Desktop(); + // update the device with new record data + DesktopInstancePtr dip = m_tdesktop.Get(); + Barry::Mode::Desktop &desktop = dip->Desktop(); bool iv = Barry::IsVerbose(); Barry::Verbose(true); - try { - desktop.SetRecord(m_dbid, (*record)->GetStateIndex(), *bp); - } catch( Barry::ReturnCodeError &rce ) { - if( rce.IsReadOnly() ) { - ShowReadOnlyMsg(parent, rce); - } - - throw; + try { + desktop.DeleteRecord(m_dbid, (*record)->GetStateIndex()); + desktop.AddRecord(m_dbid, *bp); + } catch( Barry::ReturnCodeError &rce ) { + if( rce.IsReadOnly() ) { + ShowReadOnlyMsg(parent, rce); + return false; } + + throw; + } Barry::Verbose(iv); - return true; + // update our copy of the record state table from device + desktop.GetRecordStateTable(m_dbid, m_state); +cout << m_state << endl; + + // find our record_id in list, to find the state index + IndexType new_index; + if( !m_state.GetIndex((*record)->GetRecordId(), &new_index) ) { + throw std::logic_error("DAA: Need to reconnect for adding a record?"); + } + + // update new state_index in the data cache record + (*record)->SetIds(new_index, (*record)->GetRecordId()); + + return true; +} + +bool DBCache::Edit(wxWindow *parent, + const Barry::TimeZones &zones, + iterator record) +{ + if( record == end() ) + return false; + + if( (*record)->Edit(parent, true, zones) && (*record)->IsBuildable() ) { + // see if this record is part of the Tasks database + RecordCache *tp = dynamic_cast< RecordCache*> ((*record).get()); + + if( tp ) { + // yes, it is... the Tasks database has a bug + // so we need to "edit" by deleting and adding + // the record again + return DeleteAndAddRecord(parent, record); + } + else { + // use the normal code for all other records + return OverwriteRecord(parent, record); + } } else { return false; diff --git a/desktop/src/Mode_Browse.h b/desktop/src/Mode_Browse.h index 29b82450..4fbf494b 100644 --- a/desktop/src/Mode_Browse.h +++ b/desktop/src/Mode_Browse.h @@ -315,6 +315,11 @@ private: // per-record load state IndexType m_index; +protected: + // helper functions, to work around Tasks bug in device + bool OverwriteRecord(wxWindow *parent, iterator record); + bool DeleteAndAddRecord(wxWindow *parent, iterator record); + public: // loads records in constructor DBCache(ThreadableDesktop &tdesktop, const std::string &dbname); -- 2.11.4.GIT