db2GetSnapshot() ルーチンは、ユーザー提供のバッファーに、 自己記述型データ・ストリームとしてスナップショット・データを戻します。 データは スナップショット要求に説明されている、 論理データ・グループに分けられて戻されます。
スナップショット要求によって戻される各アイテムには、 そのサイズおよびタイプを指定するフィールドが含まれます (スナップショット出力を参照してください)。 サイズを使用して、戻りデータ全体を解析できます。
また、サイズを使用して、 任意の論理データ・グループを読み飛ばすこともできます。 たとえば、db2 レコードを読み飛ばすには、データ・ストリーム内の
size of the db2 logical data grouping + sizeof(sqlm_header_info)
のバイト数を判別する必要があります。
以下のコード例は、スナップショット出力バッファーに戻されたデータをアプリケーションが解析する方法を示しています。 関数に渡される要素 datastream は、 db2GetSnapshot() 呼び出しから戻されたバッファーです。
#include "stdlib.h" #include "stdio.h" #include "sqlutil.h" #include "string.h" #include "sqlmon.h" // System Monitor interface void pocess_buffer(sqlm_header_info *datastream) { long data_len = datastream-->size; sqlm_header_info *traversal_ptr = datastream; // presume that we aren't interested in the "collected" data // elements ++traversal_ptr; //------------------------------------------------------------------------ // PROCESS EACH RECORD THAT MAY BE RETURNED IN THE SNAPSHOT OUTPUT BUFFER //------------------------------------------------------------------------ while (data_len > 0) { // Switch on the element switch (traversal_ptr-->element) { case SQLM_ELM_DB2: // Process the database manager snapshot printf("Processing database manager snapshot\n"); // ... break; case SQLM_ELM_DBASE: // Process the snapshot ... printf("Processing database snapshot\n"); // ... break; case SQLM_ELM_APPL: printf("Processing application snapshot\n"); // ... break; case SQLM_ELM_APPL_INFO: printf("Processing list application\n"); // ... break; case SQLM_DCS_APPL_INFO: printf("Processing list dcs application\n"); // ... break; case SQLM_ELM_TABLE_LIST: printf("Processing list tables\n"); // ... break; case SQLM_ELM_DBASE_LOCK_LIST: printf("Processing snapshot for locks on database\n"); // ... break; case SQLM_ELM_APPL_LOCK: { printf("Processing snapshot for locks for application\n"); // ... break; case SQLM_ELM_TABLESPACE_LIST: { printf("Processing snapshot for tablespaces\n"); // ... break; default: // Do nothing. This could be a new logical data element we aren't // interested in, or it could be one of the collected data elements. } // end check the current snapshot buffer structure // Skip the record we just processed data_len -= traversal_ptr-->size + sizeof(sqlm_header_info); traversal_ptr = (sqlm_header_info *)((char *)traversal_ptr + traversal_ptr-->size + sizeof(sqlm_header_info)); } // end while there are top-level structures in the snapshot output buffer }
新しいデータ・ストリームの各部分の処理は、 そのストリームの最上部の処理と同様です。 以下の例では、データ要素のデータベース論理グループから db 名を選び出して、 事前に割り当てたストリングにそれを戻す方法を示します。
ストリームのどのデータ要素を処理する場合でも、 同様の方法をとることができます。
void process_db2_info(sqlm_header_info *db2inf, char *db_name) { long data_size = db2inf-->header.size; sqlm_header_data *traverse_ptr = NULL; db2inf++; traverse_ptr = (sqlm_header_data *)db2inf; while(data_size) { switch(traverse_ptr-->header.element) { case SQLM_ELM_DB_NAME: memcpy(db_name, traverse_ptr-->data, traverse_ptr-->header.size); // Add the null terminator db_name[traverse_ptr-->header.size] = '\0'; break; // cases to access other elements of interest // ... default: break; } data_size -= (traverse_ptr-->header.size + sizeof(sqlm_header_info)); traverse_ptr = (sqlm_header_data *)((char *)traverse_ptr-->header.size + sizeof(sqlm_header_info)); } }