Tutorials and Guide to Samples (v11)

Pascal (Btrieve API 用の言語インターフェイス)

ここでは、以下の項目について説明します。

プログラムの例

Web ダウンロードにより提供される以下のプログラム例では、Btrieve の一般的な操作方法を説明します。これらの操作は、MicroKernel との依存関係で要求される順番(ファイルを開いてから I/O を実行するなど)で行われます。

Btrsampw.pas

{********************************************************** 
** 
**  Copyright 2003 Pervasive Software Inc. All Rights Reserved 
** 
***********************************************************} 
{********************************************************** 
  BTRSAMPW.PAS 
    このプログラムでは、Borland Pascal バージョン 7.0 または Turbo Pascal for  
    Windows バージョン 1.5 を使用して、MS Windows 対応の Btrieve インターフェイス 
    について説明します。 
 
    このプログラムでは、サンプル ファイルで以下の操作を行います。 
    - BTRVID を使用して Microkernel Database エンジンのバージョン情報を取得する 
    - sample.btr を開く 
    - Key 0 の既知の値を持つレコードを取得する 
    - 読み込んだレコードを表示する 
    - Stat オペレーションを実行する 
    - 空の sample.btr のクローンを作成して開く 
    - Get Next Extended を実行して sample.btr のレコードのサブセットを抽出する 
    - クローン ファイルにこれらのレコードを挿入する 
    - 両ファイルを閉じる 
 
    重要: 
    Btrieve データ ファイルのサンプル sample.btr が保存されているディレクトリヘの 
    フルパスを指定してください。また、それぞれの「重要」項目も参考にしてください。 
***********************************************************} 
program btrsampw; 
 
uses 
  WinCrt,     { text mode I/O library for Windows } 
  Strings,    { Pascal System functions } 
  btrapiw,    { btrieve interface unit } 
  btrconst;   { Btrieve Constants Unit } 
 
const 
  {**************************************************************** 
    重要:以下を変更し、使用する sample.btr へのフルパスを指定してください。 
  *****************************************************************} 
  FILE1_NAME          = 'c:¥samples¥sample.btr' + #0; 
  FILE2_NAME          = 'c:¥samples¥sample2.btr' + #0; 
 
  { プログラム定数 } 
  MY_THREAD_ID        = 50; 
  EXIT_WITH_ERROR     = 1; 
  VERSION_OFFSET      = 0; 
  REVISION_OFFSET     = 2; 
  PLATFORM_ID_OFFSET  = 4; 
 
{********************************************************** 
  バージョン処理用のレコードの型定義 
***********************************************************} 
type 
  CLIENT_ID = packed record 
    networkandnode :array[0..11]  of char; 
    applicationID  :array[0..1]  of char; 
    threadID       :integer; 
  end; 
 
  VERSION_STRUCT = packed record 
    version   :integer; 
    revision  :integer; 
    MKDEId    :char; 
  end; 
 
{********************************************************** 
  sample.btr からのレコードの定義 
***********************************************************} 
 
  {* writeln() への対応のため、ゼロ基準のキャラクター配列を使用 *} 
  PERSON_STRUCT = packed record 
    ID          :longint; 
    FirstName   :array[0..15]  of char; 
    LastName    :array[0..25]  of char; 
    Street      :array[0..30]  of char; 
    City        :array[0..30]  of char; 
    State       :array[0..2]   of char; 
    Zip         :array[0..10]  of char; 
    Country     :array[0..20]  of char; 
    Phone       :array[0..13]  of char; 
  end; 
 
{********************************************************** 
  Stat および Create 処理用のレコードの型定義 
***********************************************************} 
  FILE_SPECS = packed record 
    recLength   :integer; 
    pageSize    :integer; 
    indexCount  :integer; 
    reserved    :array[0..3]  of char; 
    flags       :integer; 
    dupPointers :byte; 
    notUsed     :byte; 
    allocations :integer; 
  end; 
 
  KEY_SPECS = packed record 
    position        :integer; 
    length          :integer; 
    flags           :integer; 
    reserved        :array[0..3]  of char; 
    keyType         :char; 
    nullChar        :char; 
    notUsed         :array[0..1]  of char; 
    manualKeyNumber :byte; 
    acsNumber       :byte; 
  end; 
 
  FILE_CREATE_BUF = packed record 
    fileSpecs :FILE_SPECS; 
    keySpecs  :array[0..4] of KEY_SPECS; 
  end; 
 
{********************************************************** 
  Get Next Extended 処理用のレコードの型定義 
***********************************************************} 
 
  GNE_HEADER = packed record 
    descriptionLen  :integer; 
    currencyConst   :array[0..1]  of char; 
    rejectCount     :integer; 
    numberTerms     :integer; 
  end; 
 
  TERM_HEADER = packed record 
    fieldType       :byte; 
    fieldLen        :integer; 
    fieldOffset     :integer; 
    comparisonCode  :byte; 
    connector       :byte; 
    value           :array[0..2]  of char; 
  end; 
 
  RETRIEVAL_HEADER = packed record 
    maxRecsToRetrieve   :integer; 
    noFieldsToRetrieve  :integer; 
  end; 
 
  FIELD_RETRIEVAL_HEADER = packed record 
    fieldLen        :integer; 
    fieldOffset     :integer; 
  end; 
 
  PRE_GNE_BUFFER = packed record 
    gneHeader :GNE_HEADER; 
    term1     :TERM_HEADER; 
    term2     :TERM_HEADER; 
    retrieval :RETRIEVAL_HEADER; 
    recordRet :FIELD_RETRIEVAL_HEADER; 
  end; 
 
  RETURNED_REC = packed record 
    recLen        :integer; 
    recPos        :longint; 
    personRecord  :PERSON_STRUCT; 
  end; 
 
  POST_GNE_BUFFER = packed record 
    numReturned :integer; 
    recs        :packed array[0..19] of RETURNED_REC; 
  end; 
 
  GNE_BUFFER_PTR = ^GNE_BUFFER; 
  GNE_BUFFER = packed record 
  case byte of 
    1 : (preBuf  :PRE_GNE_BUFFER); 
    2 : (postBuf :POST_GNE_BUFFER); 
  end; 
 
{********************************************************** 
  変数 
***********************************************************} 
var 
  { Btrieve 関数パラメーター } 
  posBlock1     :string[128]; 
  posBlock2     :string[128]; 
  dataBuffer    :array[0..255]  of char; 
  dataLen       :word; 
  keyBuf1       :string[255]; 
  keyBuf2       :string[255]; 
  keyNum        :integer; 
 
  btrieveLoaded :boolean; 
  personID      :longint; 
  file1Open     :boolean; 
  file2Open     :boolean; 
  status:integer; 
  getStatus     :integer; 
  i             :integer; 
  posCtr        :integer; 
 
  client        :CLIENT_ID; 
  versionBuffer :array[1..3] of VERSION_STRUCT; 
  fileCreateBuf :FILE_CREATE_BUF; 
  gneBuffer     :GNE_BUFFER_PTR; 
  personRecord  :PERSON_STRUCT; 
 
{********************************************************** 
  ここからプログラム開始 
***********************************************************} 
begin { btrsamp } 
  { 変数の初期化 } 
  btrieveLoaded := FALSE; 
  file1Open := FALSE; 
  file2Open := FALSE; 
  keyNum := 0; 
  status := B_NO_ERROR; 
  getStatus := B_NO_ERROR; 
 
  writeln; 
  writeln('************ Btrieve Pascal Interface for Windows Demo ************'); 
  writeln; 
 
  { クライアント ID のセットアップ } 
  fillchar(client.networkAndNode, sizeof(client.networkAndNode), #0); 
 
{$ifdef ver70} {Note:Delphi 1.0 is ver80} 
  client.applicationID := 'MT' + #0;  { "AA" 以上を設定 } 
{$else} 
  strpcopy(client.applicationID, 'MT');  { "AA" 以上を設定 } 
  strcat(client.applicationID, #0); 
{$endif} 
 
  client.threadID := MY_THREAD_ID; 
 
  fillchar(versionBuffer, sizeof(versionBuffer), #0); 
  dataLen := sizeof(versionBuffer); 
 
  status = BTRVID( 
              B_VERSION, 
              posBlock1, 
              versionBuffer, 
              dataLen, 
              keyBuf1[1], 
              keyNum, 
              client); 
 
  if status = B_NO_ERROR then begin 
    writeln('Btrieve Versions returned are:'); 
    for i := 1 to 3 do begin 
      with versionBuffer[i] do begin 
        if (version > 0) then begin 
          writeln(version, '.', revision, ' ', MKDEId); 
        end 
      end 
    end; 
    btrieveLoaded := TRUE; 
  end else begin 
    writeln('Btrieve B_VERSION status = ', status); 
    if status <> B_RECORD_MANAGER_INACTIVE then begin 
      btrieveLoaded := TRUE; 
    end 
  end; 
 
  {* sample.btr を開く *} 
  if status = B_NO_ERROR then begin 
    fillchar(dataBuffer, sizeof(dataBuffer), #0); 
    fillchar(keyBuf1, sizeof(keyBuf1), #0); 
    keyNum  := 0; 
    dataLen := 0; 
 
    keyBuf1 := FILE1_NAME; 
    keyBuf2 := FILE2_NAME; 
 
    status = BTRVID( 
                  B_OPEN, 
                  posBlock1, 
                  dataBuffer, 
                  dataLen, 
                  keyBuf1[1], 
                  keyNum, 
                  client); 
 
    writeln('Btrieve B_OPEN status = ', status); 
    if status = B_NO_ERROR then begin 
      file1Open := TRUE; 
    end 
  end; 
 
  {* B_GET_EQUAL を使用して key 0 が既知の値であるレコードを取得 *} 
  if status = B_NO_ERROR then begin 
    fillchar(personRecord, sizeof(personRecord), #0); 
    dataLen := sizeof(personRecord); 
    personID := 263512477;  {* 実際これは社会保障番号 *} 
 
    status = BTRVID( 
                B_GET_EQUAL, 
                posBlock1, 
                personRecord, 
                dataLen, 
                personID, 
                keyNum, 
                client); 
 
    writeln('Btrieve B_GET_EQUAL status = ', status); 
    if status = B_NO_ERROR then with personRecord do begin 
      writeln; 
      writeln('Selected fields from the retrieved record are:'); 
      writeln('ID:', ID); 
      writeln('Name:', FirstName, ' ', LastName); 
      writeln('Street:', Street); 
      writeln('City:', City); 
      writeln('State:', State); 
      writeln('Zip:', Zip); 
      writeln('Country:', Country); 
      writeln('Phone:', Phone); 
      writeln; 
    end; 
  end; 
 
  { Stat オペレーションを実行し、CreateBuffe(作成バッファー)を取得 } 
  fillchar(fileCreateBuf, sizeof(fileCreateBuf), #0); 
  dataLen := sizeof(fileCreateBuf); 
  keyNum  := -1; 
  status := BTRVID(B_STAT, 
                posBlock1, 
                fileCreateBuf, 
                dataLen, 
                keyBuf1[1], 
                keyNum, 
                client); 
 
  if (status = B_NO_ERROR) then begin 
    { sample2.btr を作成して開く } 
    keyNum  := 0; 
    dataLen := sizeof(fileCreateBuf); 
    status := BTRVID(B_CREATE, 
                  posBlock2, 
                  fileCreateBuf, 
                  dataLen, 
                  keyBuf2[1], 
                  keyNum, 
                  client); 
 
    writeln('Btrieve B_CREATE status = ', status); 
  end; 
 
  if (status = B_NO_ERROR) then begin 
    keyNum  := 0; 
    dataLen := 0; 
 
    status = BTRVID( 
                B_OPEN, 
                posBlock2, 
                dataBuffer, 
                dataLen, 
                keyBuf2[1], 
                keyNum, 
                client); 
    writeln('Btrieve B_OPEN status (sample2.btr) = ', status); 
    if (status = B_NO_ERROR) then begin 
      file2Open := TRUE; 
    end; 
  end; 
 
  { 元のファイルからデータを抽出し、新しいファイルへ挿入 } 
  if (status = B_NO_ERROR) then begin 
    { getFirst を実行してカレンシーを確立 } 
    keyNum := 2; { STATE-CITY index } 
    fillchar(personRecord, sizeof(personRecord), #0); 
    fillchar(keyBuf1, sizeof(keyBuf1), #0); 
    dataLen := sizeof(personRecord); 
 
    getStatus := BTRVID( 
                   B_GET_FIRST, 
                   posBlock1, 
                   personRecord, 
                   dataLen, 
                   keyBuf1[1], 
                   keyNum, 
                   client); 
 
    writeln('Btrieve B_GET_FIRST status (sample.btr) = ', getStatus); 
    writeln; 
  end; 
 
  if maxavail < SizeOf(GNE_BUFFER) then begin 
    writeln('Insufficient memory to allocate buffer'); 
    halt(EXIT_WITH_ERROR); 
  end else begin 
    { ヒープ メモリの割り当て } 
    gneBuffer := new(GNE_BUFFER_PTR); 
  end; 
  fillchar(gneBuffer^, sizeof(GNE_BUFFER), #0); 
  strPCopy(gneBuffer^.preBuf.gneHeader.currencyConst, 'UC'); 
  while (getStatus = B_NO_ERROR) do begin 
    gneBuffer^.preBuf.gneHeader.rejectCount := 0; 
    gneBuffer^.preBuf.gneHeader.numberTerms := 2; 
    posCtr := sizeof(GNE_HEADER); 
 
    { 最初の条件を代入 } 
    gneBuffer^.preBuf.term1.fieldType := 11; 
    gneBuffer^.preBuf.term1.fieldLen := 3; 
    gneBuffer^.preBuf.term1.fieldOffset := 108; 
    gneBuffer^.preBuf.term1.comparisonCode := 1; 
    gneBuffer^.preBuf.term1.connector := 2; 
 
    strPCopy(gneBuffer^.preBuf.term1.value, 'TX'); 
    inc(posCtr, (sizeof(TERM_HEADER))); 
 
    { 2 つ目の条件を代入 } 
    gneBuffer^.preBuf.term2.fieldType := 11; 
    gneBuffer^.preBuf.term2.fieldLen := 3; 
    gneBuffer^.preBuf.term2.fieldOffset := 108; 
    gneBuffer^.preBuf.term2.comparisonCode := 1; 
    gneBuffer^.preBuf.term2.connector := 0; 
    strPCopy(gneBuffer^.preBuf.term2.value, 'CA'); 
    inc(posCtr, sizeof(TERM_HEADER)); 
 
    { プロジェクション ヘッダーを設定してレコード全体を読み込む } 
    gneBuffer^.preBuf.retrieval.maxRecsToRetrieve := 20; 
    gneBuffer^.preBuf.retrieval.noFieldsToRetrieve := 1; 
    inc(posCtr, sizeof(RETRIEVAL_HEADER)); 
    gneBuffer^.preBuf.recordRet.fieldLen := sizeof(PERSON_STRUCT); 
    gneBuffer^.preBuf.recordRet.fieldOffset := 0; 
    inc(posCtr, sizeof(FIELD_RETRIEVAL_HEADER)); 
    gneBuffer^.preBuf.gneHeader.descriptionLen := posCtr; 
 
    dataLen := sizeof(GNE_BUFFER); 
    getStatus := BTRVID( 
                   B_GET_NEXT_EXTENDED, 
                   posBlock1, 
                   gneBuffer^, 
                   dataLen, 
                   keyBuf1, 
                   keyNum, 
                   client); 
 
     writeln('Btrieve B_GET_NEXT_EXTENDED status = ', getStatus); 
 
    { Get Next Extended は、ファイルの終わりまで到達してもレコードを返すことがあります } 
    if ((getStatus = B_NO_ERROR) or (getStatus = B_END_OF_FILE)) then begin 
      writeln('GetNextExtended returned ', gneBuffer^.postBuf.numReturned, ' 
records.'); 
      for i := 0 to gneBuffer^.postBuf.numReturned - 1 do begin 
 
{$ifdef ver70} 
        dataLen := sizeof(PERSON_STRUCT); 
        personRecord := gneBuffer^.postBuf.recs[i].personRecord; 
        status = BTRVID( 
                    B_INSERT, 
                    posBlock2, 
                    personRecord, 
                    dataLen, 
                    keyBuf2, 
                    -1,   { カレンシー変更なし } 
                    client); 
        if (status <> B_NO_ERROR) then begin 
          writeln('Btrieve B_INSERT status = ', status); 
          break; 
        end; 
 
{$else} {Turbo Pascal for Windows 1.5 は break に対応していません} 
        if (status = B_NO_ERROR) then begin 
          dataLen := sizeof(PERSON_STRUCT); 
          personRecord := gneBuffer^.postBuf.recs[i].personRecord; 
          status = BTRVID( 
                      B_INSERT, 
                      posBlock2, 
                      personRecord, 
                      dataLen, 
                      keyBuf2, 
                      -1,   { カレンシー変更なし } 
                      client); 
        end; 
        if (status <> B_NO_ERROR) then begin 
          writeln('Btrieve B_INSERT status = ', status); 
        end; 
{$endif} 
 
      end; 
 
      writeln('Inserted ', gneBuffer^.postBuf.numReturned, ' records in new file, 
status = ', status); 
      writeln; 
    end; 
    fillchar(gneBuffer^, sizeof(GNE_BUFFER), #0); 
    gneBuffer^.preBuf.gneHeader.currencyConst := 'EG'; 
  end; 
  dispose(gneBuffer); 
 
  { 開いているファイルを閉じる } 
  keyNum  := 0; 
  if file1Open = TRUE then begin 
    dataLen := 0; 
 
    status = BTRVID( 
                B_CLOSE, 
                posBlock1, 
                dataBuffer, 
                dataLen, 
                keyBuf1[1], 
                keyNum, 
                client); 
 
    writeln('Btrieve B_CLOSE status (sample.btr) = ', status); 
  end; 
 
  if file2Open = TRUE then begin 
    dataLen := 0; 
 
    status = BTRVID( 
                B_CLOSE, 
                posBlock2, 
                dataBuffer, 
                dataLen, 
                keyBuf2[1], 
                keyNum, 
                client); 
 
    writeln('Btrieve B_CLOSE status (sample2.btr) = ', status); 
  end; 
 
end. 

Pascal インターフェイスを使用したコンパイルとリンク

このセクションでは、一般的な開発環境に共通する操作方法を説明します。お使いの開発環境が該当しない場合は、この操作方法を参考にしてください。

Borland Pascal 7 for Windows を使用してサンプル プログラムをコンパイル、リンク、実行するには

  1. File]メニューの[Open]を選択し、BtrSampW.pas ファイルを開きます。
  2. BtrSampW.pas ファイルで、Sample.btr および Sample2.btr のパスを適切なものに変更します。
  3. Compile]メニューの[Make]を選択します。[OK]をクリックします。
    サンプル プログラムがコンパイル、およびリンクされます。
  4. Run]メニューの[Run]を選択します。
    サンプル プログラムが実行されます。

Borland Pascal 7 for DOS を使用してサンプル プログラムをコンパイル、リンク、実行するには

  1. File]メニューの[Open]を選択し、以下のファイルを開きます。
  2. BtrSampD.pas ファイルで、Sample.btr および Sample2.btr のパスを適切なものに変更します。
  3. Options]メニューの[Compiler]を選択し、[Conditional Defines]を "BTI_DOS" に設定します。
  4. Options]メニューの[Directories]を選択し、[EXE]および[TPU]を "¥Intf¥Pascal" ディレクトリに設定します。
  5. BtrConst.pas ファイルで、[Compile]メニューの[Make]を選択します。
  6. BtrApiD.pas ファイルで、[Compile]メニューの[Make]を選択します。
  7. BtrSampD.pas ファイルで、[Compile]メニューの[Make]を選択します。
  8. DOS プロンプトから BtrSampD.exe を実行します。

    メモ

    サンプル プログラムでは、BtrvID 呼び出しが使用されるため、/T:1 フラグのある Btrieve DOS リクエスターをロードしてください。また、同時に適切なリクエスター(Windows サーバーでは BReqNT)もロードする必要があります。


Borland Turbo Pascal 1.5 for Windows を使用してサンプル プログラムをコンパイル、リンク、実行するには

  1. File]メニューの[Open]を選択し、以下のファイルを開きます。
  2. BtrSampW.pas ファイルで、Sample.btr および Sample2.btr のパスを適切なものに変更します。
  3. BtrConst.pas ファイルで、[Compile]メニューの[Make]を選択します。
  4. BtrApiW.pas ファイルで、[Compile]メニューの[Make]を選択します。
  5. BtrSampW.pas ファイルで、[Compile]メニューの[Make]を選択します。
  6. Run]メニューの[Run]を選択します。
    サンプル プログラムが実行されます。

Delphi (Btrieve API 用の言語インターフェイス)

Visual Basic (Btrieve API 用の言語インターフェイス)