2016-05-12 7 views
3

Firebird 3に含まれる新しいFirebird.pasインターフェイスを使用しています。カスタムトランザクションパラメータブロックを使用しようとすると問題が発生します。ブロックにタグを追加すると、エラー「トランザクションパラメータブロックの無効な形式」が表示されるようです。これを行う方法の唯一の例は、Firebird 3に含まれている "Using_OO_API.html"ドキュメントです。ここでは、エラーを再現するためのコードを示します。どんな提案も感謝しています!Firebird 3 OO APIでトランザクションパラメータブロックを使用する方法

procedure TForm1.Connect2ButtonClick(Sender: TObject); 
var 
    Master: IMaster; 
    Status: IStatus; 
    Dispatcher: IProvider; 
    Util: IUtil; 
    dpb: IXpbBuilder; 
    tpb: IXpbBuilder; 
    Attachment: IAttachment; 
    Transaction: ITransaction; 
    Statement: IStatement; 
    ErrorString: AnsiString; 
    StatusVector: NativeIntPtr; 
    UseCustomTransaction: Boolean; 
begin 
    // Connect to Firebird 3 and use a custom transaction object. 
    try 
    Master := fb_get_master_interface(); 
    Status := Master.getStatus(); 

    Dispatcher := master.getDispatcher(); 
    Util := Master.getUtilInterface(); 
    dpb := Util.getXpbBuilder(status, IXpbBuilder.DPB, nil, 0); 
    dpb.insertString(status, isc_dpb_user_name, 'SYSDBA'); 
    dpb.insertString(status, isc_dpb_password, 'sillypw'); 
    Attachment := Dispatcher.attachDatabase(status, PAnsiChar('myserver:testdb'), dpb.getBufferLength(status), dpb.getBuffer(status)); 

    UseCustomTransaction := True; 
    if UseCustomTransaction then 
    begin 
     // Transaction := attachment.startTransaction(status, 0, nil); 
     tpb := Util.getXpbBuilder(status, IXpbBuilder.TPB, nil, 0); 
     tpb.insertTag(status, isc_tpb_version3); 
     tpb.insertTag(status, isc_tpb_write); 
     tpb.insertTag(status, isc_tpb_read_committed); 
     tpb.insertTag(status, isc_tpb_nowait); 
     tpb.insertTag(status, isc_tpb_rec_version); 

     // This always seems to error with "invalid format for transaction parameter block" 
     Transaction := attachment.startTransaction(status, tpb.getBufferLength(status), tpb.getBuffer(status)); 
    end 
    else 
    begin 
     // Creating default transaction works fine. As an aside, what are the default transaction properties? 
     Transaction := attachment.startTransaction(status, 0, nil); 
    end; 

    Statement := attachment.prepare(status, transaction, 0, 
      'select rdb$relation_id relid, rdb$relation_name csname ' + 
      ' from rdb$relations ' + 
      ' where rdb$relation_id < ?', 
      3, 0); 

    Memo1.Lines.Add('Simple Plan: ' + Statement.getPlan(status, false)); 
    Memo1.Lines.Add('Detailed Plan: ' + Statement.getPlan(status, true)); 
    Memo1.Lines.Add(''); 

     transaction.rollback(status); 

     Statement.free(status); 
     attachment.detach(status); 

    dpb.dispose; 
    if UseCustomTransaction then 
     tpb.dispose; 

    except 
    on E: FbException do 
    begin 
     SetLength(ErrorString, 2000); 
     StatusVector := E.getStatus().getErrors(); 
     // Note that fb_interpret does not seem to appear in firebird.pas so we added it by hand. 
     // function fb_interpret(s: PAnsiChar; n: Cardinal; var statusVector: NativeIntPtr): Integer; cdecl; external 'fbclient'; 
     SetLength(ErrorString, fb_interpret(PAnsiChar(ErrorString), 2000, StatusVector)); 
     ShowMessage(String(ErrorString)); 
    end 
    end; 

end; 
+4

私はFirebirdのコア開発者の外は、このAPIはしていないと思われるように私は、あなたがFirebirdの-develのメーリングリストに尋ねる示唆しますまだ多くの使用を見た;私はここの答えにチャンスがあまりないと思う。 –

+0

ありがとうございました。私もそのショットを与えるでしょう。 – MarkF

答えて

3

それは無効なトランザクションパラメータバッファを作成するような(TPBまたはInsertTagに、おそらく特定)IXpbBuilderに問題があるように見えます。これは、次のコードのように手でバッファを作成することで回避することができます。

// var TransParamBuffer: TBytes 
SetLength(TransParamBuffer, 5); 
TransParamBuffer[0] := isc_tpb_version3; 
TransParamBuffer[1] := isc_tpb_write; 
TransParamBuffer[2] := isc_tpb_read_committed; 
TransParamBuffer[3] := isc_tpb_nowait; 
TransParamBuffer[4] := isc_tpb_rec_version; 
Transaction := attachment.startTransaction(status, Length(TransParamBuffer), @TransParamBuffer[0]); 
+4

あなた自身の解決策を投稿するためによくできました、+1。私はより多くの人々が単に彼らのqを放棄するよりもこれを行うだろうと思います。 – MartynA

関連する問題