diff options
Diffstat (limited to 'db/mork/src/morkPortTableCursor.cpp')
-rw-r--r-- | db/mork/src/morkPortTableCursor.cpp | 430 |
1 files changed, 430 insertions, 0 deletions
diff --git a/db/mork/src/morkPortTableCursor.cpp b/db/mork/src/morkPortTableCursor.cpp new file mode 100644 index 000000000..2542fcc49 --- /dev/null +++ b/db/mork/src/morkPortTableCursor.cpp @@ -0,0 +1,430 @@ +/* -*- 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 + +//3456789_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; +} + +//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 |