Back to index

lightning-sunbird  0.9+nobinonly
orkinSorting.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 _MORKSORTING_
00055 #include "morkSorting.h"
00056 #endif
00057 
00058 #ifndef _MORKTABLE_
00059 #include "morkTable.h"
00060 #endif
00061 
00062 #ifndef _MORKENV_
00063 #include "morkEnv.h"
00064 #endif
00065 
00066 #ifndef _ORKINTABLE_
00067 #include "orkinTable.h"
00068 #endif
00069 
00070 #ifndef _ORKINSORTING_
00071 #include "orkinSorting.h"
00072 #endif
00073 
00074 #ifndef _ORKINROW_
00075 #include "orkinRow.h"
00076 #endif
00077 
00078 #ifndef _MORKTABLEROWCURSOR_
00079 #include "morkTableRowCursor.h"
00080 #endif
00081 
00082 #ifndef _ORKINTABLEROWCURSOR_
00083 #include "orkinTableRowCursor.h"
00084 #endif
00085 
00086 #ifndef _MORKROWSPACE_
00087 #include "morkRowSpace.h"
00088 #endif
00089 
00090 #ifndef _MORKSTORE_
00091 #include "morkStore.h"
00092 #endif
00093 
00094 #ifndef _ORKINSTORE_
00095 #include "orkinStore.h"
00096 #endif
00097 
00098 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00099 
00100 /* public virtual*/
00101 orkinSorting:: ~orkinSorting() // morkHandle destructor does everything
00102 {
00103 }
00104 
00105 /*protected non-poly construction*/
00106 orkinSorting::orkinSorting(morkEnv* ev, // morkUsage is morkUsage_kPool
00107     morkHandleFace* ioFace,    // must not be nil, cookie for this handle
00108     morkSorting* ioObject)  // must not be nil, the object for this handle
00109 : morkHandle(ev, ioFace, ioObject, morkMagic_kSorting)
00110 {
00111   // do not modify mNode_Derived; leave it equal to morkDerived_kHandle
00112 }
00113 
00114 
00115 /*static */ orkinSorting*
00116 orkinSorting::MakeSorting(morkEnv* ev, morkSorting* ioObject)
00117 {
00118   mork_bool isEnv = ev->IsEnv();
00119   MORK_ASSERT(isEnv);
00120   if ( isEnv )
00121   {
00122     morkHandleFace* face = ev->NewHandle(sizeof(orkinSorting));
00123     if ( face )
00124       return new(face) orkinSorting(ev, face, ioObject);
00125     else
00126       ev->OutOfMemoryError();
00127   }
00128     
00129   return (orkinSorting*) 0;
00130 }
00131 
00132 morkEnv*
00133 orkinSorting::CanUseSorting(nsIMdbEnv* mev,
00134   mork_bool inMutable, mdb_err* outErr) const
00135 {
00136   morkEnv* outEnv = 0;
00137   morkEnv* ev = morkEnv::FromMdbEnv(mev);
00138   if ( ev )
00139   {
00140     morkSorting* self = (morkSorting*)
00141       this->GetGoodHandleObject(ev, inMutable, morkMagic_kSorting,
00142         /*inClosedOkay*/ morkBool_kFalse);
00143     if ( self )
00144     {
00145       if ( self->IsSorting() )
00146         outEnv = ev;
00147       else
00148         self->NonSortingTypeError(ev);
00149     }
00150     *outErr = ev->AsErr();
00151   }
00152   MORK_ASSERT(outEnv);
00153   return outEnv;
00154 }
00155 
00156 
00157 // { ===== begin nsIMdbISupports methods =====
00158 NS_IMPL_QUERY_INTERFACE0(orkinSorting)
00159 
00160 /*virtual*/ nsrefcnt
00161 orkinSorting::AddRef() // add strong ref with no
00162 {
00163   morkEnv* ev = mHandle_Env;
00164   if ( ev && ev->IsEnv() )
00165     return this->Handle_AddStrongRef(ev->AsMdbEnv());
00166   else
00167     return morkEnv_kNonEnvTypeError;
00168 }
00169 
00170 /*virtual*/ nsrefcnt
00171 orkinSorting::Release() // cut strong ref
00172 {
00173   morkEnv* ev = mHandle_Env;
00174   if ( ev && ev->IsEnv() )
00175     return this->Handle_CutStrongRef(ev->AsMdbEnv());
00176   else
00177     return morkEnv_kNonEnvTypeError;
00178 }
00179 // } ===== end nsIMdbISupports methods =====
00180 
00181 // { ===== begin nsIMdbObject methods =====
00182 
00183 // { ----- begin attribute methods -----
00184 /*virtual*/ mdb_err
00185 orkinSorting::IsFrozenMdbObject(nsIMdbEnv* mev, mdb_bool* outIsReadonly)
00186 {
00187   return this->Handle_IsFrozenMdbObject(mev, outIsReadonly);
00188 }
00189 // same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port.
00190 // } ----- end attribute methods -----
00191 
00192 // { ----- begin factory methods -----
00193 /*virtual*/ mdb_err
00194 orkinSorting::GetMdbFactory(nsIMdbEnv* mev, nsIMdbFactory** acqFactory)
00195 {
00196   return this->Handle_GetMdbFactory(mev, acqFactory);
00197 } 
00198 // } ----- end factory methods -----
00199 
00200 // { ----- begin ref counting for well-behaved cyclic graphs -----
00201 /*virtual*/ mdb_err
00202 orkinSorting::GetWeakRefCount(nsIMdbEnv* mev, // weak refs
00203   mdb_count* outCount)
00204 {
00205   return this->Handle_GetWeakRefCount(mev, outCount);
00206 }  
00207 /*virtual*/ mdb_err
00208 orkinSorting::GetStrongRefCount(nsIMdbEnv* mev, // strong refs
00209   mdb_count* outCount)
00210 {
00211   return this->Handle_GetStrongRefCount(mev, outCount);
00212 }
00213 
00214 /*virtual*/ mdb_err
00215 orkinSorting::AddWeakRef(nsIMdbEnv* mev)
00216 {
00217   return this->Handle_AddWeakRef(mev);
00218 }
00219 /*virtual*/ mdb_err
00220 orkinSorting::AddStrongRef(nsIMdbEnv* mev)
00221 {
00222   return this->Handle_AddStrongRef(mev);
00223 }
00224 
00225 /*virtual*/ mdb_err
00226 orkinSorting::CutWeakRef(nsIMdbEnv* mev)
00227 {
00228   return this->Handle_CutWeakRef(mev);
00229 }
00230 /*virtual*/ mdb_err
00231 orkinSorting::CutStrongRef(nsIMdbEnv* mev)
00232 {
00233   return this->Handle_CutStrongRef(mev);
00234 }
00235 
00236 /*virtual*/ mdb_err
00237 orkinSorting::CloseMdbObject(nsIMdbEnv* mev)
00238 {
00239   return this->Handle_CloseMdbObject(mev);
00240 }
00241 
00242 /*virtual*/ mdb_err
00243 orkinSorting::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
00244 {
00245   return this->Handle_IsOpenMdbObject(mev, outOpen);
00246 }
00247 // } ----- end ref counting -----
00248 
00249 // } ===== end nsIMdbObject methods =====
00250 
00251 
00252 // { ===== begin nsIMdbSorting methods =====
00253 
00254 // { ----- begin attribute methods -----
00255 
00256 
00257 /*virtual*/ mdb_err
00258 orkinSorting::GetTable(nsIMdbEnv* mev, nsIMdbTable** acqTable)
00259 {
00260   mdb_err outErr = 0;
00261   nsIMdbTable* outTable = 0;
00262   morkEnv* ev = this->CanUseSorting(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00263   if ( ev )
00264   {
00265     morkSorting* sorting = (morkSorting*) mHandle_Object;
00266     morkTable* table = sorting->mSorting_Table;
00267     if ( table && ev->Good() )
00268     {
00269       outTable = table->AcquireTableHandle(ev);
00270     }
00271     outErr = ev->AsErr();
00272   }
00273   if ( acqTable )
00274     *acqTable = outTable;
00275 
00276   return outErr;
00277 }
00278 
00279 /*virtual*/ mdb_err
00280 orkinSorting::GetSortColumn( // query which col is currently sorted
00281   nsIMdbEnv* mev, // context
00282   mdb_column* outColumn) // col the table uses for sorting (or zero)
00283 {
00284   mdb_err outErr = 0;
00285   mdb_column col = 0;
00286   morkEnv* ev = this->CanUseSorting(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00287   if ( ev )
00288   {
00289     morkSorting* sorting = (morkSorting*) mHandle_Object;
00290     col = sorting->mSorting_Col;
00291 
00292     outErr = ev->AsErr();
00293   }
00294   if ( outColumn )
00295     *outColumn = col;
00296 
00297   return outErr;
00298 }
00299 
00300 /*virtual*/ mdb_err
00301 orkinSorting::SetNewCompare(nsIMdbEnv* mev,
00302   nsIMdbCompare* ioNewCompare)
00303   // Setting the sorting's compare object will typically cause the rows
00304   // to be resorted, presumably in a lazy fashion when the sorting is
00305   // next required to be in a valid row ordering state, such as when a
00306   // call to PosToOid() happens.  ioNewCompare can be nil, in which case
00307   // implementations should revert to the default sort order, which must
00308   // be equivalent to whatever is used by nsIMdbFactory::MakeCompare().
00309 {
00310   mdb_err outErr = 0;
00311   morkEnv* ev = this->CanUseSorting(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00312   if ( ev )
00313   {
00314     if ( ioNewCompare )
00315     {
00316       morkSorting* sorting = (morkSorting*) mHandle_Object;
00317       nsIMdbCompare_SlotStrongCompare(ioNewCompare, ev,
00318         &sorting->mSorting_Compare);
00319     }
00320     else
00321       ev->NilPointerError();
00322       
00323     outErr = ev->AsErr();
00324   }
00325 
00326   return outErr;
00327 }
00328 
00329 /*virtual*/ mdb_err
00330 orkinSorting::GetOldCompare(nsIMdbEnv* mev,
00331   nsIMdbCompare** acqOldCompare)
00332   // Get this sorting instance's compare object, which handles the
00333   // ordering of rows in the sorting, by comparing yarns from the cells
00334   // in the column being sorted.  Since nsIMdbCompare has no interface
00335   // to query the state of the compare object, it is not clear what you
00336   // would do with this object when returned, except maybe compare it
00337   // as a pointer address to some other instance, to check identities.
00338 {
00339   mdb_err outErr = 0;
00340   nsIMdbCompare* outCompare = 0;
00341   morkEnv* ev = this->CanUseSorting(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00342   if ( ev )
00343   {
00344     morkSorting* sorting = (morkSorting*) mHandle_Object;
00345     nsIMdbCompare* compare = sorting->mSorting_Compare;
00346     if ( compare && ev->Good() )
00347     {
00348       compare->AddStrongRef(mev);
00349         
00350       if ( ev->Good() )
00351         outCompare = compare;
00352     }
00353     outErr = ev->AsErr();
00354   }
00355   if ( acqOldCompare )
00356     *acqOldCompare = outCompare;
00357 
00358   return outErr;
00359 }  
00360 
00361 // } ----- end attribute methods -----
00362 
00363 
00364 // { ----- begin cursor methods -----
00365 /*virtual*/ mdb_err
00366 orkinSorting::GetSortingRowCursor( // make a cursor, starting at inRowPos
00367   nsIMdbEnv* mev, // context
00368   mdb_pos inRowPos, // zero-based ordinal position of row in table
00369   nsIMdbTableRowCursor** acqCursor) // acquire new cursor instance
00370   // A cursor interface turning same info as PosToOid() or PosToRow().
00371 {
00372   mdb_err outErr = 0;
00373   nsIMdbTableRowCursor* outCursor = 0;
00374   morkEnv* ev = this->CanUseSorting(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00375   if ( ev )
00376   {
00377     morkSortingRowCursor* cursor =
00378       ((morkSorting*) mHandle_Object)->NewSortingRowCursor(ev, inRowPos);
00379     if ( cursor )
00380     {
00381       // $$$$$
00382       // if ( ev->Good() )
00383       // {
00384       //   outCursor = cursor->AcquireSortingRowCursorHandle(ev);
00385       // }
00386       // else
00387       //   cursor->CutStrongRef(ev);
00388     }
00389       
00390     outErr = ev->AsErr();
00391   }
00392   if ( acqCursor )
00393     *acqCursor = outCursor;
00394   return outErr;
00395 }
00396 
00397 // } ----- end row position methods -----
00398 
00399 // { ----- begin row position methods -----
00400 /*virtual*/ mdb_err
00401 orkinSorting::PosToOid( // get row member for a table position
00402   nsIMdbEnv* mev, // context
00403   mdb_pos inRowPos, // zero-based ordinal position of row in table
00404   mdbOid* outOid) // row oid at the specified position
00405 {
00406   mdb_err outErr = 0;
00407   mdbOid roid;
00408   roid.mOid_Scope = 0;
00409   roid.mOid_Id = (mork_id) -1;
00410   
00411   morkEnv* ev = this->CanUseSorting(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00412   if ( ev )
00413   {
00414     morkSorting* sorting = (morkSorting*) mHandle_Object;
00415     morkRow* row = sorting->SafeRowAt(ev, inRowPos);
00416     if ( row )
00417       roid = row->mRow_Oid;
00418     
00419     outErr = ev->AsErr();
00420   }
00421   if ( outOid )
00422     *outOid = roid;
00423   return outErr;
00424 }
00425 
00426 /*virtual*/ mdb_err
00427 orkinSorting::PosToRow( // get row member for a table position
00428   nsIMdbEnv* mev, // context
00429   mdb_pos inRowPos, // zero-based ordinal position of row in table
00430   nsIMdbRow** acqRow) // acquire row at table position inRowPos
00431 {
00432   mdb_err outErr = 0;
00433   nsIMdbRow* outRow = 0;
00434   morkEnv* ev = this->CanUseSorting(mev, /*inMutable*/ morkBool_kFalse, &outErr);
00435   if ( ev )
00436   {
00437     morkSorting* sorting = (morkSorting*) mHandle_Object;
00438     morkStore* store = sorting->mSorting_Table->mTable_Store;
00439     morkRow* row = sorting->SafeRowAt(ev, inRowPos);
00440     if ( row && store )
00441       outRow = row->AcquireRowHandle(ev, store);
00442       
00443     outErr = ev->AsErr();
00444   }
00445   if ( acqRow )
00446     *acqRow = outRow;
00447   return outErr;
00448 }
00449   
00450 // Note that HasRow() performs the inverse oid->pos mapping
00451 // } ----- end row position methods -----
00452 
00453 
00454 // } ===== end nsIMdbSorting methods =====
00455 
00456 
00457 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789