Working with PowerBuilder synchronization objects
When you run the MobiLink Synchronization for ASA wizard from
the Database page in the New dialog box, the wizard generates objects
that let you initiate and control MobiLink synchronization requests
from a PowerBuilder application. These objects let you obtain feedback
during the synchronization process, code PowerScript events at specific
points during synchronization, and cancel the process programmatically.
Trying out the MobiLink Synchronization for ASA
wizard
This section describes how to try out the MobiLink Synchronization
for ASA wizard in a sample application. To get started, create a
new workspace and a template application. You do not need to create
a SQL database connection, but you
do need to create a project.
Before you use the wizard to generate objects for the application,
you need to set up a remote database and add at least one publication,
user, and subscription to it, and create a PowerBuilder database
profile for the remote database. To test the synchronization objects
from your application, you need to set up a consolidated database.
You can create your own databases, as described in “Preparing consolidated databases” and “Creating remote databases”.
To test the synchronization objects, complete the following
steps:
- Run the wizard.
- Call synchronization objects
from your application. - Deploy the application and
database files. - Start the MobiLink server.
- Run the application.
Run the wizard
The wizard prompts you for a database profile and a publication.
Continue through the wizard, selecting default values, and click
Finish to generate the synchronization objects.
For help using the wizard, see the chapter on managing databases
in the User’s Guide
, or place the
mouse pointer in any wizard field and press F1.
Call synchronization objects
from your application
Open a menu for your application in the Menu painter and add
two submenu items to the File menu, called Synchronize and Sync
Options. Add the following code to the Clicked event
of the Synchronize menu item (appname is
the name of your application):
1 |
s_<i>appname</i>_sync_parms s_opt<br />gf_<i>appname</i>_sync(s_opt) |
Add the following code to the Clicked event of the Sync Options
menu item:
1 |
gf_<i>appname</i>_configure_sync() |
Deploy the application and
database files
Use the Project painter to deploy the application to the desktop
and copy this to all machines that will be connecting remotely to
the MobiLink server. You need to copy the remote database to all
end-user machines, and either register the database as an ODBC database
or include connection parameters in a data source name (DSN) file.
For information on additional files and registry entries required
on end-user machines, see “Runtime requirements for synchronization on remote machines”.
Start the MobiLink server
Select MobiLink Synchronization Server from the Utilities
folder in the Database painter. In the dialog box, select the Automatic
Addition of Users check box. This ensures that the MobiLink name
created in the remote database is recognized by the consolidated
database. Click OK to start the server.
Run the application
Run the application on the remote machine and select the File>Synchronize and
File>Sync Options menu items to test their operation.
The next section describes all the objects generated by the
wizard.
What gets generated
The wizard generates two sets of objects.
Objects that initiate and monitor synchronization
The first set of objects lets the end user initiate and monitor
synchronization:
- nvo_appname_sync – a
custom class user object that controls the MobiLink client (appname is
the name of your application) - gf_appname_sync – a
global function that instantiates the user object and calls a function
to launch a synchronization request - s_appname_sync_parms – a
structure that holds the MobiLink user’s name and password,
and the remote database user and password - w_appname_sync – a
status window that reports the progress of the synchronization process
In the wizard, you can choose whether the application uses
the status window. The alternatives are to display the standard
MobiLink dbmlsync log window or to display no
status window. The generated status window has the advantage of
including an OK button that lets the user view the status before
dismissing the window, and a Cancel button that lets the user cancel
synchronization before it completes. You can also customize the
window to fit your application’s needs.
Objects that modify synchronization options
The second set of objects is generated only if you select
Prompt User for Password and Runtime Changes in the wizard. It lets
the end user change synchronization options before initiating synchronization:
- w_appname_sync_options – an
options window that lets the end user modify the MobiLink user name
and password, the host name and port of the MobiLink server, and
other options for dbmlsync, and choose how to display
status - gf_appname_configure_sync – a
global function that opens the options window and, if the user clicked
OK, calls gf_appname_sync to
initiate synchronization
Most applications that use the options window provide two
menu items or command buttons to launch synchronization: one to
open the options window so that users can set up or modify dbmlsync options
before requesting a synchronization, and one to request a synchronization
with the preset options.
Using the synchronization objects in your application
Before you use the generated objects, you should examine them
in the PowerBuilder painters to understand how they interact. Many
of the function and event scripts contain comments that describe
their purpose.
All the source code is provided so that you have total control
over how your application manages synchronization. You can use the
objects as they are, modify them, or use them as templates for your
own objects.
Instance variables in the user object
The nvo_appname_sync user
object contains instance variables that represent specific dbmlsync arguments,
including the publication name, the MobiLink server host name and
port, and the user name and password for a connection to the remote
database.
When you run the wizard, the values that you specify for these
instance variables are set as default values in the script for the
constructor event of the user object. They are also set in the Windows
registry on the development computer in HKEY_CURRENT_USERSoftwareSybasePowerBuilder10.0appname
MobiLink,
where appname is the name of your application.
At runtime, the constructor event script gets the values of
the instance variables from the registry on the remote machine.
If they cannot be obtained from the registry, or if you override
the registry settings, the default value supplied in the script
is used instead and is written to the registry.
You can change the default values in the event script, and
you can let the user change the registry values at runtime by providing
a menu item that opens the w_appname_sync_options window.
The user object’s uf_runsync and uf_runsync_with_window functions
use the instance variables as arguments when they launch a dbmlsync process.
Launching dbmlsync
To enable the user to launch a synchronization process, code
a button or menu event script to call the gf_appname_sync global
function. This function creates an instance of the nvo_appname_sync user
object, and the user object’s constructor event script
sets the appnameMobiLink key in the
registry of the remote machine.
If you specified in the wizard that the status window should
display, the global function opens the status window, whose ue_postopen event
calls the uf_runsync_with_window function;
otherwise, the global function calls the uf_runsync function.
Both uf_runsync functions launch dbmlsync as
an external process using a special function in the PowerBuilder
VM.
Supplying a MobiLink user name and password
The global function takes a structure for its only argument.
You can pass in the s_appname_sync structure
generated by the wizard. The generated structure argument includes
four variables with string datatypes (one each for MobiLink and
remote database user names and passwords) and a fifth variable that
takes a long datatype for a return code. The structure object that
is generated by the wizard does not set default values for these
variables, so you generally need to provide them.
If you assign valid values to the structure that you pass
as an argument, the global function sets the value of the MobiLink
server and remote database instance variables to the values supplied.
For example, you could code a menu item to open a response window
with single-line edit boxes, and pass the user-supplied
values to the function in the script for an OK button:
1 |
s_<i>appname</i>_sync_parms s_opt<br />s_opt.is_mluser = sle_mlusr.text <br />s_opt.is_mlpass = sle_mlpwd.text<br />s_opt.is_dbuser = sle_dbusr.text <br />s_opt.is_dbpass = sle_dbpwd.text<br />if gf_<i>appname</i>_sync(s_opt)<>0 then<br /> MessageBox("Error", "MobiLink Error")<br />end if |
If you pass a structure with null values or empty strings
to the global function, the uf_runsync functions
of the nvo_appname_sync user
object look for MobiLink and database user name and password values
stored in the registry. The options window (described in “Using the synchronization
options window”) provides
a mechanism to store these values in the registry the first time
a user starts a synchronization. Subsequent synchronizations can
be started without the user having to reenter the information, however,
the options window can still be used to override and reset the registry
values.
Retrieving data after synchronization
After synchronizing, you would typically test for synchronization
errors, then retrieve data from the newly synchronized database.
For example:
1 |
if gf_myapp_sync(s_opt) <> 0 then<br /> MessageBox("Error", "MobiLink error")<br />else<br /> dw_1.Retrieve()<br />end if |
Capturing dbmlsync messages
The PowerBuilder VM traps messages from the dbmlsync process
and triggers events in the user object as the synchronization process
runs.
These events are triggered before synchronization begins as
the upload stream is prepared:
- ue_begin_logscan
( long rescan_log ) - ue_progress_info ( long progress_index,
long progress_max ) - ue_end_logscan ( )
These events correspond to events on the synchronization server,
as described in “Connection events”:
- ue_begin_sync ( string user_name,
string pub_names) - ue_connect_MobiLink (
) - ue_begin_upload ( )
- ue_end_upload ( )
- ue_begin_download ( )
- ue_end_download ( long upsert_rows,
long delete_rows ) - ue_disconnect_MobiLink(
) - ue_end_sync ( long status_code )
These events are triggered after ue_end_upload and
before ue_begin_download:
- ue_wait_for_upload_ack
( ) - ue_upload_ack ( long upload_status )
These events are triggered when various messages are sent
by the server:
- ue_error_msg
( string error_msg ) - ue_warning_msg ( string warning_msg )
- ue_file_msg ( string file_msg )
- ue_display_msg ( string display_msg )
The default event scripts created by the wizard trigger corresponding
events in the optional status window, if it exists. The window events
write the status to the multiline edit control in the status window.
Some window events also update a static text control that displays
the phase of the synchronization operation that is currently running
(log scan, upload, or download) and control a horizontal progress
bar showing what percentage of the operation has completed.
You can also add code to the user object or window events
that will execute at the point in the synchronization process when
the corresponding MobiLink events are triggered. The dbmlsync process
sends the event messages to the controlling PowerBuilder application
and waits until PowerBuilder event processing is completed before
continuing.
Cancelling synchronization
The Cancel button on the status window calls the uf_cancelsync user
object function to cancel the synchronization process. If your application
does not use the status window, you can call this function in an
event script elsewhere in your application.
Using the synchronization options window
To use the w_appname_sync_options window
in your application, code a menu item or button clicked event to
call the gf_appname_configure_sync function. This
function creates an instance of the s_appname_sync_parms structure
and passes it to the options window.
The window’s Open event creates an instance of the nvo_appname_sync user object,
and its ue_postopen event retrieves
values from the registry to populate the text boxes in the window–unless
you have chosen to override registry settings. The user can verify
or modify options in the window and click either OK or Cancel.
If the user clicks OK, the gf_appname_configure_sync function
calls gf_appname_sync to
launch synchronization using the MobiLink and remote database user
names and passwords that are returned from the window. The user’s
changes are also written to the registry.
The Close event of the window calls the wf_try_saving window
function. If the user clicks OK, the wf_savesettings window
function is launched. If the user clicks Cancel, no changes are
made to the registry.
The options window has four pages: Subscriptions, Connection,
MobiLink Server, and Settings.
Subscriptions page
When you used the MobiLink wizard, you selected one or more
publications from the list of available publications. The selected
publications display on the Subscriptions page, but cannot be edited
at runtime.
Each remote user can supply a MobiLink synchronization user
name on this page. The name must be associated in a subscription
with the publications displayed on the page. If the application
is always used by the same MobiLink user, this information never
needs to be supplied again. The name is saved in the registry and
used by default every time synchronization is launched from the
application on this device.
If the user checks the Remember Password check box, the password
is encrypted and saved in the registry. The uf_encrypt_pw and uf_decrypt_pw functions
use a simple algorithm to ensure that the password does not display without
encryption in the registry. You can replace this algorithm with
a more sophisticated encryption technique.
Connection page
Remote users can supply a DSN file name on this page to pass
all the arguments needed to connect to a remote database.
If a DSN file is not used, or if the DSN file does not include
a user name and password, each remote user can supply a remote database
user name on the Connection page of the options window. The name
is saved in the registry and used by default every time synchronization
is launched from the application on this device.
Users can also include additional connection string arguments
for the remote database by entering that information in the Additional
text box on the Connection page. The following syntax should be
used for additional parameters and values:
1 |
param1=value1;param2=value2;paramN=valueN |
If the user checks the Remember Password check box, the password
is encrypted and saved in the registry. The uf_encrypt_pw and uf_decrypt_pw functions
use a simple algorithm to ensure that the database password does
not display without encryption in the registry. You can replace
this algorithm with a more sophisticated encryption technique.
MobiLink Server page
When you create a subscription, you specify a protocol, host,
port, and other connection options. For ease of testing, the default
protocol is TCP/IP and the default host is localhost. The
default port is 2439 for TCP/IP, 80 for HTTP, and 443 for
HTTPS.
You might need to change these defaults when you are testing,
and your users might need to change them when your application is
in use if the server is moved to another host or the port changes.
If the user does not make any changes on this page, dbmlsync uses
the values you entered in the wizard, if any. If you did not enter
values in the wizard, dbmlsync uses the values
in the subscription.
For more information about subscriptions, see “Adding subscriptions”.
Settings page
The Settings page displays logging options, and any other dbmlsync options you
specified in the wizard. It also shows the three display options
available to the user. This page lets the user change any of these
options.
Extended options Extended options are added to the dbmlsync command
line with the -e switch. You do not need to type
the -e switch in the text box.
Modifying generated objects
If you want to give the user access to some dbmlsync options
available in the options window, but not all of them, modify the
window to suit your needs or use it as a template for your own options
window. At a minimum, you probably need to provide a way for each
user to enter a MobiLink user name and password and a remote database
user name and password.
If you want the user to be able to save options without launching dbmlsync,
you could comment out the lines in gf_appname_configure_sync that
call gf_appname_sync,
or add a third button called Save Only that contains the same code
as the OK button, but returns a non-zero value.
Runtime requirements for synchronization on remote machines
Support files required on remote machine
If you do not install PowerBuilder or ASA on remote machines,
you must copy the files listed in Table 13-1 to use MobiLink synchronization with
a PowerBuilder application. These files must be copied to the system
path on the remote machine or the directory where you copy your
PowerBuilder applications.
Required files | Description |
---|---|
PBVM100.DLL, PBDWE100.DLL, PBSHR100.DLL, PBODB100.DLL, PBODB100.INI, LIBJCC.DLL, LIBJLOG.DLL | PowerBuilder files that you can copy from the SharedPowerBuilder directory of the development machine. |
ATL71.DLL, GDIPLUS.DLL, MSVCP71.DLL, MSVCR71.DLL | Microsoft files that ship with PowerBuilder. For restrictions on distributing these files with client applications, see the PowerBuilder Release Bulletin . |
DBENG9.EXE, DBMLSYNC.EXE, DBSERV9.DLL, DBTOOL9.DLL, DBODBC9.DLL, DBMLSOCK.DLL, DBLIB9.DLL, DBGEN9.DLL, DBCON9.DLL, DBCTRS.DLL | ASA and MobiLink files that you can copy from the SybaseSQL Anywhere 9win32 directory of the development machine. You should copy these files to a “win32” subdirectory of the location where you copy the PowerBuilder application and supporting runtime files. |
Registry requirements for a remote machine
If you install ASA on all remote machines that you use with
MobiLink synchronization, the required registry entries are assigned
automatically. If you copy ASA and MobiLink files to a remote machine,
you must create the HKEY_CURRENT_USERSOFTWARESybaseAdaptive Server
Anywhere9.0 registry key and add a “Location” string
value that points to the parent directory of the win32 subdirectory
where you copied ASA and MobiLink files. (The code in the uf_runsync function
of the nvo_appname_sync user object
appends “win32dbmlsync.exe” to
the path that you assign to this registry value.)
Objects generated by the MobiLink Synchronization wizard also
require registry entries to define the ODBC data source for a remote
ASA connection. Table 13-2 lists
the required registry entries. You can create a REG file that installs
these registry entries.
Registry key | Name of string value and data to assign it |
---|---|
HKEY_LOCAL_MACHINESOFTWARE ODBCODBCINST.INIAdaptive Server Anywhere 9.0 |
Driver = full path to DBODBC9.DLL Setup = full path to DBODBC9.DLL |
HKEY_LOCAL_MACHINESOFTWARE ODBCODBCINST.INIODBC Drivers |
Adaptive Server Anywhere 9.0 = “Installed” |
HKEY_LOCAL_MACHINESOFTWARE ODBCODBC.INIODBC Data Sources |
dataSourceName = “Adaptive Server Anywhere 9.0” |
HKEY_LOCAL_MACHINESOFTWARE ODBCODBC.INIdataSourceName |
Driver = full path to DBODBC9.DLL Userid = user name for remote database Password = password for remote database DatabaseName = remoteDatabaseName DatabaseFile = full path to remote database ServerName = remoteDatabaseName Start = “dbeng9 -c 8M” CommLinks = “shmem” |
Using a file DSN instead
of a registry DSN
You can change the uf_runsync function
of the nvo_appname_sync user
object generated by the MobiLink Synchronization wizard to use a
file data source name (DSN) file instead of a registry DSN. To do
this, you must change “dsn=” to “filedsn=” in
the following line of code:
1 |
connect_string = " -c ~"dsn=" + is_desktop_dsn |
If you are using a file DSN, you must change this line to:
1 |
connect_string = " -c ~"filedsn=" + is_desktop_dsn |
For MobiLink synchronization using a file DSN, the is_desktop_dsn
instance variable in the nvo_appname_sync user
object must include the full path to the file DSN. The following
is an example of the contents of a valid file DSN:
1 |
[ODBC]<br />DRIVER=Adaptive Server Anywhere 9.0<br />UID=dba<br />Password=sql<br />Compress=NO<br />DisableMultiRowFetch=NO<br />Debug=NO<br />Integrated=No<br />AutoStop=YES<br />Start=dbeng9 -c 8M<br />EngineName=SalesDB_Remote<br />DBN=SalesDB_Remote<br />DatabaseFile=C:PB10appssalesdbsalesdb_remote.db |
Preparing to use the wizard
The previous sections described how to try out the wizard
in a test application and how to use the objects generated by the
wizard. Before you use the wizard in a production application, you
need to complete the following tasks:
- Set up
a consolidated database and write synchronization scripts as described
in “Preparing consolidated databases” - Create a remote database on the desktop and set
up one or more publications, users, and subscriptions as described
in “Creating remote databases” - Register the database with the ODBC manager on all
remote machines, or create a file DSN for the remote database, as
described in Connecting to Your Database
in
the PowerBuilder online Help and in “Using a file DSN instead
of a registry DSN” - Make sure all remote machines have the required
supporting files, as described in “Runtime requirements for synchronization on remote machines” - (Optional) Create a database connection profile
for the remote database, as described in Connecting to
Your Database
in the PowerBuilder online Help. This allows
the wizard to retrieve a list of publications in the remote database
for which MobiLink subscriptions have been entered