Revision control

Copy as Markdown

Other Tools

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "msgCore.h"
#include "nsDBFolderInfo.h"
#include "nsMsgDatabase.h"
#include "nsMsgFolderFlags.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefLocalizedString.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
#include "nsIMsgDBView.h"
#include "nsServiceManagerUtils.h"
#include "nsImapCore.h"
static const char* kDBFolderInfoScope = "ns:msg:db:row:scope:dbfolderinfo:all";
static const char* kDBFolderInfoTableKind = "ns:msg:db:table:kind:dbfolderinfo";
struct mdbOid gDBFolderInfoOID;
static const char* kNumMessagesColumnName = "numMsgs";
// have to leave this as numNewMsgs even though it's numUnread Msgs
static const char* kNumUnreadMessagesColumnName = "numNewMsgs";
static const char* kFlagsColumnName = "flags";
static const char* kFolderSizeColumnName = "folderSize";
static const char* kExpungedBytesColumnName = "expungedBytes";
static const char* kFolderDateColumnName = "folderDate";
static const char* kHighWaterMessageKeyColumnName = "highWaterKey";
static const char* kImapUidValidityColumnName = "UIDValidity";
static const char* kTotalPendingMessagesColumnName = "totPendingMsgs";
static const char* kUnreadPendingMessagesColumnName = "unreadPendingMsgs";
static const char* kMailboxNameColumnName = "mailboxName";
static const char* kKnownArtsSetColumnName = "knownArts";
static const char* kExpiredMarkColumnName = "expiredMark";
static const char* kVersionColumnName = "version";
static const char* kLocaleColumnName = "locale";
NS_IMPL_ADDREF(nsDBFolderInfo)
NS_IMPL_RELEASE(nsDBFolderInfo)
NS_IMETHODIMP
nsDBFolderInfo::QueryInterface(REFNSIID iid, void** result) {
if (!result) return NS_ERROR_NULL_POINTER;
*result = nullptr;
if (iid.Equals(NS_GET_IID(nsIDBFolderInfo)) ||
iid.Equals(NS_GET_IID(nsISupports))) {
*result = static_cast<nsIDBFolderInfo*>(this);
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
nsDBFolderInfo::nsDBFolderInfo(nsMsgDatabase* mdb)
: m_flags(0),
m_expiredMark(0),
m_tableKindToken(0),
m_expiredMarkColumnToken(0) {
m_mdbTable = NULL;
m_mdbRow = NULL;
m_version = 1; // for upgrading...
m_IMAPHierarchySeparator = 0; // imap path separator
// mail only (for now)
m_folderSize = 0;
m_folderDate = 0;
m_expungedBytes = 0; // sum of size of deleted messages in folder
m_highWaterMessageKey = 0;
m_numUnreadMessages = 0;
m_numMessages = 0;
// IMAP only
m_ImapUidValidity = kUidUnknown;
m_totalPendingMessages = 0;
m_unreadPendingMessages = 0;
m_mdbTokensInitialized = false;
m_mdb = mdb;
if (mdb) {
nsresult err;
err = m_mdb->GetStore()->StringToToken(mdb->GetEnv(), kDBFolderInfoScope,
&m_rowScopeToken);
if (NS_SUCCEEDED(err)) {
err = m_mdb->GetStore()->StringToToken(
mdb->GetEnv(), kDBFolderInfoTableKind, &m_tableKindToken);
if (NS_SUCCEEDED(err)) {
gDBFolderInfoOID.mOid_Scope = m_rowScopeToken;
gDBFolderInfoOID.mOid_Id = 1;
}
}
InitMDBInfo();
}
}
nsDBFolderInfo::~nsDBFolderInfo() {
// nsMsgDatabase strictly owns nsDBFolderInfo, so don't ref-count db.
ReleaseExternalReferences();
}
// Release any objects we're holding onto. This needs to be safe
// to call multiple times.
void nsDBFolderInfo::ReleaseExternalReferences() {
if (m_mdb) {
if (m_mdbTable) {
NS_RELEASE(m_mdbTable);
m_mdbTable = nullptr;
}
if (m_mdbRow) {
NS_RELEASE(m_mdbRow);
m_mdbRow = nullptr;
}
m_mdb = nullptr;
}
}
// this routine sets up a new db to know about the dbFolderInfo stuff...
nsresult nsDBFolderInfo::AddToNewMDB() {
nsresult ret = NS_OK;
if (m_mdb && m_mdb->GetStore()) {
nsIMdbStore* store = m_mdb->GetStore();
// create the unique table for the dbFolderInfo.
nsresult err =
store->NewTable(m_mdb->GetEnv(), m_rowScopeToken, m_tableKindToken,
true, nullptr, &m_mdbTable);
// create the singleton row for the dbFolderInfo.
err = store->NewRowWithOid(m_mdb->GetEnv(), &gDBFolderInfoOID, &m_mdbRow);
// add the row to the singleton table.
if (m_mdbRow && NS_SUCCEEDED(err))
err = m_mdbTable->AddRow(m_mdb->GetEnv(), m_mdbRow);
ret = err; // what are we going to do about nsresult's?
}
return ret;
}
nsresult nsDBFolderInfo::InitFromExistingDB() {
nsresult ret = NS_OK;
if (m_mdb && m_mdb->GetStore()) {
nsIMdbStore* store = m_mdb->GetStore();
if (store) {
mdb_pos rowPos;
mdb_count outTableCount; // current number of such tables
mdb_bool mustBeUnique; // whether port can hold only one of these
mdb_bool hasOid;
ret = store->GetTableKind(m_mdb->GetEnv(), m_rowScopeToken,
m_tableKindToken, &outTableCount, &mustBeUnique,
&m_mdbTable);
// NS_ASSERTION(mustBeUnique && outTableCount == 1, "only one global db
// info allowed");
if (m_mdbTable) {
// find singleton row for global info.
ret = m_mdbTable->HasOid(m_mdb->GetEnv(), &gDBFolderInfoOID, &hasOid);
if (NS_SUCCEEDED(ret)) {
nsIMdbTableRowCursor* rowCursor;
rowPos = -1;
ret = m_mdbTable->GetTableRowCursor(m_mdb->GetEnv(), rowPos,
&rowCursor);
if (NS_SUCCEEDED(ret)) {
ret = rowCursor->NextRow(m_mdb->GetEnv(), &m_mdbRow, &rowPos);
NS_RELEASE(rowCursor);
if (!m_mdbRow) ret = NS_ERROR_FAILURE;
if (NS_SUCCEEDED(ret)) LoadMemberVariables();
}
}
} else
ret = NS_ERROR_FAILURE;
}
}
return ret;
}
nsresult nsDBFolderInfo::InitMDBInfo() {
nsresult ret = NS_OK;
if (!m_mdbTokensInitialized && m_mdb && m_mdb->GetStore()) {
nsIMdbStore* store = m_mdb->GetStore();
nsIMdbEnv* env = m_mdb->GetEnv();
store->StringToToken(env, kNumMessagesColumnName,
&m_numMessagesColumnToken);
store->StringToToken(env, kNumUnreadMessagesColumnName,
&m_numUnreadMessagesColumnToken);
store->StringToToken(env, kFlagsColumnName, &m_flagsColumnToken);
store->StringToToken(env, kFolderSizeColumnName, &m_folderSizeColumnToken);
store->StringToToken(env, kExpungedBytesColumnName,
&m_expungedBytesColumnToken);
store->StringToToken(env, kFolderDateColumnName, &m_folderDateColumnToken);
store->StringToToken(env, kHighWaterMessageKeyColumnName,
&m_highWaterMessageKeyColumnToken);
store->StringToToken(env, kMailboxNameColumnName,
&m_mailboxNameColumnToken);
store->StringToToken(env, kImapUidValidityColumnName,
&m_imapUidValidityColumnToken);
store->StringToToken(env, kTotalPendingMessagesColumnName,
&m_totalPendingMessagesColumnToken);
store->StringToToken(env, kUnreadPendingMessagesColumnName,
&m_unreadPendingMessagesColumnToken);
store->StringToToken(env, kExpiredMarkColumnName,
&m_expiredMarkColumnToken);
store->StringToToken(env, kVersionColumnName, &m_versionColumnToken);
m_mdbTokensInitialized = true;
}
return ret;
}
nsresult nsDBFolderInfo::LoadMemberVariables() {
// it's really not an error for these properties to not exist...
GetInt32PropertyWithToken(m_numMessagesColumnToken, m_numMessages);
GetInt32PropertyWithToken(m_numUnreadMessagesColumnToken,
m_numUnreadMessages);
GetInt32PropertyWithToken(m_flagsColumnToken, m_flags);
GetInt64PropertyWithToken(m_folderSizeColumnToken, m_folderSize);
GetUint32PropertyWithToken(m_folderDateColumnToken, m_folderDate);
GetInt32PropertyWithToken(m_imapUidValidityColumnToken, m_ImapUidValidity,
kUidUnknown);
GetUint32PropertyWithToken(m_expiredMarkColumnToken, m_expiredMark);
GetInt64PropertyWithToken(m_expungedBytesColumnToken, m_expungedBytes);
GetUint32PropertyWithToken(m_highWaterMessageKeyColumnToken,
m_highWaterMessageKey);
int32_t version;
GetInt32PropertyWithToken(m_versionColumnToken, version);
m_version = (uint16_t)version;
return NS_OK;
}
NS_IMETHODIMP nsDBFolderInfo::SetVersion(uint32_t version) {
m_version = version;
return SetUint32PropertyWithToken(m_versionColumnToken, (uint32_t)m_version);
}
NS_IMETHODIMP nsDBFolderInfo::GetVersion(uint32_t* version) {
*version = m_version;
return NS_OK;
}
nsresult nsDBFolderInfo::AdjustHighWater(nsMsgKey highWater, bool force) {
if (force || m_highWaterMessageKey < highWater) {
m_highWaterMessageKey = highWater;
SetUint32PropertyWithToken(m_highWaterMessageKeyColumnToken, highWater);
}
return NS_OK;
}
NS_IMETHODIMP nsDBFolderInfo::SetHighWater(nsMsgKey highWater) {
return AdjustHighWater(highWater, true);
}
NS_IMETHODIMP nsDBFolderInfo::OnKeyAdded(nsMsgKey aNewKey) {
return AdjustHighWater(aNewKey, false);
}
NS_IMETHODIMP
nsDBFolderInfo::GetFolderSize(int64_t* size) {
NS_ENSURE_ARG_POINTER(size);
*size = m_folderSize;
return NS_OK;
}
NS_IMETHODIMP nsDBFolderInfo::SetFolderSize(int64_t size) {
m_folderSize = size;
return SetInt64Property(kFolderSizeColumnName, m_folderSize);
}
NS_IMETHODIMP
nsDBFolderInfo::GetFolderDate(uint32_t* folderDate) {
NS_ENSURE_ARG_POINTER(folderDate);
*folderDate = m_folderDate;
return NS_OK;
}
NS_IMETHODIMP nsDBFolderInfo::SetFolderDate(uint32_t folderDate) {
m_folderDate = folderDate;
return SetUint32PropertyWithToken(m_folderDateColumnToken, folderDate);
}
NS_IMETHODIMP nsDBFolderInfo::GetHighWater(nsMsgKey* result) {
// Sanity check highwater - if it gets too big, other code
// can fail. Look through last 100 messages to recalculate
// the highwater mark.
*result = m_highWaterMessageKey;
if (m_highWaterMessageKey > 0xFFFFFF00 && m_mdb) {
nsCOMPtr<nsIMsgEnumerator> hdrs;
nsresult rv = m_mdb->ReverseEnumerateMessages(getter_AddRefs(hdrs));
if (NS_FAILED(rv)) return rv;
bool hasMore = false;
nsCOMPtr<nsIMsgDBHdr> pHeader;
nsMsgKey recalculatedHighWater = 1;
int32_t i = 0;
while (i++ < 100 && NS_SUCCEEDED(rv = hdrs->HasMoreElements(&hasMore)) &&
hasMore) {
(void)hdrs->GetNext(getter_AddRefs(pHeader));
if (pHeader) {
nsMsgKey msgKey;
pHeader->GetMessageKey(&msgKey);
if (msgKey > recalculatedHighWater) recalculatedHighWater = msgKey;
}
}
NS_ASSERTION(m_highWaterMessageKey >= recalculatedHighWater,
"highwater incorrect");
m_highWaterMessageKey = recalculatedHighWater;
}
*result = m_highWaterMessageKey;
return NS_OK;
}
NS_IMETHODIMP nsDBFolderInfo::SetExpiredMark(nsMsgKey expiredKey) {
m_expiredMark = expiredKey;
return SetUint32PropertyWithToken(m_expiredMarkColumnToken, expiredKey);
}
NS_IMETHODIMP nsDBFolderInfo::GetExpiredMark(nsMsgKey* result) {
*result = m_expiredMark;
return NS_OK;
}
// The size of the argument depends on the maximum size of a single message
NS_IMETHODIMP nsDBFolderInfo::ChangeExpungedBytes(int32_t delta) {
return SetExpungedBytes(m_expungedBytes + delta);
}
NS_IMETHODIMP nsDBFolderInfo::SetMailboxName(const nsAString& newBoxName) {
return SetPropertyWithToken(m_mailboxNameColumnToken, newBoxName);
}
NS_IMETHODIMP nsDBFolderInfo::GetMailboxName(nsAString& boxName) {
return GetPropertyWithToken(m_mailboxNameColumnToken, boxName);
}
NS_IMETHODIMP nsDBFolderInfo::ChangeNumUnreadMessages(int32_t delta) {
m_numUnreadMessages += delta;
// m_numUnreadMessages can never be set to negative.
if (m_numUnreadMessages < 0) {
#ifdef DEBUG_bienvenu1
NS_ASSERTION(false, "Hardcoded assertion");
#endif
m_numUnreadMessages = 0;
}
return SetUint32PropertyWithToken(m_numUnreadMessagesColumnToken,
m_numUnreadMessages);
}
NS_IMETHODIMP nsDBFolderInfo::ChangeNumMessages(int32_t delta) {
m_numMessages += delta;
// m_numMessages can never be set to negative.
if (m_numMessages < 0) {
#ifdef DEBUG_bienvenu
NS_ASSERTION(false, "num messages can't be < 0");
#endif
m_numMessages = 0;
}
return SetUint32PropertyWithToken(m_numMessagesColumnToken, m_numMessages);
}
NS_IMETHODIMP nsDBFolderInfo::GetNumUnreadMessages(int32_t* result) {
*result = m_numUnreadMessages;
return NS_OK;
}
NS_IMETHODIMP nsDBFolderInfo::SetNumUnreadMessages(int32_t numUnreadMessages) {
m_numUnreadMessages = numUnreadMessages;
return SetUint32PropertyWithToken(m_numUnreadMessagesColumnToken,
m_numUnreadMessages);
}
NS_IMETHODIMP nsDBFolderInfo::GetNumMessages(int32_t* result) {
*result = m_numMessages;
return NS_OK;
}
NS_IMETHODIMP nsDBFolderInfo::SetNumMessages(int32_t numMessages) {
m_numMessages = numMessages;
return SetUint32PropertyWithToken(m_numMessagesColumnToken, m_numMessages);
}
NS_IMETHODIMP nsDBFolderInfo::GetExpungedBytes(int64_t* result) {
*result = m_expungedBytes;
return NS_OK;
}
NS_IMETHODIMP nsDBFolderInfo::SetExpungedBytes(int64_t expungedBytes) {
m_expungedBytes = expungedBytes;
return SetInt64PropertyWithToken(m_expungedBytesColumnToken, m_expungedBytes);
}
NS_IMETHODIMP nsDBFolderInfo::GetFlags(int32_t* result) {
*result = m_flags;
return NS_OK;
}
NS_IMETHODIMP nsDBFolderInfo::SetFlags(int32_t flags) {
nsresult ret = NS_OK;
if (m_flags != flags) {
NS_ASSERTION((m_flags & nsMsgFolderFlags::Inbox) == 0 ||
(flags & nsMsgFolderFlags::Inbox) != 0,
"lost inbox flag");
m_flags = flags;
ret = SetInt32PropertyWithToken(m_flagsColumnToken, m_flags);
}
return ret;
}
NS_IMETHODIMP nsDBFolderInfo::OrFlags(int32_t flags, int32_t* result) {
m_flags |= flags;
*result = m_flags;
return SetInt32PropertyWithToken(m_flagsColumnToken, m_flags);
}
NS_IMETHODIMP nsDBFolderInfo::AndFlags(int32_t flags, int32_t* result) {
m_flags &= flags;
*result = m_flags;
return SetInt32PropertyWithToken(m_flagsColumnToken, m_flags);
}
NS_IMETHODIMP nsDBFolderInfo::GetImapUidValidity(int32_t* result) {
*result = m_ImapUidValidity;
return NS_OK;
}
NS_IMETHODIMP nsDBFolderInfo::SetImapUidValidity(int32_t uidValidity) {
m_ImapUidValidity = uidValidity;
return SetUint32PropertyWithToken(m_imapUidValidityColumnToken,
m_ImapUidValidity);
}
bool nsDBFolderInfo::TestFlag(int32_t flags) { return (m_flags & flags) != 0; }
NS_IMETHODIMP
nsDBFolderInfo::GetLocale(nsAString& result) {
GetProperty(kLocaleColumnName, result);
return NS_OK;
}
NS_IMETHODIMP nsDBFolderInfo::SetLocale(const nsAString& locale) {
return SetProperty(kLocaleColumnName, locale);
}
NS_IMETHODIMP
nsDBFolderInfo::GetImapTotalPendingMessages(int32_t* result) {
NS_ENSURE_ARG_POINTER(result);
*result = m_totalPendingMessages;
return NS_OK;
}
void nsDBFolderInfo::ChangeImapTotalPendingMessages(int32_t delta) {
m_totalPendingMessages += delta;
SetInt32PropertyWithToken(m_totalPendingMessagesColumnToken,
m_totalPendingMessages);
}
NS_IMETHODIMP
nsDBFolderInfo::GetImapUnreadPendingMessages(int32_t* result) {
NS_ENSURE_ARG_POINTER(result);
*result = m_unreadPendingMessages;
return NS_OK;
}
NS_IMETHODIMP nsDBFolderInfo::SetImapUnreadPendingMessages(
int32_t numUnreadPendingMessages) {
m_unreadPendingMessages = numUnreadPendingMessages;
return SetUint32PropertyWithToken(m_unreadPendingMessagesColumnToken,
m_unreadPendingMessages);
}
NS_IMETHODIMP nsDBFolderInfo::SetImapTotalPendingMessages(
int32_t numTotalPendingMessages) {
m_totalPendingMessages = numTotalPendingMessages;
return SetUint32PropertyWithToken(m_totalPendingMessagesColumnToken,
m_totalPendingMessages);
}
void nsDBFolderInfo::ChangeImapUnreadPendingMessages(int32_t delta) {
m_unreadPendingMessages += delta;
SetInt32PropertyWithToken(m_unreadPendingMessagesColumnToken,
m_unreadPendingMessages);
}
/* attribute nsMsgViewTypeValue viewType; */
NS_IMETHODIMP nsDBFolderInfo::GetViewType(nsMsgViewTypeValue* aViewType) {
uint32_t viewTypeValue;
nsresult rv = GetUint32Property("viewType", nsMsgViewType::eShowAllThreads,
&viewTypeValue);
*aViewType = viewTypeValue;
return rv;
}
NS_IMETHODIMP nsDBFolderInfo::SetViewType(nsMsgViewTypeValue aViewType) {
return SetUint32Property("viewType", aViewType);
}
/* attribute nsMsgViewFlagsTypeValue viewFlags; */
NS_IMETHODIMP nsDBFolderInfo::GetViewFlags(
nsMsgViewFlagsTypeValue* aViewFlags) {
nsMsgViewFlagsTypeValue defaultViewFlags;
nsresult rv = m_mdb->GetDefaultViewFlags(&defaultViewFlags);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t viewFlagsValue;
rv = GetUint32Property("viewFlags", defaultViewFlags, &viewFlagsValue);
*aViewFlags = viewFlagsValue;
return rv;
}
NS_IMETHODIMP nsDBFolderInfo::SetViewFlags(nsMsgViewFlagsTypeValue aViewFlags) {
return SetUint32Property("viewFlags", aViewFlags);
}
/* attribute nsMsgViewSortTypeValue sortType; */
NS_IMETHODIMP nsDBFolderInfo::GetSortType(nsMsgViewSortTypeValue* aSortType) {
nsMsgViewSortTypeValue defaultSortType;
nsresult rv = m_mdb->GetDefaultSortType(&defaultSortType);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t sortTypeValue;
rv = GetUint32Property("sortType", defaultSortType, &sortTypeValue);
*aSortType = sortTypeValue;
return rv;
}
NS_IMETHODIMP nsDBFolderInfo::SetSortType(nsMsgViewSortTypeValue aSortType) {
return SetUint32Property("sortType", aSortType);
}
/* attribute nsMsgViewSortOrderValue sortOrder; */
NS_IMETHODIMP nsDBFolderInfo::GetSortOrder(
nsMsgViewSortOrderValue* aSortOrder) {
nsMsgViewSortOrderValue defaultSortOrder;
nsresult rv = m_mdb->GetDefaultSortOrder(&defaultSortOrder);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t sortOrderValue;
rv = GetUint32Property("sortOrder", defaultSortOrder, &sortOrderValue);
*aSortOrder = sortOrderValue;
return rv;
}
NS_IMETHODIMP nsDBFolderInfo::SetSortOrder(nsMsgViewSortOrderValue aSortOrder) {
return SetUint32Property("sortOrder", aSortOrder);
}
NS_IMETHODIMP nsDBFolderInfo::SetKnownArtsSet(const char* newsArtSet) {
return m_mdb->SetProperty(m_mdbRow, kKnownArtsSetColumnName, newsArtSet);
}
NS_IMETHODIMP nsDBFolderInfo::GetKnownArtsSet(char** newsArtSet) {
return m_mdb->GetProperty(m_mdbRow, kKnownArtsSetColumnName, newsArtSet);
}
// get arbitrary property, aka row cell value.
NS_IMETHODIMP nsDBFolderInfo::GetProperty(const char* propertyName,
nsAString& resultProperty) {
return m_mdb->GetPropertyAsNSString(m_mdbRow, propertyName, resultProperty);
}
NS_IMETHODIMP nsDBFolderInfo::SetCharProperty(
const char* aPropertyName, const nsACString& aPropertyValue) {
return m_mdb->SetProperty(m_mdbRow, aPropertyName,
PromiseFlatCString(aPropertyValue).get());
}
NS_IMETHODIMP nsDBFolderInfo::GetCharProperty(const char* propertyName,
nsACString& resultProperty) {
nsCString result;
nsresult rv =
m_mdb->GetProperty(m_mdbRow, propertyName, getter_Copies(result));
if (NS_SUCCEEDED(rv)) resultProperty.Assign(result);
return rv;
}
NS_IMETHODIMP nsDBFolderInfo::SetUint32Property(const char* propertyName,
uint32_t propertyValue) {
return m_mdb->SetUint32Property(m_mdbRow, propertyName, propertyValue);
}
NS_IMETHODIMP nsDBFolderInfo::SetInt64Property(const char* propertyName,
int64_t propertyValue) {
return m_mdb->SetUint64Property(m_mdbRow, propertyName,
(uint64_t)propertyValue);
}
NS_IMETHODIMP nsDBFolderInfo::SetProperty(const char* propertyName,
const nsAString& propertyStr) {
return m_mdb->SetPropertyFromNSString(m_mdbRow, propertyName, propertyStr);
}
nsresult nsDBFolderInfo::SetPropertyWithToken(mdb_token aProperty,
const nsAString& propertyStr) {
return m_mdb->SetNSStringPropertyWithToken(m_mdbRow, aProperty, propertyStr);
}
nsresult nsDBFolderInfo::SetUint32PropertyWithToken(mdb_token aProperty,
uint32_t propertyValue) {
return m_mdb->UInt32ToRowCellColumn(m_mdbRow, aProperty, propertyValue);
}
nsresult nsDBFolderInfo::SetInt64PropertyWithToken(mdb_token aProperty,
int64_t propertyValue) {
return m_mdb->UInt64ToRowCellColumn(m_mdbRow, aProperty,
(uint64_t)propertyValue);
}
nsresult nsDBFolderInfo::SetInt32PropertyWithToken(mdb_token aProperty,
int32_t propertyValue) {
nsAutoString propertyStr;
propertyStr.AppendInt(propertyValue, 16);
return SetPropertyWithToken(aProperty, propertyStr);
}
nsresult nsDBFolderInfo::GetPropertyWithToken(mdb_token aProperty,
nsAString& resultProperty) {
return m_mdb->RowCellColumnTonsString(m_mdbRow, aProperty, resultProperty);
}
nsresult nsDBFolderInfo::GetUint32PropertyWithToken(mdb_token aProperty,
uint32_t& propertyValue,
uint32_t defaultValue) {
return m_mdb->RowCellColumnToUInt32(m_mdbRow, aProperty, propertyValue,
defaultValue);
}
nsresult nsDBFolderInfo::GetInt32PropertyWithToken(mdb_token aProperty,
int32_t& propertyValue,
int32_t defaultValue) {
return m_mdb->RowCellColumnToUInt32(m_mdbRow, aProperty,
(uint32_t&)propertyValue, defaultValue);
}
NS_IMETHODIMP nsDBFolderInfo::GetUint32Property(const char* propertyName,
uint32_t defaultValue,
uint32_t* propertyValue) {
return m_mdb->GetUint32Property(m_mdbRow, propertyName, propertyValue,
defaultValue);
}
NS_IMETHODIMP nsDBFolderInfo::GetInt64Property(const char* propertyName,
int64_t defaultValue,
int64_t* propertyValue) {
return m_mdb->GetUint64Property(m_mdbRow, propertyName,
(uint64_t*)propertyValue, defaultValue);
}
nsresult nsDBFolderInfo::GetInt64PropertyWithToken(mdb_token aProperty,
int64_t& propertyValue,
int64_t defaultValue) {
return m_mdb->RowCellColumnToUInt64(m_mdbRow, aProperty,
(uint64_t*)&propertyValue, defaultValue);
}
NS_IMETHODIMP nsDBFolderInfo::GetBooleanProperty(const char* propertyName,
bool defaultValue,
bool* propertyValue) {
uint32_t defaultUint32Value = (defaultValue) ? 1 : 0;
uint32_t returnValue;
nsresult rv = m_mdb->GetUint32Property(m_mdbRow, propertyName, &returnValue,
defaultUint32Value);
*propertyValue = (returnValue != 0);
return rv;
}
NS_IMETHODIMP nsDBFolderInfo::SetBooleanProperty(const char* propertyName,
bool propertyValue) {
return m_mdb->SetUint32Property(m_mdbRow, propertyName,
propertyValue ? 1 : 0);
}
NS_IMETHODIMP nsDBFolderInfo::GetFolderName(nsACString& folderName) {
return GetCharProperty("folderName", folderName);
}
NS_IMETHODIMP nsDBFolderInfo::SetFolderName(const nsACString& folderName) {
return SetCharProperty("folderName", folderName);
}
class nsTransferDBFolderInfo : public nsDBFolderInfo {
public:
nsTransferDBFolderInfo();
virtual ~nsTransferDBFolderInfo();
// parallel arrays of properties and values
nsTArray<nsCString> m_properties;
nsTArray<nsCString> m_values;
};
nsTransferDBFolderInfo::nsTransferDBFolderInfo() : nsDBFolderInfo(nullptr) {}
nsTransferDBFolderInfo::~nsTransferDBFolderInfo() {}
/* void GetTransferInfo (out nsIDBFolderInfo transferInfo); */
NS_IMETHODIMP nsDBFolderInfo::GetTransferInfo(nsIDBFolderInfo** transferInfo) {
NS_ENSURE_ARG_POINTER(transferInfo);
NS_ENSURE_STATE(m_mdbRow);
RefPtr<nsTransferDBFolderInfo> newInfo = new nsTransferDBFolderInfo;
mdb_count numCells;
mdbYarn cellYarn;
mdb_column cellColumn;
char columnName[100];
mdbYarn cellName = {columnName, 0, sizeof(columnName), 0, 0, nullptr};
m_mdbRow->GetCount(m_mdb->GetEnv(), &numCells);
// iterate over the cells in the dbfolderinfo remembering attribute names and
// values.
for (mdb_count cellIndex = 0; cellIndex < numCells; cellIndex++) {
nsresult err = m_mdbRow->SeekCellYarn(m_mdb->GetEnv(), cellIndex,
&cellColumn, nullptr);
if (NS_SUCCEEDED(err)) {
err = m_mdbRow->AliasCellYarn(m_mdb->GetEnv(), cellColumn, &cellYarn);
if (NS_SUCCEEDED(err)) {
m_mdb->GetStore()->TokenToString(m_mdb->GetEnv(), cellColumn,
&cellName);
newInfo->m_values.AppendElement(
Substring((const char*)cellYarn.mYarn_Buf,
(const char*)cellYarn.mYarn_Buf + cellYarn.mYarn_Fill));
newInfo->m_properties.AppendElement(
Substring((const char*)cellName.mYarn_Buf,
(const char*)cellName.mYarn_Buf + cellName.mYarn_Fill));
}
}
}
newInfo.forget(transferInfo);
return NS_OK;
}
/* void InitFromTransferInfo (in nsIDBFolderInfo transferInfo); */
NS_IMETHODIMP nsDBFolderInfo::InitFromTransferInfo(
nsIDBFolderInfo* aTransferInfo) {
NS_ENSURE_ARG(aTransferInfo);
nsTransferDBFolderInfo* transferInfo =
static_cast<nsTransferDBFolderInfo*>(aTransferInfo);
for (uint32_t i = 0; i < transferInfo->m_values.Length(); i++)
SetCharProperty(transferInfo->m_properties[i].get(),
transferInfo->m_values[i]);
LoadMemberVariables();
return NS_OK;
}