Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
CursorAdapter vs Data objects.
Message
De
20/10/2009 13:34:27
Charlie Schreiner
Myers and Stauffer Consulting
Topeka, Kansas, États-Unis
 
 
À
20/10/2009 07:11:23
Walter Meester
HoogkarspelPays-Bas
Information générale
Forum:
Visual FoxPro
Catégorie:
Autre
Versions des environnements
Visual FoxPro:
VFP 9 SP1
Divers
Thread ID:
01430032
Message ID:
01430137
Vues:
97
Hi Walter.
We've been using CAs for quite a while. I'm a big fan of the way they work. We have a builder that does a good job of writing the properties. The caData class we have is ambivalent to whether we are using native tables or SQL server. I've pasted some of the properties and methods in the class just to give you some ideas.

AddNewType: Options are 0,1,2,3,or4.
0=don't add any records.
1=ensure 1 new rec and point to it.
2=Ensure the total number of records=DNORec.
3=add the DNORec to the view. Point at the first record in the set.
4=autoadd 1 record when none, else do nothing.
BuilderSchema: Additions to the CursorSchema can be specified here. Used by the caBuilder.PRG.
BuilderSelect: Changes to the SelectCmd can be specified here. This is used by the builder, caBuilder.PRG, to help create the SelectCmd. e.g. 0000 AS SomeNumber WHERE S.ID = ?This.KeyValue
ConnectionKey: Key name of connection this data object will uses to connect.
DataDir: Location for the DataSource, when using DataSourceType = Native.
DateStampField: FieldName that holds the last DateTime this record was modified.
DateTimeSaved: Consistent DateTime for all saved record during the current save operation.
DefaultNumberOfRecords: Number of records to add to a cursor so the user doesn't have to repeatedly choose "New". When we pick a CostReport, we always might want one record, 10 Detail records.
IsChanged: Flag set by SetIsChanged() to let us know the user has made a change in the record.
Islocked: A 3 state property. NULL means no lock has been attempted. .T. means we have a lock, .F. means we couldn't get a lock.
IsRecordLevel: Flag to let you know if we are running in interactive mode, or validating the entire record.
KeyBase: Can use Character Keys, or numeric. Base 36 is 0-9, A-Z; KeyBase = 10 means NUMERIC keys!! KeyBase 256, use GUIDs! 128 = binary GUID. 0 = generate no key (AutoIncremment)
KeyValue: Key value of this cursor adapter.
LockKey: The Key used by the locking methods to define actual record. By default the KeyValue.
LockName: The Name used by the locking methods to define the scope of the lock. By default the Tables property.
Message: Character string indicating what is occurring with this object. If a method returns false, and normally returns .T., check this property to find out what happened.
ParameterString: Parameter list and values suitable for sending to a Stored procedure. Set by IsInSync().
PropertyList: List of properties this class cares about to do the parameterized view. Filled in by GetPropertiesFromSelectCmd which runs when GetProperties returns EMPTY.
Severity: Numeric. Relates to the severity of a Validation issue. 0-3. 0=good, 1=review, 2=warning, 3=Saving is not allowed.
TablesOther: A list of tables needed for Rules or Validations of this class. When DataSourceType is Native, these tables are opened along with the tables listed in the Tables property.
UserIDField: FieldName that contains the last UserID to modify this record.
WasInUse: List of 0s and 1s that corresponds to the Tables property. When using Native DataSources, each table that is already open gets a 1.
WhyICantAdd: Set by the OKToAdd method, which also sets the AllowInsert property.
WhyICantDelete: Character. Reason why AllowDelete is False. Set by OKToDelete().
WhyICantEdit: Character. Reason why AllowUpdate is False. Set by OKToEdit().
WhyICantLock: Reason a lock wasn't granted.


*AddNew: Pass the number of new records to add.
*AfterRecordUpdate: Fires after each record is saved.
*AfterRequery: SubClass hook. Runs in the Requery after the CursorFill or CursorRefresh. Before Populate().
*BatchSave: When BatchUpdateCount is greater than 1, the Save method runs this method.
*BeforeKeysAssigned: Runs before every record that will be saved. Hook to put special subclass commands so they occur right before the keys are assigned. Pass whether it's a brand new record.
*BeforeRecordUpdate; Hook to put special subclass commands so they occur right before the TABLEUPDATE(). Pass whether it's a brand new record.
*Check: Returns .T. if the Alias is USED().
*Check4Dupes: Use this method to check, that when adding or editing, we don't try to update with a natural key (concantenated or a single field) that already exists.
*ClearValidMsg: Clear out any validation or severity elements left from the last record set. See aValidMsg[].
*CloseDataSources: Closes any Native DataSources.
*Connect: Logic is here to establish a connection. This method may also set DataSourceType it it is blank here.*Default: Subclass hook. Runs after Populate in the Requery(). Here you can set up the new recods the way you want them to look.
*Delete: Deletes the current record set. You can pass .T. if you only want to delete the current record.
*Disconnect: Disconnect from an ODBC data source.
*Getproperties: Returns the properties that this specific class cares about. This is a comma separated list to help make the parameterString.
*GetPropertiesFromSelectCmd: You can fill in the properties that matter to the parameterized view in GetProperties(), or this code will run. If parses the SelectCmd looking for ?This. listing the properties.
*GetUserID: Returns the User's ID.
*GetValidMsg: Pass in a FieldName and Severity by Reference. Returns the validation message, if any.
*GetValue: Get the value of a single field. Useful for querying the value from outside of the current data session.
*Index: Put Index commands here. Called from AutoOpen. Not to be called from other places.
*IsInSync: Cycle through the properties we care about and evaluate their properties. Create a parameter string suitable for sending to a Stored Procedure. Pass .T. if you wish to update an out of sync ParameterString property. Return .T. if there is a difference.
*Lock Sets .IsLocked to .F., then runs OKToLock(). Returns .T. if a lock was obtained.
*MakeAuditTrail: Stamp the record, if required, with name and timestamp, etc.
*MoveToLast: Tries to move to the record we were on last time.
*OkToAdd: Rule to set AllowInsert and WhyICantAdd.
*OkToDelete: Rule to set AllowDelete and WhyICantDelete.
*OkToEdit: Rule to set AllowUpdate and WhyICantEdit.
*OkToLock: When IsLocked is .F. we attempt to get a lock. If successful, IsLocked is .T. If not, WhyICantLock is set.
*OpenDataSources: Opens any native DataSources listed in the Tables property.
*OnNewKeyValueSave: Pass in the newly created KeyValue. This only occurs when the KeyValue property for this CA is empty and a record was just saved.
*OnSave: Pass the cursor object being saved. This is just a way of notifying ThisApp that a save occurred.
*OnTableUpdate: Runs ONCE before saving the first record for this view.
*Park: After we settle on a record, this method runs the OKToDelete, OKToEdit, etc.
*Populate: Add the default number of blank records to this cursor. Prepare it to be seen.
*Publish: Pass a newly created KeyValue to the cursors who care.
*RecordDateStamp: Save a consist DateTime with this set of records.
*RecordUserID: Save the user's ID with the record, if needed.
*RecordValidation: Pass Message and Severity by reference. Runs the v(FieldName) method for each field and returns .T. if all is good. Sets the Message and Severity.
*ReadMe: Place to put information on how to use this class.
*Release: Releases this.
*Requery: Requeries the data.
*Reset: Reset all items in this object so it's like it just got created.
*Revert: Wrapper to TABLEREVERT().
*Save: Saves all the records.
*SetEmptyDates2Null: For dates that can be null, set any that are empty to null.
*SetLockValues: Return an object with properties suitable to deterrmine which item the user wishes to lock. Normally, just the cursorAdapter itself, but it special cases, a surrogate object with the same properties.
*SetValue: Set the value of a field.
*SetDataDir: Place to set the DataDir property. Holds the folder for the dataSource.
*SetProperties: Uses the List of Properties returned by GetProperties to set this class' properties to be congruent with its Parent or oParent. Return .T. if no properties are updated.
*SQLExec: Wrapper for SQLExec(). Pass in the SQL Statement and if desired, the resulting cursor.
*TableUpdate: Wrapper to the native TABLEUPATE function.
*TableUpdated: Pass NumberSaved, NumberReverted to let us know if records were saved, how many, etc. Subclasses do things after the table update has succeeded.
*Unlock: Release the lock on the current record.
*Usermodified: Allows us to determine if the user modified the record, or the changes are due to programmatic changes to make the record suitable for display.
*Valid: Pass the FieldName you wish to Validate. Return .T. if all OK.
*Validate Validate each FieldName with the corresponding 'v'+FieldName method.






>Hi All,
>
>I'm busy in maintaining a huge VFP app where local and remote views are used. This application can use both a VFP and SQL server backend.
>
>The Maintenance on the remote views is of a concern as it does require a lot of time to create and maintain them.
>
>We are looking into two different options to get away from the remote views and create a n-tier architecture.
>1. CursorAdapters
>2. The tightline data classes
>
>To me personally the cursoradapters look very attractive to me. The transition from remote views to cursoradapters is not that much. The VFP commands like REQUERY(), REFRESH(), TABLEUPDATE(), aERROR() and tracking update conflicts are just about 100% compatible. We want to create those cursoradapters on the fly with the help of metadata stored in a table that will specify the SQL commands that will populate the cursor.
>
>The tightline data classes have been arround for a while and are supposed to be rock solid tested etc. However from looking at it, it does not seem as powerfull as cursoradapters.
>
>My question is:
>1. Who has used cursor adapters for a mission critial application? Whats your experience?
>2. Who has encountered showstoppers to use any of the two approaches. What are those?
>3. Any additional advice is welcome.
>
>Walter,
Charlie
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform