Browse DevX
Sign up for e-mail newsletters from DevX


Introducing the CursorAdapter Class : Page 2

One of the most exciting new features of Visual FoxPro 8 is the CursorAdapter class, which provides a common interface for working with data from many different sources. Chuck takes you with him on an adventure in exploring how to use CursorAdapter to change the way you relate to data in VFP 8, whether native tables, ODBC, OLE DB, or XML.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Accessing VFP data
At this point, you can try out the Data Environment to see if it retrieves the data specified by the select command in the CursorAdapter. Using the command window, instantiate the DE class and invoke the OpenTables method:

   lo = NewObject("deTest","Tests.vcx")
   ? lo.OpenTables() 
When the OpenTables method is fired, the CursorAdapter is instructed to fill its cursor with the results of the Select command that you specified in the builder. When you BROWSE, you will see only the customer records that have a CompanyName which starts with "C" (normally, five records match).

One special behavior that comes with the CursorAdapter is that the cursor is coupled to the object instance; therefore, if you destroy the object reference to the CursorAdapter class, you will also lose the cursor and its contents. This means that you'll have to ensure that any CursorAdapter object variables stay within scope for as long as you intend to access the associated cursor.

Modifying VFP Data
Now, let's see if the cursor allows updates and posts them properly to the base table. Try the following lines of code in the command window:

   REPLACE contactname WITH 'My Name Here'
   SELECT customers
Once you browse the Customers alias, you see the base table and should be positioned on the record that you modified. If you didn't move the record pointer before issuing the Replace statement, the record with 'CACTU' as the customer ID was modified. Regardless of which record you modified, this proves that the CursorAdapter is updatable and that the updates are being sent properly to the base table.

Under the Hood
Let's open the Data Environment class that you just tested to see what the builder did for us. This is not just an exercise—it is a great way to learn how to properly configure a CursorAdapter class should you decide to make your own classes outside of the Data Environment.

While the Data Environment has a few property changes and a method, we're actually not interested in those changes. Instead, look in the property sheet's object drop-down list and select the caCustomer class to see the settings that are required to make the CursorAdapter class work. Table 1 summarizes the changes made by the builder and what each PEM does.

All of the properties that contain "See Init" are populated at run time by the code generated for the Init method. That code is shown in Listing 1.

This is probably the most educational place to look after the builder is finished to see how the properties have been set. Note that you can change these values here or through the builder. However, by changing them here, you run the risk of breaking functionality, as your property changes are not verified as they are within the builder.

Regardless, you can see in the Init() code how the SelectCmd property is specified, as well as the KeyFieldList, UpdatableFieldList, and the UpdateNameList. Pay particular attention to the format of the UpdateNameList property—this property lists each field from the cursor and its corresponding field (with table name) in the base table.

When creating your own CursorAdapter classes from scratch, you may be tempted to leave out the table name in this listing. However, without this exact format, your updates will fail, but without errors. I'll reiterate this point later when creating a class without the builder.

Earlier I stated that the CursorAdapter, using the Native data source, is essentially a replacement for a Local View. If you have ever built a local view, you probably can see the similarities: a SQL Select statement is constructed, you specify which fields you wish to be updatable, you specify the field or fields that comprise the primary key, and then let VFP do the rest. Once you retrieve the data in the cursor, you can use TableUpdate() to send the changes back to the base table, and VFP automatically builds the necessary Update, Insert or Delete statements to carry out the modifications.

As an example, recall the earlier Replace statement that changed the value of the Contact field in the cCustomer alias. Upon issuing the TableUpdate statement, VFP automatically generates (and submits) the following Update command to attempt the modification:

   UPDATE customers ;
     SET CONTACTNAME=ccustomer.contactname ;
     WHERE ;
     AND ;
VFP was able to generate the WHERE clause by referencing the KeyFieldList property of the CursorAdapter as well as parts of the UpdateNameList property. It also takes into account which field was changed and adds in the necessary clauses to ensure that you don't attempt to update a record that has been changed by someone else. Note that this is because we left the WhereType property at its default of "key fields and any modified fields."

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date