Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Beginner - Business object
Message
General information
Forum:
Visual FoxPro
Category:
Object Oriented Programming
Miscellaneous
Thread ID:
00612101
Message ID:
00614184
Views:
35
Your business tier requires some additional classes... The business tier is really a framework within itself. Without going into great detail, my business tier consists of the following classes.

1) Connection Manager Class
2) Connection Class
3) Data Class
4) Business Class
5) ID Generator Class

A business class should not "touch" data sources directly. A business class should manage and interact with data classes, apply business logic and provide a data interface to the interface layer. Your business class save method code should be broken into two methods in the data class – SetRS() and Save().

The SetRS should contain something like this:
LPARAMETER toDataRec
LOCAL lnLastArea
lnLastArea = SELECT()
SELECT (THIS.cAlias)
GATHER NAME toDataRec MEMO
SELECT (lnLastArea)
The Save should look something like this:
LPARAMETER tlForce
LOCAL lnRecNo
THIS.ClearError()
lnRecNo = RECNO(THIS.cAlias)
IF NOT TABLEUPDATE( .T., tlForce, THIS.cAlias )  && Update all records
  THIS.cError = THIS.GetErrorMessage()
  THIS.lError = .T.
ENDIF
IF lnRecNo > 0 AND lnRecNo < RECCOUNT(THIS.cAlias)
  GOTO (lnRecNo) IN (THIS.cAlias)
ENDIF
RETURN NOT THIS.lError
The business class has a UpdateData() and SaveData() method with code something like this:

SaveData method – base_business_data
LOCAL loRS,llReturn,loDataObject

llReturn = .F.

THIS.ClearError()

DODebug('About to save...')
loDataObject = THIS.GetDataObject()
IF VARTYPE(loDataObject) = 'O'
  IF THIS.UpdateRecord() AND THIS.ValidateBusinessRules()
    IF loDataObject.SAVE()
      llReturn = .T.
      THIS.oData = loDataObject.GETRS()
    ELSE
      loDataObject.REVERT()
    ENDIF
  ENDIF
ENDIF
RETURN llReturn AND NOT THIS.lError
UpdateData method – base_business_data
LOCAL llReturn,loDataObject,loRS
llReturn = .T.
loDataObject = THIS.GetDataObject()
*DoDebug('We are in the UpdateRecord method...')
IF NOT loDataObject.lEOF
  loRS = loDataObject.GetRS()
  IF VARTYPE(THIS.oData) = 'O' ;
    AND NOT THIS.CompareRS(loRS ,THIS.oData) ;
    AND (VARTYPE(loRS.ID)='C' OR loRS.ID = THIS.oData.ID)
    THIS.Set_Dependence()
    IF PEMSTATUS(THIS.oData,'edit_userid',5)
      THIS.oData.edit_userid = THIS.cCurrentUser
    ENDIF
    IF PEMSTATUS(THIS.oData,'edit_date',5)
      THIS.oData.edit_Date = DATETIME()
    ENDIF
    llReturn = loDataObject.SetRS(THIS.oData)
    IF THIS.lPopulateArray
      THIS.PopulateArray()
    ENDIF
  ENDIF
ENDIF
RETURN llReturn AND NOT THIS.lError
Now the above code only takes into account a single data object being involved which is rarely the case. Here is a sample of a more complex SaveData() method which answers your question about Transactions. My base business class has a BeginTransaction, CommitTransaction and RollbackTransaction method. I included the BeginTransaction code below:

SaveData method – tran_data
LOCAL llReturn

*DoDebug('We are in the save of business object '+THIS.Name)

IF THIS.UpdateRecord()
  LOCAL loTran,loDockTran,loDetail,loEmployee,;
    loDist,loEmployeeSick,loEmployeeVacation
  loTran = THIS.GetDataObject()
  IF NOT EMPTY(THIS.cDataClass_Dist)
    loDist = EVAL('THIS.o'+THIS.cDataClass_Dist)
  ENDIF
  IF NOT EMPTY(THIS.cDataClass_Dock)
    loDockTran = EVAL('THIS.o'+THIS.cDataClass_Dock)
  ENDIF
  IF NOT EMPTY(THIS.cDataClass_Detail)
    loDetail = EVAL('THIS.o'+THIS.cDataClass_Detail)
  ENDIF
  IF NOT EMPTY(THIS.cDataClass_Employee)
    loEmployee = EVAL('THIS.o'+THIS.cDataClass_Employee)
  ENDIF
  IF NOT EMPTY(THIS.cDataClass_Employee_Sick)
    loEmployeeSick = EVAL('THIS.o'+THIS.cDataClass_Employee_Sick)
  ENDIF
  IF NOT EMPTY(THIS.cDataClass_Employee_Vacation)
    loEmployeeVacation = EVAL('THIS.o'+THIS.cDataClass_Employee_Vacation)
  ENDIF

  THIS.BeginTransaction()

  IF VARTYPE(loTran) = 'O'
    llReturn = loTran.SAVE()
  ENDIF
  IF llReturn AND VARTYPE(loDist) = 'O'
    llReturn = loDist.SAVE()
  ENDIF
  IF llReturn AND VARTYPE(loDockTran) = 'O'
    llReturn = loDockTran.SAVE()
  ENDIF
  IF llReturn AND VARTYPE(loDetail) = 'O'
    llReturn = loDetail.SAVE()
  ENDIF
  IF llReturn AND VARTYPE(loEmployee) = 'O'
    llReturn = loEmployee.SAVE()
  ENDIF

  IF llReturn AND VARTYPE(loEmployeeSick) = 'O'
    llReturn = loEmployeeSick.SAVE()
  ENDIF
  IF llReturn AND VARTYPE(loEmployeeVacation) = 'O'
    llReturn = loEmployeeVacation.SAVE()
  ENDIF

  IF llReturn
    THIS.oData = loTran.GetRS()
    IF VARTYPE(loEmployee) = 'O'
      THIS.oEmployeeData = loEmployee.GetRS()
    ENDIF
    THIS.CommitTransaction()
  ELSE
    THIS.RollBackTransaction()
  ENDIF
ENDIF
RETURN llReturn AND NOT THIS.lError
The business class BeginTransaction code iterates through the data objects and calls the BeginTransaction method for each connection used. Depending on the connection class – VFP, Oracle, MS SQL Server the required code is executed for a transaction to begin.
*BeginTransaction method – base_business_class
LOCAL lcConnectionsProcessed,llReturn
lcConnectionsProcessed = ''
llReturn = .f.
LOCAL loDataObject
WITH THIS
  FOR EACH loDataObject IN .CONTROLS
    IF NOT loDataObject.oConnection.NAME + ',' $ lcConnectionsProcessed
      lcConnectionsProcessed = lcConnectionsProcessed + loDataObject.oConnection.NAME + ','
      llReturn = loDataObject.oConnection.BeginTransaction(THIS.DataSessionID)
    ENDIF
  ENDFOR
ENDWITH
RETURN llReturn
Lots of code I know… It is not meant to be the answer just a sample to give you some ideas.

Will

>My base class:
>
>business.Save()
>
>SELECT (calias)
>SCATTER NAME THIS.oData MEMO
>
>if TABLEUPDATE(.t.,.f.,calias)
>   return .t.
>else
>   **error handle
>   return .f.
>endif
>
>
>
>I would like to know, how to handle transaction in bussines object?
>
>Let's say, I have simple business object. Customer, saleorder and lineitems. Once a sales done, I have to update all of these relevant table. Where should I place my BEGIN TRANSACTION?
>
>I subclass business object to be my customer, salesorder and lineitems (for example).
>
>How should my code look like for transaction ?
>
>**What to put before this
>
>**BEGN TRANSACTION - If I place the statement here, will VFP confuse?
>
>SalesOrder.Save()
>Lineitem.save()
>
>**What to put after that to end transaction
>
>Thank you
Heavy Metal Pedal - click with care
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform