diff options
Diffstat (limited to 'db/mork/src/morkRowObject.cpp')
-rw-r--r-- | db/mork/src/morkRowObject.cpp | 622 |
1 files changed, 622 insertions, 0 deletions
diff --git a/db/mork/src/morkRowObject.cpp b/db/mork/src/morkRowObject.cpp new file mode 100644 index 000000000..33909c36d --- /dev/null +++ b/db/mork/src/morkRowObject.cpp @@ -0,0 +1,622 @@ +/* -*- 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 _MORKROWOBJECT_ +#include "morkRowObject.h" +#endif + +#ifndef _MORKENV_ +#include "morkEnv.h" +#endif + +#ifndef _MORKSTORE_ +#include "morkStore.h" +#endif + +#ifndef _MORKROWCELLCURSOR_ +#include "morkRowCellCursor.h" +#endif + +#ifndef _MORKCELLOBJECT_ +#include "morkCellObject.h" +#endif + +#ifndef _MORKROW_ +#include "morkRow.h" +#endif + +//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 + +// ````` ````` ````` ````` ````` +// { ===== begin morkNode interface ===== + +/*public virtual*/ void +morkRowObject::CloseMorkNode(morkEnv* ev) // CloseRowObject() only if open +{ + if ( this->IsOpenNode() ) + { + this->MarkClosing(); + this->CloseRowObject(ev); + this->MarkShut(); + } +} + +/*public virtual*/ +morkRowObject::~morkRowObject() // assert CloseRowObject() executed earlier +{ + CloseMorkNode(mMorkEnv); + MORK_ASSERT(this->IsShutNode()); +} + +/*public non-poly*/ +morkRowObject::morkRowObject(morkEnv* ev, + const morkUsage& inUsage, nsIMdbHeap* ioHeap, + morkRow* ioRow, morkStore* ioStore) +: morkObject(ev, inUsage, ioHeap, morkColor_kNone, (morkHandle*) 0) +, mRowObject_Row( 0 ) +, mRowObject_Store( 0 ) +{ + if ( ev->Good() ) + { + if ( ioRow && ioStore ) + { + mRowObject_Row = ioRow; + mRowObject_Store = ioStore; // morkRowObjects don't ref-cnt the owning store. + + if ( ev->Good() ) + mNode_Derived = morkDerived_kRowObject; + } + else + ev->NilPointerError(); + } +} + +NS_IMPL_ISUPPORTS_INHERITED(morkRowObject, morkObject, nsIMdbRow) +// { ===== begin nsIMdbCollection methods ===== + +// { ----- begin attribute methods ----- +NS_IMETHODIMP +morkRowObject::GetSeed(nsIMdbEnv* mev, + mdb_seed* outSeed) +{ + nsresult outErr = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + *outSeed = (mdb_seed) mRowObject_Row->mRow_Seed; + outErr = ev->AsErr(); + } + return outErr; +} +NS_IMETHODIMP +morkRowObject::GetCount(nsIMdbEnv* mev, + mdb_count* outCount) +{ + nsresult outErr = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + *outCount = (mdb_count) mRowObject_Row->mRow_Length; + outErr = ev->AsErr(); + } + return outErr; +} + +NS_IMETHODIMP +morkRowObject::GetPort(nsIMdbEnv* mev, + nsIMdbPort** acqPort) +{ + nsresult outErr = NS_OK; + nsIMdbPort* outPort = 0; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + morkRowSpace* rowSpace = mRowObject_Row->mRow_Space; + if ( rowSpace && rowSpace->mSpace_Store ) + { + morkStore* store = mRowObject_Row->GetRowSpaceStore(ev); + if ( store ) + outPort = store->AcquireStoreHandle(ev); + } + else + ev->NilPointerError(); + + outErr = ev->AsErr(); + } + if ( acqPort ) + *acqPort = outPort; + + return outErr; +} +// } ----- end attribute methods ----- + +// { ----- begin cursor methods ----- +NS_IMETHODIMP +morkRowObject::GetCursor( // make a cursor starting iter at inMemberPos + nsIMdbEnv* mev, // context + mdb_pos inMemberPos, // zero-based ordinal pos of member in collection + nsIMdbCursor** acqCursor) +{ + return this->GetRowCellCursor(mev, inMemberPos, + (nsIMdbRowCellCursor**) acqCursor); +} +// } ----- end cursor methods ----- + +// { ----- begin ID methods ----- +NS_IMETHODIMP +morkRowObject::GetOid(nsIMdbEnv* mev, + mdbOid* outOid) +{ + *outOid = mRowObject_Row->mRow_Oid; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + return (ev) ? ev->AsErr() : NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +morkRowObject::BecomeContent(nsIMdbEnv* mev, + const mdbOid* inOid) +{ + NS_ASSERTION(false, "not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; + // remember row->MaybeDirtySpaceStoreAndRow(); +} +// } ----- end ID methods ----- + +// { ----- begin activity dropping methods ----- +NS_IMETHODIMP +morkRowObject::DropActivity( // tell collection usage no longer expected + nsIMdbEnv* mev) +{ + NS_ASSERTION(false, "not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} +// } ----- end activity dropping methods ----- + +// } ===== end nsIMdbCollection methods ===== + +// { ===== begin nsIMdbRow methods ===== + +// { ----- begin cursor methods ----- +NS_IMETHODIMP +morkRowObject::GetRowCellCursor( // make a cursor starting iteration at inCellPos + nsIMdbEnv* mev, // context + mdb_pos inPos, // zero-based ordinal position of cell in row + nsIMdbRowCellCursor** acqCursor) +{ + nsresult outErr = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + nsIMdbRowCellCursor* outCursor = 0; + if ( ev ) + { + morkRowCellCursor* cursor = mRowObject_Row->NewRowCellCursor(ev, inPos); + if ( cursor ) + { + if ( ev->Good() ) + { + cursor->mCursor_Seed = (mork_seed) inPos; + outCursor = cursor; + NS_ADDREF(cursor); + } + } + outErr = ev->AsErr(); + } + if ( acqCursor ) + *acqCursor = outCursor; + return outErr; +} +// } ----- end cursor methods ----- + +// { ----- begin column methods ----- +NS_IMETHODIMP +morkRowObject::AddColumn( // make sure a particular column is inside row + nsIMdbEnv* mev, // context + mdb_column inColumn, // column to add + const mdbYarn* inYarn) +{ + nsresult outErr = NS_ERROR_FAILURE; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + if ( mRowObject_Store && mRowObject_Row) + mRowObject_Row->AddColumn(ev, inColumn, inYarn, mRowObject_Store); + + outErr = ev->AsErr(); + } + return outErr; +} + +NS_IMETHODIMP +morkRowObject::CutColumn( // make sure a column is absent from the row + nsIMdbEnv* mev, // context + mdb_column inColumn) +{ + nsresult outErr = NS_ERROR_FAILURE; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + mRowObject_Row->CutColumn(ev, inColumn); + outErr = ev->AsErr(); + } + return outErr; +} + +NS_IMETHODIMP +morkRowObject::CutAllColumns( // remove all columns from the row + nsIMdbEnv* mev) +{ + nsresult outErr = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + mRowObject_Row->CutAllColumns(ev); + outErr = ev->AsErr(); + } + return outErr; +} +// } ----- end column methods ----- + +// { ----- begin cell methods ----- +NS_IMETHODIMP +morkRowObject::NewCell( // get cell for specified column, or add new one + nsIMdbEnv* mev, // context + mdb_column inColumn, // column to add + nsIMdbCell** acqCell) +{ + nsresult outErr = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + GetCell(mev, inColumn, acqCell); + if ( !*acqCell ) + { + if ( mRowObject_Store ) + { + mdbYarn yarn; // to pass empty yarn into morkRowObject::AddColumn() + yarn.mYarn_Buf = 0; + yarn.mYarn_Fill = 0; + yarn.mYarn_Size = 0; + yarn.mYarn_More = 0; + yarn.mYarn_Form = 0; + yarn.mYarn_Grow = 0; + AddColumn(ev, inColumn, &yarn); + GetCell(mev, inColumn, acqCell); + } + } + + outErr = ev->AsErr(); + } + return outErr; +} + +NS_IMETHODIMP +morkRowObject::AddCell( // copy a cell from another row to this row + nsIMdbEnv* mev, // context + const nsIMdbCell* inCell) +{ + nsresult outErr = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + morkCell* cell = 0; + morkCellObject* cellObj = (morkCellObject*) inCell; + if ( cellObj->CanUseCell(mev, morkBool_kFalse, &outErr, &cell) ) + { + + morkRow* cellRow = cellObj->mCellObject_Row; + if ( cellRow ) + { + if ( mRowObject_Row != cellRow ) + { + morkStore* store = mRowObject_Row->GetRowSpaceStore(ev); + morkStore* cellStore = cellRow->GetRowSpaceStore(ev); + if ( store && cellStore ) + { + mork_column col = cell->GetColumn(); + morkAtom* atom = cell->mCell_Atom; + mdbYarn yarn; + morkAtom::AliasYarn(atom, &yarn); // works even when atom is nil + + if ( store != cellStore ) + col = store->CopyToken(ev, col, cellStore); + if ( ev->Good() ) + AddColumn(ev, col, &yarn); + } + else + ev->NilPointerError(); + } + } + else + ev->NilPointerError(); + } + + outErr = ev->AsErr(); + } + return outErr; +} + +NS_IMETHODIMP +morkRowObject::GetCell( // find a cell in this row + nsIMdbEnv* mev, // context + mdb_column inColumn, // column to find + nsIMdbCell** acqCell) +{ + nsresult outErr = NS_OK; + nsIMdbCell* outCell = 0; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + + if ( ev ) + { + if ( inColumn ) + { + mork_pos pos = 0; + morkCell* cell = mRowObject_Row->GetCell(ev, inColumn, &pos); + if ( cell ) + { + outCell = mRowObject_Row->AcquireCellHandle(ev, cell, inColumn, pos); + } + } + else + mRowObject_Row->ZeroColumnError(ev); + + outErr = ev->AsErr(); + } + if ( acqCell ) + *acqCell = outCell; + return outErr; +} + +NS_IMETHODIMP +morkRowObject::EmptyAllCells( // make all cells in row empty of content + nsIMdbEnv* mev) +{ + nsresult outErr = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + EmptyAllCells(ev); + outErr = ev->AsErr(); + } + return outErr; +} +// } ----- end cell methods ----- + +// { ----- begin row methods ----- +NS_IMETHODIMP +morkRowObject::AddRow( // add all cells in another row to this one + nsIMdbEnv* mev, // context + nsIMdbRow* ioSourceRow) +{ + nsresult outErr = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + morkRow* unsafeSource = (morkRow*) ioSourceRow; // unsafe cast +// if ( unsafeSource->CanUseRow(mev, morkBool_kFalse, &outErr, &source) ) + { + mRowObject_Row->AddRow(ev, unsafeSource); + } + outErr = ev->AsErr(); + } + return outErr; +} + +NS_IMETHODIMP +morkRowObject::SetRow( // make exact duplicate of another row + nsIMdbEnv* mev, // context + nsIMdbRow* ioSourceRow) +{ + nsresult outErr = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + morkRowObject *sourceObject = (morkRowObject *) ioSourceRow; // unsafe cast + morkRow* unsafeSource = sourceObject->mRowObject_Row; +// if ( unsafeSource->CanUseRow(mev, morkBool_kFalse, &outErr, &source) ) + { + mRowObject_Row->SetRow(ev, unsafeSource); + } + outErr = ev->AsErr(); + } + return outErr; +} +// } ----- end row methods ----- + +// { ----- begin blob methods ----- +NS_IMETHODIMP +morkRowObject::SetCellYarn( // synonym for AddColumn() + nsIMdbEnv* mev, // context + mdb_column inColumn, // column to add + const mdbYarn* inYarn) +{ + nsresult outErr = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + if ( mRowObject_Store ) + AddColumn(ev, inColumn, inYarn); + + outErr = ev->AsErr(); + } + return outErr; +} +NS_IMETHODIMP +morkRowObject::GetCellYarn( + nsIMdbEnv* mev, // context + mdb_column inColumn, // column to read + mdbYarn* outYarn) // writes some yarn slots +// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form +{ + nsresult outErr = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + if ( mRowObject_Store && mRowObject_Row) + { + morkAtom* atom = mRowObject_Row->GetColumnAtom(ev, inColumn); + morkAtom::GetYarn(atom, outYarn); + } + + outErr = ev->AsErr(); + } + return outErr; +} + +NS_IMETHODIMP +morkRowObject::AliasCellYarn( + nsIMdbEnv* mev, // context + mdb_column inColumn, // column to alias + mdbYarn* outYarn) // writes ALL yarn slots +{ + nsresult outErr = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + if ( mRowObject_Store && mRowObject_Row) + { + morkAtom* atom = mRowObject_Row->GetColumnAtom(ev, inColumn); + morkAtom::AliasYarn(atom, outYarn); + // note nil atom works and sets yarn correctly + } + outErr = ev->AsErr(); + } + return outErr; +} + +NS_IMETHODIMP +morkRowObject::NextCellYarn(nsIMdbEnv* mev, // iterative version of GetCellYarn() + mdb_column* ioColumn, // next column to read + mdbYarn* outYarn) // writes some yarn slots +// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form +// +// The ioColumn argument is an inout parameter which initially contains the +// last column accessed and returns the next column corresponding to the +// content read into the yarn. Callers should start with a zero column +// value to say 'no previous column', which causes the first column to be +// read. Then the value returned in ioColumn is perfect for the next call +// to NextCellYarn(), since it will then be the previous column accessed. +// Callers need only examine the column token returned to see which cell +// in the row is being read into the yarn. When no more columns remain, +// and the iteration has ended, ioColumn will return a zero token again. +// So iterating over cells starts and ends with a zero column token. +{ + nsresult outErr = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + if ( mRowObject_Store && mRowObject_Row) + mRowObject_Row->NextColumn(ev, ioColumn, outYarn); + + outErr = ev->AsErr(); + } + return outErr; +} + +NS_IMETHODIMP +morkRowObject::SeekCellYarn( // resembles nsIMdbRowCellCursor::SeekCell() + nsIMdbEnv* mev, // context + mdb_pos inPos, // position of cell in row sequence + mdb_column* outColumn, // column for this particular cell + mdbYarn* outYarn) // writes some yarn slots +// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form +// Callers can pass nil for outYarn to indicate no interest in content, so +// only the outColumn value is returned. NOTE to subclasses: you must be +// able to ignore outYarn when the pointer is nil; please do not crash. + +{ + nsresult outErr = NS_OK; + morkEnv* ev = morkEnv::FromMdbEnv(mev); + if ( ev ) + { + if ( mRowObject_Store && mRowObject_Row) + mRowObject_Row->SeekColumn(ev, inPos, outColumn, outYarn); + + outErr = ev->AsErr(); + } + return outErr; +} + +// } ----- end blob methods ----- + + +// } ===== end nsIMdbRow methods ===== + + + +/*public non-poly*/ void +morkRowObject::CloseRowObject(morkEnv* ev) // called by CloseMorkNode(); +{ + if ( this->IsNode() ) + { + morkRow* row = mRowObject_Row; + mRowObject_Row = 0; + this->CloseObject(ev); + this->MarkShut(); + + if ( row ) + { + MORK_ASSERT(row->mRow_Object == this); + if ( row->mRow_Object == this ) + { + row->mRow_Object = 0; // just nil this slot -- cut ref down below + + mRowObject_Store = 0; // morkRowObjects don't ref-cnt the owning store. + + this->CutWeakRef(ev->AsMdbEnv()); // do last, because it might self destroy + } + } + } + else + this->NonNodeError(ev); +} + +// } ===== end morkNode methods ===== +// ````` ````` ````` ````` ````` + +/*static*/ void +morkRowObject::NonRowObjectTypeError(morkEnv* ev) +{ + ev->NewError("non morkRowObject"); +} + +/*static*/ void +morkRowObject::NilRowError(morkEnv* ev) +{ + ev->NewError("nil mRowObject_Row"); +} + +/*static*/ void +morkRowObject::NilStoreError(morkEnv* ev) +{ + ev->NewError("nil mRowObject_Store"); +} + +/*static*/ void +morkRowObject::RowObjectRowNotSelfError(morkEnv* ev) +{ + ev->NewError("mRowObject_Row->mRow_Object != self"); +} + + +nsIMdbRow* +morkRowObject::AcquireRowHandle(morkEnv* ev) // mObject_Handle +{ + AddRef(); + return this; +} + + +//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 |