Back to index

lightning-sunbird  0.9+nobinonly
orkinTable.h
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 _ORKINTABLE_
00039 #define _ORKINTABLE_ 1
00040 
00041 #ifndef _MDB_
00042 #include "mdb.h"
00043 #endif
00044 
00045 #ifndef _MORK_
00046 #include "mork.h"
00047 #endif
00048 
00049 #ifndef _MORKNODE_
00050 #include "morkNode.h"
00051 #endif
00052 
00053 #ifndef _MORKHANDLE_
00054 #include "morkHandle.h"
00055 #endif
00056 
00057 #ifndef _MORKTABLE_
00058 #include "morkTable.h"
00059 #endif
00060 
00061 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00062 
00063 #define morkMagic_kTable 0x5461626C /* ascii 'Tabl' */
00064 
00065 /*| orkinTable: 
00066 |*/
00067 class orkinTable : public morkHandle, public nsIMdbTable { // nsIMdbTable
00068 
00069 // { ===== begin morkNode interface =====
00070 public: // morkNode virtual methods
00071   // virtual void CloseMorkNode(morkEnv* ev); // morkHandle is fine
00072   virtual ~orkinTable(); // morkHandle destructor does everything
00073   
00074 protected: // construction is protected (use the static Make() method)
00075   orkinTable(morkEnv* ev, // note morkUsage is always morkUsage_kPool
00076     morkHandleFace* ioFace,    // must not be nil, cookie for this handle
00077     morkTable* ioObject); // must not be nil, the object for this handle
00078     
00079   // void CloseHandle(morkEnv* ev); // don't need to specialize closing
00080 
00081 private: // copying is not allowed
00082   orkinTable(const orkinTable& other);
00083   orkinTable& operator=(const orkinTable& other);
00084 
00085 // public: // dynamic type identification
00086   // mork_bool IsHandle() const //
00087   // { return IsNode() && mNode_Derived == morkDerived_kHandle; }
00088 // } ===== end morkNode methods =====
00089 
00090 protected: // morkHandle memory management operators
00091   void* operator new(size_t inSize, morkPool& ioPool, morkZone& ioZone, morkEnv* ev) CPP_THROW_NEW
00092   { return ioPool.NewHandle(ev, inSize, &ioZone); }
00093   
00094   void* operator new(size_t inSize, morkPool& ioPool, morkEnv* ev) CPP_THROW_NEW
00095   { return ioPool.NewHandle(ev, inSize, (morkZone*) 0); }
00096   
00097   void* operator new(size_t inSize, morkHandleFace* ioFace) CPP_THROW_NEW
00098   { MORK_USED_1(inSize); return ioFace; }
00099   
00100   
00101 public: // construction:
00102 
00103   static orkinTable* MakeTable(morkEnv* ev, morkTable* ioObject);
00104 
00105 public: // utilities:
00106 
00107   morkEnv* CanUseTable(nsIMdbEnv* mev, mork_bool inMutable,
00108     mdb_err* outErr) const;
00109 
00110 public: // type identification
00111   mork_bool IsOrkinTable() const
00112   { return mHandle_Magic == morkMagic_kTable; }
00113 
00114   mork_bool IsOrkinTableHandle() const
00115   { return this->IsHandle() && this->IsOrkinTable(); }
00116 
00117   NS_DECL_ISUPPORTS
00118 // { ===== begin nsIMdbObject methods =====
00119 
00120   // { ----- begin attribute methods -----
00121   NS_IMETHOD IsFrozenMdbObject(nsIMdbEnv* ev, mdb_bool* outIsReadonly);
00122   // same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port.
00123   // } ----- end attribute methods -----
00124 
00125   // { ----- begin factory methods -----
00126   NS_IMETHOD GetMdbFactory(nsIMdbEnv* ev, nsIMdbFactory** acqFactory); 
00127   // } ----- end factory methods -----
00128 
00129   // { ----- begin ref counting for well-behaved cyclic graphs -----
00130   NS_IMETHOD GetWeakRefCount(nsIMdbEnv* ev, // weak refs
00131     mdb_count* outCount);  
00132   NS_IMETHOD GetStrongRefCount(nsIMdbEnv* ev, // strong refs
00133     mdb_count* outCount);
00134 
00135   NS_IMETHOD AddWeakRef(nsIMdbEnv* ev);
00136   NS_IMETHOD AddStrongRef(nsIMdbEnv* ev);
00137 
00138   NS_IMETHOD CutWeakRef(nsIMdbEnv* ev);
00139   NS_IMETHOD CutStrongRef(nsIMdbEnv* ev);
00140   
00141   NS_IMETHOD CloseMdbObject(nsIMdbEnv* ev); // called at strong refs zero
00142   NS_IMETHOD IsOpenMdbObject(nsIMdbEnv* ev, mdb_bool* outOpen);
00143   // } ----- end ref counting -----
00144   
00145 // } ===== end nsIMdbObject methods =====
00146 
00147 // { ===== begin nsIMdbCollection methods =====
00148 
00149   // { ----- begin attribute methods -----
00150   NS_IMETHOD GetSeed(nsIMdbEnv* ev,
00151     mdb_seed* outSeed);    // member change count
00152   NS_IMETHOD GetCount(nsIMdbEnv* ev,
00153     mdb_count* outCount); // member count
00154 
00155   NS_IMETHOD GetPort(nsIMdbEnv* ev,
00156     nsIMdbPort** acqPort); // collection container
00157   // } ----- end attribute methods -----
00158 
00159   // { ----- begin cursor methods -----
00160   NS_IMETHOD GetCursor( // make a cursor starting iter at inMemberPos
00161     nsIMdbEnv* ev, // context
00162     mdb_pos inMemberPos, // zero-based ordinal pos of member in collection
00163     nsIMdbCursor** acqCursor); // acquire new cursor instance
00164   // } ----- end cursor methods -----
00165 
00166   // { ----- begin ID methods -----
00167   NS_IMETHOD GetOid(nsIMdbEnv* ev,
00168     mdbOid* outOid); // read object identity
00169   NS_IMETHOD BecomeContent(nsIMdbEnv* ev,
00170     const mdbOid* inOid); // exchange content
00171   // } ----- end ID methods -----
00172 
00173   // { ----- begin activity dropping methods -----
00174   NS_IMETHOD DropActivity( // tell collection usage no longer expected
00175     nsIMdbEnv* ev);
00176   // } ----- end activity dropping methods -----
00177 
00178 // } ===== end nsIMdbCollection methods =====
00179 
00180 // { ===== begin nsIMdbTable methods =====
00181 
00182   // { ----- begin meta attribute methods -----
00183   NS_IMETHOD SetTablePriority(nsIMdbEnv* ev, mdb_priority inPrio);
00184   NS_IMETHOD GetTablePriority(nsIMdbEnv* ev, mdb_priority* outPrio);
00185   
00186   NS_IMETHOD GetTableBeVerbose(nsIMdbEnv* ev, mdb_bool* outBeVerbose);
00187   NS_IMETHOD SetTableBeVerbose(nsIMdbEnv* ev, mdb_bool inBeVerbose);
00188   
00189   NS_IMETHOD GetTableIsUnique(nsIMdbEnv* ev, mdb_bool* outIsUnique);
00190 
00191   NS_IMETHOD GetTableKind(nsIMdbEnv* ev, mdb_kind* outTableKind);
00192   NS_IMETHOD GetRowScope(nsIMdbEnv* ev, mdb_scope* outRowScope);
00193   
00194   NS_IMETHOD GetMetaRow(
00195     nsIMdbEnv* ev, // context
00196     const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying 
00197     mdbOid* outOid, // output meta row oid, can be nil to suppress output
00198     nsIMdbRow** acqRow); // acquire table's unique singleton meta row
00199     // The purpose of a meta row is to support the persistent recording of
00200     // meta info about a table as cells put into the distinguished meta row.
00201     // Each table has exactly one meta row, which is not considered a member
00202     // of the collection of rows inside the table.  The only way to tell
00203     // whether a row is a meta row is by the fact that it is returned by this
00204     // GetMetaRow() method from some table. Otherwise nothing distinguishes
00205     // a meta row from any other row.  A meta row can be used anyplace that
00206     // any other row can be used, and can even be put into other tables (or
00207     // the same table) as a table member, if this is useful for some reason.
00208     // The first attempt to access a table's meta row using GetMetaRow() will
00209     // cause the meta row to be created if it did not already exist.  When the
00210     // meta row is created, it will have the row oid that was previously
00211     // requested for this table's meta row; or if no oid was ever explicitly
00212     // specified for this meta row, then a unique oid will be generated in
00213     // the row scope named "metaScope" (so obviously MDB clients should not
00214     // manually allocate any row IDs from that special meta scope namespace).
00215     // The meta row oid can be specified either when the table is created, or
00216     // else the first time that GetMetaRow() is called, by passing a non-nil
00217     // pointer to an oid for parameter inOptionalMetaRowOid.  The meta row's
00218     // actual oid is returned in outOid (if this is a non-nil pointer), and
00219     // it will be different from inOptionalMetaRowOid when the meta row was
00220     // already given a different oid earlier.
00221   // } ----- end meta attribute methods -----
00222 
00223   // { ----- begin cursor methods -----
00224   NS_IMETHOD GetTableRowCursor( // make a cursor, starting iteration at inRowPos
00225     nsIMdbEnv* ev, // context
00226     mdb_pos inRowPos, // zero-based ordinal position of row in table
00227     nsIMdbTableRowCursor** acqCursor); // acquire new cursor instance
00228   // } ----- end row position methods -----
00229 
00230   // { ----- begin row position methods -----
00231   NS_IMETHOD PosToOid( // get row member for a table position
00232     nsIMdbEnv* ev, // context
00233     mdb_pos inRowPos, // zero-based ordinal position of row in table
00234     mdbOid* outOid); // row oid at the specified position
00235 
00236   NS_IMETHOD OidToPos( // test for the table position of a row member
00237     nsIMdbEnv* ev, // context
00238     const mdbOid* inOid, // row to find in table
00239     mdb_pos* outPos); // zero-based ordinal position of row in table
00240      
00241   NS_IMETHOD PosToRow( // test for the table position of a row member
00242     nsIMdbEnv* ev, // context
00243     mdb_pos inRowPos, // zero-based ordinal position of row in table
00244     nsIMdbRow** acqRow); // acquire row at table position inRowPos
00245    
00246   NS_IMETHOD RowToPos( // test for the table position of a row member
00247     nsIMdbEnv* ev, // context
00248     nsIMdbRow* ioRow, // row to find in table
00249     mdb_pos* outPos); // zero-based ordinal position of row in table
00250 
00251   // } ----- end row position methods -----
00252 
00253   // { ----- begin oid set methods -----
00254   NS_IMETHOD AddOid( // make sure the row with inOid is a table member 
00255     nsIMdbEnv* ev, // context
00256     const mdbOid* inOid); // row to ensure membership in table
00257 
00258   NS_IMETHOD HasOid( // test for the table position of a row member
00259     nsIMdbEnv* ev, // context
00260     const mdbOid* inOid, // row to find in table
00261     mdb_bool* outHasOid); // whether inOid is a member row
00262 
00263   NS_IMETHOD CutOid( // make sure the row with inOid is not a member 
00264     nsIMdbEnv* ev, // context
00265     const mdbOid* inOid); // row to remove from table
00266   // } ----- end oid set methods -----
00267 
00268   // { ----- begin row set methods -----
00269   NS_IMETHOD NewRow( // create a new row instance in table
00270     nsIMdbEnv* ev, // context
00271     mdbOid* ioOid, // please use zero (unbound) rowId for db-assigned IDs
00272     nsIMdbRow** acqRow); // create new row
00273 
00274   NS_IMETHOD AddRow( // make sure the row with inOid is a table member 
00275     nsIMdbEnv* ev, // context
00276     nsIMdbRow* ioRow); // row to ensure membership in table
00277 
00278   NS_IMETHOD HasRow( // test for the table position of a row member
00279     nsIMdbEnv* ev, // context
00280     nsIMdbRow* ioRow, // row to find in table
00281     mdb_bool* outHasRow); // whether row is a table member
00282 
00283   NS_IMETHOD CutRow( // make sure the row with inOid is not a member 
00284     nsIMdbEnv* ev, // context
00285     nsIMdbRow* ioRow); // row to remove from table
00286 
00287   NS_IMETHOD CutAllRows( // remove all rows from the table
00288     nsIMdbEnv* ev); // context
00289   // } ----- end row set methods -----
00290 
00291   // { ----- begin hinting methods -----
00292   NS_IMETHOD SearchColumnsHint( // advise re future expected search cols  
00293     nsIMdbEnv* ev, // context
00294     const mdbColumnSet* inColumnSet); // columns likely to be searched
00295     
00296   NS_IMETHOD SortColumnsHint( // advise re future expected sort columns  
00297     nsIMdbEnv* ev, // context
00298     const mdbColumnSet* inColumnSet); // columns for likely sort requests
00299 
00300   NS_IMETHOD StartBatchChangeHint( // advise before many adds and cuts  
00301     nsIMdbEnv* ev, // context
00302     const void* inLabel); // intend unique address to match end call
00303     // If batch starts nest by virtue of nesting calls in the stack, then
00304     // the address of a local variable makes a good batch start label that
00305     // can be used at batch end time, and such addresses remain unique.
00306   NS_IMETHOD EndBatchChangeHint( // advise before many adds and cuts  
00307     nsIMdbEnv* ev, // context
00308     const void* inLabel); // label matching start label
00309     // Suppose a table is maintaining one or many sort orders for a table,
00310     // so that every row added to the table must be inserted in each sort,
00311     // and every row cut must be removed from each sort.  If a db client
00312     // intends to make many such changes before needing any information
00313     // about the order or positions of rows inside a table, then a client
00314     // might tell the table to start batch changes in order to disable
00315     // sorting of rows for the interim.  Presumably a table will then do
00316     // a full sort of all rows at need when the batch changes end, or when
00317     // a surprise request occurs for row position during batch changes.
00318   // } ----- end hinting methods -----
00319 
00320   // { ----- begin searching methods -----
00321   NS_IMETHOD FindRowMatches( // search variable number of sorted cols
00322     nsIMdbEnv* ev, // context
00323     const mdbYarn* inPrefix, // content to find as prefix in row's column cell
00324     nsIMdbTableRowCursor** acqCursor); // set of matching rows
00325     
00326   NS_IMETHOD GetSearchColumns( // query columns used by FindRowMatches()
00327     nsIMdbEnv* ev, // context
00328     mdb_count* outCount, // context
00329     mdbColumnSet* outColSet); // caller supplied space to put columns
00330     // GetSearchColumns() returns the columns actually searched when the
00331     // FindRowMatches() method is called.  No more than mColumnSet_Count
00332     // slots of mColumnSet_Columns will be written, since mColumnSet_Count
00333     // indicates how many slots are present in the column array.  The
00334     // actual number of search column used by the table is returned in
00335     // the outCount parameter; if this number exceeds mColumnSet_Count,
00336     // then a caller needs a bigger array to read the entire column set.
00337     // The minimum of mColumnSet_Count and outCount is the number slots
00338     // in mColumnSet_Columns that were actually written by this method.
00339     //
00340     // Callers are expected to change this set of columns by calls to
00341     // nsIMdbTable::SearchColumnsHint() or SetSearchSorting(), or both.
00342   // } ----- end searching methods -----
00343 
00344   // { ----- begin sorting methods -----
00345   // sorting: note all rows are assumed sorted by row ID as a secondary
00346   // sort following the primary column sort, when table rows are sorted.
00347 
00348   NS_IMETHOD
00349   CanSortColumn( // query which column is currently used for sorting
00350     nsIMdbEnv* ev, // context
00351     mdb_column inColumn, // column to query sorting potential
00352     mdb_bool* outCanSort); // whether the column can be sorted
00353     
00354   NS_IMETHOD GetSorting( // view same table in particular sorting
00355     nsIMdbEnv* ev, // context
00356     mdb_column inColumn, // requested new column for sorting table
00357     nsIMdbSorting** acqSorting); // acquire sorting for column
00358     
00359   NS_IMETHOD SetSearchSorting( // use this sorting in FindRowMatches()
00360     nsIMdbEnv* ev, // context
00361     mdb_column inColumn, // often same as nsIMdbSorting::GetSortColumn()
00362     nsIMdbSorting* ioSorting); // requested sorting for some column
00363     // SetSearchSorting() attempts to inform the table that ioSorting
00364     // should be used during calls to FindRowMatches() for searching
00365     // the column which is actually sorted by ioSorting.  This method
00366     // is most useful in conjunction with nsIMdbSorting::SetCompare(),
00367     // because otherwise a caller would not be able to override the
00368     // comparison ordering method used during searchs.  Note that some
00369     // database implementations might be unable to use an arbitrarily
00370     // specified sort order, either due to schema or runtime interface
00371     // constraints, in which case ioSorting might not actually be used.
00372     // Presumably ioSorting is an instance that was returned from some
00373     // earlier call to nsIMdbTable::GetSorting().  A caller can also
00374     // use nsIMdbTable::SearchColumnsHint() to specify desired change
00375     // in which columns are sorted and searched by FindRowMatches().
00376     //
00377     // A caller can pass a nil pointer for ioSorting to request that
00378     // column inColumn no longer be used at all by FindRowMatches().
00379     // But when ioSorting is non-nil, then inColumn should match the
00380     // column actually sorted by ioSorting; when these do not agree,
00381     // implementations are instructed to give precedence to the column
00382     // specified by ioSorting (so this means callers might just pass
00383     // zero for inColumn when ioSorting is also provided, since then
00384     // inColumn is both redundant and ignored).
00385   // } ----- end sorting methods -----
00386 
00387   // { ----- begin moving methods -----
00388   // moving a row does nothing unless a table is currently unsorted
00389   
00390   NS_IMETHOD MoveOid( // change position of row in unsorted table
00391     nsIMdbEnv* ev, // context
00392     const mdbOid* inOid,  // row oid to find in table
00393     mdb_pos inHintFromPos, // suggested hint regarding start position
00394     mdb_pos inToPos,       // desired new position for row inRowId
00395     mdb_pos* outActualPos); // actual new position of row in table
00396 
00397   NS_IMETHOD MoveRow( // change position of row in unsorted table
00398     nsIMdbEnv* ev, // context
00399     nsIMdbRow* ioRow,  // row oid to find in table
00400     mdb_pos inHintFromPos, // suggested hint regarding start position
00401     mdb_pos inToPos,       // desired new position for row inRowId
00402     mdb_pos* outActualPos); // actual new position of row in table
00403   // } ----- end moving methods -----
00404   
00405   // { ----- begin index methods -----
00406   NS_IMETHOD AddIndex( // create a sorting index for column if possible
00407     nsIMdbEnv* ev, // context
00408     mdb_column inColumn, // the column to sort by index
00409     nsIMdbThumb** acqThumb); // acquire thumb for incremental index building
00410   // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
00411   // then the index addition will be finished.
00412   
00413   NS_IMETHOD CutIndex( // stop supporting a specific column index
00414     nsIMdbEnv* ev, // context
00415     mdb_column inColumn, // the column with index to be removed
00416     nsIMdbThumb** acqThumb); // acquire thumb for incremental index destroy
00417   // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
00418   // then the index removal will be finished.
00419   
00420   NS_IMETHOD HasIndex( // query for current presence of a column index
00421     nsIMdbEnv* ev, // context
00422     mdb_column inColumn, // the column to investigate
00423     mdb_bool* outHasIndex); // whether column has index for this column
00424 
00425   
00426   NS_IMETHOD EnableIndexOnSort( // create an index for col on first sort
00427     nsIMdbEnv* ev, // context
00428     mdb_column inColumn); // the column to index if ever sorted
00429   
00430   NS_IMETHOD QueryIndexOnSort( // check whether index on sort is enabled
00431     nsIMdbEnv* ev, // context
00432     mdb_column inColumn, // the column to investigate
00433     mdb_bool* outIndexOnSort); // whether column has index-on-sort enabled
00434   
00435   NS_IMETHOD DisableIndexOnSort( // prevent future index creation on sort
00436     nsIMdbEnv* ev, // context
00437     mdb_column inColumn); // the column to index if ever sorted
00438   // } ----- end index methods -----
00439 
00440 // } ===== end nsIMdbTable methods =====
00441 };
00442  
00443 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00444 
00445 #endif /* _ORKINTABLE_ */