DumontEXE 0.0.1
cmcCursor.h
00001 /* ***************************************************************************
00002 **
00003 ** Copyright (C) 2007 Lorimark Solutions, LLC. All rights reserved.
00004 **
00005 ** This file is part of the DumontEXE Scripting Extension Kit
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://dumont.showoff-db.org/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://dumont.showoff-db.org/licensing.html 
00017 ** or contact the sales department at sales@lorimarksolutions.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ** author: Mark Petryk ~ Lorimark Solutions, LLC
00023 ** **************************************************************************/
00024 
00025 #ifndef CDA_CURSOR_H_422FD07F_0597_4cbb_A034_9AE85166472E
00026 #define CDA_CURSOR_H_422FD07F_0597_4cbb_A034_9AE85166472E
00027 
00028 #include <QStringList>
00029 
00030 #include "cmcApi.h"
00031 #include "cmcCategoryDef.h"
00032 
00033 namespace cmcDatabaseApi {
00034 
00035 class cmcRowSet;
00036 
00037 /*!
00038 ** \page rowsets Of Cursors and RowSets
00039 **
00040 ** A Cursor is an object that Commence uses to hand-out RowSets to the
00041 **  application.  A RowSet is an object that the application uses to
00042 **  Query, Add, Edit and Delete data from the database.
00043 **
00044 ** In Commence, there is the concept of a single cursor, and four 
00045 **  different types of RowSet objects.  The different row set types are:
00046 **
00047 **  \li 1 ~ QUERY
00048 **  \li 2 ~ ADD
00049 **  \li 3 ~ DELETE
00050 **  \li 4 ~ EDIT
00051 **
00052 ** Each of these row set types performs one or more functions.  For instance,
00053 **  the Query row set type can read data from a category, but it cannot write
00054 **  or delete or add data.  The Edit row set can read the data, just like the 
00055 **  query row set can, but it cannot delete data, or add data.  
00056 **
00057 ** The purpose for having four different row set types is unclear to this
00058 **  software developer.  Therefore, due to that general lack-of-understanding
00059 **  on my part, the Dumont implementation of the Cursors and RowSets is 
00060 **  slightly different than the Commence implementation.  Functionally, this
00061 **  means nothing, since the Dumont implementation is completely compatible
00062 **  with the current Commence implementation.  The result, however, is a great
00063 **  simplification of the Cursor/RowSet API.
00064 **
00065 ** I'll explain the differences by providing a typical programming example.
00066 **  The first step is to get your hands on a cursor object, this is typically
00067 **  done with the following code:
00068 **
00069 ** \par vbScript Example - Getting A Cursor
00070 ** \code
00071 ** dim dexe: set dexe = createObject("Dumont.EXE") ' get a handle on dumont
00072 ** dim dapp: set dapp = dexe.applications("MyDB")  ' Get a specific app instance
00073 ** '
00074 ** dim cursor: set cursor = dapp.db.getCursor( "Person" )
00075 ** \endcode
00076 **
00077 ** You now have a handle on a standard Cursor object, assigned to a category,
00078 **  and the category name is called "Person".  I'm assuming there are people's
00079 **  names and phone numbers stored there.
00080 **
00081 ** Now, here is where the fun begins.  Normally, when connected directly to 
00082 **  Commence, you would fetch cursors using the following codes:
00083 **
00084 ** \par vbScript Example - Fetching Different Rowset Types
00085 ** \code
00086 ** dim qrs: set qrs = cursor.getQueryRowSet(  cursor.rowCount )
00087 ** dim ers: set ers = cursor.getEditRowSet(   cursor.rowCount )
00088 ** dim drs: set drs = cursor.getDeleteRowSet( cursor.rowCount )
00089 ** dim ars: set ars = cursor.getAddRowSet( 10 )
00090 ** \endcode
00091 **
00092 ** What you would have now is four different row set types, one for each of
00093 **  the row set types available from the Commence API.  Note that this code 
00094 **  example is still running through Dumont, and the Commands shown above still
00095 **  work in Dumont, even though Dumont has been enhanced greatly.
00096 **
00097 ** Here is another way to fetch the same row set objects using some of the new
00098 **  syntax that is available through Dumont:
00099 **
00100 ** \par vbScript Example - Fetching Different Rowset Types ~ The Dumont Alternative
00101 ** \code
00102 ** const ROWSET_QUERY  = 1
00103 ** const ROWSET_ADD    = 2
00104 ** const ROWSET_DELETE = 3
00105 ** const ROWSET_EDIT   = 4
00106 ** dim qrs: set qrs = cursor.getRowSet(  ROWSET_QUERY      )
00107 ** dim ers: set ers = cursor.getRowSet(  ROWSET_EDIT,   5  )
00108 ** dim drs: set drs = cursor.getRowSet(  ROWSET_DELETE, 10, "do-we-deletem-and-howe" )
00109 ** dim ars: set ars = cursor.getRowSet(  ROWSET_ADD,    10 )
00110 ** \endcode
00111 **
00112 ** Here is the thing to notice in the above two code examples.  In both examples
00113 **  the *same* rowset object wrapper was fetched.  It's just that each rowset wrapper
00114 **  has different properties.  One of those properties is the rowset type.  It is
00115 **  this type value that determines what the rowset is capable of doing.  In each
00116 **  case, different types of rowsets are capable of doing different things.  One can
00117 **  add, one can delete.
00118 **
00119 ** Another thing to notice, is that in the first "getRowSet" example, where we fetch a
00120 **  query rowset, we do not specify the row count.  Why is that?  Because we don't have
00121 **  to!  The cursor already knows how many rows are on the rowset, so why does it
00122 **  need to be specified every time we ask for a rowset?  It doesn't!  And I've made
00123 **  Dumont not require this parameter value.  You can put it on or leave it off if 
00124 **  you like - your preference!  If you leave the rowCount specification off the request
00125 **  then you will end up with a row set object that has the same number of rows in
00126 **  the originating cursor.  How handy is that?  Incidently the same thing can be
00127 **  done with the original call to getWhateverRowset.  Behold:
00128 **
00129 ** \par vbScript Example - Fetching a RowSet sans RowCount
00130 ** \code
00131 ** dim qrs: set qrs = cursor.getQueryRowSet  ' get cursor.rowCount rows
00132 ** dim ers: set ers = cursor.getEditRowSet   ' get cursor.rowCount rows
00133 ** dim drs: set drs = cursor.getDeleteRowSet ' get cursor.rowCount rows
00134 ** dim ars: set ars = cursor.getAddRowSet    ' add just one row by default
00135 ** \endcode
00136 **
00137 ** That's the whole idea behind Dumont - making programming Commence easier.
00138 **
00139 ** Yet another thing to notice is that in one of the rowset fetch functions, I have
00140 **  specified another string "do-we-deletem-and-howe".  What is this for?  Well,
00141 **  the simple answer is, every object in Dumont has a name.  And, a rowset, by
00142 **  way of Commence, doesn't have a name, but since we're wrapping a Commence rowset
00143 **  in Dumont, Dumont can provide one - if you want!  You don't have to name your
00144 **  rowsets, but, depending on what you're doing you might want to.
00145 **
00146 ** Now,. you're wondering, what's the big deal?  Why is it so important that there is
00147 **  only one object in dumont (cmcRowSet) that is wrapping all the four different
00148 **  Commence row sets objects?  Here's the answer: "all of the four rowset objects
00149 **  are nearly identical, and use nearly the same code".  I hate code duplication.
00150 **  It is the number one source to having bugs creep in to your programs; being
00151 **  forced to duplicate code when you shouldn't have to, but I digress.  Let it 
00152 **  suffice to say that I avoid code duplication as a first priority - otherwise
00153 **  what's the point?
00154 **
00155 ** The cmcRowSet object that is housed in Dumont is a smart object, and it knows
00156 **  from whence it sprang, and what type of rowset object is was springed as.
00157 **  With this knowledge, it is able to insure that you don't do something like take
00158 **  a QueryRowSet type of object wrapper and delete some rows with it.  If you do,
00159 **  then you will get a stern warning from Dumont.  So, don't do it.  Don't even 
00160 **  think about doing it!
00161 **
00162 ** But, if you do accidently use the generic row set object wrapper for a function it wasn't
00163 **  set up to do, that's all you will get - a stern warning.  The function won't complete.
00164 **  and nothing will be requested (incorrectly) from Commence.  Dumont will intervene
00165 **  before the request gets that far.  And, that's another thing.  If you have your
00166 **  hands on a rowset object, and you try to acess some data that is beyond the range
00167 **  of the rowset, Dumont will intervene there as well.
00168 **
00169 ** These are all good things, and makes working with Cursors and Rowsets in Dumont a
00170 **  pretty easy thing to do.  Plus it's all documented here.  Hey, what a concept - 
00171 **  documentation!
00172 **
00173 ** ~ ~ ~ ~ ~
00174 **
00175 ** Now, here is another topic on Cursors and Rowsets.  There is somewhat of a new feature
00176 **  in Commence Cursors that allows one to fetch from the cursor the THID value from
00177 **  an item in question.  This "feature", however, is nearly completely undocumented
00178 **  except for a few renegade .pdf files on the topic, and of course the most
00179 **  totally awesome http://www.freedomcomputing.com newsgroup.
00180 **
00181 ** These THID values are fetched from the Row Sets by making a call to the 
00182 **  cmcRowSet::getRowID function.  However, before you are able to make that call, you
00183 **  have to first open the cursor with the USE_THIDS parameter turned on.  There is a
00184 **  problem with turning on THID values on cursors.  It's complicated, but it has 
00185 **  mostly to do with connection fields.  When THIDS are turned on, and you request
00186 **  values from connection fields, you will get THID values for those connections
00187 **  rather than name values.  This is something you need to think about before attempting
00188 **  to use the USE_THIDS feature of a Commence cursor object.
00189 **
00190 ** Take a look at the default values for the two functions:
00191 **
00192 ** \li \ref cmcDatabase::getCursor( long, const QString &, long ) "getCursor( mode, categoryName, flags = USE_THIDS )"
00193 ** \li \ref cmcDatabase::getCursor( const QString &, long ) "getCursor( categoryName, flags = USE_THIDS )"
00194 **
00195 ** The default values are for the flag (the last) parameter, and have the following
00196 **  meaning:
00197 **
00198 ** \todo figure out what the two values are for opening a cursor.
00199 ** \par
00200 ** \code
00201 ** #define USE_THIDS      256
00202 ** #define SOMETHING_ELSE 512
00203 ** \endcode
00204 **
00205 ** By applying these two values when opening a cursor, then the rowsets created with
00206 **  that cursor will respond to getRowID function calls.  If you desire, you can 
00207 **  override this value when you make your calls to get a cursor object, but I'm not
00208 **  sure why you'd want to.
00209 **
00210 ** Once you have the cursor open, you can get a query row set on that cursor and
00211 **  begin probing it for THID values or whatever other values you want from the
00212 **  category.
00213 **
00214 ** There is a very long article in this documentation set that discusses how to
00215 **  open a cursor properly and assign columns to it and walk the items and
00216 **  columns and so on.  That article is located here: \ref columnLabels
00217 **
00218 */
00219 
00220 /*!
00221 ** \page relatedColumns Setting Data on Cursor Connections
00222 **
00223 ** Did you know that if you are accessing data through the cursor/rowset
00224 **  mechanism that you can actually establish a connection between two 
00225 **  categories.  You can do this using the "SetRelatedColumn function.
00226 **
00227 ** Once you have established a column using setrelatedcolumn, then you
00228 **  actually assign connection values to it using modify row on that
00229 **  column.  It really helps if you have unique items in the 
00230 **  related category.
00231 **
00232 **
00233 **
00234 */
00235 
00236 
00237 /*!
00238 ** \page columnLabels Accessing Cursor Data using Column Labels
00239 **
00240 ** <b>The purpose of Dumont</b> is to make the life of the Commence Developer easier.
00241 **  It does this by subclassing existing Commence objects, and adding additional
00242 **  functionalities to them making them easier to work with.
00243 **
00244 ** <b>What is subclassing?</b>  Subclassing is a programming term whereby
00245 **  an 'object' within a software program is "wrapped" with another object
00246 **  in another software program.  When this "wrapping" occurs, all of the
00247 **  functions in the first object are exposed in their original form, so as
00248 **  to maintain compatibility with existing programs that use them, and then,
00249 **  usually, additional functions are added to the new object (the wrapper
00250 **  object) so that it looks like the original object but with additional
00251 **  new features.
00252 **
00253 ** This is what Dumont does.  It sub-classes all the Commence objects (wraps them)
00254 **  then exposes them in their original form, while at the same time adding new
00255 **  features and functionalities to them, thus making them easier to work with.
00256 **
00257 ** In the following example, the Commence cursor object is wrapped with a Dumont
00258 **  object that looks just like the original cursor object.  The difference is, 
00259 **  the Dumont cursor object adds special column handling functionality to the
00260 **  cursor object.  For one thing, it aleviates the programmer from having to 
00261 **  deal with column numbering.  The Dumont cursor object handles all the 
00262 **  column numbering internally allowing the programmer to easily get to column
00263 **  values by name rather than by column index number.  This small improvement
00264 **  can mean a great deal when it comes to working with a large program.
00265 **
00266 ** Secondly, when Dumont is accessing columns by name rather than index number,
00267 **  it is doing so internally, using internal index name/value pairs.  What
00268 **  this means is that a translation from a column name to a column number happens
00269 **  very quickly, and does not involve the Commence API.  Translation: your
00270 **  programs will run faster and be easier to work with.
00271 **
00272 ** Furthermore, by handling duplicate columns in a safe manner, and if you are in
00273 **  a situation where you have designated a column twice (either by accident or
00274 **  intentionally) Dumont will not barf on your program.  It will simply accept 
00275 **  the duplicate column designation, prevent the request from propagating into
00276 **  the Commence API (because that WOULD be a mistake) and continues along without
00277 **  error.
00278 **
00279 ** Finally, Dumont adds some additional functions to the cursor object for 
00280 **  designating both static fields and connections using 
00281 **  \ref cmcCursor::setColumn( const QString &, const QString &, const QString &, long ) "the same basic syntax".
00282 **  This makes programming far easier, makes the programs much more reliable and 
00283 **  therefore easier to maintain in the long term.
00284 **
00285 ** \par vbScript Example of accessing column data using column labels.
00286 ** \code
00287 ** '
00288 ** ' Hook into Dumont
00289 ** '
00290 ** dim dexe: set dexe = createObject("Dumont.EXE")
00291 **
00292 ** '
00293 ** ' Get to the application via the R.O.T. (running object table)
00294 ** '
00295 ** dim dapp: set dapp = dexe.applications("KES.mwp")
00296 ** 
00297 ** '
00298 ** ' Open the cursor
00299 ** '
00300 ** dim cursor: set cursor = dapp.db.getCursor( "Matters" )
00301 ** 
00302 ** '
00303 ** ' Assign the columns
00304 ** '
00305 ** dexe.debug "Matter No:      " & cursor.setColumn( "Matter No"                          )
00306 ** dexe.debug "Matter Name:    " & cursor.setColumn( "Matter Name"                        )
00307 ** dexe.debug "Client Contact: " & cursor.setColumn( "Client", "Contacts", "Contact Name" )
00308 ** dexe.debug "Label:          " & cursor.setColumn( "Label"                              )
00309 **
00310 ** '
00311 ** ' Try connecting the same column twice, see if we get an error.
00312 ** '
00313 ** dexe.debug "Matter Name:    " & cursor.setColumn( "Matter Name" ) ' no error, no duplicate!
00314 ** 
00315 ** '
00316 ** ' Show a few things
00317 ** '
00318 ** dexe.debug "rowCount " & cursor.rowCount
00319 ** dexe.debug "colCount " & cursor.columnCount
00320 ** 
00321 ** '
00322 ** ' Show all the column labels
00323 ** '
00324 ** dim i: for i = 0 to cursor.columnCount - 1
00325 **   dexe.debug "col " & i & " label " & cursor.getColumnLabel(i)
00326 ** next
00327 ** 
00328 ** '
00329 ** ' Dump some columns, accessing the values by index number
00330 ** '
00331 ** dim qrs: set qrs = cursor.getQueryRowSet(1)
00332 ** for i = 0 to qrs.columnCount - 1
00333 **   dexe.debug "------"
00334 **   dexe.debug "col " & i & " label " & qrs.getColumnLabel(i)
00335 **   dexe.debug "value: " & qrs.getRowValue( 0, i )
00336 ** next
00337 **
00338 ** '
00339 ** ' Dump some more stuff, accessing the values by label
00340 ** '
00341 ** dexe.debug "------"
00342 ** dexe.debug "Matter No:   " & qrs.getRowValue( 0, "Matter No"                    )
00343 ** dexe.debug "Client Cont: " & qrs.getRowValue( 0, "Client Contacts Contact Name" )
00344 ** dexe.debug "Label:       " & qrs.getRowValue( 0, "Label"                        )
00345 ** dexe.debug "Matter Name: " & qrs.getRowValue( 0, "Matter Name"                  )
00346 ** \endcode
00347 **
00348 **
00349 ** \par Produces the following output:
00350 ** \code
00351 ** Matter No:                    0
00352 ** Matter Name:                  1
00353 ** Client Contacts Contact Name: 2
00354 ** Label:                        3
00355 ** Matter Name:                  1
00356 ** rowCount 3684
00357 ** colCount 4
00358 ** col 0 label Matter No
00359 ** col 1 label Matter Name
00360 ** col 2 label Client Contacts Contact Name
00361 ** col 3 label Label
00362 ** ------
00363 ** col 0 label Matter No
00364 ** value: 00001
00365 ** ------
00366 ** col 1 label Matter Name
00367 ** value: WITTER
00368 ** ------
00369 ** col 2 label Client Contacts Contact Name
00370 ** value: TAG Consulting Services
00371 ** ------
00372 ** col 3 label Label
00373 ** value: TAG - WITTER
00374 ** ------
00375 ** Matter No:   00001
00376 ** Client Cont: TAG Consulting Services
00377 ** Label:       TAG - WITTER
00378 ** Matter Name: WITTER
00379 ** \endcode
00380 **
00381 ** \par Setting Columns (overkill)
00382 ** \code
00383 ** dim cursor: set cursor = cmdb.getCursor("Person")
00384 ** dim colFullName: colFullName = cursor.setColumn( "Full Name" )
00385 ** dim colLastName: colLastName = cursor.setColumn( "Last Name" )
00386 ** dim colEmplBy:   colEmplBy   = cursor.setRelatedColumn( "Employed by", "Company", "Company Name" )
00387 **
00388 ** '
00389 ** ' This code duplicates the "Last Name" column setting, but the application
00390 ** '  does not generate an error, and the index number returned is the same
00391 ** '  as the colLastName value.
00392 ** '
00393 ** dim colDupeName: colDupeName = cursor.setColumn( "Last Name" )
00394 **
00395 ** dim i: for i = 0 to qrs.rowCount - 1
00396 **   dexe.debug qrs.getRowValue( i, colFullName ) & vbCrLf & _
00397 **              qrs.getRowValue( i, colLastName ) & vbCrLf & _
00398 **              qrs.getRowValue( i, colEmplBy   )
00399 ** next
00400 ** \endcode
00401 **
00402 ** \note In the code above, the column numbers that are assigned to each 
00403 **  column are, truthfully, of little value to your application, since it is
00404 **  possible to access the column values directly by column name rather than by
00405 **  column number, and the API wrapper functions cache the column number values
00406 **  making accessing columns by name a very fast procedure.  See the following:
00407 **
00408 ** \par Setting Columns using the internal column number cache (preferred method)
00409 ** \code
00410 ** dim cursor: set cursor = cmdb.getCursor("Person")
00411 ** cursor.setColumn "Full Name"
00412 ** cursor.setColumn "Last Name"
00413 ** cursor.setColumn "Employed by", "Company", "Company Name"
00414 ** dim qrs: set qrs = cursor.getQueryRowSet( cursor.rowCount )
00415 ** dim i: for i = 0 to qrs.rowCount - 1
00416 **   dexe.debug qrs.getRowValue( i, "Full Name" ) & vbCrLf & _
00417 **              qrs.getRowValue( i, "Last Name" ) & vbCrLf & _
00418 **              qrs.getRowValue( i, "Employed by Company Company Name" )
00419 ** next
00420 ** \endcode
00421 **
00422 ** \note In the code above, the column numbers that are actually assigned to
00423 **  the listed columns are ignored.  Columns are accessed by their "Name" values
00424 **  and not their column number values.  The cmcCursor object caches the 
00425 **  column number values and can, therefore, look up the actual assigned 
00426 **  column numbers very quickly without calling in to the Commence API.
00427 **
00428 ** If you are determined to write good code that checks for error conditions
00429 **  on various calls, and deals with them properly, you might implement a
00430 **  function like this:
00431 **
00432 ** \par Setting Columns and Checking Return Values
00433 ** \code
00434 ** function setColumns( ByRef cursor )
00435 **   setColumns = false ' false means we ended in error
00436 **   if( cursor.setColumn("Full Name") = -1 ) then exit function
00437 **   if( cursor.setColumn("Last Name") = -1 ) then exit function 
00438 **   if( cursor.setColumn("Employed by", "Company", "Company Name") = -1 ) then exit function
00439 **   setColumns = true ' success!
00440 ** next
00441 ** \endcode
00442 **
00443 */
00444 
00445 /*!
00446 ** \brief Cursor Object Wrapper
00447 **
00448 ** This object wraps the regular Commence Cursor object, and adds a few
00449 **  functional enhancements without affecting existing programs that are
00450 **  written for the original (unwrapped) Cursor object.
00451 **
00452 **
00453 ** \todo It is quite possible to have the cursor object "reissue" itself
00454 **  if a column is requested that was not initially defined in the cursor
00455 **  column set.  This would be a convenience function.  It would allow 
00456 **  the developer to spend less attention to what columns he *might* be
00457 **  needing for a particular task, and just request them in the cmcRowSet
00458 **  functions.  Since all the cmcObject wrappers are wrapping commence
00459 **  objects, and there is no state-data in those commence objects, then
00460 **  re-requesting a commence object should not cause any wrapper difficulty.
00461 **  It could cause some latency in the rowset if a new rowset had to
00462 **  be called up from a new cursor just to add a single column, but for
00463 **  small rowsets or properly filtered rowsets it might be quite handy to
00464 **  have a rowset automatically add columns to a cursor on demand.
00465 **
00466 ** \todo It is possible to create calculated columns as well.  It would be
00467 **  possible to create simple calculated columns that operate on some simple
00468 **  concatination of fields, but if we can get the scripting module hooked
00469 **  in to this system, then we would be able to create a new cursor object
00470 **  call it a cursor model or something, and have that object have access
00471 **  to the scripting module whereby we can create truly calculated 
00472 **  columns.
00473 */
00474 class cmcCursor:
00475   public cmcApi
00476 {
00477   Q_OBJECT
00478   public:
00479 
00480     /*!
00481     ** \brief Type of Commence data to access with this cursor \n
00482     **
00483     ** \ingroup cmcBase
00484     **
00485     ** A category is the most common method of accessing data.  However, you
00486     **  can also access data from a filtered view.  Using a filtered view
00487     **  you will get and already column-populated and filtered cursor to
00488     **  which you can acquire a rowset.  A cursor object is also the API
00489     **  tool to use when accessing PALM type data.
00490     **
00491     ** \note If you are going to be working with cursors and THID values
00492     **        then there are some issues to be aware of.  Refer to the
00493     **        section \ref thidBugs "THID Bugs" for more information.
00494     */
00495     enum CURSOR_MODES
00496     {
00497       /*! 0 ~ Use the Commence category specified by pName. */
00498       CATEGORY = 0,
00499     
00500       /*! 1 ~ Use the Commence view specified by pName. */
00501       VIEW = 1,
00502     
00503       /*! 2 ~ Use the Commence category and fields defined from 
00504       **       Preferences - Other Apps - 3Com Pilot Address Book
00505       */
00506       PILOTAB = 2,
00507     
00508       /*! 3 ~ Use the Commence category and fields defined from
00509       **       Preferences - Other Apps - 3Com Pilot Memo Pad
00510       */
00511       PILOTMEMO = 3,
00512     
00513       /*! 5 ~ Use the Commence category and fields defined from
00514       **       Preferences - Other Apps - 3Com Pilot To Do List
00515       */
00516       PILOTTODO = 5,
00517     
00518       /*! 6 ~ Use the Commence category and fields defined from
00519       **       Preferences - Other Apps - 3Com Pilot Date Book
00520       */
00521       PILOTAPPT = 6
00522     };
00523 
00524     /*!
00525     ** \brief Copy Constructor \n
00526     **
00527     */
00528     cmcCursor( const cmcCursor & copy );
00529 
00530     /*!
00531     ** \brief Default Constructor \n
00532     **
00533     ** This constructor builds the Cursor wrapper object.
00534     **
00535     */
00536     cmcCursor
00537     (
00538       /*! Cursor Mode <br><br> */
00539       const long mode,
00540 
00541       /*! Cursor Name <br><br> */
00542       const QString & name,
00543 
00544       /*! Cursor Flags <br><br> */
00545       const long flags,
00546 
00547       /*! Dispatch Pointer <br><br> */
00548       IDispatch * disp,
00549 
00550       /*! Application reference <br><br> */
00551       cmcApplication * app,
00552 
00553       /*! Object Parent <br><br> */
00554       QObject * parent = NULL 
00555 
00556     ); // endcmcCursor
00557 
00558     virtual ~cmcCursor();
00559 
00560   public slots:
00561 
00562     /*!
00563     ** \brief <b>extended:</b> Category Definition object for this cursor \n
00564     **
00565     ** The categoryDef object is part of the dumont extension library.  This
00566     **  object provides information about the category in question, it's
00567     **  available field and connection properties and such.
00568     **
00569     */
00570     cmcCategoryDef * categoryDef();
00571 
00572     /*!
00573     ** \brief Cursor Flags \n
00574     **
00575     ** \sa mode
00576     **
00577     ** \return long 'flags' value the cursor was created with
00578     */
00579     long flags();
00580 
00581     /*!
00582     ** \brief Cursor Mode \n
00583     **
00584     ** Type of Commence data to access with this cursor.
00585     **
00586     ** \code
00587     **  0 - CMC_CURSOR_CATEGORY
00588     **      Use the Commence category specified by pName.
00589     **
00590     **  1 - CMC_CURSOR_VIEW
00591     **      Use the Commence view specified by pName.
00592     **
00593     **  2 - CMC_CURSOR_PILOTAB
00594     **      Use the Commence category and fields defined from
00595     **      Preferences - Other Apps - 3Com Pilot Address Book
00596     **
00597     **  3 - CMC_CURSOR_PILOTMEMO
00598     **      Use the Commence category and fields defined from
00599     **      Preferences - Other Apps - 3Com Pilot Memo Pad
00600     **
00601     **  5 - CMC_CURSOR_PILOTTODO
00602     **      Use the Commence category and fields defined from
00603     **      Preferences - Other Apps - 3Com Pilot To Do List
00604     **
00605     **  6 - CMC_CURSOR_PILOTAPPT
00606     **      Use the Commence category and fields defined from
00607     **      Preferences - Other Apps - 3Com Pilot Date Book
00608     ** \endcode
00609     **
00610     ** \sa flags
00611     **
00612     ** \return long 'mode' value the cursor was created with
00613     */
00614     long mode();
00615 
00616     /*!
00617     ** \brief Indicates if this cursor is using THIDS \n
00618     **
00619     ** \return True if USE_THIDS was provided at cursor open
00620     */
00621     bool useThids();
00622 
00623     /*!
00624     ** \brief (read-only) Name of the underlying Commence category \n
00625     **
00626     ** This returns the read/only name of the underlying category.
00627     **
00628     ** \sa categoryName
00629     */
00630     QString category();
00631 
00632     /*!
00633     ** \brief <b>extended:</b> (read-only) Name of the underlying Commence category \n
00634     **
00635     ** This returns the read/only name of the underlying category.
00636     **
00637     */
00638     QString categoryName();
00639 
00640     /*!
00641     ** \brief (read-only) Number of rows in this cursor (-1 on error) \n
00642     **
00643     ** This returns the current row count.
00644     **
00645     */
00646     long rowCount();
00647 
00648     /*!
00649     ** \brief (read-only) Number of columns in this cursor (-1 on error)\n
00650     **
00651     ** This returns the API column count of the cursor.  Note that the
00652     **  value returned by this call depends on the state of the column
00653     **  definitions.  If no columns have been defined, then this call
00654     **  will return the total number of fields and connections defined
00655     **  for this category.  As soon as a column is defined, then this
00656     **  call returns the number of 'presently defined' columns.  Therefore,
00657     **  the results of this call could be misleading depending on if you
00658     **  have defined columns for this cursor yet or not.
00659     **
00660     */
00661     long columnCount();
00662 
00663     /*!
00664     ** \brief <b>extended alias:</b> Rowset Column Count \n
00665     **
00666     ** This is just an alias for columnCount() because I like it when my source
00667     **  files all line up properly, and
00668     **
00669     ** \code
00670     ** dim rowCount: rowCount = rs.rowCount()
00671     ** dim colCount: colCount = rs.colCount()
00672     ** \endcode
00673     **
00674     ** Looks better than
00675     **
00676     ** \code
00677     ** dim rowCount: rowCount = rs.rowCount()
00678     ** dim columnCount: columnCount = rs.columnCount()
00679     ** \endcode
00680     **
00681     ** but, that's just me!
00682     **
00683     ** \sa columnCount()
00684     */
00685     long colCount();
00686 
00687     /*!
00688     ** \brief (read-only) TRUE if category is shared in a workgroup \n
00689     **
00690     **
00691     */
00692     bool shared();
00693 
00694     /*!
00695     ** \brief Clear a Filter \n
00696     **
00697     **
00698     **
00699     */
00700     void clearFilter
00701     (
00702       /*! long ~ filter index number (-1 default == ALL filters) */
00703       long filterNumber = -1
00704     );
00705 
00706     /*!
00707     ** \brief Defines a filter clause for the cursor \n
00708     **
00709     ** This function applys a filter to the cursor.  
00710     **
00711     ** \note If the the filter could not be set this function will return
00712     ** false.  In this condition, the program can query the err object
00713     ** to read the error message as follows:
00714     **
00715     ** \par vbScript Example ~ checking a filter set for errors (Equal is misspelled)
00716     ** \code
00717     ** if( not cursor.setFilter("[ViewFilter(1,F,,First Name,Equal to,""Jim"")]") ) then
00718     **   Quit cursor.error.description
00719     ** end if
00720     ** \endcode
00721     **
00722     ** This function has an added bonus in that if you do not include
00723     **  the regular "[ViewFilter()]" parameterization formatting,
00724     **  it will be included for you.  This means that you can specify
00725     **  your filter strings as easily as:
00726     **
00727     ** \par vbScript Example ~ really simple strings
00728     ** \code
00729     ** if( not cursor.filter("1,F,,First Name,Equal to,Jim") ) then
00730     **   Quit cursor.error.description
00731     ** end if
00732     ** \endcode
00733     **
00734     ** \return True if filter set successfully
00735     **
00736     **
00737     ** \sa filters
00738     ** \sa \ref viewFilter
00739     */
00740     virtual bool setFilter
00741     (
00742       /*! string expression ~ see \ref viewFilter \n\n */
00743       const QString & filter,
00744 
00745       /*! optional ~ default zero \n\n */
00746       long flags = 0
00747     );
00748 
00749     /*!
00750     ** \brief Set Filter Alias \n
00751     **
00752     ** This is a simplified filter command that does not require the
00753     **  "[ViewFilter()]" syntax expression.  Filters can be expressed
00754     **  with just the essentials.
00755     **
00756     */
00757     virtual bool filter
00758     (
00759       /*! string ~ simplified filter string \n\n */
00760       const QString & filterString,
00761 
00762       /*! option ~ default to zero \n\n */
00763       long flags = 0
00764     );
00765 
00766     /*!
00767     ** \brief <b>extended:</b> Return Defined Filters \n
00768     **
00769     ** This returns a delimited list of filters that are presently applied
00770     **  to the cursor object.
00771     **
00772     ** \sa setFilter
00773     ** \sa \ref viewFilter
00774     */
00775     virtual QString filters
00776     (
00777       /*! optional ~ defaults to CrLf \n\n */
00778       const QString & delimiter = "\r\n"
00779     );
00780 
00781     /*!
00782     ** \brief Defines the filter logic for the cursor \n
00783     **
00784     ** The logic string that this function requires is identical to the
00785     **  DDE [ViewConjunction(AndOr12, AndOr13, AndOr34)] command.  You'll
00786     **  have to refer to the Commence help file for syntax until I get
00787     **  this help file finished.
00788     **
00789     ** \par vbScript Example ~ Setting the Cursor Filter Logic
00790     ** \code
00791     ** if( not cursor.setLogic("[ViewConjunction(And,Or,And,Or,Or,Or)]") ) then
00792     **   msgBox "Error: " & cursor.error.description
00793     **   exit function
00794     ** end if
00795     ** \endcode
00796     **
00797     ** \return True if logic could be set
00798     */
00799     virtual bool setLogic
00800     (
00801       /*! Logic String \n\n */
00802       const QString & logic,
00803 
00804       /*! optional ~ default zero \n\n */
00805       long flags = 0
00806     );
00807 
00808     /*!
00809     ** \brief Defines the sort criteria for the cursor \n
00810     **
00811     **
00812     ** \note This function will automatically add 
00813     **  the string '[ViewSort()' formatting to the
00814     **  sort string if you do not provide it.
00815     **
00816     */
00817     virtual bool setSort
00818     (
00819       /*! sort ~ string */
00820       const QString & sort,
00821 
00822       /*! optional ~ default zero \n\n */
00823       long flags = 0
00824     );
00825 
00826     /*!
00827     ** \brief Seek to a particular row in the cursor \n
00828     **
00829     **
00830     */
00831     virtual long seekRow
00832     (
00833       long origin,
00834       long rows
00835     );
00836 
00837     /*!
00838     ** \brief Seek to an approximate position in the cursor \n
00839     **
00840     */
00841     virtual long seekRowApprox
00842     (
00843       long numerator,
00844       long denominator
00845     );
00846 
00847     /*!
00848     ** \brief <b>extended preferred:</b> Set Field Column \n
00849     **
00850     ** This function is preferred over the standard Commence API setColumn
00851     **  function call onaccounta it is easier to use.
00852     **
00853     ** This function is provided as a matter of convenience for setting columns.
00854     **  It is intended to allow the programmer to be able to set columns and
00855     **  not have to worry about the actual numbers (indexes) of the columns that 
00856     **  are being defined for a cursor.  Furthermore, this function detects
00857     **  duplicate column references and returns the existing column reference
00858     **  number rather than generating an error.
00859     **
00860     ** \sa \ref setColumn( const QString &, const QString &, const QString &, long ) "setColumn( Connection Name ) ' preferred"
00861     ** \sa \ref columnLabels
00862     **
00863     ** \return Index number of referenced column.  -1 indicates the column 
00864     **          reference could not be made.
00865     **
00866     */
00867     virtual long setColumn
00868     (
00869       /*!
00870       ** The string-value of the column name.  Note that this must match
00871       **  an existing field value within the category.  If not, a -1 index
00872       **  value is returned.
00873       ** \n\n
00874       **
00875       */
00876       const QString & name,
00877 
00878       /*! optional ~ default zero \n\n */
00879       long flags = 0
00880 
00881     ); // endvirtual long setColumn
00882 
00883     /*!
00884     ** \brief <b>extended preferred:</b> Set Related Column \n
00885     **
00886     ** This function sets a related column.  It uses the same basic syntax as its
00887     **  \ref setColumn( const QString & name, long flags ) "setColumn(FieldName)" counterpart, 
00888     **  but is easier to remember than the actual 
00889     **  \ref setRelatedColumn( long column, const QString &, const QString &, const QString &, long ) 
00890     **  "setRelatedColumn(ConName,CatName,FieldName,flags)" Commence API Call.  It also makes the
00891     **  vbScript code look a little cleaner, since all the calls to set column are
00892     **  virtually the same.  Behold:
00893     **
00894     ** \par vbScript Example of setting mixed column types
00895     ** \code
00896     ** dim cursor: set cursor = cmdb.getCursor("Inventory")
00897     ** cursor.setColumn "inventoryKey"
00898     ** cursor.setColumn "Quantity on Hand"
00899     ** cursor.setColumn "Relates to", "Inventory Location", "inventoryLocationKey"
00900     ** cursor.setColumn "Minimum Order Qty"
00901     ** \endcode
00902     **
00903     ** \note In the code above, both static-fields and connection-fields are referenced
00904     **  using the same basic code syntax, keeping the vbScript code lined up cleanly.  This
00905     **  makes programs more readable and therefore more maintainable (I like it when things
00906     **  line up).  Furthermore, the syntax of the procedure for setting columns is the 
00907     **  same for regular static fields as it is for connection field, and this makes 
00908     **  remembering the function calls easier.
00909     **
00910     ** \sa \ref setColumn( const QString &, long flags ) "setColumn( Field Name ) ' preferred"
00911     ** \sa \ref columnLabels
00912     **
00913     ** \return Index number of referenced column.  -1 indicates the column 
00914     **          reference could not be made.
00915     **
00916     */
00917     virtual long setColumn
00918     (
00919       /*! The Connection Name (often 'Relates to' or 'Employed by') \n\n */
00920       const QString & connecionName,
00921 
00922       /*! The Target Category Name \n\n */
00923       const QString & targetCategoryName,
00924 
00925       /*! The Target Category Target Field Name \n\n */
00926       const QString & fieldName = "",
00927 
00928       /*! optional ~ default zero \n\n */
00929       long flags = 0
00930 
00931     ); // endvirtual long setColumn
00932 
00933 
00934     /*!
00935     ** \brief Set Column \n
00936     **
00937     ** This wraps the existing Commence setColumn API function call.  It 
00938     **  requires a column parameter, and a field name parameter.  However, 
00939     **  the flags parameter is optional and may be excluded.
00940     **
00941     ** Like the Commence implementation, this function requires each column to
00942     **  be assigned in sequence.  Column numbers cannot be skipped, duplicated, 
00943     **  folded, bent or mutilated.  If you reference a column out of sequence,
00944     **  or if you duplicate a reference to a column then you will receive a
00945     **  pop-up warning message, and this function will return false.
00946     **
00947     ** \par vbScript Example
00948     ** \code
00949     ** dim cursor: set cursor = cmdb.getCursor( "Person" )
00950     ** if( not cursor.setColumn(0,"First Name")  ) then exit sub
00951     ** if( not cursor.setColumn(1,"Last Name")   ) then exit sub
00952     ** if( not cursor.setColumn(2,"Middle Name") ) then exit sub
00953     ** \endcode
00954     **
00955     ** \note Your best best is to use one of the preferred functions instead.
00956     **
00957     ** \sa \ref setColumn( const QString &, long flags ) "setColumn( Field Name ) ' preferred"
00958     ** \sa \ref columnLabels
00959     **
00960     ** \return True/False if the column could be set
00961     **
00962     */
00963     virtual bool setColumn
00964     (
00965       /*! The column number to be assigned... this should be sequential \n\n */
00966       long column,
00967 
00968       /*! The column name to be assigned... this cannot be duplicated \n\n */
00969       const QString & name,
00970 
00971       /*! optional ~ default zero \n\n */
00972       long flags = 0
00973     );
00974 
00975     /*!
00976     ** \brief Set Related Column \n
00977     **
00978     ** This wraps the existing Commence setRelatedColumn API function call.
00979     **  It requires a column number, a Connection name, Target Category name,
00980     **  a Target Field name, and a flag.  However, the flag parameter is
00981     **  optional and may be excluded.
00982     **
00983     ** Like the Commence implementation, this function requires each column to
00984     **  be assigned in sequence.  Column numbers cannot be skipped, duplicated, 
00985     **  folded, bent or mutilated.
00986     **
00987     ** This function checks the requested column against the
00988     **  \ref m_columnLabelCache "columnLabelCache" of previously defined columns.
00989     **  During this check it is able to determine if the column is being applied
00990     **  is out of sequence and if the column itself has been applied previously.
00991     **  Both of these conditions are failure conditions.
00992     **
00993     ** If the column is being added out of sequence, then this call will quit with
00994     **  an error message.  If the column has been defined previously then this 
00995     **  function will again quit with an error message indicating so.  In either 
00996     **  case the column will not be applied to the Commence API call and the function
00997     **  will return false.
00998     **
00999     ** \par vbScript Example
01000     ** \code
01001     ** dim cursor: set cursor = cmdb.getCursor( "Person" )
01002     ** if( not cursor.setRelatedColumn(0,"Relates to","Calendar","calendarKey")   ) then exit sub
01003     ** if( not cursor.setRelatedColumn(1,"Family Member", "Person", "First Name") ) then exit sub
01004     ** if( not cursor.setRelatedColumn(2,"has", "Notes", "notesKey")              ) then exit sub
01005     ** \endcode
01006     **
01007     ** \note Your best best is to use one of the preferred functions instead.
01008     **
01009     ** \sa \ref setColumn( const QString &, const QString &, const QString &, long ) "setColumn( Connection Name ) ' preferred"
01010     ** \sa \ref setRelatedColumn( long, const QString &, const QString &, const QString &, long ) "setRelatedColumn( Connection Name ) ' original"
01011     ** \sa \ref columnLabels
01012     **
01013     ** \return True/False if column could be set
01014     **
01015     */
01016     virtual bool setRelatedColumn
01017     (
01018       /*! The Column Number to be assigned... this should be sequential \n\n */
01019       long column,
01020 
01021       /*! The Connection Name as defined in the database. \n\n */
01022       const QString & connectionName,
01023 
01024       /*! The Target Category name \n\n */
01025       const QString & targetCategoryName,
01026 
01027       /*! The Target Field name (from the target category) \n\n */
01028       const QString & fieldName,
01029 
01030       /*! optional ~ default zero \n\n */
01031       long flags = 0
01032     );
01033 
01034     /*!
01035     ** \brief <b>extended alias:</b> Set Related Column \n
01036     **
01037     ** See \ref setRelatedColumn( long, const QString &, const QString &, const QString &, long ) "original setRelatedColumn()"
01038     **  for documentation notes.
01039     **
01040     ** \note Your best best is to use one of the preferred functions instead.
01041     **
01042     ** \sa \ref setColumn( const QString &, const QString &, const QString &, long ) "setColumn( Connection Name ) ' preferred"
01043     ** \sa \ref setRelatedColumn( long, const QString &, const QString &, const QString &, long ) "setRelatedColumn( Connection Name ) ' original"
01044     ** \sa \ref columnLabels
01045     **
01046     ** \return True/False if column could be set
01047     */
01048     virtual bool setColumn
01049     (
01050       /*! The Column Number to be assigned... this should be sequential \n\n */
01051       long column,
01052 
01053       /*! The Connection Name as defined in the database. \n\n */
01054       const QString & connectionName,
01055 
01056       /*! The Target Category name \n\n */
01057       const QString & targetCategoryName,
01058 
01059       /*! The Target Field name (from the target category) \n\n */
01060       const QString & fieldName,
01061 
01062       /*! optional ~ default zero \n\n */
01063       long flags = 0
01064     );
01065 
01066     /*!
01067     ** \brief <b>extended:</b> Set Related Column \n
01068     **
01069     ** This function is the same as its 
01070     ** \ref setRelatedColumn( long, const QString &, const QString &, const QString &, long flags ) "original setRelatedColumn()"
01071     **  counterpart, except that the column specification is not provided.  Like the other
01072     **  new setColumn function calls, it returns the index number of the newly added
01073     **  column.
01074     **
01075     ** \par vbScript Example
01076     ** \code
01077     ** dim cursor: set cursor = cmdb.getCursor( "Person" )
01078     ** if( not cursor.setRelatedColumn("Relates to","Calendar","calendarKey")   ) then exit sub
01079     ** if( not cursor.setRelatedColumn("Family Member", "Person", "First Name") ) then exit sub
01080     ** if( not cursor.setRelatedColumn("has", "Notes", "notesKey")              ) then exit sub
01081     ** \endcode
01082     **
01083     ** \sa \ref setColumn( const QString &, const QString &, const QString &, long ) "setColumn( Connection Name ) ' preferred"
01084     ** \sa \ref columnLabels
01085     **
01086     ** \return Index number of referenced column.  -1 indicates the column 
01087     **          reference could not be made.
01088     */
01089     virtual long setRelatedColumn
01090     (
01091       /*! The Connection Name as defined in the database. \n\n */
01092       const QString & connectionName,
01093 
01094       /*! The Target Category name \n\n */
01095       const QString & targetCategoryName = "",
01096 
01097       /*! The Target Field name (from the target category) \n\n */
01098       const QString & fieldName = "",
01099 
01100       /*! optional ~ default zero \n\n */
01101       long flags = 0
01102     );
01103 
01104     /*!
01105     ** \brief <b>extended:</b> Return Defined Column Index \n
01106     **
01107     ** This function accesses the cursor \ref m_columnLabelCache "Column Label Cache".  
01108     **  Normally this function has no meaning unless some columns have been designated 
01109     **  for this cursor using one of the setColumn() or setRelatedColumn() function calls.  
01110     **  If a column index is requested but has not yet been defined in the cursor
01111     **  then a -1 index value is returned.
01112     **
01113     ** \note Define a column before calling this function
01114     **
01115     ** \sa \ref setColumn( const QString &, long flags ) "setColumn( Field Name ) ' preferred"
01116     ** \sa \ref columnLabels
01117     */
01118     virtual long getColumnIndex
01119     (
01120       /*! column label \n\n */
01121       const QString name,
01122 
01123       /*! optional ~ default zero \n\n */
01124       long flags = 0
01125 
01126     );
01127 
01128     /*!
01129     ** \brief <b>extended:</b> Return Defined Column Name \n
01130     **
01131     ** This function accesses the cursor column index cache.  Normally this function
01132     **  has no meaning unless some columns have been designated for this cursor.
01133     **  If a column label is requested but has not yet been defined in the cursor
01134     **  then an empty string is returned.
01135     **
01136     ** \note Define a column before calling this function.
01137     **
01138     ** \sa \ref setColumn( const QString &, long flags ) "setColumn( Field Name ) ' preferred"
01139     ** \sa \ref columnLabels
01140     */
01141     virtual QString getColumnLabel
01142     ( 
01143       /*! column index \n\n */
01144       long index, 
01145 
01146       /*! optional ~ default zero \n\n */
01147       long flags = 0 
01148 
01149     ); // endvirtual QString getColumnLabel
01150 
01151     /*!
01152     ** \brief <b>extended:</b> Get Row Set \n
01153     **
01154     ** This function gets a generic row set.  This is really a low-level function.
01155     **  You should consider using one of the higher-level rowset get functions.
01156     **
01157     ** \sa \ref rowsets
01158     */
01159     virtual cmcRowSet * getRowSet
01160     (
01161       /*! see \ref cmcRowSet::ROWSET_TYPES "RowSet Types" \n\n */
01162       long type,
01163 
01164       /*!
01165       ** optional ~ number of rows to fetch.  If omitted, the rowset will 
01166       **  return all the rows in the cursor.
01167       ** \n\n
01168       **
01169       */
01170       long rowCount = -1,
01171 
01172       /*!
01173       ** optional ~ Normally, rowsets receive the same name as the 
01174       **  categoryName, but they can be individually named.  Naming a
01175       **  rowset has no functional impact over the rowset operation.
01176       ** \n\n
01177       **
01178       */
01179       const QString & name = "",
01180 
01181       /*! optional ~ default zero \n\n */
01182       long flags = 0
01183 
01184     ); // endvirtual cmcRowSet * getRowSet
01185 
01186     /*!
01187     ** \brief <b>extended:</b> Get Row Set by ID \n
01188     **
01189     ** This function gets a generic row set.  This is really a low-level function.
01190     **  You should consider using one of the higher-level rowset get functions.
01191     **
01192     ** \sa \ref rowsets
01193     */
01194     virtual cmcRowSet * getRowSet
01195     (
01196       /*! see \ref cmcRowSet::ROWSET_TYPES "RowSet Types" \n\n */
01197       long type,
01198 
01199       /*! see \ref thids \n\n */
01200       const QString & id,
01201 
01202       /*!
01203       ** optional ~ Normally, rowsets receive the same name as the 
01204       **  categoryName, but they can be individually named.  Naming a
01205       **  rowset has no functional impact over the rowset operation.
01206       ** \n\n
01207       **
01208       */
01209       const QString & name = "",
01210 
01211       /*! optional ~ default zero \n\n */
01212       long flags = 0
01213 
01214     );
01215 
01216     /*!
01217     ** \brief Create a rowset object with the results of a query \n
01218     **
01219     **
01220     ** \sa \ref rowsets
01221     */
01222     virtual cmcRowSet * getQueryRowSet
01223     (
01224       /*! number of requested rows ~ default to ALL rows \n\n */
01225       long rowCount = -1,
01226 
01227       /*! optional ~ default zero \n\n */
01228       long flags = 0 
01229     );
01230 
01231     /*!
01232     ** \brief Create a rowset object with a particular row loaded \n
01233     **
01234     **
01235     ** \sa \ref rowsets
01236     */
01237     virtual cmcRowSet * getQueryRowSetByID
01238     (
01239       /*! see \ref thids \n\n */
01240       const QString & rowID,
01241 
01242       /*! optional ~ default zero \n\n */
01243       long flags = 0
01244     );
01245 
01246     /*!
01247     ** \brief Rowset By ID alias \n
01248     **
01249     **
01250     */
01251     virtual cmcRowSet * getQueryRowSetByTHID
01252     (
01253       const QString & rowID,
01254       long flags = 0
01255     )
01256     {
01257       return( getQueryRowSetByID(rowID,flags) );
01258     }
01259 
01260     /*!
01261     ** \brief Create a rowset of existing items for editing \n
01262     **
01263     **
01264     ** \sa \ref rowsets
01265     */
01266     virtual cmcRowSet * getEditRowSet
01267     (
01268       /*! number of requested rows ~ default to ALL rows \n\n */
01269       long rowCount = -1,
01270 
01271       /*! optional ~ default zero \n\n */
01272       long flags = 0
01273     );
01274 
01275     /*!
01276     ** \brief Create a rowset for editing a particular row \n
01277     **
01278     **
01279     ** \sa \ref rowsets
01280     */
01281     virtual cmcRowSet * getEditRowSetByID
01282     (
01283       /*! see \ref thids \n\n */
01284       const QString & rowID,
01285 
01286       /*! optional ~ default zero \n\n */
01287       long flags = 0
01288     );
01289 
01290     /*!
01291     ** \brief Rowset By ID alias \n
01292     **
01293     **
01294     */
01295     virtual cmcRowSet * getEditRowSetByTHID
01296     (
01297       const QString & rowID,
01298       long flags = 0
01299     )
01300     {
01301       return( getEditRowSetByID(rowID,flags) );
01302     }
01303 
01304     /*!
01305     ** \brief Create a rowset of new items to add to the database \n
01306     **
01307     **
01308     ** \sa \ref rowsets
01309     */
01310     virtual cmcRowSet * getAddRowSet
01311     (
01312       /*! number of requested rows ~ default to ALL rows \n\n */
01313       long rowCount = 1,
01314 
01315       /*! optional ~ default zero \n\n */
01316       long flags = 0
01317     );
01318 
01319     /*!
01320     ** \brief Create a rowset of existing items for deletion \n
01321     **
01322     **
01323     ** \sa \ref rowsets
01324     */
01325     virtual cmcRowSet * getDeleteRowSet
01326     ( 
01327       /*! number of requested rows ~ default to ALL rows \n\n */
01328       long rowCount = -1,
01329 
01330       /*! optional ~ default zero \n\n */
01331       long flags = 0
01332     );
01333 
01334     /*!
01335     ** \brief Create a rowset for deleting a particular row \n
01336     **
01337     **
01338     ** \sa \ref rowsets
01339     */
01340     virtual cmcRowSet * getDeleteRowSetByID
01341     (
01342       /*! see \ref thids \n\n */
01343       const QString & rowID,
01344 
01345       /*! optional ~ default zero \n\n */
01346       long flags = 0
01347     );
01348 
01349     /*!
01350     ** \brief Rowset By ID alias \n
01351     **
01352     **
01353     */
01354     virtual cmcRowSet * getDeleteRowSetByTHID
01355     (
01356       const QString & rowID,
01357       long flags = 0
01358     )
01359     {
01360       return( getDeleteRowSetByID(rowID,flags) );
01361     }
01362 
01363     /*!
01364     ** \brief Set active item used for view cursors using a view linking filter \n
01365     **
01366     **
01367     */
01368     virtual bool setActiveItem
01369     (
01370       /*! Category name of the active item used with view linking filter \n\n */
01371       const QString & categoryName,
01372 
01373       /*! see \ref thids \n\n */
01374       const QString & rowID,
01375 
01376       /*! optional ~ default zero \n\n */
01377       long flags = 0
01378     );
01379 
01380     /*!
01381     ** \brief <b>passthrough:</b> Set active date used for view cursors using a view linking filter \n
01382     **
01383     **
01384     */
01385     virtual bool setActiveDate
01386     (
01387       /*! Date value used with view linking filter; supports AI date values such as 'today' \n\n */
01388       const QDate & date,
01389 
01390       /*! optional ~ default zero \n\n */
01391       long flags = 0
01392     );
01393 
01394     /*!
01395     ** \brief <b>passthrough:</b> Set active date range used for view cursors using a view linking filter \n
01396     **
01397     */
01398     virtual bool setActiveDateRange
01399     (
01400       /*! Date value of start date used with view linking filter; supports AI date values such as 'today'.\n\n */
01401       const QDate & startDate,
01402 
01403       /*! Date value of end date used with view linking filter; supports AI date values such as 'next monday'.\n\n */
01404       const QDate & endDate,
01405 
01406       /*! optional ~ default zero \n\n */
01407       long flags = 0
01408     );
01409 
01410     /*!
01411     ** \brief <b>extended:</b> Return the Max Field Size \n
01412     **
01413     **
01414     */
01415     virtual long maxFieldSize();
01416 
01417     /*!
01418     ** \brief <b>extended:</b> Return the Max Rows \n
01419     **
01420     **
01421     */
01422     virtual long maxRows();
01423 
01424 
01425     /*!
01426     ** \brief <b>extended:</b> Get a cursor from a related column \n
01427     **
01428     ** This returns a cursor like a sub-query.  It can include a filter (and should)
01429     **  but will default to no filter if one isn't specified.  If the filter can 
01430     **  be derived by a simple parent key (meaning the parent category has a key
01431     **  field (name field) and 'no-duplicates-allowed' is turned on, then this function
01432     **  will apply that (simple) filter directly.
01433     **
01434     ** /note If a parent key is specified but this call was unable to apply that filter
01435     **  properly then a NULL cursor will be returned to prevent the caller from attempting
01436     **  to operate on a cursor with too many rows.
01437     **
01438     */
01439     virtual cmcCursor * getRelatedCursor
01440     (
01441       const QString & connectionName,
01442       const QString parentKey = ""
01443     );
01444 
01445 
01446   signals:
01447 
01448   protected:
01449 
01450   private:
01451 
01452 
01453     /*!
01454     ** \brief <b>(internal)</b> Return a RowSet dispatch pointer \n
01455     **
01456     ** This formats the API call to acquire a rowset handle.  The dispatch pointer returned
01457     **  must be freed by the caller.
01458     **
01459     */
01460     virtual IDispatch * getRowSet
01461     (
01462       /*! \ref cmcRowSet::ROWSET_TYPES "RowSet Types" \n\n */
01463       const QString & rowSetType,
01464 
01465       /*! number of requested rows \n\n */
01466       long rowCount,
01467 
01468       /*! optional ~ default zero \n\n */
01469       long flags = 0
01470     );
01471 
01472     /*!
01473     ** \brief <b>(internal)</b> Return a RowSet by ID dispatch pointer \n
01474     **
01475     ** 
01476     **
01477     */
01478     virtual IDispatch * getRowSet
01479     (
01480       /*! see \ref cmcRowSet::ROWSET_TYPES "RowSet Types" \n\n */
01481       const QString & rowSetType,
01482 
01483       /*! see \ref thids \n\n */
01484       const QString & id,
01485 
01486       /*! optional ~ default zero \n\n */
01487       long flags = 0
01488     );
01489 
01490     /*!
01491     ** 
01492     **
01493     */
01494     QPointer<cmcCategoryDef> m_categoryDef;
01495 
01496     /*!
01497     **
01498     **
01499     */
01500     long m_mode;
01501 
01502     /*!
01503     **
01504     **
01505     */
01506     long m_flags;
01507 
01508     /*!
01509     ** \brief Column Label Cache \n
01510     **
01511     ** This holds a list of all the column names that have been specifically assigned
01512     **  to this cursor object.  If no column names have been assigned, then
01513     **  this list will be empty and the related function calls for reading the
01514     **  column label list will do nothing (ie; return empty lists or whatever)
01515     **
01516     */
01517     QStringList m_columnLabelCache;
01518 
01519     /*!
01520     **
01521     **
01522     */
01523     QStringList m_filterCache;
01524 
01525 }; // endclass cmcCursor:
01526 
01527 } // namespace cmcDatabaseApi
01528 
01529 #endif // #ifndef CDA_CURSOR_H
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties




~ ~ ~ ~ ~ ~
Source Code without Comments is like a Cranberry Garland
without the berries. Comment your Code!
 
Commence Database User Support Group Forum
http://newsgroup.showoff-db.org/
~ ~ ~ ~ ~ ~
Author: Mark Petryk
Lorimark Solutions, LLC
mark@lorimarksolutions.com