NS_ASSERTION(len != 0, "no URL"); if (! len) return NS_ERROR_INVALID_ARG;
nsGlobalHistory::AddPage(const char *aURL, const char *aReferrerURL, PRInt64 aDate){  NS_PRECONDITION(aURL != nsnull, "null ptr");  if (! aURL)    return NS_ERROR_NULL_POINTER;  NS_PRECONDITION(mEnv != nsnull, "not initialized");  if (! mEnv)    return NS_ERROR_NOT_INITIALIZED;  NS_PRECONDITION(mStore != nsnull, "not initialized");  if (! mStore)    return NS_ERROR_NOT_INITIALIZED;  nsresult rv;  mdb_err err;  PRInt32 len = PL_strlen(aURL);  mdbYarn yarn = { (void*) aURL, len, len, 0, 0, nsnull };  mdbOid rowId;  nsMdbPtr<nsIMdbRow> row(mEnv);  err = mStore->FindRow(mEnv, kToken_HistoryRowScope, kToken_URLColumn, &yarn,                        &rowId, getter_Acquires(row));  if (err != 0) return NS_ERROR_FAILURE;  // For notifying observers, later...  nsCOMPtr<nsIRDFResource> url;  rv = gRDFService->GetResource(aURL, getter_AddRefs(url));  if (NS_FAILED(rv)) return rv;  nsCOMPtr<nsIRDFDate> date;  rv = gRDFService->GetDateLiteral(aDate, getter_AddRefs(date));  if (NS_FAILED(rv)) return rv;  if (row) {    // Update last visit date. First get the old date so we can update observers...    nsMdbPtr<nsIMdbCell> lastvisitdate(mEnv);    err = row->GetCell(mEnv, kToken_LastVisitDateColumn, getter_Acquires(lastvisitdate));    if (err != 0) return NS_ERROR_FAILURE;    lastvisitdate->AliasYarn(mEnv, &yarn);    PRInt64 oldvalue;    rv = CharsToPRInt64((const char*) yarn.mYarn_Buf, yarn.mYarn_Fill, &oldvalue);    if (NS_FAILED(rv)) return rv;    nsCOMPtr<nsIRDFDate> olddate;    rv = gRDFService->GetDateLiteral(aDate, getter_AddRefs(olddate));    if (NS_FAILED(rv)) return rv;    // ...now set the new date.    char buf[64];    PRInt64ToChars(aDate, buf, sizeof(buf));    yarn.mYarn_Buf = (void*) buf;    yarn.mYarn_Fill = yarn.mYarn_Size = PL_strlen(buf);    err = row->AddColumn(mEnv, kToken_LastVisitDateColumn, &yarn);    if (err != 0) return NS_ERROR_FAILURE;    // Notify observers    rv = NotifyChange(url, kNC_Date, olddate, date);    if (NS_FAILED(rv)) return rv;  }  else {    // Create a new row    rowId.mOid_Scope = kToken_HistoryRowScope;    rowId.mOid_Id    = mdb_id(-1);    err = mTable->NewRow(mEnv, &rowId, getter_Acquires(row));    if (err != 0) return NS_ERROR_FAILURE;    // Set the URL. 'yarn' is already set up to go.    err = row->AddColumn(mEnv, kToken_URLColumn, &yarn);    if (err != 0) return NS_ERROR_FAILURE;    // Set the referrer, if one is provided    if (aReferrerURL) {      len = PL_strlen(aReferrerURL);      yarn.mYarn_Buf  = (void*) aReferrerURL;      yarn.mYarn_Fill = yarn.mYarn_Size = len;      err = row->AddColumn(mEnv, kToken_ReferrerColumn, &yarn);      if (err != 0) return NS_ERROR_FAILURE;      // Notify observers      nsCOMPtr<nsIRDFResource> referrer;      rv = gRDFService->GetResource(aReferrerURL, getter_AddRefs(referrer));      if (NS_FAILED(rv)) return rv;      rv = NotifyAssert(url, kNC_Referrer, referrer);      if (NS_FAILED(rv)) return rv;    }    // Set the date.    char buf[64];    PRInt64ToChars(aDate, buf, sizeof(buf));    yarn.mYarn_Buf = (void*) buf;    yarn.mYarn_Fill = yarn.mYarn_Size = PL_strlen(buf);    err = row->AddColumn(mEnv, kToken_LastVisitDateColumn, &yarn);    if (err != 0) return NS_ERROR_FAILURE;    // Notify observers    rv = NotifyAssert(url, kNC_Date, date);    if (NS_FAILED(rv)) return rv;    rv = NotifyAssert(kNC_HistoryRoot, kNC_child, url);    if (NS_FAILED(rv)) return rv;  }  if (err != 0) return NS_ERROR_FAILURE;  // We'd like to do a "small commit" here, but, unfortunately, we're  // leaking the _entire_ history service :-(. So just do a "large"  // commit for now.  err = mStore->SmallCommit(mEnv);  if (err != 0) return NS_ERROR_FAILURE;#ifdef LEAKING_GLOBAL_HISTORY  {    nsMdbPtr<nsIMdbThumb> thumb(mEnv);    err = mStore->LargeCommit(mEnv, getter_Acquires(thumb));    if (err != 0) return NS_ERROR_FAILURE;    mdb_count total;    mdb_count current;    mdb_bool done;    mdb_bool broken;    do {      err = thumb->DoMore(mEnv, &total, &current, &done, &broken);    } while ((err == 0) && !broken && !done);    if ((err != 0) || !done) return NS_ERROR_FAILURE;  }#endif  return NS_OK;}