Dynamic Database Switching: Difference between revisions

Adding
m (adding)
(Adding)
Line 10: Line 10:
*NatHols - National Holidays
*NatHols - National Holidays


'''Customer Tables''' (exist many times)
'''Customer Tables''' (exist many times in different databases)
*Customers
*Customers
*Transactions
*Transactions
Line 22: Line 22:
===The Database Switching Object===
===The Database Switching Object===


<source lang="vdf">
<source lang="vdf">
Use MerTech.inc
Use MerTech.inc
Line 132: Line 131:
===DataDictionary Sub-Class===
===DataDictionary Sub-Class===


We then need to define which tables will be "customer" tables - that is the ones which will exist as different versions in different databases. To do this it is most convenient to have a subclass of the Data Access DataDictionary class, eith just in the workspace, or in a library workspace if it is to be used in more than one project (placed in the AppSrc directory it either case).  In this we will:
We then need to define which tables will be "customer" tables - that is the ones which will exist as different versions in different databases. To do this it is most convenient to have a subclass of the Data Access DataDictionary class, eith just in the workspace, or in a [[library workspace]] if it is to be used in more than one project (placed in the AppSrc directory it either case).  In this we will:


* Create a property in Construct_Object
* Create a property in Construct_Object
Line 138: Line 137:
   
   
<source lang="vdf">
<source lang="vdf">
Use DataDict.pkg
Use DataDict.pkg //


// We want to should ensure that the global handle is defined, so that this
// We want to should ensure that the global handle is defined, so that this
Line 152: Line 151:
Register_Procedure AddCustomerTable Integer iTab
Register_Procedure AddCustomerTable Integer iTab


// Our sub-class of the standard DataDictionary class, on which we will base all
// our table data disctionaries:
Class cMyDataDictionary is a DataDictionary
Class cMyDataDictionary is a DataDictionary
    
    
Line 163: Line 164:
       Forward Send End_Construct_Object
       Forward Send End_Construct_Object


       // IF this is a customer table AND we have the switcher object:
       // IF this is a customer table AND we have the switcher object, call
  // the procedure passing it the file number:
       If (pbCustomerTable(Self) and (ghoDbSwitch <> 0)) ;
       If (pbCustomerTable(Self) and (ghoDbSwitch <> 0)) ;
         Send AddCustomerTable of ghoDbSwitch (Main_File(Self))
         Send AddCustomerTable of ghoDbSwitch (Main_File(Self))
Line 170: Line 172:
End_Class  // cMyDataDictionary
End_Class  // cMyDataDictionary
</source>
</source>
In the [[Visual DataFlex Studio]] you should then set this sub-class to be the super-class for all of your data dictionaries: Tools -> Configure Workspace -> Class Preferences tab -> DataDictionary and put cMyDatadictionary (or whatever you are calling yours) and cMyDataDictionary.pkg in the two columns.
===Data Disctionaries===
In the data dictionary class file for each of your tables, you should ensure that these are based on your data dictionary sub-class, then, if the table to be marked as a "customer" table, set that property in the Construct_Object procedure:
<source lang="vdf">
Use  cMyDataDictionary.pkg          // DataDictionary Class Definition
Open Customer
Class Customer_DataDictionary  is a cMyDataDictionary
    Procedure Construct_Object
      Forward Send Construct_Object
     
      Set pbCustomerTable to True
    End_Procedure  // Construct_Object
End_Class  // Customer_DataDictionary
</source>
===Without Data Dictionaries===
If you need to have the database switching capability for tables you are opening directly, instead of using data dictionaries for them, you can just use the same call that was place in the data dictionary sub-class, but using the table's File_Number rather than the Main_File property:
<source lang="vdf">
  If (ghoDbSwitch <> 0) Send AddCustomerTable of ghoDbSwitch Customer.File_Number
</source>
===Swiching Database===
Finally, having set up all the required infrastructure, actually invoking the database change becomes very simple. Each code module which uses it should implement the conditional declaration and initialisation of the global handle and register the SwitchDB procedure to ensure it will not cause compile-time or run-time errors if the Database Switcher is not present:
<source lang="vdf">
#IFDEF ghoDbSwitch
#ELSE
  Global_Variable Handle ghoDbSwitch
  Move 0 to ghoDbSwitch  // Initalise to zero
#ENDIF
Register_Procedure SwitchDB String sDatabase
</source>
Then switching database becomes a simple matter of invoking that procedure:
<source lang="vdf">
      If ghoDbSwitch Send SwitchDB sDatabase
</source>
This might be invoked in the login module of some applications, where the database to use is determined by the user's identity, or in the Session Manager module of an [[Ajax]] [[Web Application]], or simply in the change of a visual control (such as a Combo Form) in an application in which the user can choose between many databases to work on.