Closed
Bug 164970
Opened 24 years ago
Closed 23 years ago
track AB cards deleted and save lastUpdatedTimeStamp for Palm sync
Categories
(MailNews Core Graveyard :: Palm Sync, defect)
Tracking
(Not tracked)
VERIFIED
FIXED
mozilla1.2beta
People
(Reporter: rdayal, Assigned: srilatha)
References
Details
Attachments
(1 file, 6 obsolete files)
|
18.81 KB,
patch
|
Bienvenu
:
superreview+
|
Details | Diff | Splinter Review |
Implement code to save basic information (name fields and deleted timestamp) for
cards deleted in an AB.
Mork allows to create multiple tables in a mork DB, this should be implemented
as a "deleted" table in the mork DB. A method to get a list of deleted cards
should be provided. The lastUpdatedTimeStamp field in nsIAbCard should be filled
with the timestamp when deletion happened.
Also in the AB code whenever cards are modified, the lastUpdatedTimeStamp should
be saved. However, The lastUpdatedTimeStamp should NOT be saved when new cards
are created.
| Reporter | ||
Comment 1•24 years ago
|
||
Also please make sure to add a function to get the deleted cards count. Below is
simple implementation for it:
NS_IMETHODIMP nsAddrDatabase::GetDeletedCardCount(PRUint32 *count)
{
mdb_err rv;
mdb_count c;
rv = m_mdbPalmTable->GetCount(m_mdbEnv, &c);
if (rv == NS_OK)
*count = c - 1; // Don't count LastRecordKey
return rv;
}
Please test it and make sure that it returns the correct count.
| Assignee | ||
Comment 2•24 years ago
|
||
| Reporter | ||
Comment 3•24 years ago
|
||
In the deleted cards we need to store the Palm Record Id / Remote AB Record Id.
When the GetDeletedCards function is called this Id is returned as a separate
attribute of the card. We do similiar thing for storing _DN for ldap and
_screenname for AIM using the GetStringAttribute method of the nsAbCardProperty.
Please do the same for storing the palm record id. Please define a new method
for setting int attribute for a card and use it in the nsAbAddrDatabase code to
set and get Palm/Remote record ids.
Also like you have done in DeleteCard method you need to modify EditCard method
to store the lastUpdatedTimeStamp so that it is stored every time a card is
edited even if it is not called from the UI.
| Reporter | ||
Comment 4•24 years ago
|
||
One more change about naming, instead of calling Palm table call it deletedCard
table. And instead of Palm Record Id call Remote AB Id since it could be re-used
for sync with other remote ABs. Leave the nsDirPrefs as it is here since those
prefs are specific for Palm sync.
| Reporter | ||
Comment 5•24 years ago
|
||
In the GetDeletedCardCount please add the check for m_mdbPalmTable being valid.
| Assignee | ||
Comment 6•24 years ago
|
||
updated the patch after talking to rajiv.
1) changed the name from palm table to deletedcards table
2) saving the palm record id for each card in the deleted cards table
3) setting the palm record id for each deleted card in GetDeletedCardList()
I am still doing some more testing. will post comments once I am done with it.
Attachment #96928 -
Attachment is obsolete: true
| Reporter | ||
Comment 7•24 years ago
|
||
+nsresult nsAddrDatabase::AddRowToDeletedCardsTable(nsIAbCard *card
+ PRUint32 lastModDate = 0;
+ card->GetLastModifiedDate(&lastModDate);
+ AddIntColumn(cardRow, m_LastModDateColumnToken, lastModDate);
+ NS_RELEASE(cardRow);
In the function above u need to set the last modified date as the time when the
card was deleted which is the present time, use PR_Now and set the
lastModifiedDate here.
Same way in the "nsAddrDatabase::EditCard" function use PR_Now and set the last
modified date for the card passed in as the time the card was edited.
+ server->PalmCategoryId = DIR_GetIntPref (prefstring, "PalmCategoryId",
tempstring, 0);
+ DIR_SetIntPref (prefstring, "PalmCategoryId", tempstring,
server->PalmCategoryId, 0);
Use the last parameter as -1 above which is the default value for PalmCategoryId.
| Assignee | ||
Comment 8•24 years ago
|
||
updated patch addressing Rajiv's comments.
Attachment #97860 -
Attachment is obsolete: true
| Reporter | ||
Comment 9•24 years ago
|
||
During LDAP replication, and also now Palm sync, for entries that are modified
we in fact delete the existing card and then add the modified card. This is done
because information about what fields are modified is not known. This leads to a
problem, since we keep a record for deleted entries we record this deletion too
which in fact is for modification. Thus if say, a Palm record has been modified
and synced earlier and then a Palm sync is done again the earlier modified
record might be deleted resulting into loss of the record!
Thus it makes sense that such deletions done for modifications are not recorded.
Hence we should keep a record of only those deleted entries that are deleted
from the UI by the user. This will lead to some entries deleted in LDAP being
not deleted on Palm (if the replicated LDAP AB has synced on to Palm) but that
still is better than loss of entries as mentioned in above para.
| Reporter | ||
Comment 10•24 years ago
|
||
I guess there is another alternative, just modify all the fields of the existing
card with the values in the modified card. However we will need to change the
LDAP replication too where deleting and adding card on the client side works
just fine since it is a one way sync. Anyway, I think this strategy is better
... so please keep the delete code as it is. We can file a bug for LDAP code to
change it to do as mentioned here.
| Reporter | ||
Comment 11•23 years ago
|
||
1) @@ -87,6 +91,7 @@
const char *kLowerListNameColumn = "LowercaseListName";
struct mdbOid gAddressBookTableOID;
+struct mdbOid deletedCardsTableOID;
What is the need for this variable to be global? Please make it a local variable
in the function nsAddrDatabase::InitDeletedCardsTable() you are using it.
2) Instead of doing this:
+ nsresult err;
+ if (!m_mdbDeletedCardsTable)
+ err = InitDeletedCardsTable();
+ else
+ err = NS_OK;
+ if (NS_SUCCEEDED(err)) {
just do this:
nsresult err = NS_OK;
if (!m_mdbDeletedCardsTable)
err = InitDeletedCardsTable();
if (NS_SUCCEEDED(err)) {
3) Here:
+ nsIMdbStore *store = GetStore();
+ deletedCardsTableOID.mOid_Scope = m_CardRowScopeToken;
+ deletedCardsTableOID.mOid_Id = ID_DELETEDCARDS_TABLE;
+
+ nsresult err = GetStore()->GetTable(GetEnv(), &deletedCardsTableOID,
&m_mdbDeletedCardsTable);
what if GetStore() returns null here. Use the 'store' variable you have defined
above and check that GetStore() did not return null.
4)
+ mdb_err mdberr = (nsresult) store->NewTableWithOid(GetEnv(),
&deletedCardsTableOID,
Here too make sure that 'store' is not null. If you check immediately after
+ nsIMdbStore *store = GetStore();
you will not have to do it everytime you use 'store' variable.
5) Here:
+NS_IMETHODIMP nsAddrDatabase::GetDeletedCardList(PRUint32 *aCount,
nsISupportsArray **aDeletedList)
+{
+ nsresult rv;
+ nsISupportsArray *result;
+ rv = NS_NewISupportsArray(&result);
+ if (NS_FAILED(rv)) return rv;
+ if (!result)
+ return NS_ERROR_OUT_OF_MEMORY;
+ *aCount = 0;
+ if (m_mdbDeletedCardsTable)
+ {
it is most likely that m_mdbDeletedCardsTable is null, unless the same
nsIAddrDatabase object is used to delete a card and make this GetDeletedCardList
function call, a case which i guess will never happen. So do this:
Add these lines:
+ if (!m_mdbDeletedCardsTable) {
+ struct mdbOid deletedCardsTableOID;
+ deletedCardsTableOID.mOid_Scope = m_CardRowScopeToken;
+ deletedCardsTableOID.mOid_Id = ID_DELETEDCARDS_TABLE;
+ nsIMdbStore *store = GetStore();
+ if(store)
+ store->GetTable(GetEnv(), &deletedCardsTableOID, &m_mdbDeletedCardsTable);
+ }
before this code chunk above:
+ *aCount = 0;
+ if (m_mdbDeletedCardsTable)
+ {
I have tested and made sure that this works fine.
6) Do the same as in 5 for the
+NS_IMETHODIMP nsAddrDatabase::GetDeletedCardCount(PRUint32 *count)
+{
+ if (m_mdbDeletedCardsTable) {
7) In DirPrefs:
+ /* fields for palm Sync */
+ PRUint32 PalmCategoryId;
donot define PalmCategoryId as unsigned int. It takes value -1.
| Reporter | ||
Comment 12•23 years ago
|
||
Better, for 5) and 6) above make those lines as separate function, modify the
InitDeletedCardsTable() such that it takes a boolean isCreate which if not set,
return the existing table, and if set, create a new table if one doesnot exist.
| Assignee | ||
Comment 13•23 years ago
|
||
Attachment #98050 -
Attachment is obsolete: true
| Reporter | ||
Comment 14•23 years ago
|
||
The changes to nsDirPrefs for saving PalmCategoryId to prefs.js still doesnot
initialize it properly to -1 which leads to problems during sync. Passing -1 as
the default value to DIR_SetIntPref / DIR_GetIntPref is not enogh. You will have
to initialize the PalmCategoryId field of the DIR_Server struct whenever a new
server is created or loaded.
In the function DIR_InitServer (DIR_Server *server):
// initialize the palm category
server->PalmCategoryId = -1;
Do this change and you have r=rdayal. But definitly do this change or else sync
will not work.
David would be the best person to super review this (lot of Mork usage).
| Assignee | ||
Comment 15•23 years ago
|
||
| Reporter | ||
Updated•23 years ago
|
Attachment #101466 -
Flags: review+
Comment 16•23 years ago
|
||
using comptrs makes the code a lot less fragile. It makes it so someone can't
come along and stick a return in the middle of your method and cause lots of
memory leaks.
use nsCOMPtrs for nsIMdbRows, e.g., here:
nsresult nsAddrDatabase::AddRowToDeletedCardsTable(nsIAbCard *card, nsIMdbRow
**pCardRow)
+{
+ nsresult err=NS_OK;
+ if (!m_mdbDeletedCardsTable)
+ err = InitDeletedCardsTable(PR_TRUE);
++ if (NS_SUCCEEDED(err)) {
+ nsIMdbRow *cardRow;
+ err = GetNewRow(&cardRow);
and, do an addref here:
+ *pCardRow = cardRow;
+ }
e.g., NS_IF_ADDREF(*pCardRow = cardRow);
you can use a comptr here too:
+ if (m_mdbDeletedCardsTable)
+ {
+ nsIMdbTableRowCursor* rowCursor = nsnull;
+ mdb_pos rowPos;
+ PRBool done = PR_FALSE;
+
and here:
+ nsISupportsArray *result;
+ nsresult rv = NS_NewISupportsArray(&result);
and then do an NS_IF_ADDREF(*aDeletedList = result);
here, why not just:
InitDeletedCardsTable()
if (m_mdbDeletedCardsTable)
return m_mdbDeletedCardsTable->GetCount(m_mdbEnv, count);
instead of all this:
+ InitDeletedCardsTable();
+ if (m_mdbDeletedCardsTable) {
+ mdb_err rv;
+ mdb_count c;
+ rv = m_mdbDeletedCardsTable->GetCount(m_mdbEnv, &c);
+ if (rv == NS_OK)
+ *count = c;
+
+ return rv;
+ }
no need for extra braces here:
+ PRUint32 lastModDate = 0;
+ err = GetIntColumn(cardRow, m_LastModDateColumnToken, &lastModDate, 0);
+ if (NS_SUCCEEDED(err))
+ {
+ newCard->SetLastModifiedDate(lastModDate);
+ }
+
And finally, when does the deleted cards table get cleared out/cleaned up?
| Reporter | ||
Comment 17•23 years ago
|
||
Hi David,
Currently purging of cards from the deleted table does not happen. There is a
function DeleteRowFromDeletedCardsTable(cardRow) which can be called from a
purge routine. What do you suggest would be the best place to get it called
from. What if from nsAddrDatabase::CloseMDB a purge routine is called which
removes all rows in the deleted table older than 6 months from PR_Now()? thanks.
| Reporter | ||
Comment 18•23 years ago
|
||
I would be taking care of the super review comments since Srilatha is not
available to take care of this bug.
I think it is better to call the purge routine from AddRowToDeletedCardsTable()
which is called everytime a card is deleted, instead of from the CloseMDB
function. This way everytime the DB is closed, irrespective of whether any data
is updated or not, there would not be the overhead of the purge routine, rather
it is called everytime a new record is added to the deleted table, i.e a card is
deleted from the database.
| Reporter | ||
Comment 19•23 years ago
|
||
Attachment #101323 -
Attachment is obsolete: true
| Reporter | ||
Updated•23 years ago
|
Attachment #101466 -
Attachment is obsolete: true
| Reporter | ||
Comment 20•23 years ago
|
||
Hi David,
Can u please super review this patch, thanks.
Comment 21•23 years ago
|
||
+ nsresult rv = NS_NewISupportsArray(getter_AddRefs(result));
+ if (NS_FAILED(rv)) return rv;
+ if (!result)
+ return NS_ERROR_OUT_OF_MEMORY;
you don't need to check result, rv succeeding is sufficient, I believe - the
other check is just a little bit of code bloat.
could you call result something more descriptive, like resultCardArray? It makes
the code easier to understand.
+NS_IMETHODIMP nsAddrDatabase::GetDeletedCardList(PRUint32 *aCount,
nsISupportsArray **aDeletedList)
+ nsCOMPtr<nsISupportsArray> result;
+ nsresult rv = NS_NewISupportsArray(getter_AddRefs(result));
+ if (NS_FAILED(rv)) return rv;
+ if (!result)
+ return NS_ERROR_OUT_OF_MEMORY;
"c" is not a good var name. cardCount would make the code easier to read.
+ if (m_mdbDeletedCardsTable) {
+ mdb_count c=0;
+ // if not too many cards let it be
+ m_mdbDeletedCardsTable->GetCount(m_mdbEnv, &c);
+ if(c < PURGE_CUTOFF_COUNT)
+ return NS_OK;
indentation here is inconsistent: tabs?
+ NS_IMETHOD GetDeletedCardList(PRUint32 *aCount, nsISupportsArray
**aDeletedList);
+ NS_IMETHOD GetDeletedCardCount(PRUint32 *count);
+ NS_IMETHOD PurgeDeletedCardTable();
+
+NS_IMETHODIMP nsAddrDatabase::PurgeDeletedCardTable()
this routine doesn't seem to use the strategy we talked about over aim - if a
card was deleted less than six months ago, then we know all the following cards
were deleted less than six months ago, and we can break out of the loop, right?
This will make it much less onerous to call this routine multiple times, e.g.,
when the user deletes 10 cards at a time...
| Reporter | ||
Comment 22•23 years ago
|
||
Attachment #101880 -
Attachment is obsolete: true
Comment 23•23 years ago
|
||
Comment on attachment 102039 [details] [diff] [review]
updated patch
sr=bienvenu
Attachment #102039 -
Flags: superreview+
| Reporter | ||
Comment 24•23 years ago
|
||
thanks David.
| Reporter | ||
Comment 25•23 years ago
|
||
I have checked in the code, marking it as fixed.
Also this has been QA by Gregg Meehan, changing QA contact to him.
Status: NEW → RESOLVED
Closed: 23 years ago
QA Contact: nbaca → meehansqa
Resolution: --- → FIXED
Target Milestone: --- → mozilla1.2beta
| Reporter | ||
Updated•23 years ago
|
Component: Address Book → Palm Sync
Comment 26•23 years ago
|
||
Trunk build 2003-02-20: WinXP
Verified Fixed. This has been fixed for awhile.
Status: RESOLVED → VERIFIED
Updated•21 years ago
|
Product: MailNews → Core
Updated•18 years ago
|
Product: Core → MailNews Core
You need to log in
before you can comment on or make changes to this bug.
Description
•