Class wwBusinessObject
wwBusinessObject provides a base business object for CRUD (Created, Read, Update, Delete) services. This class is a single level business object class that implements both the business and data tier in a single object to provide ease of use and maximum performance. This class is a thin wrapper over the underlying data access layer using either direct FoxPro DAL commands or SQL Pass through for SQL backends.
It provides the following features:
Easy CRUD - Automated Base Data Access
The base object provides core CRUD functionality through its base class methods. Native query based data access is also supported through native FoxPro or SQL syntax, using the class methods which can route to the appropriate server backend.
foxpro
foxpro
loCustBus = CREATEOBJECT("cCustomer")
loCustBus.New()
? loCustBus.oData.LastName
loCustBus.oData.LastName = "Strahl Jr."
? loCustBus.Save()
*** save the new PK
pnPk = loCustBus.oData.Pk
? pnPk
* New instance to demonstrate
loCustBus = CREATEOBJECT("cCustomer")
? loCustBus.Load(pnPk) && reload the record
? loCustBus.oData.LastName
loCustBus.oData.LastName = "Strahl"
loCustBus.Save()
loCustBus.Query("where pk = ?pnPk") && load data
BROWSE
loCustBus.Delete(pnPk)
Primary Keys Required for CRUD Operations
Note: Automatic CRUD operations are based on single Primary keys. By default numeric keys are used but you can override the
CreateNewId()
method to create keys as strings or Guid values.
FoxPro and SQL Backend Data Access
Fox or SQL Server are natively supported. SQL Server is supported with SQL Pass through commands.The object also supports remote data access over the Web against a SQL Server backend (with some limitations a Fox backend can be used as well). It accomplishes this through CRUD helper methods that can handle many load/save/list operations without SQL code, and string based SQL commands for SQL query execution that can run on multiple data platforms.
The commands in the previous section all would work against SQL Server for example.
Internal Data Record Representation in .oData
Single record CRUD operation operate with an internal .oData
member that receives database record data during Load()
or New()
operations.
The .oData
member hold record data (record level operations) as a class and is completely disconnected from the database while loaded in memory - free to make changes as needed. Save()
can then be used to write the changes into the database.
Query Handling via String based SQL Commands
Queries are run a string based SQL commands that are executed and returned as cursors by default. Errors are captured and return an error code and you can easily query the result count. There also options to return query results directly as JSON, XML, HTML and a few other formats.
Queries typically are run as strings using the Execute()
method, but if you implement custom business objects with your own business class methods you can also use raw FoxPro commands to return result data.
Support for Validation
wwBusinessObject
also includes a Validate()
method and an OnValidate()
handler method that business objects can implement to consistently validate business rules for field data and business rule validations.
Web Focused but works for Desktop as well
This object framework is uniquely geared towards offline operation which is ideal for Web operations and passing data around the Web. In Web applications the object's .oData
member is useful for holding Model data for databinding into HTML templates (ie. <%= loCustomer.oData.FirstName %>
or binding to these values) and reading data back in bulk using Request.FormVarsToObject().
The disconnected data model also makes it uniquely qualified for object aggregation by combining multiple objects into an object hierarchy. For example, an oInvoice
object can contain oInvoice.oCustomer
and oInvoice.oLineItems
which are accessible through the single oInvoice
object reference. Because of the self-contained nature of objects, it's easy to persist data to and from XML and pass them around the Web as well as making it very easy to use the business objects in HTML templates where data is bound to the object properties (<%= oInvoice.oCustomer.oData.LastName %>
). Web Connection's object centric approach also allows you to pull in data back into the object from forms using Request.FormVarsToObject()
resulting in very little code written to transfer data to and from HTML pages.
Easy to get started with
Because the framework consists only of a minimal set of methods on this object it's easy to get started with it. Because of the single level implementation the framework is also very efficient. In addition a Wizard is provided to help you create business objects by mapping to tables.
Required Dependencies
- wwUtils.prg
- wwApi.prg
- wwCollections.prg
Optional Dependencies
- wwSQL.prg (only if you use nDataMode = 2)
- wwHttpSql.prg (only if you use nDataMode = 4)
- wwXmlState.prg (only if you use Get/SetProperty methods)
Class Members
Member | Description | |
---|---|---|
![]() |
Load | Loads the `.oData` member with a record accessed by PK. This method or a specialized version of it should be used to load with record level objects and return them to the caller. You can overload…
o.Load(lnpk)
|
![]() |
LoadBase | A low level version of the Load() method that can be customized with a custom filter expression and a custom field list to load individual records into the oData member. This method is useful to…
o.LoadBase(lcFilter,lcFieldList)
|
![]() |
Save | Saves the current data member in the `.oData` property to the underlying table.
o.save()
|
![]() |
New | Creates a new oData member. Creates a PK value and sets any defaults coded in the New method. Overload this method to set default values on the oData object properties. ```foxpro ***Create new…
o.new(llNoNewPk)
|
![]() |
GetBlankRecord | Retrieves an empty record and creates an empty oData member. Note no defaults are set.
o.getblankrecord()
|
![]() |
Delete | Deletes the specified record from the underlying table. If no PK is passed the current PK of the loaded object is used.
o.delete(lnPk)
|
![]() |
AddValidationError | Adds a validation error to the oValidationErrors collection. Pass an error string and optional object name. The object name can optionally be used to provide direct error link in Web Pages of the…
o.AddValidationError(lcMessage,lcObjectName)
|
![]() |
Backup | Takes the full content of the table and backs it up into the specified directory.
o.Backup(lcPath,llCreatePath)
|
![]() |
Validate | Virtual method that can be used to hook up validation logic for your business objects. Validation typically gets called before saving an entity. You override this method and fill the…
o.validate()
|
![]() |
Close | Closes the currently open master table or releases the SQL connection.
o.close()
|
![]() |
CreateChildObject | Creates a child object instance that inherits the properties from the current object appropriate from the current object instance. For instance when SQL data (nDataMOde is used) the oSQL member is…
o.createchildobject(lcClass)
|
![]() |
ConvertData | Converts data from a cursor or the current object into the requested result mode. Note this functionality is also accessible via the Query() methods, `lnResultMode` parameter which uses the same…
o.ConvertData(lnResultMode, lcDocRoot, lcTable, lcRow)
|
![]() |
CreateNewId | Creates a new Primary Key ID number for the table using an ID table. The ID Table is configured via the cIDTable property. The table must contain a TableName(character) and an ID (Integer or…
o.createnewid()
|
![]() |
CreateTable | Create the primary table for this object. This method should always be subclassed and implemented by the developer. > **Tip:** You can use the CRT_DBF utility in the Tools directory to generate…
o.createtable(lcFileName)
|
![]() |
Execute | Executes a fully qualified **raw SQL statement** against the database depending on the `nDataMode`. Can be used for any backend data command using either VFP syntax or SQLExec() style SQL commands…
o.Execute(lcSQL, lcCursor)
|
![]() |
ExecuteNonQuery | Executes a fully qualified raw SQL statement through the class that **doesn't return a cursor**. Can be used for backend commands like `INSERT`, `Update` or stored procedure calls etc.
o.ExecuteNonQuery(lcSQL)
|
![]() |
Find | Return `.T.` or `.F.` if a SQL search expression (a `WHERE` clause essentially) can be found. > Only the first item found is returned so you probably want to reserve this for known lookups of…
o.find(lcFilter, llNoDataMember)
|
![]() |
GetProperty | Retrieves a property out of the XML field. Properties can be written with SetProperty.
o.getproperty(lcProperty)
|
![]() |
ImportData | Imports data using the same
o.importdata(lnMode,lcData,lcAlias)
|
![]() |
Open | Opens the data source or remote connection. For ODBC commands the oSQL member holds the SQL connection.
o.open(lcFile, lcAlias, llForceReconnect)
|
![]() |
Query | High level query method that queries the underlying data store using `SELECT` statements. You can use partial SQL syntax (without using `INTO`) to retrieve query results that can be run on different…
o.Query(lcSelect, lcCursor, lnResultmode)
|
![]() |
Reindex |
o.Reindex(llSaveIndexString)
|
![]() |
SetError | Sets the error flag and error message properties.
o.SetError(lcErrorMsg, lnError)
|
![]() |
SetProperty | Sets a property value in the XML field. Note: for performance reasons no checks are performed if the XML field exists.
o.SetProperty(lcProperty, lvValue)
|
![]() |
SetSqlObject | Assigns existing SQL object to the oSQL object or creates one if a connection string is passed. Handles updating data mode and other admin tasks. You can directly open a connection with your…
o.setsqlobject(loSQL)
|
![]() |
StatusMessage | Displays status information. Use this method to have the business object communicate with whatever output mechanism required. Default is a WAIT WINDOW...
o.StatusMessage(lcMessage)
|
![]() |
UpdateStructure | Update the structure of the file based on the CreateTable method's structure. Requires that CreateTable is implemented. Works only with Fox data at this time.
o.updatestructure()
|
![]() |
lCompareUpdates | Will send updates by only updating fields that have changed. This flag causes the various Load() methods to create an oOrigData member in addition to the oData member. This oOrigDataMember is used… |
![]() |
calias | The Alias of the master file. |
![]() |
cServerUrl | A URL on the server that's running the wwHTTPSQLServer component to process client requests. |
![]() |
cconnectstring | SQL ConnectString if DataMode=2 |
![]() |
cdatapath | Location of the data |
![]() |
cerrormsg | Any error messages that occurred. |
![]() |
cfilename | Filename of the master file of this business object. |
![]() |
cidtable | Table used to generate new PK Ids. |
![]() |
cpkfield | The field used as the primary key in the table. This field must be an integer or numeric field. |
![]() |
cresultxml | Methods returning XML will return the XML in this property. |
![]() |
cSkipFieldsForUpdates | Property that holds fields that are skipped for Insert and Update statements built on the fly. Fields are specified as a comma delimited list. Use this if your local object structure for record… |
![]() |
csql | SQL String for a query |
![]() |
csqlcursor | Requests that return a Fox cursor will use this name for the cursor name. |
![]() |
lerror | Error flag for the previous operation. Note this property must be managed by the developer for custom methods. |
![]() |
lThrowOnError | If .T. causes errors to be thrown rather than captured and return in the error info of the various invoke/get/set methods. Defaults to `.F.` |
![]() |
lValidateOnSave | Determines whether Save() automatically calls Validate(). For performance reasons this option is off by default and Validate() needs to be called manually. |
![]() |
ndatamode | Data access mode for the business object. 0 - Fox Data native, 2 - ODBC (SQL Server) |
![]() |
nresultmode | Determines how data requests are returned for `Query` or `ConvertData()` calls. Results are always returned in the `vResult` property. |
![]() |
nupdatemode | Determines whether the data member is in edit or new mode. 1. Updating record 2. New record |
![]() |
oHTTPSQL | An instance member for an wwHTTPSQL class that handles data access over the Web when nDataMode is set to 4. This member is created when Open() is called for the first time, or you can create the… |
![]() |
oData | Data member that receives all of the field names as property values. |
![]() |
oSql | An instance of a wwSQL object that handles data connection if nDatamode = 2. All SQL commands run through this object for remote data. This object is set only afer calling SetSQLObject() or Open().… |
![]() |
oValidationErrors | A collection of Validation Errors that let you indicate errors that occured during calls to the Validate() method or otherwise. Each Validation error is an instance of wwValidationError object which… |
![]() |
vResult | Variable result property. Used at this point only for ADO recordsets returned as a result from queries. |
Assembly: wwBusinessObject.prg
© West Wind Technologies, 2025 • Updated: 2025-03-12
Comment or report problem with topic