diff options
Diffstat (limited to 'comm/mailnews/db/mork/morkPortTableCursor.cpp')
-rw-r--r-- | comm/mailnews/db/mork/morkPortTableCursor.cpp | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/comm/mailnews/db/mork/morkPortTableCursor.cpp b/comm/mailnews/db/mork/morkPortTableCursor.cpp new file mode 100644 index 0000000000..8f4f62411d --- /dev/null +++ b/comm/mailnews/db/mork/morkPortTableCursor.cpp @@ -0,0 +1,381 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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/. */ + +#ifndef _MDB_ +# include "mdb.h" +#endif + +#ifndef _MORK_ +# include "mork.h" +#endif + +#ifndef _MORKNODE_ +# include "morkNode.h" +#endif + +#ifndef _MORKENV_ +# include "morkEnv.h" +#endif + +#ifndef _MORKCURSOR_ +# include "morkCursor.h" +#endif + +#ifndef _MORKPORTTABLECURSOR_ +# include "morkPortTableCursor.h" +#endif + +#ifndef _MORKSTORE_ +# include "morkStore.h" +#endif + +// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 + +// ````` ````` ````` ````` ````` +// { ===== begin morkNode interface ===== + +/*public virtual*/ void morkPortTableCursor::CloseMorkNode( + morkEnv* ev) // ClosePortTableCursor() only if open +{ + if (this->IsOpenNode()) { + this->MarkClosing(); + this->ClosePortTableCursor(ev); + this->MarkShut(); + } +} + +/*public virtual*/ +morkPortTableCursor::~morkPortTableCursor() // ClosePortTableCursor() executed + // earlier +{ + CloseMorkNode(mMorkEnv); +} + +/*public non-poly*/ +morkPortTableCursor::morkPortTableCursor(morkEnv* ev, const morkUsage& inUsage, + nsIMdbHeap* ioHeap, morkStore* ioStore, + mdb_scope inRowScope, + mdb_kind inTableKind, + nsIMdbHeap* ioSlotHeap) + : morkCursor(ev, inUsage, ioHeap), + mPortTableCursor_Store(0), + mPortTableCursor_RowScope((mdb_scope)-1) // we want != inRowScope + , + mPortTableCursor_TableKind((mdb_kind)-1) // we want != inTableKind + , + mPortTableCursor_LastTable(0) // not refcounted + , + mPortTableCursor_RowSpace(0) // strong ref to row space + , + mPortTableCursor_TablesDidEnd(morkBool_kFalse), + mPortTableCursor_SpacesDidEnd(morkBool_kFalse) { + if (ev->Good()) { + if (ioStore && ioSlotHeap) { + mCursor_Pos = -1; + mCursor_Seed = 0; // let the iterator do its own seed handling + morkStore::SlotWeakStore(ioStore, ev, &mPortTableCursor_Store); + + if (this->SetRowScope(ev, inRowScope)) + this->SetTableKind(ev, inTableKind); + + if (ev->Good()) mNode_Derived = morkDerived_kPortTableCursor; + } else + ev->NilPointerError(); + } +} + +NS_IMPL_ISUPPORTS_INHERITED(morkPortTableCursor, morkCursor, + nsIMdbPortTableCursor) + +morkEnv* morkPortTableCursor::CanUsePortTableCursor(nsIMdbEnv* mev, + mork_bool inMutable, + nsresult* outErr) const { + morkEnv* outEnv = 0; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if (ev) { + if (IsPortTableCursor()) + outEnv = ev; + else + NonPortTableCursorTypeError(ev); + *outErr = ev->AsErr(); + } + MORK_ASSERT(outEnv); + return outEnv; +} + +/*public non-poly*/ void morkPortTableCursor::ClosePortTableCursor( + morkEnv* ev) { + if (this->IsNode()) { + mCursor_Pos = -1; + mCursor_Seed = 0; + mPortTableCursor_LastTable = 0; + morkStore::SlotWeakStore((morkStore*)0, ev, &mPortTableCursor_Store); + morkRowSpace::SlotStrongRowSpace((morkRowSpace*)0, ev, + &mPortTableCursor_RowSpace); + this->CloseCursor(ev); + this->MarkShut(); + } else + this->NonNodeError(ev); +} + +// } ===== end morkNode methods ===== +// ````` ````` ````` ````` ````` + +/*static*/ void morkPortTableCursor::NilCursorStoreError(morkEnv* ev) { + ev->NewError("nil mPortTableCursor_Store"); +} + +/*static*/ void morkPortTableCursor::NonPortTableCursorTypeError(morkEnv* ev) { + ev->NewError("non morkPortTableCursor"); +} + +mork_bool morkPortTableCursor::SetRowScope(morkEnv* ev, mork_scope inRowScope) { + mPortTableCursor_RowScope = inRowScope; + mPortTableCursor_LastTable = 0; // restart iteration of space + + mPortTableCursor_TableIter.CloseMapIter(ev); + mPortTableCursor_TablesDidEnd = morkBool_kTrue; + mPortTableCursor_SpacesDidEnd = morkBool_kTrue; + + morkStore* store = mPortTableCursor_Store; + if (store) { + morkRowSpace* space = mPortTableCursor_RowSpace; + + if (inRowScope) // intend to cover a specific scope only? + { + space = store->LazyGetRowSpace(ev, inRowScope); + morkRowSpace::SlotStrongRowSpace(space, ev, &mPortTableCursor_RowSpace); + + // We want mPortTableCursor_SpacesDidEnd == morkBool_kTrue + // to show this is the only space to be covered. + } else // prepare space map iter to cover all space scopes + { + morkRowSpaceMapIter* rsi = &mPortTableCursor_SpaceIter; + rsi->InitRowSpaceMapIter(ev, &store->mStore_RowSpaces); + + space = 0; + (void)rsi->FirstRowSpace(ev, (mork_scope*)0, &space); + morkRowSpace::SlotStrongRowSpace(space, ev, &mPortTableCursor_RowSpace); + + if (space) // found first space in store + mPortTableCursor_SpacesDidEnd = morkBool_kFalse; + } + + this->init_space_tables_map(ev); + } else + this->NilCursorStoreError(ev); + + return ev->Good(); +} + +void morkPortTableCursor::init_space_tables_map(morkEnv* ev) { + morkRowSpace* space = mPortTableCursor_RowSpace; + if (space && ev->Good()) { + morkTableMapIter* ti = &mPortTableCursor_TableIter; + ti->InitTableMapIter(ev, &space->mRowSpace_Tables); + if (ev->Good()) mPortTableCursor_TablesDidEnd = morkBool_kFalse; + } +} + +mork_bool morkPortTableCursor::SetTableKind(morkEnv* ev, + mork_kind inTableKind) { + mPortTableCursor_TableKind = inTableKind; + mPortTableCursor_LastTable = 0; // restart iteration of space + + mPortTableCursor_TablesDidEnd = morkBool_kTrue; + + morkRowSpace* space = mPortTableCursor_RowSpace; + if (!space && mPortTableCursor_RowScope == 0) { + this->SetRowScope(ev, 0); + } + this->init_space_tables_map(ev); + + return ev->Good(); +} + +morkRowSpace* morkPortTableCursor::NextSpace(morkEnv* ev) { + morkRowSpace* outSpace = 0; + mPortTableCursor_LastTable = 0; + mPortTableCursor_SpacesDidEnd = morkBool_kTrue; + mPortTableCursor_TablesDidEnd = morkBool_kTrue; + + if (!mPortTableCursor_RowScope) // not just one scope? + { + morkStore* store = mPortTableCursor_Store; + if (store) { + morkRowSpaceMapIter* rsi = &mPortTableCursor_SpaceIter; + + (void)rsi->NextRowSpace(ev, (mork_scope*)0, &outSpace); + morkRowSpace::SlotStrongRowSpace(outSpace, ev, + &mPortTableCursor_RowSpace); + + if (outSpace) // found next space in store + { + mPortTableCursor_SpacesDidEnd = morkBool_kFalse; + + this->init_space_tables_map(ev); + + if (ev->Bad()) outSpace = 0; + } + } else + this->NilCursorStoreError(ev); + } + + return outSpace; +} + +morkTable* morkPortTableCursor::NextTable(morkEnv* ev) { + mork_kind kind = mPortTableCursor_TableKind; + + do // until spaces end, or until we find a table in a space + { + morkRowSpace* space = mPortTableCursor_RowSpace; + if (mPortTableCursor_TablesDidEnd) // current space exhausted? + space = this->NextSpace(ev); // go on to the next space + + if (space) // have a space remaining that might hold tables? + { +#ifdef MORK_BEAD_OVER_NODE_MAPS + morkTableMapIter* ti = &mPortTableCursor_TableIter; + morkTable* table = + (mPortTableCursor_LastTable) ? ti->NextTable(ev) : ti->FirstTable(ev); + + for (; table && ev->Good(); table = ti->NextTable(ev)) +#else /*MORK_BEAD_OVER_NODE_MAPS*/ + mork_tid* key = 0; // ignore keys in table map + morkTable* table = 0; // old value table in the map + morkTableMapIter* ti = &mPortTableCursor_TableIter; + mork_change* c = (mPortTableCursor_LastTable) + ? ti->NextTable(ev, key, &table) + : ti->FirstTable(ev, key, &table); + + for (; c && ev->Good(); c = ti->NextTable(ev, key, &table)) +#endif /*MORK_BEAD_OVER_NODE_MAPS*/ + { + if (table && table->IsTable()) { + if (!kind || kind == table->mTable_Kind) { + mPortTableCursor_LastTable = table; // ti->NextTable() hence + return table; + } + } else + table->NonTableTypeWarning(ev); + } + mPortTableCursor_TablesDidEnd = morkBool_kTrue; // space is done + mPortTableCursor_LastTable = 0; // make sure next space starts fresh + } + + } while (ev->Good() && !mPortTableCursor_SpacesDidEnd); + + return (morkTable*)0; +} + +// { ----- begin table iteration methods ----- + +// { ===== begin nsIMdbPortTableCursor methods ===== + +// { ----- begin attribute methods ----- +NS_IMETHODIMP +morkPortTableCursor::SetPort(nsIMdbEnv* mev, nsIMdbPort* ioPort) { + NS_ASSERTION(false, "not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +morkPortTableCursor::GetPort(nsIMdbEnv* mev, nsIMdbPort** acqPort) { + nsresult outErr = NS_OK; + nsIMdbPort* outPort = 0; + morkEnv* ev = + this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr); + if (ev) { + if (mPortTableCursor_Store) + outPort = mPortTableCursor_Store->AcquireStoreHandle(ev); + outErr = ev->AsErr(); + } + if (acqPort) *acqPort = outPort; + return outErr; +} + +NS_IMETHODIMP +morkPortTableCursor::SetRowScope(nsIMdbEnv* mev, // sets pos to -1 + mdb_scope inRowScope) { + nsresult outErr = NS_OK; + morkEnv* ev = + this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr); + if (ev) { + mCursor_Pos = -1; + + SetRowScope(ev, inRowScope); + outErr = ev->AsErr(); + } + return outErr; +} + +NS_IMETHODIMP +morkPortTableCursor::GetRowScope(nsIMdbEnv* mev, mdb_scope* outRowScope) { + nsresult outErr = NS_OK; + mdb_scope rowScope = 0; + morkEnv* ev = + this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr); + if (ev) { + rowScope = mPortTableCursor_RowScope; + outErr = ev->AsErr(); + } + *outRowScope = rowScope; + return outErr; +} +// setting row scope to zero iterates over all row scopes in port + +NS_IMETHODIMP +morkPortTableCursor::SetTableKind(nsIMdbEnv* mev, // sets pos to -1 + mdb_kind inTableKind) { + nsresult outErr = NS_OK; + morkEnv* ev = + this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr); + if (ev) { + mCursor_Pos = -1; + + SetTableKind(ev, inTableKind); + outErr = ev->AsErr(); + } + return outErr; +} + +NS_IMETHODIMP +morkPortTableCursor::GetTableKind(nsIMdbEnv* mev, mdb_kind* outTableKind) +// setting table kind to zero iterates over all table kinds in row scope +{ + nsresult outErr = NS_OK; + mdb_kind tableKind = 0; + morkEnv* ev = + this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr); + if (ev) { + tableKind = mPortTableCursor_TableKind; + outErr = ev->AsErr(); + } + *outTableKind = tableKind; + return outErr; +} +// } ----- end attribute methods ----- + +// { ----- begin table iteration methods ----- +NS_IMETHODIMP +morkPortTableCursor::NextTable( // get table at next position in the db + nsIMdbEnv* mev, // context + nsIMdbTable** acqTable) { + nsresult outErr = NS_OK; + nsIMdbTable* outTable = 0; + morkEnv* ev = + CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr); + if (ev) { + morkTable* table = NextTable(ev); + if (table && ev->Good()) outTable = table->AcquireTableHandle(ev); + + outErr = ev->AsErr(); + } + if (acqTable) *acqTable = outTable; + return outErr; +} + +// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 |