リモート・データベース間で Mobile Link ユーザを共有する

この文書では、2 つ以上のリモート・データベースで、同一の Mobile Link user_name を使用する技術を説明します。

概要

同期には、各リモート・データベースでユニークな user_name を持つことが必要です。Mobile Link は各 download_cursor に user_name を渡します。同期する特定のユーザに適切なデータだけを正確にダウンロードするように、同期スクリプトのセットに書き込みをします。しかし、同期中に通信エラーがある場合 (たとえば、ネットワークが利用できない場合) には、Mobile Link はこの名前をデータに矛盾がないことを確保することにも使用します。ここで説明する技術により、2 つ以上の異なるリモート・データベースで同一の user_name を使用することができるようになります。

この文書の手順は、Adaptive Server Anywhere (SQL Anywhere) リモート・データベースを使用していると仮定していますが、一部を変更するだけで Ultra Light データベースでも動作します。

必須ソフトウェア

・SQL Anywhere Studio 8.0.2、9.0.0、またはそれ以降

標準セットアップ

次の設定を行うと仮定します。
     CREATE SYNCHRONIZATION USER “102”;
download_cursor は以下だと仮定します。
     CALL ml_add_table_script( ‘DemoV1′, ‘ULOrder’,
       ’download_cursor’, ‘
     SELECT order_id, cust_id, prod_id, emp_id, disc, quant,
       notes, status, last_modified
      FROM ULOrder
      WHERE last_modified >= ?
     AND emp_id = ?
‘     );

同期するときに、Mobile Link 同期サーバが疑問符を自動的に置き換えます。リモート・データベース “102” が同期する場合は、Mobile Link は以下のように実行します。

     SELECT order_id, cust_id, prod_id, emp_id, disc, quant,
       notes, status, last_modified
      FROM ULOrder
     WHERE last_modified >= ‘2003-05-30 09:44:42.985′
     AND emp_id = ‘102’

これはビジネスロジックに依存します。ここでは、タイムスタンプによる同期方法を使用しているので、ダウンロードされるのは以下だけになります。

・emp_id = “102” に属するロー
・前回の同期以降に変更されたロー

以下のような設定はできません。

・リモート・データベース 1
・Adaptive Server Anywhere
CREATE SYNCHRONIZATION USER “102”;

・Ultra Light (使用する API により異なる。以下は embedded SQL の場合)
ul_synch_info.user_name = “102”;

・リモート・データベース 2
CREATE SYNCHRONIZATION USER “102”;

2 番目のデータベースを同期すると、Mobile Link は進行オフセットが一致しないことを示すエラーをレポートします。この進行オフセットは、同期中に問題が発生した場合、Mobile Link がリモート・データベースごとに追跡して、失われたトランザクションがないことを確認するために使用する情報の一部です。次のような一般的な問題により発生します。

    1. ネットワーク通信が失われる (モデム接続が切断される)
    2. 同期スクリプト中の構文エラー (通常は開発中に検出される)
    3. デバイスが同期中にクレードルからはずされる

共有ユーザ

2 つ (もしくはそれ以上) のリモート・データベース (Ultra Light または Adaptive Server Anywhere (SQL Anywhere)) で、同一の user_name を共有する場合、各リモート・データベースで user_name を変更する必要があります。


ユニバーサル・ユニーク識別子

同期ユーザを作成するときに、ユニバーサル・ユニーク識別子 (UUID) を使用します。この機能は 8.0.2 のリリースで、Adaptive Server Anywhere (SQL Anywhere) と Ultra Light の両方に追加されました。UUID は、ユニークであることを保証しており、ほかのリモート・データベースが同じ値を生成することはありません。

UUID をサポートするために、Adaptive Server Anywhere (SQL Anywhere) は以下の 3 つの関数を使用します。

・NEWID() 新しい UUID を生成する。UUID は、binary(16) カラムに格納されるバイナリ値です。

・UUIDTOSTR() ユニークな識別子をフォーマットがxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (x は 16 進数) の文字列値に変換する。バイナリ値が有効なユニーク識別子でない場合は、NULL を返します。

・STRTOUUID() フォーマットが xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (x は 16 進数) の文字列をユニークな識別子の値に変換する。文字列が有効な UUID 文字列でない場合は、NULL を返します。

リモート・ユーザを作成するにはさまざまな方法があります。以下のスクリプトを使用することもできます。

Adaptive Server Anywhere
BEGIN
EXECUTE IMMEDIATE ‘CREATE SYNCHRONIZATION USER “‘ +
UUIDTOSTR(NEWID()) + ‘”‘;
END;

Ultra Light (embedded SQL の場合)
EXEC SQL BEGIN DECLARE SECTION;
TCHAR sql_user_name_uuid[ 40 ];
EXEC SQL END DECLARE SECTION;

EXEC SQL SELECT uuidtostr(newid())
INTO : sql_user_name_uuid
FROM dummy;
Ultra Light リモートでは、後で参照できるように、sql_user_name_uuid を格納します。Ultra Light テーブルを作成して、この値を挿入します。同期するたびに、値をデータベースから取り出し、ul_synch_info.user_name フィールドに移植します。デフォルトでは、Ultra Light データベースのすべてのテーブルが統合データベースに同期されます。ただし、必要ならば、テーブル (ul_synch_info テーブルなど) を同期から除外することができます。同期からのテーブルの除外についての詳細は、Ultra Light マニュアルの以下のセクションを参照にしてください。

『Ultra Light ユーザーズ・ガイド』の Ultra Light アプリケーションの開発 > Ultra Light データベースの設計 > Ultra Light データベースへの非同期テーブルの組み込み

UUID を使用すると、次のような Mobile Link user_name が作成されます。

     b23fdbed-bead-418a-9d53-917e774c2f4f

download_cursor は以下だと仮定します。
     CALL ml_add_table_script( ‘DemoV1′, ‘ULOrder’,
‘     download_cursor’, ‘
     SELECT order_id, cust_id, prod_id, emp_id, disc, quant,
          notes, status, last_modified
       FROM ULOrder
      WHERE last_modified >= ?
        AND emp_id = ?
‘      );

以下のように変換されます。
      SELECT order_id, cust_id, prod_id, emp_id, disc, quant,
            notes, status, last_modified
        FROM ULOrder
       WHERE last_modified >= ‘2003-05-30 09:44:42.985′
         AND emp_id = ‘b23fdbed-bead-418a-9d53-917e774c2f4f’
emp_id が同期ユーザに置き換えられます。これは期待していた値とは異なります。期待していたのは、emp_id = <意味のある値> です。

user_name と UUID を一緒に使用する

Mobile Link スクリプトで同期ユーザに意味のある値を使用するには、user_name とUUID を連結して同期ユーザの形にすることです。次の例では、これら 2 つの値のデリミタとしてコロン (:) を使用していますが、他のデリミタでもかまいません。

       BEGIN
            EXECUTE IMMEDIATE ‘CREATE SYNCHRONIZATION USER “102:’ +
            UUIDTOSTR(NEWID()) + ‘”‘;
       END;

次のような Mobile Link user_name が作成されます。
       102:b23fdbed-bead-418a-9d53-917e774c2f4f
同期すると、download_cursor は以下のように変換されます。
        SELECT order_id, cust_id, prod_id, emp_id, disc, quant,
              notes, status, last_modified
          FROM ULOrder
         WHERE last_modified >= ‘2003-05-30 09:44:42.985′
          AND emp_id = ‘102:b23fdbed-bead-418a-9d53-
         917e774c2f4f’
これは、期待していた結果に近いですが、まだ完全ではありません。Mobile Link がuser_name の値を同期スクリプトに渡す前に、UUID を取り除くようにします。これには、Mobile Link イベントの modify_user (バージョン 8.0.1 から追加) を使用します。このイベントにより、Mobile Link ユーザを入力として受け取り、変更することができるようになりました。変更された値が、すべての Mobile Link イベントに渡されます。この例の modify_user イベントは次のようになります。
         { CALL sp_ML_modify_user( ? ) }

結果、download_cursor の値は 102 となり、102:b23fdbed-bead-418a-9d53-917e774c2f4f ではなくなります。

         SELECT order_id, cust_id, prod_id, emp_id, disc, quant,
               notes, status, last_modified
            FROM ULOrder
           WHERE last_modified >= ‘2003-05-30 09:44:42.985′
            AND emp_id = ‘102’

sp_ML_modify_user ストアド・プロシージャは、統合データベースの言語、ダイアレクトで書きます。同期スクリプトが Java または .NET で書かれているならば、これらの言語で提供しているツールや方法を使用して、Mobile Link user_name を処理することができます。以下の例は、異なる 2 つのダイアレクトでのSQL ストアド・プロシージャを表しています。1 つ目は Adaptive Server Anywhere (SQL Anywhere) データベース固有、2 つ目は、Adaptive Server Anywhere (SQL Anywhere)、Adaptive Server Enterprise、Microsoft SQL Server に対して使用できる Transact SQL を使用して書かれています。

Adaptive Server Anywhere (SQL Anywhere) データベース:

         CREATE PROCEDURE sp_ML_modify_user(
INOUT @ml_user_name VARCHAR(255)
)
BEGIN
DECLARE @colon_at INT;
SET @colon_at = LOCATE( @ml_user_name, ‘:’ );
IF( @colon_at > 0 ) THEN
— メッセージ文が縮小化されたエンジン・ウィンドウに表示されます。これはデバッ
— グ時に役に立ちます。
MESSAGE ‘UUID: ‘ +
RIGHT( @ml_user_name,
(LENGTH(@ml_user_name)-@colon_at) );
SET @ml_user_name = LEFT( @ml_user_name, (@colon_at-1) );
MESSAGE ‘New MobiLink User: ‘ + @ml_user_name;
ELSE
MESSAGE ‘No change to MobiLink User: ‘ + @ml_user_name;
END IF;
END;

Transact SQL:

     create procedure sp_ML_modify_user
@ml_user_name varchar( 128 ) OUT
as
begin
declare @colon_at integer
declare @uuid varchar(128)

set nocount on
select @colon_at=charindex( ‘:’, @ml_user_name)

if @colon_at > 0
begin
select @uuid= substring( @ml_user_name, (@colon_at+1),
LEN(@ml_user_name))
select @ml_user_name= substring( @ml_user_name, 1,
(@colon_at-1) )
end
end
go

リモート

・異なるリモート・データベース間で同一の user_name を共有することができます。Palm ハンドへルド、Windows CE デバイス、ラップトップを使用している状況を考えてみてください。これら 3 つのすべてのデバイスにデータを持つことができます。

・リモート・データベースを再設定 (もしくは再作成) する場合でも、ユニークな Mobile Link user_name により、統合データベースの進行値の再設定 (dbmluser .d の使用) をする必要はありません。

統合

・組み込み Mobile Link ユーザ認証を使用する必要がなくなります。dbmluser ユーティリティを使用して、同期を許可された user_name を追加する必要がなくなります。

・そのまま Mobile Link ユーザ認証を使用する場合は、カスタム認証スキーマを実装します。これはとても簡単な手順です。dbmluser ユーティリティを使用してユーザを追加するなら、カスタム認証ストアド・プロシージャ (または Java/.NET メソッド) は、user_name の抽出のため sp_ML_modify_user ストアド・プロシージャを使用でき、そして、ml_user テーブルに対してこれを照合して、このユーザが Mobile Link で許可されていることを確保できます。2 つの異なる接続イベント authenticate_user と authenticate_user_hashed が呼び出されます。authenticate_user_hashed イベントを使用すると、リモート・データベースから直接提供されたパスワードと、統合データベースの Mobile Link ml_user テーブルのパスワードとを比較することができます。

リモートを削除、再作成することが多い場合、ml_user テーブルが大きくなることがありました。この場合、「失効」リモート・ユーザを取り除く処理を実装する必要があります。9.0.0 バージョンの mluser/ml_subscription テーブルでは、失効ユーザを検出する機能があります。2 つの新しいカラム last_upload_time と last_download_time が追加され、Mobile Link サーバによって自動的に管理されます。ユーザが指定された時間数内で (独自のビジネスロジックで設定) アップロードに成功しなかったときは、ローを削除します。