6 カスタム・メタデータを使用したSODAコレクション構成

SODAコレクションは高度な構成が可能です。コレクション・メタデータをカスタマイズして、デフォルトで提供されている動作とは異なる動作を取得できます。

注意:

コレクション・メタデータをカスタマイズして、デフォルトで提供されている動作とは異なる動作を取得できます。ただし、一部のコンポーネントを変更するには、SQLデータ型などのOracle Databaseの概念をよく理解している必要があります。やむを得ない理由のないかぎり、そのようなコンポーネントは変更しないことをお薦めします。SODAコレクションはOracle Database表(またはビュー)の上に実装されるため、多くのコレクション・コンポーネントが基礎となる表構成に関連しています。

たとえば、コンテンツ列の型をBLOB (デフォルト値)からVARCHAR2に変更する場合、その影響(VARCHAR2のコンテンツ・サイズが32Kバイトに制限されること、キャラクタ・セットの変換が発生する場合があることなど)を理解する必要があります。

関連項目:

6.1 既存コレクションのメタデータの取得

OCI関数OCIAttrGet()を属性OCI_ATTR_SODA_DESCRIPTORとともに使用すると、コレクションのすべてのメタデータをJSONドキュメントとして一度に取得できます。また、OCIAttrGet()を使用して、個々のコレクション・メタデータ属性を取得することもできます。

表6-1 コレクション・ハンドル属性(コレクション・メタデータ)

属性 説明

OCI_ATTR_SODA_CRTIME_COL_NAME

ドキュメントの作成時のタイムスタンプを格納するデータベース列の名前。

OCI_ATTR_SODA_CTNT_CACHE

SecureFiles LOBのキャッシュ設定。

OCI_ATTR_SODA_CTNT_COL_NAME

ドキュメント・コンテンツを格納するデータベース列。

OCI_ATTR_SODA_CTNT_COMPRESS

SecureFiles LOBの圧縮設定。

OCI_ATTR_SODA_CTNT_ENCRYPT

SecureFiles LOBの暗号化設定。

OCI_ATTR_SODA_CTNT_MAX_LEN

ドキュメント・コンテンツを格納するデータベース列の最大長(バイト単位)。この属性はVARCHAR2型のコンテンツのみに適用されます。

OCI_ATTR_SODA_CTNT_SQL_TYPE

ドキュメント・コンテンツを格納するデータベース列のSQLデータ型。

OCI_ATTR_SODA_CTNT_VALIDATION

JavaScript Object Notation (JSON)コンテンツが準拠する構文 - 標準、厳密または緩和。

OCI_ATTR_SODA_DESCRIPTOR

コレクションのすべてのメタデータ(JSON形式)。

OCI_ATTR_SODA_KEY_ASSIGN_METHOD

コレクションに挿入されたドキュメントにキーを割り当てるために使用するメソッド。

OCI_ATTR_SODA_KEY_COL_NAME

ドキュメント・キーを格納するデータベース列の名前。

OCI_ATTR_SODA_KEY_MAX_LEN

ドキュメント・キーを格納するデータベース列の最大長(バイト単位)。この属性はVARCHAR2型のコンテンツのみに適用されます。

OCI_ATTR_SODA_KEY_SEQ_NAME

キーの割当てメソッドがSEQUENCEの場合にコレクションに挿入するドキュメントのキーを生成するデータベース順序の名前です。

OCI_ATTR_SODA_KEY_SQL_TYPE

ドキュメント・キーを格納するデータベース列のSQLデータ型。

OCI_ATTR_SODA_MODTIME_COL_NAME

ドキュメントの最終変更のタイムスタンプを格納するデータベース列の名前。

OCI_ATTR_SODA_MODTIME_INDEX

最終変更のタイムスタンプを格納するデータベース列の索引の名前。

OCI_ATTR_SODA_READONLY

コレクションが読取り専用かどうかの表示。

OCI_ATTR_SODA_SCHEMA

コレクションがマップされる表またはビューを所有するOracleスキーマ(ユーザー)の名前。

OCI_ATTR_SODA_TABLE_NAME

コレクションがマップされるデータベース表の名前。

OCI_ATTR_SODA_VERSION_COL_NAME

ドキュメント・バージョンを格納するデータベース列の名前。

OCI_ATTR_SODA_VERSION_METHOD

ドキュメントがコレクションに挿入または置換されるときにそのバージョン値を計算するために使用されるメソッド。

OCI_ATTR_SODA_VIEW_NAME

コレクションがマップされるデータベース・ビューの名前。

例6-1 コレクションのすべてのメタデータの取得

この例では、例3-2を使用して作成されたデフォルト構成を含むコレクションでコレクション・ハンドル属性OCI_ATTR_SODA_DESCRIPTORに対して関数OCIAttrGet()を呼び出した結果が表示されます。これにより、すべてのコレクション・メタデータがJSONデータとして取得されます。例6-3に、コレクションのデフォルト・メタデータを示します。

OraText *fetchedMetadata;
ub4      fetchedMetadataLen = 0;

rc = OCIAttrGet((dvoid *)collhp, 
                OCI_HTYPE_SODA_COLLECTION,
                (dvoid *)fetchedMetadata,
                &fetchedMetadataLen,
                OCI_ATTR_SODA_DESCRIPTOR, errhp);

if (rc == OCI_SUCCESS)
  printf ("Collection specification: %.*s\n", fetchedMetadataLen, fetchedMetadata);

例6-2 個々のコレクション・メタデータ属性の取得

この例では、OCIAttrGet()を使用して個々のコレクション・メタデータ属性を取得します。属性ごとに、コレクション・ハンドル、属性および属性タイプを渡します。

// String collection metadata attribute
oratext *collAttr = NULL;

// Length of collection metadata attribute
// (relevant only for string attributes).
ub4      collAttrLen = 0;

ub1      ub1CollAttr = 0;
ub4      ub4CollAttr = 0;
boolean  boolCollAttr = FALSE;

// Get and print collection metadata components.
// (For brevity we omit checking the return values of the OCIAttrGet calls here.)

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)collAttr,
           &collAttrLen,
           OCI_ATTR_SODA_COLL_NAME,
           errhp);
printf("Collection name: %.*s\n", collAttrLen, collAttr);

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)collAttr,
           &collAttrLen,
           OCI_ATTR_SODA_TABLE_NAME,
           errhp);
printf("Table name: %.*s\n", collAttrLen, collAttr);

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)collAttr,
           &collAttrLen,
           OCI_ATTR_SODA_SCHEMA,
           errhp);
printf("Schema name: %.*s\n", collAttrLen, collAttr);

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)collAttr,
           &collAttrLen,
           OCI_ATTR_SODA_KEY_COL_NAME,
           errhp);
printf("Key column name: %.*s\n", collAttrLen, collAttr);

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)(&ub1CollAttr),
           &collAttrLen,
           OCI_ATTR_SODA_KEY_SQL_TYPE,
           errhp);
if (ub1CollAttr == SQLT_CHR)
  printf ("Key column type: VARCHAR2\n");
else if (ub1CollAttr == SQLT_BIN)
  printf ("Key column type: RAW\n");
else if (ub1CollAttr == SQLT_NUM)
  printf ("Key column type: NUMBER\n");

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)(&ub4CollAttr),
           &collAttrLen,
           OCI_ATTR_SODA_KEY_MAX_LEN,
           errhp);
printf ("Key column max length: %d\n", ub4CollAttr);

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)(&ub1CollAttr),
           &collAttrLen,
           OCI_ATTR_SODA_KEY_ASSIGN_METHOD,
           errhp);

if (ub1CollAttr == OCI_SODA_KEY_METHOD_UUID)
  printf ("Key assignment method: UUID\n");
else if (ub1CollAttr == OCI_SODA_KEY_METHOD_GUID)
  printf ("Key assignment method: GUID\n");
else if (ub1CollAttr == OCI_SODA_KEY_METHOD_SEQUENCE)
  printf ("Key assignment method: SEQUENCE\n");
else if (ub1CollAttr == OCI_SODA_KEY_METHOD_CLIENT)
  printf ("Key assignment method: CLIENT\n");

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)collAttr,
           &collAttrLen,
           OCI_ATTR_SODA_CTNT_COL_NAME,
           errhp);
printf("Content column name: %.*s\n", collAttrLen, collAttr);

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)(&ub1CollAttr),
           &collAttrLen, 
           OCI_ATTR_SODA_CTNT_SQL_TYPE,
           errhp);
if (ub1CollAttr == SQLT_CHR)
  printf ("Content column type: VARCHAR2\n");
else if (ub1CollAttr == SQLT_BLOB)
  printf ("Content column type: BLOB\n");
else if (ub1CollAttr == SQLT_CLOB)
  printf ("Content column type: CLOB\n");

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)(&ub4CollAttr),
           &collAttrLen,
           OCI_ATTR_SODA_CTNT_MAX_LEN,
           errhp);
printf ("Content column max length: %d\n", ub4CollAttr);

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION, 
           (dvoid *)(&ub1CollAttr),
           &collAttrLen,
           OCI_ATTR_SODA_CTNT_VALIDATION,
           errhp);
if (ub1CollAttr == OCI_SODA_JSON_VALIDATION_STRICT)
  printf ("Content column validation: STRICT\n");
else if (ub1CollAttr == OCI_SODA_JSON_VALIDATION_LAX)
  printf ("Content column validation: LAX\n");
else if (ub1CollAttr == OCI_SODA_JSON_VALIDATION_STD)
  printf ("Content column validation: STANDARD\n");

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)(&ub1CollAttr),
           &collAttrLen, 
           OCI_ATTR_SODA_CTNT_COMPRESS,
           errhp);
if (ub1CollAttr == OCI_SODA_LOB_COMPRESS_NONE)
  printf ("Content column compress: NONE\n");
else if (ub1CollAttr == OCI_SODA_LOB_COMPRESS_HIGH)
  printf ("Content column compress: HIGH\n");
else if (ub1CollAttr == OCI_SODA_LOB_COMPRESS_MEDIUM)
  printf ("Content column compress:  MEDIUM\n");
else if (ub1CollAttr == OCI_SODA_LOB_COMPRESS_LOW)
  printf ("Content column compress: LOW\n");

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)(&ub1CollAttr),
           &collAttrLen,
           OCI_ATTR_SODA_CTNT_ENCRYPT,
           errhp);
if (ub1CollAttr == OCI_SODA_LOB_ENCRYPT_NONE)
  printf ("Content column encrypt: NONE\n");
else if (ub1CollAttr == OCI_SODA_LOB_ENCRYPT_3DES168)
  printf ("Content column encrypt: 3DES168\n");
else if (ub1CollAttr == OCI_SODA_LOB_ENCRYPT_AES128)
  printf ("Content column encrypt: AES128\n");
else if (ub1CollAttr == OCI_SODA_LOB_ENCRYPT_AES192)
  printf ("Content column encrypt: AES192\n");
else if (ub1CollAttr == OCI_SODA_LOB_ENCRYPT_AES256)
  printf ("Content column encrypt: AES256\n");

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)(&boolCollAttr),
           &collAttrLen,
           OCI_ATTR_SODA_CTNT_CACHE,
           errhp);
if (boolCollAttr == TRUE)
  printf ("Content column cache: TRUE\n");
else
  printf ("Content column cache: FALSE\n");

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)collAttr,
           &collAttrLen,
           OCI_ATTR_SODA_VERSION_COL_NAME,
           errhp);
printf("Version column name: %.*s\n", collAttrLen, collAttr);

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)(&ub1CollAttr),
           &collAttrLen,
           OCI_ATTR_SODA_VERSION_METHOD,
           errhp);
if (ub1CollAttr == OCI_SODA_VERSION_NONE)
  printf ("Version method: NONE\n");
else if (ub1CollAttr == OCI_SODA_VERSION_TIMESTAMP)
  printf ("Version method: TIMESTAMP\n");
else if (ub1CollAttr == OCI_SODA_VERSION_MD5)
  printf ("Version method: MD5\n");
else if (ub1CollAttr == OCI_SODA_VERSION_SHA256)
  printf ("Version method: SHA256\n");
else if (ub1CollAttr == OCI_SODA_VERSION_SEQUENTIAL)
  printf ("Version method: SEQUENTIAL\n");

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)collAttr,
           &collAttrLen,
           OCI_ATTR_SODA_MODTIME_COL_NAME,
           errhp);
printf("Last-modified column name: %.*s\n", collAttrLen, collAttr);

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)collAttr,
           &collAttrLen,
           OCI_ATTR_SODA_MODTIME_INDEX,
           errhp);
printf("Last-modified index name: %.*s\n", collAttrLen, collAttr);

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)collAttr,
           &collAttrLen,
           OCI_ATTR_SODA_CRTIME_COL_NAME,
           errhp);
printf("Created-on column name: %.*s\n", collAttrLen, collAttr);

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)collAttr,
           &collAttrLen,
           OCI_ATTR_SODA_MTYPE_COL_NAME,
           errhp);
printf("Media type column name: %.*s\n", collAttrLen, collAttr);

OCIAttrGet((dvoid *)collhp,
           OCI_HTYPE_SODA_COLLECTION,
           (dvoid *)&boolCollAttr,
           &collAttrLen,
           OCI_ATTR_SODA_READONLY,
           errhp);

if (boolCollAttr == TRUE)
  printf("Collection is read-only");
else
  printf("Collection is not read-only");

例6-3 デフォルトのコレクション・メタデータ

{
   "schemaName" : "mySchemaName",
   "tableName" : "myTableName",
   "keyColumn" :
   {
      "name" : "ID",
      "sqlType" : "VARCHAR2",
      "maxLength" : 255,
      "assignmentMethod" : "UUID"
   },
   "contentColumn" :
   {
      "name" : "JSON_DOCUMENT",
      "sqlType" : "BLOB",
      "compress" : "NONE",
      "cache" : true,
      "encrypt" : "NONE",
      "validation" : "STANDARD"
   },
   "versionColumn" :
   {
     "name" : "VERSION",
     "method" : "SHA256"
   },
   "lastModifiedColumn" :
   {
     "name" : "LAST_MODIFIED"
   },
   "creationTimeColumn" :
   {
      "name" : "CREATED_ON"
   },
   "readOnly" : false
}

6.2 カスタム・メタデータが含まれるコレクションの作成

カスタム・メタデータを持つドキュメント・コレクションを作成するには、そのメタデータをJSONデータとしてOCI関数OCISodaCollCreateWithMetadata()に渡します。

OCI関数OCISodaCollCreateWithMetadata()に対するオプションのメタデータ引数は、SODAコレクション仕様です。これは、新しいコレクションのメタデータを指定するJSONデータです。

同じ名前のコレクションがすでに存在する場合は、コレクションが単に開かれてそのハンドルが返されます。関数OCISodaCollCreateWithMetadata()に渡されたメタデータが既存のコレクションのメタデータと一致しない場合、コレクションは開かれず、エラーが発生します。一致するには、すべてのメタデータ・フィールドが同じ値である必要があります。

関連項目:

例6-4 カスタム・メタデータが含まれるコレクションの作成

この例では、KEY (ドキュメント・キー用)とJSON (ドキュメント・コンテンツ・タイプJSON用)の2つのメタデータ列を指定するカスタム・メタデータを含むコレクションを作成します。キーの割当て方法はCLIENTで、コンテンツ列のSQLデータ型はVARCHAR2です。この例では、コレクション・ハンドル属性OCI_ATTR_SODA_DESCRIPTORを使用して、新しく作成したコレクションから完全なメタデータを取得します。

sword        rc = OCI_SUCCESS;
OCISodaColl *collhp = NULL;
OraText     *metadata ="{\"keyColumn\" : \
{\"name\" : \"KEY\", \"assignmentMethod\": \"CLIENT\" }, \
\"contentColumn\" : { \"name\" : \"JSON\", \"sqlType\": \"VARCHAR2\" } }";
OraText     *collName = "myCustomCollection";
OraText     *fetchedMetadata = NULL;
ub4          fetchedMetadataLen = 0;

rc = OCISodaCollCreateWithMetadata(svchp, 
                                   collName,
                                   (ub4) strlen(collName),
                                   metadata,
                                   (ub4) strlen(metadata),
                                   &collhp,
                                   errhp,
                                   OCI_DEFAULT));
if (rc != OCI_SUCCESS)
{
  printf(OCISodaCollCreateWithMetadata failed\n");
  goto finally;
}

rc = OCIAttrGet((dvoid *)collhp,
                OCI_HTYPE_SODA_COLLECTION,
                (dvoid *)fetchedMetadata,
                &fetchedMetadataLen,
                OCI_ATTR_SODA_DESCRIPTOR,
                errhp);

if (rc == OCI_SUCCESS)
{
  printf ("Collection specification: %.*s\n", fetchedMetadataLen, fetchedMetadata);
}

finally: ...

ここに、読みやすさを考慮して書式設定された出力があります。コレクション仕様で指定されていないkeyColumnおよびcontentColumnのフィールドの値はデフォルトに設定されます。コレクション仕様(keyColumnおよびcontentColumn)に提供されている以外のフィールドの値もデフォルトに設定されます。フィールドtableNameの値は、コレクション名からデフォルト設定されます。フィールドschemaNameの値は、コレクションの作成時の現行のデータベース・スキーマ(ユーザー)です。

Collection specification: {
  "schemaName" : "mySchemaName",
  "tableName" : "myCustomCollection",
  "keyColumn" :
  {
    "name" : "KEY",
    "sqlType" : "VARCHAR2",
    "maxLength" : 255,
    "assignmentMethod" : "CLIENT"
  },

"contentColumn" :
  {
    "name" : "JSON",
    "sqlType" : "VARCHAR2",
    "maxLength" : 4000,
    "validation" : "STANDARD"
  },
  "readOnly" : false
}