Back to index

lightning-sunbird  0.9+nobinonly
orkinTable.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-  */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef _MDB_
00039 #include "mdb.h"
00040 #endif
00041 
00042 #ifndef _MORK_
00043 #include "mork.h"
00044 #endif
00045 
00046 #ifndef _MORKNODE_
00047 #include "morkNode.h"
00048 #endif
00049 
00050 #ifndef _MORKHANDLE_
00051 #include "morkHandle.h"
00052 #endif
00053 
00054 #ifndef _MORKTABLE_
00055 #include "morkTable.h"
00056 #endif
00057 
00058 #ifndef _MORKENV_
00059 #include "morkEnv.h"
00060 #endif
00061 
00062 #ifndef _ORKINTABLE_
00063 #include "orkinTable.h"
00064 #endif
00065 
00066 #ifndef _ORKINROW_
00067 #include "orkinRow.h"
00068 #endif
00069 
00070 #ifndef _MORKTABLEROWCURSOR_
00071 #include "morkTableRowCursor.h"
00072 #endif
00073 
00074 #ifndef _ORKINTABLEROWCURSOR_
00075 #include "orkinTableRowCursor.h"
00076 #endif
00077 
00078 #ifndef _MORKROWSPACE_
00079 #include "morkRowSpace.h"
00080 #endif
00081 
00082 #ifndef _MORKSTORE_
00083 #include "morkStore.h"
00084 #endif
00085 
00086 #ifndef _ORKINSTORE_
00087 #include "orkinStore.h"
00088 #endif
00089 
00090 #ifndef _MORKROWOBJECT_
00091 #include "morkRowObject.h"
00092 #endif
00093 
00094 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00095 
00096 /* public virtual*/
00097 orkinTable:: ~orkinTable() // morkHandle destructor does everything
00098 {
00099 }
00100 
00101 /*protected non-poly construction*/
00102 orkinTable::orkinTable(morkEnv* ev, // morkUsage is morkUsage_kPool
00103     morkHandleFace* ioFace,    // must not be nil, cookie for this handle
00104     morkTable* ioObject)  // must not be nil, the object for this handle
00105 : morkHandle(ev, ioFace, ioObject, morkMagic_kTable)
00106 {
00107   // do not modify mNode_Derived; leave it equal to morkDerived_kHandle
00108 }
00109 
00110 
00111 /*static */ orkinTable*
00112 orkinTable::MakeTable(morkEnv* ev, morkTable* ioObject)
00113 {
00114   mork_bool isEnv = ev->IsEnv();
00115   MORK_ASSERT(isEnv);
00116   if ( isEnv )
00117   {
00118     morkHandleFace* face = ev->NewHandle(sizeof(orkinTable));
00119     if ( face )
00120       return new(face) orkinTable(ev, face, ioObject);
00121     else
00122       ev->OutOfMemoryError();
00123   }
00124     
00125   return (orkinTable*) 0;
00126 }
00127 
00128 morkEnv*
00129 orkinTable::CanUseTable(nsIMdbEnv* mev,
00130   mork_bool inMutable, mdb_err* outErr) const
00131 {
00132   morkEnv* outEnv = 0;
00133   morkEnv* ev = morkEnv::FromMdbEnv(mev);
00134   if ( ev )
00135   {
00136     morkTable* self = (morkTable*)
00137       this->GetGoodHandleObject(ev, inMutable, morkMagic_kTable,
00138         /*inClosedOkay*/ morkBool_kFalse);
00139     if ( self )
00140     {
00141       if ( self->IsTable() )
00142         outEnv = ev;
00143       else
00144         self->NonTableTypeError(ev);
00145     }
00146     *outErr = ev->AsErr();
00147   }
00148   MORK_ASSERT(outEnv);
00149   return outEnv;
00150 }
00151 
00152 
00153 // { ===== begin nsIMdbISupports methods =====
00154 NS_IMPL_QUERY_INTERFACE0(orkinTable)
00155 
00156 /*virtual*/ nsrefcnt
00157 orkinTable::AddRef() // add strong ref with no
00158 {
00159   morkEnv* ev = mHandle_Env;
00160   if ( ev && ev->IsEnv() )
00161     return this->Handle_AddStrongRef(ev->AsMdbEnv());
00162   else
00163     return morkEnv_kNonEnvTypeError;
00164 }
00165 
00166 /*virtual*/ nsrefcnt
00167 orkinTable::Release() // cut strong ref
00168 {
00169   morkEnv* ev = mHandle_Env;
00170   if ( ev && ev->IsEnv() )
00171     return this->Handle_CutStrongRef(ev->AsMdbEnv());
00172   else
00173     return morkEnv_kNonEnvTypeError;
00174 }
00175 // } ===== end nsIMdbISupports methods =====
00176 
00177 // { ===== begin nsIMdbObject methods =====
00178 
00179 // { ----- begin attribute methods -----
00180 /*virtual*/ mdb_err
00181 orkinTable::IsFrozenMdbObject(nsIMdbEnv* mev, mdb_bool* outIsReadonly)
00182 {
00183   return this->Handle_IsFrozenMdbObject(mev, outIsReadonly);
00184 }
00185 // same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port.
00186 // } ----- end attribute methods -----
00187 
00188 // { ----- begin factory methods -----
00189 /*virtual*/ mdb_err
00190 orkinTable::GetMdbFactory(nsIMdbEnv* mev, nsIMdbFactory** acqFactory)
00191 {
00192   return this->Handle_GetMdbFactory(mev, acqFactory);
00193 } 
00194 // } ----- end factory methods -----
00195 
00196 // { ----- begin ref counting for well-behaved cyclic graphs -----
00197 /*virtual*/ mdb_err
00198 orkinTable::GetWeakRefCount(nsIMdbEnv* mev, // weak refs
00199   mdb_count* outCount)
00200 {
00201   return this->Handle_GetWeakRefCount(mev, outCount);
00202 }  
00203 /*virtual*/ mdb_err
00204 orkinTable::GetStrongRefCount(nsIMdbEnv* mev, // strong refs
00205   mdb_count* outCount)
00206 {
00207   return this->Handle_GetStrongRefCount(mev, outCount);
00208 }
00209 
00210 /*virtual*/ mdb_err
00211 orkinTable::AddWeakRef(nsIMdbEnv* mev)
00212 {
00213   return this->Handle_AddWeakRef(mev);
00214 }
00215 /*virtual*/ mdb_err
00216 orkinTable::AddStrongRef(nsIMdbEnv* mev)
00217 {
00218   return this->Handle_AddStrongRef(mev);
00219 }
00220 
00221 /*virtual*/ mdb_err
00222 orkinTable::CutWeakRef(nsIMdbEnv* mev)
00223 {
00224   return this->Handle_CutWeakRef(mev);
00225 }
00226 /*virtual*/ mdb_err
00227 orkinTable::CutStrongRef(nsIMdbEnv* mev)
00228 {
00229   return this->Handle_CutStrongRef(mev);
00230 }
00231 
00232 /*virtual*/ mdb_err
00233 orkinTable::CloseMdbObject(nsIMdbEnv* mev)
00234 {
00235   return this->Handle_CloseMdbObject(mev);
00236 }
00237 
00238 /*virtual*/ mdb_err
00239 orkinTable::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
00240 {
00241   return this->Handle_IsOpenMdbObject(mev, outOpen);
00242 }
00243 // } ----- end ref counting -----
00244 
00245 // } ===== end nsIMdbObject methods =====
00246 
00247 // { ===== begin nsIMdbCollection methods =====
00248 
00249 // { ----- begin attribute methods -----
00250 /*virtual*/ mdb_err
00251 orkinTable::GetSeed(nsIMdbEnv* mev,
00252   mdb_seed* outSeed)    // member change count
00253 {
00254   mdb_err outErr = 0;
00255   mdb_seed seed = 0;
00256   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00257   if ( ev )
00258   {
00259     morkTable* table = (morkTable*) mHandle_Object;
00260     seed = table->mTable_RowArray.mArray_Seed;
00261     outErr = ev->AsErr();
00262   }
00263   if ( outSeed )
00264     *outSeed = seed;
00265   return outErr;
00266 }
00267   
00268 /*virtual*/ mdb_err
00269 orkinTable::GetCount(nsIMdbEnv* mev,
00270   mdb_count* outCount) // member count
00271 {
00272   mdb_err outErr = 0;
00273   mdb_count count = 0;
00274   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00275   if ( ev )
00276   {
00277     morkTable* table = (morkTable*) mHandle_Object;
00278     count = table->mTable_RowArray.mArray_Fill;
00279     outErr = ev->AsErr();
00280   }
00281   if ( outCount )
00282     *outCount = count;
00283   return outErr;
00284 }
00285 
00286 /*virtual*/ mdb_err
00287 orkinTable::GetPort(nsIMdbEnv* mev,
00288   nsIMdbPort** acqPort) // collection container
00289 {
00290   mdb_err outErr = 0;
00291   nsIMdbPort* outPort = 0;
00292   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00293   if ( ev )
00294   {
00295     morkTable* table = (morkTable*) mHandle_Object;
00296     morkStore* store = table->mTable_Store;
00297     if ( store )
00298       outPort = store->AcquireStoreHandle(ev);
00299     outErr = ev->AsErr();
00300   }
00301   if ( acqPort )
00302     *acqPort = outPort;
00303   return outErr;
00304 }
00305 // } ----- end attribute methods -----
00306 
00307 // { ----- begin cursor methods -----
00308 /*virtual*/ mdb_err
00309 orkinTable::GetCursor( // make a cursor starting iter at inMemberPos
00310   nsIMdbEnv* mev, // context
00311   mdb_pos inMemberPos, // zero-based ordinal pos of member in collection
00312   nsIMdbCursor** acqCursor) // acquire new cursor instance
00313 {
00314   return this->GetTableRowCursor(mev, inMemberPos,
00315     (nsIMdbTableRowCursor**) acqCursor);
00316 }
00317 // } ----- end cursor methods -----
00318 
00319 // { ----- begin ID methods -----
00320 /*virtual*/ mdb_err
00321 orkinTable::GetOid(nsIMdbEnv* mev,
00322   mdbOid* outOid) // read object identity
00323 {
00324   mdb_err outErr = 0;
00325   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00326   if ( ev )
00327   {
00328     morkTable* table = (morkTable*) mHandle_Object;
00329     table->GetTableOid(ev, outOid);
00330     outErr = ev->AsErr();
00331   }
00332   return outErr;
00333 }
00334 
00335 /*virtual*/ mdb_err
00336 orkinTable::BecomeContent(nsIMdbEnv* mev,
00337   const mdbOid* inOid) // exchange content
00338 {
00339   MORK_USED_1(inOid);
00340   mdb_err outErr = 0;
00341   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00342   if ( ev )
00343   {
00344     // remember table->MaybeDirtySpaceStoreAndTable();
00345     
00346     morkTable* table = (morkTable*) mHandle_Object;
00347     MORK_USED_1(table);
00348 
00349     ev->StubMethodOnlyError();
00350     outErr = ev->AsErr();
00351   }
00352   return outErr;
00353 }
00354 // } ----- end ID methods -----
00355 
00356 // { ----- begin activity dropping methods -----
00357 /*virtual*/ mdb_err
00358 orkinTable::DropActivity( // tell collection usage no longer expected
00359   nsIMdbEnv* mev)
00360 {
00361   mdb_err outErr = 0;
00362   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00363   if ( ev )
00364   {
00365     morkTable* table;
00366     table = (morkTable*) mHandle_Object;
00367     // ev->StubMethodOnlyError(); // okay to do nothing
00368     outErr = ev->AsErr();
00369   }
00370   return outErr;
00371 }
00372 // } ----- end activity dropping methods -----
00373 
00374 // } ===== end nsIMdbCollection methods =====
00375 
00376 // { ===== begin nsIMdbTable methods =====
00377 
00378 // { ----- begin attribute methods -----
00379 
00380 /*virtual*/ mdb_err
00381 orkinTable::SetTablePriority(nsIMdbEnv* mev, mdb_priority inPrio)
00382 {
00383   mdb_err outErr = 0;
00384   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00385   if ( ev )
00386   {
00387     morkTable* table = (morkTable*) mHandle_Object;
00388     if ( inPrio > morkPriority_kMax )
00389       inPrio = morkPriority_kMax;
00390       
00391     table->mTable_Priority = inPrio;
00392     outErr = ev->AsErr();
00393   }
00394   return outErr;
00395 }
00396 
00397 /*virtual*/ mdb_err
00398 orkinTable::GetTablePriority(nsIMdbEnv* mev, mdb_priority* outPrio)
00399 {
00400   mdb_err outErr = 0;
00401   mork_priority prio = 0;
00402   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00403   if ( ev )
00404   {
00405     morkTable* table = (morkTable*) mHandle_Object;
00406     prio = table->mTable_Priority;
00407     if ( prio > morkPriority_kMax )
00408     {
00409       prio = morkPriority_kMax;
00410       table->mTable_Priority = prio;
00411     }
00412     outErr = ev->AsErr();
00413   }
00414   if ( outPrio )
00415     *outPrio = prio;
00416   return outErr;
00417 }
00418 
00419 
00420 /*virtual*/ mdb_err
00421 orkinTable:: GetTableBeVerbose(nsIMdbEnv* mev, mdb_bool* outBeVerbose)
00422 {
00423   mdb_err outErr = 0;
00424   mdb_bool beVerbose = morkBool_kFalse;
00425   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00426   if ( ev )
00427   {
00428     morkTable* table = (morkTable*) mHandle_Object;
00429     beVerbose = table->IsTableVerbose();
00430     outErr = ev->AsErr();
00431   }
00432   if ( outBeVerbose )
00433     *outBeVerbose = beVerbose;
00434   return outErr;
00435 }
00436 
00437 /*virtual*/ mdb_err
00438 orkinTable::SetTableBeVerbose(nsIMdbEnv* mev, mdb_bool inBeVerbose)
00439 {
00440   mdb_err outErr = 0;
00441   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00442   if ( ev )
00443   {
00444     morkTable* table = (morkTable*) mHandle_Object;
00445     if ( inBeVerbose )
00446       table->SetTableVerbose();
00447     else
00448        table->ClearTableVerbose();
00449    
00450     outErr = ev->AsErr();
00451   }
00452   return outErr;
00453 }
00454 
00455 /*virtual*/ mdb_err
00456 orkinTable::GetTableIsUnique(nsIMdbEnv* mev, mdb_bool* outIsUnique)
00457 {
00458   mdb_err outErr = 0;
00459   mdb_bool isUnique = morkBool_kFalse;
00460   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00461   if ( ev )
00462   {
00463     morkTable* table = (morkTable*) mHandle_Object;
00464     isUnique = table->IsTableUnique();
00465     outErr = ev->AsErr();
00466   }
00467   if ( outIsUnique )
00468     *outIsUnique = isUnique;
00469   return outErr;
00470 }
00471 
00472 /*virtual*/ mdb_err
00473 orkinTable::GetTableKind(nsIMdbEnv* mev, mdb_kind* outTableKind)
00474 {
00475   mdb_err outErr = 0;
00476   mdb_kind tableKind = 0;
00477   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00478   if ( ev )
00479   {
00480     morkTable* table = (morkTable*) mHandle_Object;
00481     tableKind = table->mTable_Kind;
00482     outErr = ev->AsErr();
00483   }
00484   if ( outTableKind )
00485     *outTableKind = tableKind;
00486   return outErr;
00487 }
00488 
00489 /*virtual*/ mdb_err
00490 orkinTable::GetRowScope(nsIMdbEnv* mev, mdb_scope* outRowScope)
00491 {
00492   mdb_err outErr = 0;
00493   mdb_scope rowScope = 0;
00494   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00495   if ( ev )
00496   {
00497     morkTable* table = (morkTable*) mHandle_Object;
00498     morkRowSpace* space = table->mTable_RowSpace;
00499     if ( space )
00500       rowScope = space->SpaceScope();
00501     else
00502       table->NilRowSpaceError(ev);
00503 
00504     outErr = ev->AsErr();
00505   }
00506   if ( outRowScope )
00507     *outRowScope = rowScope;
00508   return outErr;
00509 }
00510 
00511 /*virtual*/ mdb_err
00512 orkinTable::GetMetaRow( nsIMdbEnv* mev,
00513   const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying 
00514   mdbOid* outOid, // output meta row oid, can be nil to suppress output
00515   nsIMdbRow** acqRow) // acquire table's unique singleton meta row
00516   // The purpose of a meta row is to support the persistent recording of
00517   // meta info about a table as cells put into the distinguished meta row.
00518   // Each table has exactly one meta row, which is not considered a member
00519   // of the collection of rows inside the table.  The only way to tell
00520   // whether a row is a meta row is by the fact that it is returned by this
00521   // GetMetaRow() method from some table. Otherwise nothing distinguishes
00522   // a meta row from any other row.  A meta row can be used anyplace that
00523   // any other row can be used, and can even be put into other tables (or
00524   // the same table) as a table member, if this is useful for some reason.
00525   // The first attempt to access a table's meta row using GetMetaRow() will
00526   // cause the meta row to be created if it did not already exist.  When the
00527   // meta row is created, it will have the row oid that was previously
00528   // requested for this table's meta row; or if no oid was ever explicitly
00529   // specified for this meta row, then a unique oid will be generated in
00530   // the row scope named "metaScope" (so obviously MDB clients should not
00531   // manually allocate any row IDs from that special meta scope namespace).
00532   // The meta row oid can be specified either when the table is created, or
00533   // else the first time that GetMetaRow() is called, by passing a non-nil
00534   // pointer to an oid for parameter inOptionalMetaRowOid.  The meta row's
00535   // actual oid is returned in outOid (if this is a non-nil pointer), and
00536   // it will be different from inOptionalMetaRowOid when the meta row was
00537   // already given a different oid earlier.
00538 {
00539   mdb_err outErr = 0;
00540   nsIMdbRow* outRow = 0;
00541   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00542   if ( ev )
00543   {
00544     morkTable* table = (morkTable*) mHandle_Object;
00545     morkRow* row = table->GetMetaRow(ev, inOptionalMetaRowOid);
00546     if ( row && ev->Good() )
00547     {
00548       if ( outOid )
00549         *outOid = row->mRow_Oid;
00550         
00551       outRow = row->AcquireRowHandle(ev, table->mTable_Store);
00552     }
00553     outErr = ev->AsErr();
00554   }
00555   if ( acqRow )
00556     *acqRow = outRow;
00557     
00558   if ( ev->Bad() && outOid )
00559   {
00560     outOid->mOid_Scope = 0;
00561     outOid->mOid_Id = morkRow_kMinusOneRid;
00562   }
00563   return outErr;
00564 }
00565 
00566 // } ----- end attribute methods -----
00567 
00568 // { ----- begin cursor methods -----
00569 /*virtual*/ mdb_err
00570 orkinTable::GetTableRowCursor( // make a cursor, starting iteration at inRowPos
00571   nsIMdbEnv* mev, // context
00572   mdb_pos inRowPos, // zero-based ordinal position of row in table
00573   nsIMdbTableRowCursor** acqCursor) // acquire new cursor instance
00574 {
00575   mdb_err outErr = 0;
00576   nsIMdbTableRowCursor* outCursor = 0;
00577   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00578   if ( ev )
00579   {
00580     morkTableRowCursor* cursor =
00581       ((morkTable*) mHandle_Object)->NewTableRowCursor(ev, inRowPos);
00582     if ( cursor )
00583     {
00584       if ( ev->Good() )
00585       {
00586         // cursor->mCursor_Seed = (mork_seed) inRowPos;
00587         outCursor = cursor->AcquireTableRowCursorHandle(ev);
00588       }
00589       cursor->CutStrongRef(mev);
00590     }
00591       
00592     outErr = ev->AsErr();
00593   }
00594   if ( acqCursor )
00595     *acqCursor = outCursor;
00596   return outErr;
00597 }
00598 // } ----- end row position methods -----
00599 
00600 // { ----- begin row position methods -----
00601 /*virtual*/ mdb_err
00602 orkinTable::PosToOid( // get row member for a table position
00603   nsIMdbEnv* mev, // context
00604   mdb_pos inRowPos, // zero-based ordinal position of row in table
00605   mdbOid* outOid) // row oid at the specified position
00606 {
00607   mdb_err outErr = 0;
00608   mdbOid roid;
00609   roid.mOid_Scope = 0;
00610   roid.mOid_Id = (mork_id) -1;
00611   
00612   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00613   if ( ev )
00614   {
00615     morkTable* table = (morkTable*) mHandle_Object;
00616     morkRow* row = table->SafeRowAt(ev, inRowPos);
00617     if ( row )
00618       roid = row->mRow_Oid;
00619     
00620     outErr = ev->AsErr();
00621   }
00622   if ( outOid )
00623     *outOid = roid;
00624   return outErr;
00625 }
00626 
00627 /*virtual*/ mdb_err
00628 orkinTable::OidToPos( // test for the table position of a row member
00629   nsIMdbEnv* mev, // context
00630   const mdbOid* inOid, // row to find in table
00631   mdb_pos* outPos) // zero-based ordinal position of row in table
00632 {
00633   mdb_err outErr = 0;
00634   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00635   if ( ev )
00636   {
00637     mork_pos pos = ((morkTable*) mHandle_Object)->ArrayHasOid(ev, inOid);
00638     if ( outPos )
00639       *outPos = pos;
00640     outErr = ev->AsErr();
00641   }
00642   return outErr;
00643 }
00644 
00645 /*virtual*/ mdb_err
00646 orkinTable::PosToRow( // get row member for a table position
00647   nsIMdbEnv* mev, // context
00648   mdb_pos inRowPos, // zero-based ordinal position of row in table
00649   nsIMdbRow** acqRow) // acquire row at table position inRowPos
00650 {
00651   mdb_err outErr = 0;
00652   nsIMdbRow* outRow = 0;
00653   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00654   if ( ev )
00655   {
00656     morkTable* table = (morkTable*) mHandle_Object;
00657     morkStore* store = table->mTable_Store;
00658     morkRow* row = table->SafeRowAt(ev, inRowPos);
00659     if ( row && store )
00660       outRow = row->AcquireRowHandle(ev, store);
00661       
00662     outErr = ev->AsErr();
00663   }
00664   if ( acqRow )
00665     *acqRow = outRow;
00666   return outErr;
00667 }
00668 
00669 /*virtual*/ mdb_err
00670 orkinTable::RowToPos( // test for the table position of a row member
00671   nsIMdbEnv* mev, // context
00672   nsIMdbRow* ioRow, // row to find in table
00673   mdb_pos* outPos) // zero-based ordinal position of row in table
00674 {
00675   mdb_err outErr = 0;
00676   mork_pos pos = -1;
00677   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00678   if ( ev )
00679   {
00680     morkRow* row = (morkRow*) ioRow;
00681     morkTable* table = (morkTable*) mHandle_Object;
00682     pos = table->ArrayHasOid(ev, &row->mRow_Oid);
00683     outErr = ev->AsErr();
00684   }
00685   if ( outPos )
00686     *outPos = pos;
00687   return outErr;
00688 }
00689   
00690 // Note that HasRow() performs the inverse oid->pos mapping
00691 // } ----- end row position methods -----
00692 
00693 // { ----- begin oid set methods -----
00694 /*virtual*/ mdb_err
00695 orkinTable::AddOid( // make sure the row with inOid is a table member 
00696   nsIMdbEnv* mev, // context
00697   const mdbOid* inOid) // row to ensure membership in table
00698 {
00699   MORK_USED_1(inOid);
00700   mdb_err outErr = 0;
00701   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00702   if ( ev )
00703   {
00704     ev->StubMethodOnlyError();
00705     outErr = ev->AsErr();
00706   }
00707   return outErr;
00708 }
00709 
00710 /*virtual*/ mdb_err
00711 orkinTable::HasOid( // test for the table position of a row member
00712   nsIMdbEnv* mev, // context
00713   const mdbOid* inOid, // row to find in table
00714   mdb_bool* outHasOid) // whether inOid is a member row
00715 {
00716   mdb_err outErr = 0;
00717   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00718   if ( ev )
00719   {
00720     if ( outHasOid )
00721       *outHasOid = ((morkTable*) mHandle_Object)->MapHasOid(ev, inOid);
00722     outErr = ev->AsErr();
00723   }
00724   return outErr;
00725 }
00726 
00727 /*virtual*/ mdb_err
00728 orkinTable::CutOid( // make sure the row with inOid is not a member 
00729   nsIMdbEnv* mev, // context
00730   const mdbOid* inOid) // row to remove from table
00731 {
00732   mdb_err outErr = 0;
00733   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00734   if ( ev )
00735   {
00736     morkTable* table = (morkTable*) mHandle_Object;
00737     morkStore* store = table->mTable_Store;
00738     if ( inOid && store )
00739     {
00740       morkRow* row = store->GetRow(ev, inOid);
00741       if ( row )
00742         table->CutRow(ev, row);
00743     }
00744     else
00745       ev->NilPointerError();
00746       
00747     outErr = ev->AsErr();
00748   }
00749   return outErr;
00750 }
00751 // } ----- end oid set methods -----
00752 
00753 // { ----- begin row set methods -----
00754 /*virtual*/ mdb_err
00755 orkinTable::NewRow( // create a new row instance in table
00756   nsIMdbEnv* mev, // context
00757   mdbOid* ioOid, // please use zero (unbound) rowId for db-assigned IDs
00758   nsIMdbRow** acqRow) // create new row
00759 {
00760   mdb_err outErr = 0;
00761   nsIMdbRow* outRow = 0;
00762   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00763   if ( ev )
00764   {
00765     morkTable* table = (morkTable*) mHandle_Object;
00766     morkStore* store = table->mTable_Store;
00767     if ( ioOid && store )
00768     {
00769       morkRow* row = 0;
00770       if ( ioOid->mOid_Id == morkRow_kMinusOneRid )
00771         row = store->NewRow(ev, ioOid->mOid_Scope);
00772       else
00773         row = store->NewRowWithOid(ev, ioOid);
00774         
00775       if ( row && table->AddRow(ev, row) )
00776         outRow = row->AcquireRowHandle(ev, store);
00777     }
00778     else
00779       ev->NilPointerError();
00780       
00781     outErr = ev->AsErr();
00782   }
00783   if ( acqRow )
00784     *acqRow = outRow;
00785   return outErr;
00786 }
00787 
00788 /*virtual*/ mdb_err
00789 orkinTable::AddRow( // make sure the row with inOid is a table member 
00790   nsIMdbEnv* mev, // context
00791   nsIMdbRow* ioRow) // row to ensure membership in table
00792 {
00793   mdb_err outErr = 0;
00794   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00795   if ( ev )
00796   {
00797     morkRowObject *rowObj = (morkRowObject *) ioRow;
00798     morkRow* row = rowObj->mRowObject_Row;
00799     ((morkTable*) mHandle_Object)->AddRow(ev, row);
00800     outErr = ev->AsErr();
00801   }
00802   return outErr;
00803 }
00804 
00805 /*virtual*/ mdb_err
00806 orkinTable::HasRow( // test for the table position of a row member
00807   nsIMdbEnv* mev, // context
00808   nsIMdbRow* ioRow, // row to find in table
00809   mdb_bool* outBool) // zero-based ordinal position of row in table
00810 {
00811   mdb_err outErr = 0;
00812   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00813   if ( ev )
00814   {
00815     morkRowObject *rowObj = (morkRowObject *) ioRow;
00816     morkRow* row = rowObj->mRowObject_Row;
00817     morkTable* table = (morkTable*) mHandle_Object;
00818     if ( outBool )
00819       *outBool = table->MapHasOid(ev, &row->mRow_Oid);
00820     outErr = ev->AsErr();
00821   }
00822   return outErr;
00823 }
00824 
00825 
00826 /*virtual*/ mdb_err
00827 orkinTable::CutRow( // make sure the row with inOid is not a member 
00828   nsIMdbEnv* mev, // context
00829   nsIMdbRow* ioRow) // row to remove from table
00830 {
00831   mdb_err outErr = 0;
00832   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00833   if ( ev )
00834   {
00835     morkRowObject *rowObj = (morkRowObject *) ioRow;
00836     morkRow* row = rowObj->mRowObject_Row;
00837     ((morkTable*) mHandle_Object)->CutRow(ev, row);
00838     outErr = ev->AsErr();
00839   }
00840   return outErr;
00841 }
00842 
00843 /*virtual*/ mdb_err
00844 orkinTable::CutAllRows( // remove all rows from the table 
00845   nsIMdbEnv* mev) // context
00846 {
00847   mdb_err outErr = 0;
00848   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00849   if ( ev )
00850   {
00851     ((morkTable*) mHandle_Object)->CutAllRows(ev);
00852     outErr = ev->AsErr();
00853   }
00854   return outErr;
00855 }
00856 // } ----- end row set methods -----
00857 
00858 // { ----- begin searching methods -----
00859 /*virtual*/ mdb_err
00860 orkinTable::FindRowMatches( // search variable number of sorted cols
00861   nsIMdbEnv* mev, // context
00862   const mdbYarn* inPrefix, // content to find as prefix in row's column cell
00863   nsIMdbTableRowCursor** acqCursor) // set of matching rows
00864 {
00865   MORK_USED_1(inPrefix);
00866   nsIMdbTableRowCursor* outCursor = 0;
00867   mdb_err outErr = 0;
00868   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00869   if ( ev )
00870   {
00871     ev->StubMethodOnlyError();
00872     outErr = ev->AsErr();
00873   }
00874   if ( acqCursor )
00875     *acqCursor = outCursor;
00876   return outErr;
00877 }
00878   
00879 /*virtual*/ mdb_err
00880 orkinTable::GetSearchColumns( // query columns used by FindRowMatches()
00881   nsIMdbEnv* mev, // context
00882   mdb_count* outCount, // context
00883   mdbColumnSet* outColSet) // caller supplied space to put columns
00884   // GetSearchColumns() returns the columns actually searched when the
00885   // FindRowMatches() method is called.  No more than mColumnSet_Count
00886   // slots of mColumnSet_Columns will be written, since mColumnSet_Count
00887   // indicates how many slots are present in the column array.  The
00888   // actual number of search column used by the table is returned in
00889   // the outCount parameter; if this number exceeds mColumnSet_Count,
00890   // then a caller needs a bigger array to read the entire column set.
00891   // The minimum of mColumnSet_Count and outCount is the number slots
00892   // in mColumnSet_Columns that were actually written by this method.
00893   //
00894   // Callers are expected to change this set of columns by calls to
00895   // nsIMdbTable::SearchColumnsHint() or SetSearchSorting(), or both.
00896 {
00897   MORK_USED_1(outColSet);
00898   mdb_count count = 0;
00899   mdb_err outErr = 0;
00900 //  nsIMdbThumb* outThumb = 0;
00901   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00902   if ( ev )
00903   {
00904     ev->StubMethodOnlyError();
00905     outErr = ev->AsErr();
00906   }
00907   if ( outCount )
00908     *outCount = count;
00909   return outErr;
00910 }
00911 // } ----- end searching methods -----
00912 
00913 // { ----- begin hinting methods -----
00914 /*virtual*/ mdb_err
00915 orkinTable::SearchColumnsHint( // advise re future expected search cols  
00916   nsIMdbEnv* mev, // context
00917   const mdbColumnSet* inColumnSet) // columns likely to be searched
00918 {
00919   MORK_USED_1(inColumnSet);
00920   mdb_err outErr = 0;
00921   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00922   if ( ev )
00923   {
00924     // ev->StubMethodOnlyError(); // legal to do nothing
00925     outErr = ev->AsErr();
00926   }
00927   return outErr;
00928 }
00929   
00930 /*virtual*/ mdb_err
00931 orkinTable::SortColumnsHint( // advise re future expected sort columns  
00932   nsIMdbEnv* mev, // context
00933   const mdbColumnSet* inColumnSet) // columns for likely sort requests
00934 {
00935   MORK_USED_1(inColumnSet);
00936   mdb_err outErr = 0;
00937   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00938   if ( ev )
00939   {
00940     // ev->StubMethodOnlyError(); // legal to do nothing
00941     outErr = ev->AsErr();
00942   }
00943   return outErr;
00944 }
00945 
00946 /*virtual*/ mdb_err
00947 orkinTable::StartBatchChangeHint( // advise before many adds and cuts  
00948   nsIMdbEnv* mev, // context
00949   const void* inLabel) // intend unique address to match end call
00950   // If batch starts nest by virtue of nesting calls in the stack, then
00951   // the address of a local variable makes a good batch start label that
00952   // can be used at batch end time, and such addresses remain unique.
00953 {
00954   MORK_USED_1(inLabel);
00955   mdb_err outErr = 0;
00956   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00957   if ( ev )
00958   {
00959     // ev->StubMethodOnlyError(); // legal to do nothing
00960     outErr = ev->AsErr();
00961   }
00962   return outErr;
00963 }
00964 
00965 /*virtual*/ mdb_err
00966 orkinTable::EndBatchChangeHint( // advise before many adds and cuts  
00967   nsIMdbEnv* mev, // context
00968   const void* inLabel) // label matching start label
00969   // Suppose a table is maintaining one or many sort orders for a table,
00970   // so that every row added to the table must be inserted in each sort,
00971   // and every row cut must be removed from each sort.  If a db client
00972   // intends to make many such changes before needing any information
00973   // about the order or positions of rows inside a table, then a client
00974   // might tell the table to start batch changes in order to disable
00975   // sorting of rows for the interim.  Presumably a table will then do
00976   // a full sort of all rows at need when the batch changes end, or when
00977   // a surprise request occurs for row position during batch changes.
00978 {
00979   MORK_USED_1(inLabel);
00980   mdb_err outErr = 0;
00981   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00982   if ( ev )
00983   {
00984     // ev->StubMethodOnlyError(); // legal to do nothing
00985     outErr = ev->AsErr();
00986   }
00987   return outErr;
00988 }
00989 // } ----- end hinting methods -----
00990 
00991 // { ----- begin sorting methods -----
00992 // sorting: note all rows are assumed sorted by row ID as a secondary
00993 // sort following the primary column sort, when table rows are sorted.
00994 
00995 /*virtual*/ mdb_err
00996 orkinTable::CanSortColumn( // query which column is currently used for sorting
00997   nsIMdbEnv* mev, // context
00998   mdb_column inColumn, // column to query sorting potential
00999   mdb_bool* outCanSort) // whether the column can be sorted
01000 {
01001   MORK_USED_1(inColumn);
01002   mdb_bool canSort = mdbBool_kFalse;
01003   mdb_err outErr = 0;
01004   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
01005   if ( ev )
01006   {
01007     // ev->StubMethodOnlyError();
01008     outErr = ev->AsErr();
01009   }
01010   if ( outCanSort )
01011     *outCanSort = canSort;
01012   return outErr;
01013 }
01014 
01015 /*virtual*/ mdb_err
01016 orkinTable::GetSorting( // view same table in particular sorting
01017   nsIMdbEnv* mev, // context
01018   mdb_column inColumn, // requested new column for sorting table
01019   nsIMdbSorting** acqSorting) // acquire sorting for column
01020 {
01021   MORK_USED_1(inColumn);
01022   nsIMdbSorting* outSorting = 0;
01023   mdb_err outErr = 0;
01024   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
01025   if ( ev )
01026   {
01027     ev->StubMethodOnlyError();
01028     outErr = ev->AsErr();
01029   }
01030   if ( acqSorting )
01031     *acqSorting = outSorting;
01032   return outErr;
01033 }
01034 
01035 /*virtual*/ mdb_err
01036 orkinTable::SetSearchSorting( // use this sorting in FindRowMatches()
01037   nsIMdbEnv* mev, // context
01038   mdb_column inColumn, // often same as nsIMdbSorting::GetSortColumn()
01039   nsIMdbSorting* ioSorting) // requested sorting for some column
01040   // SetSearchSorting() attempts to inform the table that ioSorting
01041   // should be used during calls to FindRowMatches() for searching
01042   // the column which is actually sorted by ioSorting.  This method
01043   // is most useful in conjunction with nsIMdbSorting::SetCompare(),
01044   // because otherwise a caller would not be able to override the
01045   // comparison ordering method used during searchs.  Note that some
01046   // database implementations might be unable to use an arbitrarily
01047   // specified sort order, either due to schema or runtime interface
01048   // constraints, in which case ioSorting might not actually be used.
01049   // Presumably ioSorting is an instance that was returned from some
01050   // earlier call to nsIMdbTable::GetSorting().  A caller can also
01051   // use nsIMdbTable::SearchColumnsHint() to specify desired change
01052   // in which columns are sorted and searched by FindRowMatches().
01053   //
01054   // A caller can pass a nil pointer for ioSorting to request that
01055   // column inColumn no longer be used at all by FindRowMatches().
01056   // But when ioSorting is non-nil, then inColumn should match the
01057   // column actually sorted by ioSorting; when these do not agree,
01058   // implementations are instructed to give precedence to the column
01059   // specified by ioSorting (so this means callers might just pass
01060   // zero for inColumn when ioSorting is also provided, since then
01061   // inColumn is both redundant and ignored).
01062 {
01063   MORK_USED_1(inColumn);
01064   mdb_err outErr = 0;
01065   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
01066   if ( ev )
01067   {
01068     if ( ioSorting )
01069     {
01070       ev->StubMethodOnlyError();
01071     }
01072     else
01073       ev->NilPointerError();
01074       
01075     outErr = ev->AsErr();
01076   }
01077   return outErr;
01078 }
01079 
01080 // } ----- end sorting methods -----
01081 
01082 // { ----- begin moving methods -----
01083 // moving a row does nothing unless a table is currently unsorted
01084 
01085 /*virtual*/ mdb_err
01086 orkinTable::MoveOid( // change position of row in unsorted table
01087   nsIMdbEnv* mev, // context
01088   const mdbOid* inOid,  // row oid to find in table
01089   mdb_pos inHintFromPos, // suggested hint regarding start position
01090   mdb_pos inToPos,       // desired new position for row inOid
01091   mdb_pos* outActualPos) // actual new position of row in table
01092 {
01093   mdb_err outErr = 0;
01094   mdb_pos actualPos = -1; // meaning it was never found in table
01095   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
01096   if ( ev )
01097   {
01098     morkTable* table = (morkTable*) mHandle_Object;
01099     morkStore* store = table->mTable_Store;
01100     if ( inOid && store )
01101     {
01102       morkRow* row = store->GetRow(ev, inOid);
01103       if ( row )
01104         actualPos = table->MoveRow(ev, row, inHintFromPos, inToPos);
01105     }
01106     else
01107       ev->NilPointerError();
01108 
01109     outErr = ev->AsErr();
01110   }
01111   if ( outActualPos )
01112     *outActualPos = actualPos;
01113   return outErr;
01114 }
01115 
01116 /*virtual*/ mdb_err
01117 orkinTable::MoveRow( // change position of row in unsorted table
01118   nsIMdbEnv* mev, // context
01119   nsIMdbRow* ioRow,  // row oid to find in table
01120   mdb_pos inHintFromPos, // suggested hint regarding start position
01121   mdb_pos inToPos,       // desired new position for row ioRow
01122   mdb_pos* outActualPos) // actual new position of row in table
01123 {
01124   mdb_pos actualPos = -1; // meaning it was never found in table
01125   mdb_err outErr = 0;
01126   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
01127   if ( ev )
01128   {
01129     morkRowObject *rowObj = (morkRowObject *) ioRow;
01130     morkRow* row = rowObj->mRowObject_Row;
01131     morkTable* table = (morkTable*) mHandle_Object;
01132     actualPos = table->MoveRow(ev, row, inHintFromPos, inToPos);
01133     outErr = ev->AsErr();
01134   }
01135   if ( outActualPos )
01136     *outActualPos = actualPos;
01137   return outErr;
01138 }
01139 // } ----- end moving methods -----
01140 
01141 // { ----- begin index methods -----
01142 /*virtual*/ mdb_err
01143 orkinTable::AddIndex( // create a sorting index for column if possible
01144   nsIMdbEnv* mev, // context
01145   mdb_column inColumn, // the column to sort by index
01146   nsIMdbThumb** acqThumb) // acquire thumb for incremental index building
01147 // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
01148 // then the index addition will be finished.
01149 {
01150   MORK_USED_1(inColumn);
01151   nsIMdbThumb* outThumb = 0;
01152   mdb_err outErr = 0;
01153   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
01154   if ( ev )
01155   {
01156     // ev->StubMethodOnlyError(); // legal to do nothing
01157      
01158     outErr = ev->AsErr();
01159   }
01160   if ( acqThumb )
01161     *acqThumb = outThumb;
01162 
01163   return outErr;
01164 }
01165 
01166 /*virtual*/ mdb_err
01167 orkinTable::CutIndex( // stop supporting a specific column index
01168   nsIMdbEnv* mev, // context
01169   mdb_column inColumn, // the column with index to be removed
01170   nsIMdbThumb** acqThumb) // acquire thumb for incremental index destroy
01171 // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
01172 // then the index removal will be finished.
01173 {
01174   MORK_USED_1(inColumn);
01175   mdb_err outErr = 0;
01176   nsIMdbThumb* outThumb = 0;
01177   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
01178   if ( ev )
01179   {
01180     // ev->StubMethodOnlyError(); // legal to do nothing
01181     
01182     outErr = ev->AsErr();
01183   }
01184   if ( acqThumb )
01185     *acqThumb = outThumb;
01186     
01187   return outErr;
01188 }
01189 
01190 /*virtual*/ mdb_err
01191 orkinTable::HasIndex( // query for current presence of a column index
01192   nsIMdbEnv* mev, // context
01193   mdb_column inColumn, // the column to investigate
01194   mdb_bool* outHasIndex) // whether column has index for this column
01195 {
01196   MORK_USED_1(inColumn);
01197   mdb_bool hasIndex = morkBool_kFalse;
01198   mdb_err outErr = 0;
01199   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
01200   if ( ev )
01201   {
01202       
01203     outErr = ev->AsErr();
01204   }
01205   if ( outHasIndex )
01206     *outHasIndex = hasIndex;
01207   return outErr;
01208 }
01209 
01210 /*virtual*/ mdb_err
01211 orkinTable::EnableIndexOnSort( // create an index for col on first sort
01212   nsIMdbEnv* mev, // context
01213   mdb_column inColumn) // the column to index if ever sorted
01214 {
01215   MORK_USED_1(inColumn);
01216   mdb_err outErr = 0;
01217   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
01218   if ( ev )
01219   {
01220     // ev->StubMethodOnlyError(); // legal to do nothing
01221     outErr = ev->AsErr();
01222   }
01223   return outErr;
01224 }
01225 
01226 /*virtual*/ mdb_err
01227 orkinTable::QueryIndexOnSort( // check whether index on sort is enabled
01228   nsIMdbEnv* mev, // context
01229   mdb_column inColumn, // the column to investigate
01230   mdb_bool* outIndexOnSort) // whether column has index-on-sort enabled
01231 {
01232   MORK_USED_1(inColumn);
01233   mdb_bool indexOnSort = morkBool_kFalse;
01234   mdb_err outErr = 0;
01235   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
01236   if ( ev )
01237   {
01238       
01239     outErr = ev->AsErr();
01240   }
01241   if ( outIndexOnSort )
01242     *outIndexOnSort = indexOnSort;
01243   return outErr;
01244 }
01245 
01246 /*virtual*/ mdb_err
01247 orkinTable::DisableIndexOnSort( // prevent future index creation on sort
01248   nsIMdbEnv* mev, // context
01249   mdb_column inColumn) // the column to index if ever sorted
01250 {
01251   MORK_USED_1(inColumn);
01252   mdb_err outErr = 0;
01253   morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
01254   if ( ev )
01255   {
01256     // ev->StubMethodOnlyError(); // legal to do nothing
01257     outErr = ev->AsErr();
01258   }
01259   return outErr;
01260 }
01261 // } ----- end index methods -----
01262 
01263 // } ===== end nsIMdbTable methods =====
01264 
01265 
01266 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789