Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (中文) » MobiLink - 服务器管理 » 使用 MobiLink 服务器技术 » MobiLink 基于文件的下载 » 基于文件的下载示例

 

基于时间戳的示例

此示例将实现基于文件的下载以便进行基于时间戳的同步。它将建立三个数据库,然后演示如何基于文件下载数据。所提供的示例既可以只用于阅读,也通过剪切和粘贴文本来运行该示例。

为示例创建数据库

以下命令将创建示例中使用的三个数据库:统一数据库、远程数据库和文件定义数据库。

dbinit tcons.db
dbinit tremote.db
dbinit tfdef.db

以下命令将启动这三个数据库,并创建 MobiLink 连接到统一数据库时使用的数据源名。

dbeng11 -n tfdef_eng tfdef.db
dbeng11 -n tcons_eng tcons.db
dbeng11 -n tremote_eng tremote.db
dbdsn -y -w tfbd_demo -c "eng=tcons_eng;dbf=tcons.db;uid=DBA;
   pwd=sql;astart=off;astop=off"

打开 Interactive SQL,连接到 tcons.db,然后运行 MobiLink 安装脚本。例如:

read "c:\Program Files\SQL Anywhere 11\MobiLink\setup\syncsa.sql"

启动 MobiLink 服务器:

start mlsrv11 -v+ -c "dsn=tfbd_demo" -zu+ -ot tcons.txt
建立时间戳示例统一数据库

在此示例中,统一数据库包含一个名为 T1 的表。连接到统一数据库后,您可以运行以下代码来创建 T1:

CREATE TABLE T1 (
 pk  INTEGER PRIMARY KEY,
 c1  INTEGER,
 last_modified TIMESTAMP DEFAULT TIMESTAMP
);

以下代码定义名为 normal 的脚本版本,该脚本版本中包含最少量的脚本。此脚本版本将被用于使用基于文件的下载的同步。

CALL ml_add_table_script( 'normal', 'T1', 
   'upload_insert',
   'INSERT INTO T1( pk, c1) VALUES( {ml r.pk}, {ml r.c1} )' );
 
CALL ml_add_table_script( 'normal', 'T1',
   'upload_update', 
   'UPDATE T1 SET c1 = {ml r.c1} WHERE pk = {ml r.pk} ' );

CALL ml_add_table_script( 'normal', 'T1',
   'upload_delete', 
   'DELETE FROM T1 WHERE pk = {ml r.pk}' );

CALL ml_add_table_script( 'normal', 'T1',
   'download_cursor',
   'SELECT pk, c1 FROM T1 
      WHERE last_modified >= {ml s.last_table_download}' );

以下代码将所有预订的世代号设置为 1。使用世代号是个很好的做法,可用于因统一数据库丢失或损坏而需要强制实施上载的情形。

CREATE PROCEDURE begin_pub ( 
       INOUT generation_num integer,
       IN    username       varchar(128),
       IN    pubname        varchar(128) )
BEGIN
 SET generation_num = 1;
END;
 
CALL ml_add_connection_script( 'normal', 
    'begin_publication', 
    '{ call begin_pub( 
        {ml s.generation_number},
        {ml s.username},
        {ml s.publication_name},
        {ml s.last_publication_upload},
        {ml s.last_publication_download} ) }' );
    
COMMIT;

以下代码将定义名为 filebased 的脚本版本。此脚本版本将被用于创建基于文件的下载。

CALL ml_add_connection_script( 'filebased', 
    'begin_publication', 
    '{ call begin_pub( 
        {ml s.generation_number},
        {ml s.username},
        {ml s.publication_name} ) }' );

CALL ml_add_table_script( 'filebased', 'T1',
    'download_cursor',
    'SELECT pk, c1 FROM T1 
        WHERE last_modified >= {ml s.last_table_download}' );

以下代码设置上次下载时间,以便将过去五天中发生的所有更改包含在下载文件中。任何缺少过去五天里创建的所有下载文件的远程数据库必须先执行常规同步,然后才能应用其它基于文件的下载。

CREATE PROCEDURE ModifyLastDownloadTimestamp( 
       INOUT last_download_timestamp TIMESTAMP,
       IN    ml_username             VARCHAR(128) )
BEGIN
    SELECT dateadd( day, -5, CURRENT TIMESTAMP )
    INTO last_download_timestamp;
END;
 
CALL ml_add_connection_script( 'filebased', 
   'modify_last_download_timestamp',
   'CALL ModifyLastDownloadTimestamp(
      {ml s.last_download}, {ml s.username} )' );
    
COMMIT;
创建时间戳示例远程数据库

在此示例中,远程数据库也包含一个名为 T1 的表。连接到远程数据库后,运行下列代码以创建表 T1、一个名为 P1 的发布和一个名为 U1 的用户。该代码还会为 U1 创建 P1 的预订。

CREATE TABLE T1 (
 pk INTEGER PRIMARY KEY,
 c1 INTEGER
);

CREATE PUBLICATION P1 (
    TABLE T1
);

CREATE SYNCHRONIZATION USER U1;

CREATE SYNCHRONIZATION SUBSCRIPTION 
TO P1
FOR U1;

以下代码定义 sp_hook_dbmlsync_validate_download_file 存储过程。此存储过程可防止应用其中未嵌入字符串 "ok" 的下载文件。

CREATE PROCEDURE sp_hook_dbmlsync_validate_download_file()
BEGIN
    DECLARE udata varchar(256);
    
    SELECT value 
    INTO udata
    FROM #hook_dict
    WHERE name = 'user data';
    
    IF udata <> 'ok' THEN 
      UPDATE #hook_dict 
      SET value = 'FALSE'
      WHERE name = 'apply file';
    END IF;
END
创建时间戳示例文件定义数据库

以下代码将为此时间戳示例定义文件定义数据库。它将创建一个表、一个发布、一个用户以及该用户的一个发布预订。

CREATE TABLE T1 (
 pk INTEGER PRIMARY KEY,
 c1 INTEGER
);

CREATE PUBLICATION P1 (
    TABLE T1
);

CREATE SYNCHRONIZATION USER G1;

CREATE SYNCHRONIZATION SUBSCRIPTION 
TO P1
FOR G1;
为初始同步做准备

要对新的远程数据库进行准备以便应用下载文件,您需要执行常规同步或使用 dbmlsync -bg 选项创建下载文件。此示例说明如何使用 -bg。

以下代码将为统一数据库定义名为 filebased_init 的脚本版本。此脚本版本有一个 begin_publication 脚本。

CALL ml_add_table_script( 
  'filebased_init', 'T1', 'download_cursor',
  'SELECT pk, c1 FROM T1' );

CALL ml_add_connection_script( 
  'filebased_init', 
  'begin_publication', 
  '{ call begin_pub(
      {ml s.generation_number},
      {ml s.username},
      {ml s.publication_name} ) }' );
    
COMMIT;

以下两个命令行使用名为 filebased_init 的脚本版本和 -bg 选项,创建并应用初始下载文件。

dbmlsync -c "uid=DBA;pwd=sql;eng=tfdef_eng;dbf=tfdef.db" 
  -v+ -e "sv=filebased_init" -bc tfile1.df -be ok -bg 
  -ot tfdef1.txt

dbmlsync -c "uid=DBA;pwd=sql;eng=tremote_eng;dbf=tremote.db" 
  -v+ -ba tfile1.df -ot tremote.txt
演示时间戳示例基于文件的下载

连接到统一数据库,并插入一些由基于文件的下载进行同步的数据(例如以下数据):

INSERT INTO T1(pk, c1) VALUES( 1, 1 );
INSERT INTO T1(pk, c1) VALUES( 2, 4 );
INSERT INTO T1(pk, c1) VALUES( 3, 9 );
commit;

以下命令行创建包含新数据的下载文件。

dbmlsync -c 
   "uid=DBA;pwd=sql;eng=tfdef_eng;dbf=tfdef.db" 
   -v+ -e "sv=filebased" -bc tfile2.df -be ok -ot tfdef2.txt

以下命令行将下载文件应用到远程数据库。

dbmlsync -c "uid=DBA;pwd=sql;eng=tremote_eng;dbf=tremote.db" 
   -v+ -ba tfile2.df -ot tfdef3.txt

现在已将更改应用到远程数据库。打开 Interactive SQL,连接到远程数据库,然后运行以下 SQL 语句,检查远程数据库中是否有这些数据:

SELECT * FROM T1
清理时间戳示例

以下命令停止所有三个数据库服务器,然后消除文件。

del tfile1.df
mlstop -h -w
dbstop -y -c "eng=tfdef_eng; uid=DBA; pwd=sql"
dbstop -y -c "eng=tcons_eng; uid=DBA; pwd=sql"
dbstop -y -c "eng=tremote_eng; uid=DBA; pwd=sql"
dberase -y tfdef.db
dberase -y tcons.db
dberase -y tremote.db