In Commence, there is the concept of a single cursor, and four different types of RowSet objects. The different row set types are:
The purpose for having four different row set types is unclear to this software developer. Therefore, due to that general lack-of-understanding on my part, the Dumont implementation of the Cursors and RowSets is slightly different than the Commence implementation. Functionally, this means nothing, since the Dumont implementation is completely compatible with the current Commence implementation. The result, however, is a great simplification of the Cursor/RowSet API.
I'll explain the differences by providing a typical programming example. The first step is to get your hands on a cursor object, this is typically done with the following code:
dim dexe: set dexe = createObject("Dumont.EXE") ' get a handle on dumont dim dapp: set dapp = dexe.applications("MyDB") ' Get a specific app instance ' dim cursor: set cursor = dapp.db.getCursor( "Person" )
Now, here is where the fun begins. Normally, when connected directly to Commence, you would fetch cursors using the following codes:
dim qrs: set qrs = cursor.getQueryRowSet( cursor.rowCount ) dim ers: set ers = cursor.getEditRowSet( cursor.rowCount ) dim drs: set drs = cursor.getDeleteRowSet( cursor.rowCount ) dim ars: set ars = cursor.getAddRowSet( 10 )
Here is another way to fetch the same row set objects using some of the new syntax that is available through Dumont:
const ROWSET_QUERY = 1 const ROWSET_ADD = 2 const ROWSET_DELETE = 3 const ROWSET_EDIT = 4 dim qrs: set qrs = cursor.getRowSet( ROWSET_QUERY ) dim ers: set ers = cursor.getRowSet( ROWSET_EDIT, 5 ) dim drs: set drs = cursor.getRowSet( ROWSET_DELETE, 10, "do-we-deletem-and-howe" ) dim ars: set ars = cursor.getRowSet( ROWSET_ADD, 10 )
Another thing to notice, is that in the first "getRowSet" example, where we fetch a query rowset, we do not specify the row count. Why is that? Because we don't have to! The cursor already knows how many rows are on the rowset, so why does it need to be specified every time we ask for a rowset? It doesn't! And I've made Dumont not require this parameter value. You can put it on or leave it off if you like - your preference! If you leave the rowCount specification off the request then you will end up with a row set object that has the same number of rows in the originating cursor. How handy is that? Incidently the same thing can be done with the original call to getWhateverRowset. Behold:
dim qrs: set qrs = cursor.getQueryRowSet ' get cursor.rowCount rows dim ers: set ers = cursor.getEditRowSet ' get cursor.rowCount rows dim drs: set drs = cursor.getDeleteRowSet ' get cursor.rowCount rows dim ars: set ars = cursor.getAddRowSet ' add just one row by default
Yet another thing to notice is that in one of the rowset fetch functions, I have specified another string "do-we-deletem-and-howe". What is this for? Well, the simple answer is, every object in Dumont has a name. And, a rowset, by way of Commence, doesn't have a name, but since we're wrapping a Commence rowset in Dumont, Dumont can provide one - if you want! You don't have to name your rowsets, but, depending on what you're doing you might want to.
Now,. you're wondering, what's the big deal? Why is it so important that there is only one object in dumont (cmcRowSet) that is wrapping all the four different Commence row sets objects? Here's the answer: "all of the four rowset objects are nearly identical, and use nearly the same code". I hate code duplication. It is the number one source to having bugs creep in to your programs; being forced to duplicate code when you shouldn't have to, but I digress. Let it suffice to say that I avoid code duplication as a first priority - otherwise what's the point?
The cmcRowSet object that is housed in Dumont is a smart object, and it knows from whence it sprang, and what type of rowset object is was springed as. With this knowledge, it is able to insure that you don't do something like take a QueryRowSet type of object wrapper and delete some rows with it. If you do, then you will get a stern warning from Dumont. So, don't do it. Don't even think about doing it!
But, if you do accidently use the generic row set object wrapper for a function it wasn't set up to do, that's all you will get - a stern warning. The function won't complete. and nothing will be requested (incorrectly) from Commence. Dumont will intervene before the request gets that far. And, that's another thing. If you have your hands on a rowset object, and you try to acess some data that is beyond the range of the rowset, Dumont will intervene there as well.
These are all good things, and makes working with Cursors and Rowsets in Dumont a pretty easy thing to do. Plus it's all documented here. Hey, what a concept - documentation!
~ ~ ~ ~ ~
Now, here is another topic on Cursors and Rowsets. There is somewhat of a new feature in Commence Cursors that allows one to fetch from the cursor the THID value from an item in question. This "feature", however, is nearly completely undocumented except for a few renegade .pdf files on the topic, and of course the most totally awesome http://www.freedomcomputing.com newsgroup.
These THID values are fetched from the Row Sets by making a call to the cmcRowSet::getRowID function. However, before you are able to make that call, you have to first open the cursor with the USE_THIDS parameter turned on. There is a problem with turning on THID values on cursors. It's complicated, but it has mostly to do with connection fields. When THIDS are turned on, and you request values from connection fields, you will get THID values for those connections rather than name values. This is something you need to think about before attempting to use the USE_THIDS feature of a Commence cursor object.
Take a look at the default values for the two functions:
#define USE_THIDS 256 #define SOMETHING_ELSE 512
Once you have the cursor open, you can get a query row set on that cursor and begin probing it for THID values or whatever other values you want from the category.
There is a very long article in this documentation set that discusses how to open a cursor properly and assign columns to it and walk the items and columns and so on. That article is located here: Accessing Cursor Data using Column Labels
~ ~ ~ ~ ~ ~
Source Code without Comments is like a Cranberry Garland
without the berries. Comment your Code!
Commence Database Support User Group Forum
~ ~ ~ ~ ~ ~
Author: Mark Petryk
Lorimark Solutions, LLC