|
このセクションでは、以下について説明します。
Web ダウンロードにより提供される以下のプログラム例では、Btrieve の一般的な操作方法を説明します。これらの操作は、MicroKernel との依存関係で要求される順番(ファイルを開いてから I/O を実行するなど)で行われます。
たとえば、Btrieve Login オペレーションの例については、Btrieve Login の C++ プログラムの例を参照してください。
/************************************************************* Copyright 2003 Pervasive Software Inc. All Rights Reserved **************************************************************/ /*********************************************************** BTRSAMP.C これは、目的の環境で、コンパイラ ツールを使用した Btrieve アプリケーションの コンパイル、リンク、実行が可能なことを確認するための簡単なサンプルです。 このプログラムでは、Btrieve の Windows 用 C/C++ インターフェイスを示します。 このプログラムでは、サンプル データベースで以下の操作を行います。 - Microkernel Database エンジンのバージョン情報を取得する - sample.btr を開く - Key 0 の既知の値を持つレコードを取得する - 読み込んだレコードを表示する - Stat オペレーションを実行する - 空の sample.btr のクローンを作成して開く - Get Next Extended を実行して sample.btr のレコードのサブセットを 抽出する - クローン ファイルにこれらのレコードを挿入する - 両ファイルを閉じる 重要:Btrieve データ ファイルのサンプル sample.btr が保存されている ディレクトリヘのフルパスを指定してください。また、それぞれの「重要」項目も 参考にしてください。 このプログラムは、インターフェイス モジュールが対応するプラットフォームで 実行できます。プラットフォームは btrapi.h にリストされているプラットフォーム スイッチで表されます。Windows では、コンソール アプリケーションで標準出力 printf() を使用できるようにしてください。多くの C/C++ コンパイラは、 標準 I/O を使用した Windows アプリケーションに対応しています。 アプリケーションのターゲット プラットフォーム選択に関する情報は、btrapi.h の 始まりを参照してください。ターゲット プラットフォームを指定してください。 ************************************************************/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <btrapi.h> #include <btrconst.h> /*********************************************************** 定数 ************************************************************/ /*********************************************************** 重要:以下を変更し、使用する sample.btr へのフルパスを指定してください。 ***********************************************************/ #ifdef BTI_WIN_32 #define FILE1_NAME #endif "<path>¥¥samples¥¥sample.btr" #ifdef BTI_WIN_32 #define FILE2_NAME "<path>¥¥samples¥¥sample2.btr" #endif #define EXIT_WITH_ERROR 1 #define TRUE 1 #define FALSE 0 #define VERSION_OFFSET 0 #define REVISION_OFFSET 2 #define PLATFORM_ID_OFFSET 4 #define MY_THREAD_ID 50 /* 弊社の構造体に定義を加えないでください。*/ #if defined(__BORLANDC__) #pragma option -a- #else #if defined(_MSC_VER) || defined(__WATCOMC__) #pragma pack(1) #endif #endif /*********************************************************** クライアント ID とバージョンの構造体の型定義 ************************************************************/ typedef struct { BTI_CHAR networkAndNode[12]; BTI_CHAR applicationID[2]; BTI_WORD threadID; } CLIENT_ID; typedef struct { BTI_SINT Version; BTI_SINT Revision; BTI_CHAR MKDEId; } VERSION_STRUCT; /*********************************************************** sample.btr からのレコードの定義 ************************************************************/ typedef struct { BTI_LONG ID; BTI_CHAR FirstName[16]; BTI_CHAR LastName[26]; BTI_CHAR Street[31]; BTI_CHAR City[31]; BTI_CHAR State[3]; BTI_CHAR Zip[11]; BTI_CHAR Country[21]; BTI_CHAR Phone[14]; } PERSON_STRUCT; /*********************************************************** Stat/Create 構造体の型定義 ************************************************************/ typedef struct { BTI_SINT recLength; BTI_SINT pageSize; BTI_SINT indexCount; BTI_CHAR reserved[4]; BTI_SINT flags; BTI_BYTE dupPointers; BTI_BYTE notUsed; BTI_SINT allocations; } FILE_SPECS; typedef struct { BTI_SINT position; BTI_SINT length; BTI_SINT flags; BTI_CHAR reserved[4]; BTI_CHAR type; BTI_CHAR null; BTI_CHAR notUsed[2]; BTI_BYTE manualKeyNumber; BTI_BYTE acsNumber; } KEY_SPECS; typedef struct { FILE_SPECS fileSpecs; KEY_SPECS keySpecs[5]; } FILE_CREATE_BUF; /*********************************************************** Get Next Extended 処理用の構造体の型定義 ************************************************************/ typedef struct { BTI_SINT descriptionLen; BTI_CHAR currencyConst[2]; BTI_SINT rejectCount; BTI_SINT numberTerms; } GNE_HEADER; typedef struct { BTI_CHAR fieldType; BTI_SINT fieldLen; BTI_SINT fieldOffset; BTI_CHAR comparisonCode; BTI_CHAR connector; BTI_CHAR value[3]; } TERM_HEADER; typedef struct { BTI_SINT maxRecsToRetrieve; BTI_SINT noFieldsToRetrieve; } RETRIEVAL_HEADER; typedef struct { BTI_SINT fieldLen; BTI_SINT fieldOffset; } FIELD_RETRIEVAL_HEADER; typedef struct { GNE_HEADER gneHeader; TERM_HEADER term1; TERM_HEADER term2; RETRIEVAL_HEADER retrieval; FIELD_RETRIEVAL_HEADER recordRet; } PRE_GNE_BUFFER; typedef struct { BTI_SINT recLen; BTI_LONG recPos; PERSON_STRUCT personRecord; } RETURNED_REC; typedef struct { BTI_SINT numReturned; RETURNED_REC recs[20]; } POST_GNE_BUFFER; typedef union { PRE_GNE_BUFFER preBuf; POST_GNE_BUFFER postBuf; } GNE_BUFFER, BTI_FAR* GNE_BUFFER_PTR; /*構造体パッキングの復元 */ #if defined(__BORLANDC__) #pragma option -a. #else #if defined(_MSC_VER) || defined(__WATCOMC__) #pragma pack() #endif #endif /*********************************************************** メイン ***********************************************************/ int main(void) { /* Btrieve 関数パラメーター */ BTI_BYTE posBlock1[128]; BTI_BYTE posBlock2[128]; BTI_BYTE dataBuf[255]; BTI_WORD dataLen; BTI_BYTE keyBuf1[255]; BTI_BYTE keyBuf2[255]; BTI_WORD keyNum = 0; BTI_BYTE btrieveLoaded = FALSE; BTI_LONG personID; BTI_BYTE file1Open = FALSE; BTI_BYTE file2Open = FALSE; BTI_SINT status; BTI_SINT getStatus = -1; BTI_SINT i; BTI_SINT posCtr; CLIENT_ID clientID; VERSION_STRUCT versionBuffer[3]; FILE_CREATE_BUF fileCreateBuf; GNE_BUFFER_PTR gneBuffer; PERSON_STRUCT personRecord; printf("**************** Btrieve C/C++ Interface Demo ****************¥n¥n"); /* クライアント ID のセットアップ */ memset(clientID.networkAndNode, 0, sizeof(clientID.networkAndNode)); memcpy(clientID.applicationID, "MT", 2); /* "AA" 以上を設定 */ clientID.threadID = MY_THREAD_ID; memset(versionBuffer, 0, sizeof(versionBuffer)); dataLen = sizeof(versionBuffer); status = BTRVID( B_VERSION, posBlock1, &versionBuffer, &dataLen, keyBuf1, keyNum, (BTI_BUFFER_PTR)&clientID); if (status == B_NO_ERROR) { printf("Btrieve Versions returned are:¥n"); for (i = 0; i < 3; i++) { if (versionBuffer[i].Version != 0) { printf(" %d.%d %c¥n", versionBuffer[i].Version, versionBuffer[i].Revision, versionBuffer[i].MKDEId ); } } printf("¥n"); btrieveLoaded = TRUE; } else { printf("Btrieve B_VERSION status = %d¥n", status); if (status != B_RECORD_MANAGER_INACTIVE) { btrieveLoaded = TRUE; } } /* バッファーのクリア */ if (status == B_NO_ERROR) { memset(dataBuf, 0, sizeof(dataBuf)); memset(keyBuf1, 0, sizeof(keyBuf1)); memset(keyBuf2, 0, sizeof(keyBuf2)); } /* sample.btr を開く */ if (status == B_NO_ERROR) { strcpy((BTI_CHAR *)keyBuf1, FILE1_NAME); strcpy((BTI_CHAR *)keyBuf2, FILE2_NAME); keyNum = 0; dataLen = 0; status = BTRVID( B_OPEN, posBlock1, dataBuf, &dataLen, keyBuf1, keyNum, (BTI_BUFFER_PTR)&clientID); printf("Btrieve B_OPEN status (sample.btr) = %d¥n", status); if (status == B_NO_ERROR) { file1Open = TRUE; } } /* B_GET_EQUAL を使用して key 0 = 263512477 のレコードを取得 */ if (status == B_NO_ERROR) { memset(&personRecord, 0, sizeof(personRecord)); dataLen = sizeof(personRecord); personID = 263512477; /* 実際これは社会保障番号 */ *(BTI_LONG BTI_FAR *)&keyBuf1[0] = personID; keyNum = 0; status = BTRVID( B_GET_EQUAL, posBlock1, &personRecord, &dataLen, keyBuf1, keyNum, (BTI_BUFFER_PTR)&clientID); printf("Btrieve B_GET_EQUAL status = %d¥n", status); if (status == B_NO_ERROR) { printf("¥n"); printf("The retrieved record is:¥n"); printf("ID:%ld¥n", personRecord.ID); printf("Name:%s %s¥n", personRecord.FirstName, personRecord.LastName ); printf("Street:%s¥n", personRecord.Street); printf("City:%s¥n", personRecord.City); printf("State:%s¥n", personRecord.State); printf("Zip:%s¥n", personRecord.Zip); printf("Country:%s¥n", personRecord.Country); printf("Phone:%s¥n", personRecord.Phone); printf("¥n"); } } /* Stat オペレーションを実行し、fileCreateBuf(作成バッファー)を取得 */ memset(&fileCreateBuf, 0, sizeof(fileCreateBuf)); dataLen = sizeof(fileCreateBuf); keyNum = (BTI_WORD)-1; status = BTRVID(B_STAT, posBlock1, &fileCreateBuf, &dataLen, keyBuf1, keyNum, (BTI_BUFFER_PTR)&clientID); if (status == B_NO_ERROR) { /* sample2.btr を作成して開く */ keyNum = 0; dataLen = sizeof(fileCreateBuf); status = BTRVID(B_CREATE, posBlock2, &fileCreateBuf, &dataLen, keyBuf2, keyNum, (BTI_BUFFER_PTR)&clientID); printf("Btrieve B_CREATE status = %d¥n", status); } if (status == B_NO_ERROR) { keyNum = 0; dataLen = 0; status = BTRVID( B_OPEN, posBlock2, dataBuf, &dataLen, keyBuf2, keyNum, (BTI_BUFFER_PTR)&clientID); printf("Btrieve B_OPEN status (sample2.btr) = %d¥n", status); if (status == B_NO_ERROR) { file2Open = TRUE; } } /* オリジナルのファイルからデータを抽出し、新しいファイルへ挿入 */ if (status == B_NO_ERROR) { /* getFirst を実行してカレンシーを確立 */ keyNum = 2; /* STATE-CITY index */ memset(&personRecord, 0, sizeof(personRecord)); memset(&keyBuf2[0], 0, sizeof(keyBuf2)); dataLen = sizeof(personRecord); getStatus = BTRVID( B_GET_FIRST, posBlock1, &personRecord, &dataLen, keyBuf1, keyNum, (BTI_BUFFER_PTR)&clientID); printf("Btrieve B_GET_FIRST status (sample.btr) = %d¥n¥n", getStatus); } gneBuffer = malloc(sizeof(GNE_BUFFER)); if (gneBuffer == NULL) { printf("バッファーに割り当てるメモリが不足しています"); return(EXIT_WITH_ERROR); } memset(gneBuffer, 0, sizeof(GNE_BUFFER)); memcpy(&gneBuffer->preBuf.gneHeader.currencyConst[0], "UC", 2); while (getStatus == B_NO_ERROR) { 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; memcpy(&gneBuffer->preBuf.term1.value[0], "TX", 2); 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; memcpy(&gneBuffer->preBuf.term2.value[0], "CA", 2); posCtr += sizeof(TERM_HEADER); /* プロジェクション ヘッダーを設定してレコード全体を読み込む */ gneBuffer->preBuf.retrieval.maxRecsToRetrieve = 20; gneBuffer->preBuf.retrieval.noFieldsToRetrieve = 1; posCtr += sizeof(RETRIEVAL_HEADER); gneBuffer->preBuf.recordRet.fieldLen = sizeof(PERSON_STRUCT); gneBuffer->preBuf.recordRet.fieldOffset = 0; 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, (BTI_BUFFER_PTR)&clientID); printf("Btrieve B_GET_NEXT_EXTENDED status = %d¥n", getStatus); /* Get Next Extended はファイルの終わりに達してもレコードを返すことがある */ if ((getStatus == B_NO_ERROR) || (getStatus == B_END_OF_FILE)) { printf("GetNextExtended returned %d records.¥n", gneBuffer- >postBuf.numReturned); for (i = 0; i < gneBuffer->postBuf.numReturned; i++) { dataLen = sizeof(PERSON_STRUCT); memcpy(dataBuf, &gneBuffer->postBuf.recs[i].personRecord, dataLen); status = BTRVID( B_INSERT, posBlock2, dataBuf, &dataLen, keyBuf2, -1, /* カレンシー変更なし */ (BTI_BUFFER_PTR)&clientID); } printf("Inserted %d records in new file, status = %d¥n¥n", gneBuffer->postBuf.numReturned, status); } memset(gneBuffer, 0, sizeof(GNE_BUFFER)); memcpy(&gneBuffer->preBuf.gneHeader.currencyConst[0], "EG", 2); } free(gneBuffer); gneBuffer = NULL; /* 開いているファイルを閉じる */ if (file1Open) { dataLen = 0; status = BTRVID( B_CLOSE, posBlock1, dataBuf, &dataLen, keyBuf1, keyNum, (BTI_BUFFER_PTR)&clientID); printf("Btrieve B_CLOSE status (sample.btr) = %d¥n", status); } if (file2Open) { dataLen = 0; status = BTRVID( B_CLOSE, posBlock2, dataBuf, &dataLen, keyBuf2, keyNum, (BTI_BUFFER_PTR)&clientID); printf("Btrieve B_CLOSE status (sample2.btr) = %d¥n", status); } return(status); }
loginapi.c と同様に Web ダウンロードにより提供される以下のプログラム例では、他のオペレーションのコンテキストで Btrieve のログイン操作を実行する方法について説明します。この操作は、MicroKernel との依存関係で要求される順番(ファイルを開いてから I/O を実行するなど)で行われます。
Btrieve オペレーションの例については、C++ プログラムの例を参照してください。
/********************************************************************* ** Copyright 1982-2003 Pervasive Software Inc. All Rights Reserved *********************************************************************/ /********************************************************************* LOGINAPI.C これは、目的の環境で、コンパイラ ツールを使用した Btrieve アプリケーションの コンパイル、リンク、実行が可能なことを確認するための簡単なサンプルです。 このプログラムは、セキュリティで保護されたデータベースを使用した Btrieve ログイン API の使用方法を示します。ログイン API は Pervasive.SQL 8.50 以降のバージョンで は使用されていません。プログラムを実行するには、DefaultDb データベースをセキュリ ティで保護し、セキュリティ モードにデータベース認証および許可を設定してくだい。これ を設定するには PCC を使用します。 このプログラムでは、DefaultDb データベースで以下の操作を行います。 - Btrieve オペレーション B_LOGIN (78) を使用して DefaultDb データベースに ログインする - sample.btr を開く - Key 0 の既知の値を持つレコードを取得する - 読み込んだレコードを表示する - sample.btr を閉じる - DefaultDB データベースからログアウトする 次のパートでは Btrieve Open 呼び出しで URI を使用する方法を示します。 - キー バッファーで URI 文字列を使用して sample.btr を開く - Key 0 の既知の値を持つレコードを取得する - 読み込んだレコードを表示する - sample.btr を閉じる 重要:Btrieve データ ファイルのサンプル sample.btr が保存されている ディレクトリは、フルパスを指定してください。また、それぞれの「重要」項目も 参考にしてください。 このプログラムは、インターフェイス モジュールが対応するプラットフォームで 実行できます。プラットフォームは、'btrapi.h' でリストされるプラットフォーム スイッチで表されます。Windows の場合は、コンソール アプリケーションで標準出力 printf() を使用できるようにしてください。 メモ:多くの C/C++ コンパイラは、標準 I/O を使用した Windows アプリケーションに 対応しています。 btrapi.h の冒頭部分で、アプリケーションのターゲット プラットフォーム選択に関する 情報を参照してください。ターゲット プラットフォームを指定してください。 *********************************************************************/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <btrapi.h> #include <btrconst.h> /********************************************************************* 定数 *********************************************************************/ /********************************************************************* 重要:以下を変更し、使用する sample.btr へのフルパスを指定してください。 *********************************************************************/ #ifdef BTI_LINUX #define FILE_NAME "/usr/local/psql/data/samples/sample.btr" #else #ifdef BTI_WIN_32 #define FILE_NAME "<path>¥¥samples¥¥sample.btr" #endif #endif #define EXIT_WITH_ERROR 1 #define TRUE 1 #define FALSE 0 #define MY_THREAD_ID 50 /* 弊社の構造体の定義を加えないでください。*/ #if defined(__BORLANDC__) #pragma option -a- #else #if defined(_MSC_VER) || defined(__WATCOMC__) #pragma pack(1) #endif #endif /********************************************************************* クライアント ID とバージョンの構造体の型定義 *********************************************************************/ typedef struct { BTI_CHAR networkAndNode[12]; BTI_CHAR applicationID[2]; BTI_WORD threadID; } CLIENT_ID; typedef struct { BTI_SINT Version; BTI_SINT Revision; BTI_CHAR MKDEId; } VERSION_STRUCT; /********************************************************************* sample.btr のレコードの定義 *********************************************************************/ typedef struct { BTI_LONG ID; BTI_CHAR FirstName[16]; BTI_CHAR LastName[26]; BTI_CHAR Street[31]; BTI_CHAR City[31]; BTI_CHAR State[3]; BTI_CHAR Zip[11]; BTI_CHAR Country[21]; BTI_CHAR Phone[14]; } PERSON_STRUCT; /*構造体パッキングの復元 */ #if defined(__BORLANDC__) #pragma option -a. #else #if defined(_MSC_VER) || defined(__WATCOMC__) #pragma pack() #endif #endif /********************************************************************* メイン *********************************************************************/ int main(void) { /* Btrieve 関数パラメーター */ BTI_BYTE posBlock[128]; BTI_BYTE dataBuf[255]; BTI_WORD dataLen; BTI_BYTE keyBuf[255]; BTI_WORD keyNum = 0; BTI_LONG personID; BTI_BYTE fileOpen = FALSE; BTI_SINT status = 0; CLIENT_ID clientID; PERSON_STRUCT personRecord; /* URI 文字列を定義して DefaultDb データベースの sample.btr を開く*/ /* DefaultDb データベースに対し、ユーザー名を "Master"、パスワードを */ /* "master" で SQL セキュリティを設定*/ BTI_CHAR *URI_STRING1 = "btrv://Master@localhost/defaultdb?pwd=master"; BTI_CHAR *URI_STRING2 = "btrv://Master@localhost/defaultdb?file=/usr/local/psql/data/samples/s ample.btr&pwd=master"; printf("****** Btrieve C/C++ Interface Demo for Login API *****¥n¥n"); /* クライアント ID のセットアップ */ memset(clientID.networkAndNode, 0, sizeof(clientID.networkAndNode)); memcpy(clientID.applicationID, "MT", 2); /* "AA" >以上を設定 */ clientID.threadID = MY_THREAD_ID; /* セキュリティで保護されたデータベースにログイン */ memset(dataBuf, 0, sizeof(dataBuf)); strcpy(keyBuf, URI_STRING1); keyNum = 0; status = BTRVID( B_LOGIN, posBlock, dataBuf, &dataLen, keyBuf, keyNum, (BTI_BUFFER_PTR)&clientID); printf("Btrieve B_LOGIN status = %d¥n", status); /* バッファーのクリア */ memset(dataBuf, 0, sizeof(dataBuf)); memset(keyBuf , 0, sizeof(keyBuf)); /* sample.btr を開く */ strcpy((BTI_CHAR *)keyBuf, FILE_NAME); keyNum = 0; dataLen = 0; status = BTRVID( B_OPEN, posBlock, dataBuf, &dataLen, keyBuf, keyNum, (BTI_BUFFER_PTR)&clientID); printf("Btrieve B_OPEN status (sample.btr) = %d¥n", status); if (status == B_NO_ERROR) { fileOpen = TRUE; } /* B_GET_EQUAL を使用して key 0 = 263512477 のレコードを取得 */ if (status == B_NO_ERROR) { memset(&personRecord, 0, sizeof(personRecord)); dataLen = sizeof(personRecord); personID = 263512477; /* 実際これは社会保障番号 */ *(BTI_LONG BTI_FAR *)&keyBuf[0] = personID; keyNum = 0; status = BTRVID( B_GET_EQUAL, posBlock, &personRecord, &dataLen, keyBuf, keyNum, (BTI_BUFFER_PTR)&clientID); printf("Btrieve B_GET_EQUAL status = %d¥n", status); if (status == B_NO_ERROR) { printf("¥n"); printf("The retrieved record is:¥n"); printf("ID:%ld¥n", personRecord.ID); printf("Name:%s %s¥n", personRecord.FirstName, personRecord.LastName ); printf("Street:%s¥n", personRecord.Street); printf("City:%s¥n", personRecord.City); printf("State:%s¥n", personRecord.State); printf("Zip:%s¥n", personRecord.Zip); printf("Country:%s¥n", personRecord.Country); printf("Phone:%s¥n", personRecord.Phone); printf("¥n"); } } /* 開いているファイルを閉じる */ if (fileOpen) { dataLen = 0; status = BTRVID( B_CLOSE, posBlock, dataBuf, &dataLen, keyBuf, keyNum, (BTI_BUFFER_PTR)&clientID); printf("Btrieve B_CLOSE status (sample.btr) = %d¥n", status); } /* セキュリティで保護されたデータベースからログアウト */ memset(dataBuf, 0, sizeof(dataBuf)); strcpy(keyBuf, URI_STRING1); keyNum = 1; status = BTRVID( B_LOGIN, posBlock, dataBuf, &dataLen, keyBuf, keyNum, (BTI_BUFFER_PTR)&clientID); printf("Btrieve logout status = %d¥n", status); printf("¥n¥n"); /* 以下の例では Btrieve Open 呼び出しで URI 文字列を使用する */ printf("*** 以下の例では Btrieve Open 呼び出しで URI 文字列を使用する ***¥n¥n"); /* クライアント ID のセットアップ */ memset(clientID.networkAndNode, 0, sizeof(clientID.networkAndNode)); memcpy(clientID.applicationID, "MT", 2); /* "AA" >以上を設定 */ clientID.threadID = MY_THREAD_ID; /* バッファーのクリア */ memset(dataBuf, 0, sizeof(dataBuf)); memset(keyBuf , 0, sizeof(keyBuf)); /* sample.btr を開く */ strcpy((BTI_CHAR *)keyBuf, URI_STRING2); keyNum = 0; dataLen = 0; status = BTRVID( B_OPEN, posBlock, dataBuf, &dataLen, keyBuf, keyNum, (BTI_BUFFER_PTR)&clientID); printf("Btrieve B_OPEN status (sample.btr) = %d¥n", status); if (status == B_NO_ERROR) { fileOpen = TRUE; } /* B_GET_EQUAL を使用して key 0 = 263512477 のレコードを取得 */ if (status == B_NO_ERROR) { memset(&personRecord, 0, sizeof(personRecord)); dataLen = sizeof(personRecord); personID = 263512477; /* 実際これは社会保障番号 */ *(BTI_LONG BTI_FAR *)&keyBuf[0] = personID; keyNum = 0; status = BTRVID( B_GET_EQUAL, posBlock, &personRecord, &dataLen, keyBuf, keyNum, (BTI_BUFFER_PTR)&clientID); printf("Btrieve B_GET_EQUAL status = %d¥n", status); if (status == B_NO_ERROR) { printf("¥n"); printf("The retrieved record is:¥n"); printf("ID:%ld¥n", personRecord.ID); printf("Name:%s %s¥n", personRecord.FirstName, personRecord.LastName ); printf("Street:%s¥n", personRecord.Street); printf("City:%s¥n", personRecord.City); printf("State:%s¥n", personRecord.State); printf("Zip:%s¥n", personRecord.Zip); printf("Country:%s¥n", personRecord.Country); printf("Phone:%s¥n", personRecord.Phone); printf("¥n"); } } /* 開いているファイルを閉じる */ if (fileOpen) { dataLen = 0; status = BTRVID( B_CLOSE, posBlock, dataBuf, &dataLen, keyBuf, keyNum, (BTI_BUFFER_PTR)&clientID); printf("Btrieve B_CLOSE status (sample.btr) = %d¥n", status); } return(status); }
Btrieve 用 C インターフェイスは、プラットフォームとコンパイラにより操作が異なります。通常は、以下の操作を行います。
このセクションでは、一般的な開発環境に共通する操作方法を説明します。お使いの開発環境が該当しない場合は、この操作方法を参考にしてください。
Microsoft Visual C++ では、サンプル プログラムのコンパイル、リンク、実行を、以下の方法で行います。
Watcom C++ では、サンプル プログラムのコンパイル、リンク、実行を、以下の方法で行います。
Borland C++ では、サンプル プログラムのコンパイル、リンク、実行を、以下の方法で行います。
C++ Builder では、サンプル プログラムのコンパイル、リンク、実行を、以下の方法で行います。
以下の C++ Builder プログラムの例では、Btrieve の一般的な操作の実行方法をいくつか説明します。これらの操作は、MicroKernel との依存関係で要求される順番(ファイルを開いてから I/O を実行するなど)で行われます。
/********************************************************** ** ** Copyright 2003 Pervasive Software Inc. ** All Rights Reserved ***********************************************************/ /*********************************************************** CBBMain.cpp これは、目的の環境で、コンパイラ ツールを使用した Btrieve アプリケーションの コンパイル、リンク、実行が可能なことを確認するための簡単なサンプルです。 このプログラムでは、Btrieve の C/C++ インターフェイスを示します。 これは、Borland C++ Builder がインストールされた MS Windows NT および Windows 9X/ME 環境での例です。 このプログラムでは、サンプル データベースで以下の操作を行います。 - Microkernel Database エンジンのバージョン情報を取得する - sample.btr を開く - Key 0 の既知の値を持つレコードを取得する - 読み込んだレコードを表示する - Stat オペレーションを実行する - 空の sample.btr のクローンを作成して開く - Get Next Extended オペレーションを実行して sample.btr のレコードの サブセットを抽出する - クローン ファイルにこれらのレコードを挿入する - 両ファイルを閉じる このサンプルをコンパイルするには、IDE で使用可能な以下のファイルを、 Btrieve "C" インターフェイス ディレクトリから作成する必要があります。 - btrapi.c - btrapi.h - btrconst.h 重要:Btrieve データ ファイルのサンプル sample.btr が保存されている ディレクトリへのフルパスを必ず指定する必要があります。また、下の「重要」 項目も参考にしてください。 ***********************************************************/ //---------------------------------------------------------- #include <vcl¥vcl.h> #pragma hdrstop #include "CBBMain.h" #include <btrapi.h> #include <btrconst.h> //---------------------------------------------------------- #pragma resource "*.dfm" /*********************************************************** 定数 ***********************************************************/ #define EXIT_WITH_ERROR 1 #define TRUE 1 #define FALSE 0 #define VERSION_OFFSET 0 #define REVISION_OFFSET 2 #define PLATFORM_ID_OFFSET 4 #define MY_THREAD_ID 50 /* 弊社の構造体に定義を加えないでください。*/ /* Borland のヘルプではこれがデフォルトとなっていますが、正しくありません。*/ #pragma option -a1 /*********************************************************** クライアント ID とバージョンの構造体の型定義 ***********************************************************/ typedef struct { BTI_CHAR networkAndNode[12]; BTI_CHAR applicationID[2]; BTI_WORD threadID; } CLIENT_ID; typedef struct { BTI_SINT Version; BTI_SINT Revision; BTI_CHAR MKDEId; } VERSION_STRUCT; /*********************************************************** sample.btr からのレコードの定義 ***********************************************************/ typedef struct { BTI_LONG ID; BTI_CHAR FirstName[16]; BTI_CHAR LastName[26]; BTI_CHAR Street[31]; BTI_CHAR City[31]; BTI_CHAR State[3]; BTI_CHAR Zip[11]; BTI_CHAR Country[21]; BTI_CHAR Phone[14]; } PERSON_STRUCT; /*********************************************************** Stat/Create 構造体の型定義 ***********************************************************/ typedef struct { BTI_SINT recLength; BTI_SINT pageSize; BTI_SINT indexCount; BTI_CHAR reserved[4]; BTI_SINT flags; BTI_BYTE dupPointers; BTI_BYTE notUsed; BTI_SINT allocations; } FILE_SPECS; typedef struct { BTI_SINT position; BTI_SINT length; BTI_SINT flags; BTI_CHAR reserved[4]; BTI_CHAR type; BTI_CHAR null; BTI_CHAR notUsed[2]; BTI_BYTE manualKeyNumber; BTI_BYTE acsNumber; } KEY_SPECS; typedef struct { FILE_SPECS fileSpecs; KEY_SPECS keySpecs[5]; } FILE_CREATE_BUF; /*********************************************************** Get Next Extended 処理用の構造体の型定義 ***********************************************************/ typedef struct { BTI_SINT descriptionLen; BTI_CHAR currencyConst[2]; BTI_SINT rejectCount; BTI_SINT numberTerms; } GNE_HEADER; typedef struct { BTI_CHAR fieldType; BTI_SINT fieldLen; BTI_SINT fieldOffset; BTI_CHAR comparisonCode; BTI_CHAR connector; BTI_CHAR value[3]; } TERM_HEADER; typedef struct { BTI_SINT maxRecsToRetrieve; BTI_SINT noFieldsToRetrieve; } RETRIEVAL_HEADER; typedef struct { BTI_SINT fieldLen; BTI_SINT fieldOffset; } FIELD_RETRIEVAL_HEADER; typedef struct { GNE_HEADER gneHeader; TERM_HEADER term1; TERM_HEADER term2; RETRIEVAL_HEADER retrieval; FIELD_RETRIEVAL_HEADER recordRet; } PRE_GNE_BUFFER; typedef struct { BTI_SINT recLen; BTI_LONG recPos; PERSON_STRUCT personRecord; } RETURNED_REC; typedef struct { BTI_SINT numReturned; RETURNED_REC recs[20]; } POST_GNE_BUFFER; typedef union { PRE_GNE_BUFFER preBuf; POST_GNE_BUFFER postBuf; } GNE_BUFFER, BTI_FAR* GNE_BUFFER_PTR; //---------------------------------------------------------- // エクスポートされない事前宣言 void printLB(TListBox *LB, char *msg); TForm1 *Form1; //---------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //---------------------------------------------------------- void __fastcall TForm1::ExitButtonClick(TObject *Sender) { Form1->Close(); } //---------------------------------------------------------- void __fastcall TForm1::RunButtonClick(TObject *Sender) { runTest(); } /*********************************************************** ListBox に書き出すヘルパー関数 ***********************************************************/ void printLB(TListBox *LB, char *msg) { LB->Items->Add(msg); } /*********************************************************** ここですべての処理が行われる ***********************************************************/ BTI_SINT runTest(void) { /* Btrieve 関数パラメーター */ BTI_BYTE posBlock1[128]; BTI_BYTE posBlock2[128]; BTI_BYTE dataBuf[255]; BTI_WORD dataLen; BTI_BYTE keyBuf1[255]; BTI_BYTE keyBuf2[255]; BTI_WORD keyNum = 0; BTI_BYTE btrieveLoaded = FALSE; BTI_LONG personID; BTI_BYTE file1Open = FALSE; BTI_BYTE file2Open = FALSE; BTI_SINT status; BTI_SINT getStatus; BTI_SINT i; BTI_SINT posCtr; CLIENT_ID clientID; VERSION_STRUCT versionBuffer[3]; FILE_CREATE_BUF fileCreateBuf; GNE_BUFFER_PTR gneBuffer; PERSON_STRUCT personRecord; BTI_CHAR tmpBuf[1024]; /********************************************************** プログラム タイトルの出力 **********************************************************/ printLB(Form1->ListBox1, "**** Btrieve -- C++ Builder Sample ****" ); /* クライアント ID のセットアップ */ memset(clientID.networkAndNode, 0, sizeof(clientID.networkAndNode)); memcpy(clientID.applicationID, "MT", 2); /* "AA" 以上を設定 */ clientID.threadID = MY_THREAD_ID; memset(versionBuffer, 0, sizeof(versionBuffer)); dataLen = sizeof(versionBuffer); status = BTRVID( B_VERSION, posBlock1, &versionBuffer, &dataLen, keyBuf1, keyNum, (BTI_BUFFER_PTR)&clientID); if (status == B_NO_ERROR) { strcpy(tmpBuf, "Btrieve Versions returned are: " ); printLB(Form1->ListBox1, tmpBuf); for (i = 0; i < 3; i++) { if (versionBuffer[i].Version != 0) { sprintf(tmpBuf, " %d.%d %c", versionBuffer[i].Version, versionBuffer[i].Revision, versionBuffer[i].MKDEId ); printLB(Form1->ListBox1, tmpBuf); } } printLB(Form1->ListBox1, ""); btrieveLoaded = TRUE; } else { sprintf(tmpBuf, "Btrieve B_VERSION status = %d", status ); printLB(Form1->ListBox1, tmpBuf); if (status != B_RECORD_MANAGER_INACTIVE) { btrieveLoaded = TRUE; } } /* バッファーのクリア */ if (status == B_NO_ERROR) { memset(dataBuf, 0, sizeof(dataBuf)); memset(keyBuf1, 0, sizeof(keyBuf1)); memset(keyBuf2, 0, sizeof(keyBuf2)); } /* sample.btr を開く */ if (status == B_NO_ERROR) { /*************************************************************** 重要:以下を変更し、使用する sample.btr へのフルパスを指定してください。 ****************************************************************/ strcpy((BTI_CHAR *)keyBuf1, "c:¥¥sample¥¥sample.btr"); strcpy((BTI_CHAR *)keyBuf2, "c:¥¥sample¥¥sample2.btr"); keyNum = 0; dataLen = 0; status = BTRVID( B_OPEN, posBlock1, dataBuf, &dataLen, keyBuf1, keyNum, (BTI_BUFFER_PTR)&clientID); sprintf(tmpBuf, "Btrieve B_OPEN status = %d", status ); printLB(Form1->ListBox1, tmpBuf); if (status == B_NO_ERROR) { file1Open = TRUE; } } /* B_GET_EQUAL を使用して key 0 = 263512477 のレコードを取得 */ if (status == B_NO_ERROR) { memset(&personRecord, 0, sizeof(personRecord)); dataLen = sizeof(personRecord); personID = 263512477; /* 実際これは社会保障番号 */ *(BTI_LONG BTI_FAR *)&keyBuf1[0] = personID; keyNum = 0; status = BTRVID( B_GET_EQUAL, posBlock1, &personRecord, &dataLen, keyBuf1, keyNum, (BTI_BUFFER_PTR)&clientID); sprintf(tmpBuf, "Btrieve B_GET_EQUAL status = %d", status ); printLB(Form1->ListBox1, tmpBuf); if (status == B_NO_ERROR) { sprintf(tmpBuf, "" ); printLB(Form1->ListBox1, tmpBuf); sprintf(tmpBuf, "The retrieved record is:" ); printLB(Form1->ListBox1, tmpBuf); sprintf(tmpBuf, "ID:%ld", personRecord.ID ); printLB(Form1->ListBox1, tmpBuf); sprintf(tmpBuf, "Name:%s %s", personRecord.FirstName, personRecord.LastName ); printLB(Form1->ListBox1, tmpBuf); sprintf(tmpBuf, "Street:%s", personRecord.Street ); printLB(Form1->ListBox1, tmpBuf); sprintf(tmpBuf, "City:%s", personRecord.City ); printLB(Form1->ListBox1, tmpBuf); sprintf(tmpBuf, "State:%s", personRecord.State ); printLB(Form1->ListBox1, tmpBuf); sprintf(tmpBuf, "Zip:%s", personRecord.Zip ); printLB(Form1->ListBox1, tmpBuf); sprintf(tmpBuf, "Country:%s", personRecord.Country ); printLB(Form1->ListBox1, tmpBuf); sprintf(tmpBuf, "Phone:%s", personRecord.Phone ); printLB(Form1->ListBox1, tmpBuf); sprintf(tmpBuf, "" ); printLB(Form1->ListBox1, tmpBuf); } } /* Stat オペレーションを実行し、fileCreateBuf(作成バッファー)を取得 */ memset(&fileCreateBuf, 0, sizeof(fileCreateBuf)); dataLen = sizeof(fileCreateBuf); keyNum = (BTI_WORD)-1; status = BTRVID(B_STAT, posBlock1, &fileCreateBuf, &dataLen, keyBuf1, keyNum, (BTI_BUFFER_PTR)&clientID); if (status == B_NO_ERROR) { /* sample2.btr を作成して開く */ keyNum = 0; dataLen = sizeof(fileCreateBuf); status = BTRVID(B_CREATE, posBlock2, &fileCreateBuf, &dataLen, keyBuf2, keyNum, (BTI_BUFFER_PTR)&clientID); sprintf(tmpBuf, "Btrieve B_CREATE status = %d", status ); printLB(Form1->ListBox1, tmpBuf); } if (status == B_NO_ERROR) { keyNum = 0; dataLen = 0; status = BTRVID( B_OPEN, posBlock2, dataBuf, &dataLen, keyBuf2, keyNum, (BTI_BUFFER_PTR)&clientID); sprintf(tmpBuf, "Btrieve B_OPEN status = %d", status ); printLB(Form1->ListBox1, tmpBuf); if (status == B_NO_ERROR) { file2Open = TRUE; } } /* 元のファイルからデータを抽出し、新しいファイルへ挿入 */ if (status == B_NO_ERROR) { /* getFirst を実行してカレンシーを確立 */ keyNum = 2; /* STATE-CITY index */ memset(&personRecord, 0, sizeof(personRecord)); memset(&keyBuf2[0], 0, sizeof(keyBuf2)); dataLen = sizeof(personRecord); getStatus = BTRVID( B_GET_FIRST, posBlock1, &personRecord, &dataLen, keyBuf1, keyNum, (BTI_BUFFER_PTR)&clientID); sprintf(tmpBuf, "Btrieve B_GET_FIRST status = %d", getStatus ); printLB(Form1->ListBox1, tmpBuf); } gneBuffer = (GNE_BUFFER_PTR)malloc(sizeof(GNE_BUFFER)); if (gneBuffer == NULL) { strcpy(tmpBuf, "バッファーに割り当てるメモリが不足しています" ); printLB(Form1->ListBox1, tmpBuf); return(EXIT_WITH_ERROR); } memset(gneBuffer, 0, sizeof(GNE_BUFFER)); memcpy(&gneBuffer->preBuf.gneHeader.currencyConst[0], "UC", 2); while (getStatus == B_NO_ERROR) { 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; memcpy(&gneBuffer->preBuf.term1.value[0], "TX", 2); 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; memcpy(&gneBuffer->preBuf.term2.value[0], "CA", 2); posCtr += sizeof(TERM_HEADER); /* プロジェクション ヘッダーを設定してレコード全体を読み込む */ gneBuffer->preBuf.retrieval.maxRecsToRetrieve = 20; gneBuffer->preBuf.retrieval.noFieldsToRetrieve = 1; posCtr += sizeof(RETRIEVAL_HEADER); gneBuffer->preBuf.recordRet.fieldLen = sizeof(PERSON_STRUCT); gneBuffer->preBuf.recordRet.fieldOffset = 0; 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, (BTI_BUFFER_PTR)&clientID); sprintf(tmpBuf, "Btrieve B_GET_NEXT_EXTENDED status = %d", getStatus ); printLB(Form1->ListBox1, tmpBuf); /* Get Next Extended は、ファイルの終わりに達しても */ /* レコードを返すことがあります */ if ((getStatus == B_NO_ERROR) || (getStatus == B_END_OF_FILE)) { sprintf(tmpBuf, "GetNextExtended returned %d records.", gneBuffer->postBuf.numReturned); printLB(Form1->ListBox1, tmpBuf); for (i = 0; i < gneBuffer->postBuf.numReturned; i++) { dataLen = sizeof(PERSON_STRUCT); memcpy(dataBuf, &gneBuffer-> postBuf.recs[i].personRecord, dataLen); status = BTRVID( B_INSERT, posBlock2, dataBuf, &dataLen, keyBuf2, -1, /* カレンシー変更なし */ (BTI_BUFFER_PTR)&clientID); } sprintf(tmpBuf, "Inserted %d records in new file, status = %d", gneBuffer->postBuf.numReturned, status); printLB(Form1->ListBox1, tmpBuf); } memset(gneBuffer, 0, sizeof(GNE_BUFFER)); memcpy(&gneBuffer->preBuf.gneHeader.currencyConst[0], "EG", 2); } free(gneBuffer); gneBuffer = NULL; /* 開いているファイルを閉じる */ if (file1Open) { dataLen = 0; status = BTRVID( B_CLOSE, posBlock1, dataBuf, &dataLen, keyBuf1, keyNum, (BTI_BUFFER_PTR)&clientID); sprintf(tmpBuf, "Btrieve B_CLOSE status (sample.btr) = %d", status ); printLB(Form1->ListBox1, tmpBuf); } if (file2Open) { dataLen = 0; status = BTRVID( B_CLOSE, posBlock2, dataBuf, &dataLen, keyBuf2, keyNum, (BTI_BUFFER_PTR)&clientID); sprintf(tmpBuf, "Btrieve B_CLOSE status (sample2.btr) = %d", status ); printLB(Form1->ListBox1, tmpBuf); } return(status); }
|