概要
この記事では、Oracle NoSQL Database Cドライバの概要について説明します。このドライバは、ネイティブCクライアントがOracle NoSQL Database表に格納されているデータにアクセスできるようにします。(Oracle NoSQL Databaseデータへのアクセス用のキー/値APIを提供するC JNIドライバがあります。そのドライバはJNIレイヤーに依存し、この記事では説明しません。)
Cドライバは、Oracle NoSQL Databaseサーバー・パッケージとは別のダウンロードとして入手できます。サーバーとドライバのダウンロード・パッケージは、Oracle Technology Networkから入手できます。
Cドライバが動作するためには、CクライアントとOracle NoSQL Databaseストアとの間のネットワーク・アクティビティを変換するプロキシ・サーバーを使用する必要があります。プロキシはJavaで記述されており、Cクライアント・コードとOracle NoSQL Databaseストアの両方からネットワーク・アクセスが可能な任意のマシン上で実行できます。ただし、パフォーマンスとセキュリティ上の理由から、プロキシはドライバと同じローカル・ホスト上で実行し、プロキシをドライバと1:1構成で使用することをお薦めします(つまり、プロキシの各インスタンスを単一ドライバ・インスタンスとともに使用する必要があります)。
このクイック・スタートでは、読者がSQLリファレンス・ガイド内の概念説明を読み理解していると想定しています。
Cドライバによって使用されるAPIの全体的な説明については、C表ドライバ・リファレンスを参照してください。
インストール
Cドライバとプロキシは、どちらも共通ダウンロード・パッケージで入手できます。プロキシ・サーバーはkvproxyディレクトリにあり、Java jarファイル(kvproxy.jar)として提供されています。プロキシを使用するには、Oracle NoSQL Databaseサーバーのインストールも必要です。具体的には、インストールのkvclient.jarファイルがプロキシで使用可能である必要があります。
Cドライバ・ライブラリは、クライアント・コードで使用する前にコンパイルする必要があります。このライブラリのソース・コード、およびライブラリ付属物は、ドライバ・パッケージのcディレクトリにあります。コンパイル手順は、Oracle NoSQL Databaseの表Cドライバの構築チュートリアルで説明されています。
Cドライバはプリコンパイル済バイナリとしても入手できます。このバイナリにアクセスするには、関連するrpmまたはdebファイルをダウンロードしてインストールします。rpmまたはdebを使用すると、必要なJava jarファイルもシステムにインストールされます。このケースでは、関連するライブラリおよびjarファイルが/usr/local/libにインストールされます。これらを使用するには、このディレクトリを含むようにCLASSPATHおよびLD_LIBRARY_PATH環境変数を調整する必要があります。
プロキシ・サーバーの使用方法
プロキシ・サーバーは、表C APIからのネットワーク・トラフィックを受け入れ、それをOracle NoSQL Databaseストアが理解できるリクエストに変換してから、変換したリクエストをストアに転送するJavaアプリケーションです。プロキシは、ストアのレスポンスを解釈し、それらをクライアントに転送する逆変換サービスも提供します。
プロキシ・サーバーは、ネットワーク・アクセス可能な任意のマシンで実行できます。リソース要件は最小限で、多くの場合、クライアント・ノードが実行されているのと同じマシンで実行できます。
Cクライアントがストアにアクセスするには、プロキシ・サーバーが実行されている必要があります。java -cpコマンド・ライン・オプションを使用するかCLASSPATH環境変数を使用することで、クラス・パスに次のjarファイルが設定されている必要があります。
-
KVHOME/lib/kvclient.jar
-
.../kv-c-driver-X.Y.Z/kvproxy/lib/kvproxy.jar
注意:
rpmまたはdebを使用してインストールした場合、これらのファイルは/usr/local/libに配置されます。
プロキシ・サーバー自体は、oracle.kv.proxy.KVProxyコマンドを使用して起動します。少なくとも、プロキシ・サーバーの起動時には次の情報が必要です。
-
-helper-hostsこれは、プロキシ・サーバーがストアへの接続に使用できる、Oracle NoSQL Databaseストレージ・ノードを表すホスト:ポートのペアが1つ以上示されているリストです。
-
-portクライアント・コードがプロキシ・サーバーのこのインスタンスに接続できるポート。
-
-storeプロキシ・サーバーが接続するストアの名前。
他の一連のコマンド・ライン・オプションを使用できます。特に、安全なストアでプロキシ・サーバーを使用している場合は、プロキシ・サーバーに認証情報を提供する必要があります。また、プロキシ・サーバーにストア名を識別することが必要になる可能性があります。プロキシ・サーバーとそのコマンド・ライン・オプションの詳細な説明は、プロキシ・サーバー・リファレンスを参照してください。
このクイック・スタート・ガイドで提供している単純な例は、デフォルト値で起動されたkvliteインスタンスに接続しているプロキシ・サーバーで動作するように作成されています。kvclient.jarおよびkvproxy.jarファイルの場所は、CLASSPATH環境変数を使用して提供されています。プロキシ・サーバーの起動に使用したコマンド・ライン・コールは次のとおりです。
nohup java oracle.kv.proxy.KVProxy -port 7010 \
-helper-hosts localhost:5000 -store kvstore Cクライアントのコンパイルと実行
Cクライアントをコンパイルするには、libkvstore.soまたはlibkvstore-static.aをリンクします。これらは、cmakeに提供したインストール場所に含まれるlibディレクトリにあります。
.soファイルを使用する場合は、実行時にライブラリが見つかるように、LD_LIBRARY_PATH環境変数にインストール・ディレクトリを追加してください。
kvstore.hヘッダー・ファイルは、cmakeに提供したインストール場所に含まれるincludeディレクトリにあります。
ストアへの接続
ストア操作を実行するには、クライアント・コードとストア間にネットワーク接続を確立する必要があります。提供する必要のある2つの情報があります。
-
kv_config_t構造を使用して、ストアの名前、ホストおよびポートを識別します。この構造に提供するホストとポートは、ストア内のノードをホストする任意のマシンです。(ストアは多くのホストから構成されるため、複数のホスト/ポートのペアから選択する必要があります。)kv_config_t構造体を作成するにはkv_create_config()を使用します。構造体はkv_release_config()を使用して解放できます。 -
プロキシが実行されているホストとポートを識別します。これは、
kv_open_store()を使用して行います。この関数は、後続のすべてのストア操作に使用するkv_store_t構造体を作成します。この構造体は、kv_close_store()を使用して解放します。
たとえば、MyNoSQLStoreという名前のOracle NoSQL Databaseストアがあり、それに、ポート5000でn1.example.org上で実行されているノードがあるとします。さらに、ポート7010を使用してローカルホストでプロキシを実行しているとします。さらに、次の方法でストアへの接続をオープンおよびクローズします。
#include <stdlib.h>
#include <stdio.h>
#include "kvstore.h"
void open_store(kv_store_t **);
void do_store_ops(kv_store_t *);
int main(void) {
kv_store_t *store = NULL;
open_store(&store);
if (!store) {
goto ERROR;
}
do_store_ops(store);
ERROR:
/* Close the store handle. */
if (store) {
kv_close_store(&store);
}
return 0;
}
void do_store_ops(kv_store_t *store)
{
printf("Do store operations here.\n");
}
void
open_store(kv_store_t **store)
{
kv_config_t *config = NULL;
kv_error_t ret;
ret = kv_create_config("kvstore", // store name
"localhost", // host name
5000, // host port
&config);
if (ret != KV_SUCCESS) {
return;
}
/* Connect to a proxy server */
ret = kv_open_store(store, "localhost", 7010, config);
if (ret != KV_SUCCESS) {
printf("could not connect to the store.\n");
// Release the configuration structure
kv_release_config(&config);
}
} 安全なストアを使用している場合、ストア・ハンドルの構成にはユーザー名も含まれている必要があります。この目的にはkv_config_set_auth_user()を使用します。
プロキシ・サーバーの自動的な起動
クライアント・コードは、kv_open_store_with_proxy()を使用してストアを開く際にローカル・ホストでプロキシ・サーバーを起動できます。この関数では、kv_open_store()に必要なすべてのものに加え、kvclient.jarおよびkvproxy.jarファイルのディスク上の場所に移入されたkv_proxy_config_t構造体が必要です。
kv_proxy_config_t構造体は、kv_create_proxy_config()を使用して移入します。この構造体は、kv_release_proxy_config()を使用して解放できます(ストアを開くときにエラーが発生する場合にのみ必要です)。コードがプロキシ・サーバーで完了したら、kv_shutdown_proxy()を使用してシャット・ダウンします。
次に例を示します。
int main(void) {
kv_store_t *store = NULL;
open_store(&store);
if (!store) {
goto ERROR;
}
do_store_ops(store);
ERROR:
/* Close the store handle. */
if (store) {
kv_shutdown_proxy(store);
kv_close_store(&store);
}
return 0;
}
// do_store_ops() not implemented in this example
void
open_store(kv_store_t **store)
{
kv_config_t *config = NULL;
kv_proxy_config_t *proxy_config = NULL;
kv_error_t ret;
const char *path2kvclient = "/export/kvstore/lib/kvclient.jar";
const char *path2kvproxy =
"/export/c_driver/kvproxy/lib/kvproxy.jar";
ret = kv_create_config("kvstore", // store name
"localhost", // host name
5000, // host port
&config);
// All configs are correct for kvlite
if (ret != KV_SUCCESS) {
return;
}
// Create the proxy configuration structure.
// This must identify where the two relevant jar
// files reside on disk.
ret = kv_create_proxy_config(path2kvclient,
path2kvproxy,
&proxy_config);
if (ret != KV_SUCCESS) {
printf("could not create proxy config.\n");
return;
}
ret = kv_open_store_with_proxy(store,
"localhost",
7010,
config,
proxy_config);
if (ret != KV_SUCCESS) {
printf("could not connect to the store.\n");
// Release the configuration structure
if (config) {
kv_release_config(&config);
}
if (proxy_config) {
kv_release_proxy_config(&proxy_config);
}
store = NULL;
}
} 表および索引定義の作成
ストアの表にデータを書き込む前に、表DDL文を使用して表を定義する必要があります。DDL文を使用して索引を定義することもできます。表DDLについては、SQLリファレンス・ガイドで詳しく説明されています。
表DDL文をCクライアント・コードからストアに送信する場合は、kv_table_execute_sync()またはkv_table_execute()を使用します。後者の関数はDDL文をストアに非同期で送信します。索引の作成または表の削除操作には長時間かかることがあるため、これらの操作時には非同期での送信が必要になることがあります。
たとえば、表を同期的に作成するには、次のようにします。
void do_store_ops(kv_store_t *store)
{
kv_error_t ret;
/* ... Data operations ... */
kv_statement_result_t *result = NULL;
const char *statement = "CREATE TABLE Users2 (\
id INTEGER, \
firstName STRING, \
lastName STRING, \
description STRING, \
PRIMARY KEY (SHARD(id, firstName), lastName)\
)";
ret = kv_table_execute_sync(store, statement, &result);
if (ret != KV_SUCCESS) {
printf("Table creation failed.\n");
printf("Error message is %s\n",
kv_statement_result_get_error_message(result));
} else {
printf("Table create succeeded.\n");
}
} 表の行への書込み
ストアに表を定義した後で、kv_create_row()を使用して空の表の行を作成します。次に、適切なkv_row_put_xxx()関数(xxxは書き込んでいるフィールドのデータ型)を使用して各フィールドにデータを移入します。最後に、kv_table_put()を使用して、表の行を実際にストアに書き込みます。たとえば、次のように表が設計されているとします。
"CREATE TABLE myTable (item STRING, \
description STRING, \
count INTEGER, \
percentage FLOAT, \
PRIMARY KEY (item))" 表の行は次の形式で記述できます(簡潔にするために、ストアを開く操作と閉じる操作はスキップしています)。
void
do_store_ops(kv_store_t *store)
{
kv_error_t ret;
kv_row_t *row = NULL;
row = kv_create_row();
if (!row) {
printf("row creation failed.\n");
goto cleanup;
}
ret = kv_row_put_string(row, "item", "Bolts");
if (ret != KV_SUCCESS) {
printf("row put 'item' failed.\n");
goto cleanup;
}
ret = kv_row_put_string(row, "description",
"Hex head, stainless");
if (ret != KV_SUCCESS) {
printf("row put 'description' failed.\n");
goto cleanup;
}
ret = kv_row_put_int(row, "count", 5);
if (ret != KV_SUCCESS) {
printf("row put 'count' failed.\n");
goto cleanup;
}
ret = kv_row_put_float(row, "percentage", 0.2173913);
if (ret != KV_SUCCESS) {
printf("row put 'percentage' failed.\n");
goto cleanup;
}
ret = kv_table_put(store, "myTable", row,
NULL); // new version
if (ret != KV_SUCCESS) {
printf("Store put failed.\n");
goto cleanup;
} else {
printf("Store put succeeded.\n");
}
cleanup:
if (row) {
kv_release_row(&row);
}
} オプションやバージョン情報などを提供できる他のバージョンのkv_table_put()が存在します。
表の行の削除
表の行を削除するにはkv_table_delete()を使用します。この関数はKV_ERROR_Tを返さずに、整数を返します。
void
do_store_ops(kv_store_t *store)
{
kv_error_t ret;
kv_row_t *key = NULL;
key = kv_create_row();
if (!key) {
printf("key creation failed.\n");
goto cleanup;
}
ret = kv_row_put_string(key, "item", "Bolts");
if (ret != KV_SUCCESS) {
printf("row put 'item' failed.\n");
goto cleanup;
}
ret = kv_table_delete(store, "myTable", key);
// ret is 1 if a row was deleted
// 0 if no row with the provided key was found
// < 0 if an error occurred.
if (ret < 0) {
printf("Row deletion failed. %i\n", ret);
goto cleanup;
} else {
printf("Row deletion succeeded.\n");
}
cleanup:
if (key) {
kv_release_row(&key);
}
} オプションやバージョン情報などを提供できる他のバージョンのkv_table_delete()が存在します。
単一の表の行の読取り
単一の表の行を読み取るには、取得する行に含まれるフィールド名とフィールド値が設定されたkv_row_t構造体を作成します。次に、取得された行の保持に使用する2つ目のkv_row_t構造体を作成します。行はkv_table_get()を使用して取得されます。適切なバージョンのkv_row_get_xxxx()を使用して、取得した行の各種フィールドを検証できます。xxxxは、検証しているフィールドのデータ型です。
たとえば、「表の行への書込み」で作成した表の行を取得するには、次のようにします。
void
do_store_ops(kv_store_t *store)
{
kv_error_t ret;
kv_row_t *key = NULL;
key = kv_create_row();
if (!key) {
printf("key creation failed.\n");
goto cleanup;
}
ret = kv_row_put_string(key, "item", "Bolts");
if (ret != KV_SUCCESS) {
printf("row put 'item' failed.\n");
goto cleanup;
}
kv_row_t *retRow = NULL;
retRow = kv_create_row();
if (!retRow) {
printf("retRow creation failed.\n");
goto cleanup;
}
ret = kv_table_get(store, "myTable", key, &retRow);
if (!retRow) {
printf("Row retrieval failed.\n");
goto cleanup;
}
const char *retItem = NULL, *retDescription = NULL;
int retCount = 0;
float retPercentage = 0.0;
kv_row_get_string(retRow, "item", &retItem);
kv_row_get_string(retRow, "description", &retDescription);
kv_row_get_int(retRow, "count", &retCount);
kv_row_get_float(retRow, "percentage", &retPercentage);
printf("Item: %s. Desc: %s. Count is %i. Percent is %f\n",
retItem, retDescription, retCount, retPercentage);
cleanup:
if (key) {
kv_release_row(&key);
}
if (retRow) {
kv_release_row(&retRow);
}
} 複数の表の行の読取り
表から一度に複数行を読み取るにはkv_table_multi_get()またはkv_table_iterator()を使用します。これらの関数には、参照キーとして機能するkv_row_t構造体を提供する必要があります。提供するキーには、使用する関数に応じて異なる制限が適用されます。ここに示す例では、提供するキーに少なくともすべての表のshardキーが含まれていることを必要とするkv_table_multi_get()を使用します。存在しないshardキーがある場合、関数はエラーを返しませんが結果も返しません。
kv_table_multi_get()は、kv_iterator_next()を使用して繰り返すkv_iterator_t構造体を移入します。結果セット内の各部分で使用可能な行を取得するにはkv_iterator_get_result()およびkv_result_get_row()を使用します。
たとえば、次のような表を設計するとします。
CREATE TABLE myTable (
itemType STRING,
itemCategory STRING,
itemClass STRING,
itemColor STRING,
itemSize STRING,
price FLOAT,
inventoryCount INTEGER,
PRIMARY KEY (SHARD(itemType, itemCategory, itemClass), itemColor,
itemSize)
) また、これに次のようなデータを移入します。
int main(void) {
kv_store_t *store = NULL;
open_store(&store);
if (!store) {
goto ERROR;
}
do_store_ops(store, "Hats", "baseball", "longbill",
"red", "small", 12.07, 127);
do_store_ops(store, "Hats", "baseball", "longbill",
"red", "medium", 13.07, 201);
do_store_ops(store, "Hats", "baseball", "longbill",
"red", "large", 14.07, 309);
retrieve_table_rows(store);
ERROR:
/* Close the store handle. */
if (store) {
kv_close_store(&store);
}
return 0;
}
void
do_store_ops(kv_store_t *store,
const char *itemType, const char *itemCategory,
const char *itemClass, const char *itemColor,
const char *itemSize, float price, int inventoryCount)
{
kv_error_t ret;
kv_row_t *row = NULL;
row = kv_create_row();
if (!row) {
printf("row creation failed.\n");
goto cleanup;
}
ret = kv_row_put_string(row, "itemType", itemType);
if (ret != KV_SUCCESS) {
printf("row put 'itemType' failed.\n");
goto cleanup;
}
ret = kv_row_put_string(row, "itemCategory", itemCategory);
if (ret != KV_SUCCESS) {
printf("row put 'itemCategory' failed.\n");
goto cleanup;
}
ret = kv_row_put_string(row, "itemClass", itemClass);
if (ret != KV_SUCCESS) {
printf("row put 'itemClass' failed.\n");
goto cleanup;
}
ret = kv_row_put_string(row, "itemColor", itemColor);
if (ret != KV_SUCCESS) {
printf("row put 'itemColor' failed.\n");
goto cleanup;
}
ret = kv_row_put_string(row, "itemSize", itemSize);
if (ret != KV_SUCCESS) {
printf("row put 'itemSize' failed.\n");
goto cleanup;
}
ret = kv_row_put_float(row, "price", price);
if (ret != KV_SUCCESS) {
printf("row put 'price' failed.\n");
goto cleanup;
}
ret = kv_row_put_int(row, "inventoryCount", inventoryCount);
if (ret != KV_SUCCESS) {
printf("row put 'inventoryCount' failed.\n");
goto cleanup;
}
ret = kv_table_put(store, "myTable", row,
NULL); // new version
if (ret != KV_SUCCESS) {
printf("Store put failed.\n");
goto cleanup;
} else {
printf("Store put succeeded.\n");
}
cleanup:
if (row) {
kv_release_row(&row);
}
} その後、この例ではshardキーは表のすべての行に対して同一であるため、shardキーのみを提供するだけで表のすべての行を取得できます。(通常、表のすべての行を表示する場合は、keyパラメータに空の行を指定したkv_table_iteratorを使用します。)
void
retrieve_table_rows(kv_store_t *store)
{
kv_error_t ret;
kv_iterator_t *iter = NULL;
kv_row_t *key = NULL;
key = kv_create_row();
if (!key) {
printf("key creation failed.\n");
goto cleanup;
}
ret = kv_row_put_string(key, "itemType", "Hats");
if (ret != KV_SUCCESS) {
printf("row put 'itemType' failed.\n");
goto cleanup;
}
ret = kv_row_put_string(key, "itemCategory", "baseball");
if (ret != KV_SUCCESS) {
printf("row put 'itemCategory' failed.\n");
goto cleanup;
}
ret = kv_row_put_string(key, "itemClass", "longbill");
if (ret != KV_SUCCESS) {
printf("row put 'itemClass' failed.\n");
goto cleanup;
}
ret = kv_table_multi_get(store,
"myTable",
key,
KV_FALSE /* Keyonly*/,
NULL /* Field range */,
NULL /* Included tables */,
NULL /* Read options */,
&iter);
int nRows = 0;
while (kv_iterator_next(iter) == KV_SUCCESS) {
const kv_result_t *result;
kv_row_t *retRow;
const char *itemType = NULL;
const char *itemCategory = NULL;
const char *itemClass = NULL;
const char *itemColor = NULL;
const char *itemSize = NULL;
float price = 0.0;
int inventoryCount = 0;
result = kv_iterator_get_result(iter);
retRow = kv_result_get_row(result);
nRows++;
kv_row_get_string(retRow, "itemType", &itemType);
kv_row_get_string(retRow, "itemCategory", &itemCategory);
kv_row_get_string(retRow, "itemClass", &itemClass);
kv_row_get_string(retRow, "itemSize", &itemSize);
kv_row_get_string(retRow, "itemColor", &itemColor);
kv_row_get_float(retRow, "price", &price);
kv_row_get_int(retRow, "inventoryCount", &inventoryCount);
printf("Row %d:\n", nRows);
printf("\t%s, %s, %s:\n", itemType, itemCategory, itemClass);
printf("\t\tColor: %s itemSize: %s\n", itemColor,
itemSize);
printf("\t\tprice: %f inventory: %d\n", price,
inventoryCount);
}
cleanup:
if (key) {
kv_release_row(&key);
}
if (iter) {
kv_release_iterator(&iter);
}
} 索引を使用した読取り
kv_index_iterator()を使用して、指定した索引に基づいて表の行を読み取ります。この関数を使用するには、まずCREATE INDEX文を使用して索引を作成する必要があります。
結果セットのベースにする索引値を識別する方法は2つあります。最初の方法は、取得した索引付きフィールドと値を表すkv_row_t構造体を提供することです。2つ目の方法は、返される索引の開始値と終了値を識別するkv_field_range_t構造体を提供することです。kv_field_range_t構造体とkv_row_t構造体を一緒に使用して、戻りセット値を制限できます。
kv_row_tとkv_field_range_tの両方の値がNULLの場合、指定した索引と一致する表のすべての行が戻りセットに含まれます。
たとえば、次のように定義された表があるとします。
CREATE TABLE myTable (
surname STRING,
familiarName STRING,
userID STRING,
phonenumber STRING,
address STRING,
email STRING,
dateOfBirth STRING,
PRIMARY KEY (SHARD(surname, familiarName), userID)) 索引は次のとおりです。
CREATE INDEX DoB ON myTable (dateOfBirth)また、次のようなデータを表に移入します。
int main(void) {
kv_store_t *store = NULL;
open_store(&store);
if (!store) {
goto ERROR;
}
do_store_ops(store, "Anderson", "Pete", "panderson",
"555-555-5555", "1122 Somewhere Court",
"panderson@example.com", "1994-05-01");
do_store_ops(store, "Andrews", "Veronica", "vandrews",
"666-666-6666", "5522 Nowhere Court",
"vandrews@example.com", "1973-08-21");
do_store_ops(store, "Bates", "Pat", "pbates",
"777-777-7777", "12 Overhere Lane",
"pbates@example.com", "1988-02-20");
do_store_ops(store, "Macar", "Tarik", "tmacar",
"888-888-8888", "100 Overthere Street",
"tmacar@example.com", "1990-05-17");
read_index(store);
ERROR:
/* Close the store handle. */
if (store) {
kv_close_store(&store);
}
return 0;
}
void
do_store_ops(kv_store_t *store,
const char *surname, const char *familiarName,
const char *userID, const char *phone,
const char *address, const char *email,
const char *birthdate)
{
kv_error_t ret;
kv_row_t *row = NULL;
row = kv_create_row();
if (!row) {
printf("row creation failed.\n");
goto cleanup;
}
ret = kv_row_put_string(row, "surname", surname);
if (ret != KV_SUCCESS) {
printf("row put 'surname' failed.\n");
goto cleanup;
}
ret = kv_row_put_string(row, "familiarName", familiarName);
if (ret != KV_SUCCESS) {
printf("row put 'familiarName' failed.\n");
goto cleanup;
}
ret = kv_row_put_string(row, "userID", userID);
if (ret != KV_SUCCESS) {
printf("row put 'userID' failed.\n");
goto cleanup;
}
ret = kv_row_put_string(row, "phonenumber", phone);
if (ret != KV_SUCCESS) {
printf("row put 'phonenumber' failed.\n");
goto cleanup;
}
ret = kv_row_put_string(row, "address", address);
if (ret != KV_SUCCESS) {
printf("row put 'address' failed.\n");
goto cleanup;
}
ret = kv_row_put_string(row, "email", email);
if (ret != KV_SUCCESS) {
printf("row put 'email' failed.\n");
goto cleanup;
}
ret = kv_row_put_string(row, "dateOfBirth", birthdate);
if (ret != KV_SUCCESS) {
printf("row put 'birthdate' failed.\n");
goto cleanup;
}
ret = kv_table_put(store, "myTable", row,
NULL); // new version
if (ret != KV_SUCCESS) {
printf("Store put failed.\n");
goto cleanup;
} else {
printf("Store put succeeded.\n");
}
cleanup:
if (row) {
kv_release_row(&row);
}
} さらに、次の関数を使用し、DoB索引を使用して読み取ることができます。次の例では、BLOCK 1 (コード内のコメントを参照)は、BLOCK 2とともに使用すると結果セットが空になるためコメント・アウトされています。表全体を出力するにはBLOCK 1とBLOCK 2の両方をコメントにします。
void
read_index(kv_store_t *store)
{
kv_error_t ret;
kv_iterator_t *iter = NULL;
kv_row_t *key = NULL;
kv_field_range_t *rangep = NULL;
key = kv_create_row();
if (!key) {
printf("key creation failed.\n");
goto cleanup;
}
// BLOCK 1:
// Uncomment this block to look up only table rows with a
// dateOfBirth field set to "1988-02-20". If this
// block and BLOCK 2 are both used, then the result set
// will be empty.
//
//ret = kv_row_put_string(key, "dateOfBirth", "1988-02-20");
//if (ret != KV_SUCCESS) {
// printf("row put 'dateOfBirth' failed.\n");
// goto cleanup;
//}
// BLOCK 2:
// This field range restricts the results set to only
// those rows with a dateOfBirth field value between
// "1990-01-01" and "2000-01-01", inclusive.
ret = kv_create_field_range("dateOfBirth", // Field
"1990-01-01", // Start value
KV_TRUE, // Inclusive?
"2000-01-01", // End value
KV_TRUE, // Inclusive?
&rangep);
if (ret != KV_SUCCESS) {
printf("field range creation failed.\n");
goto cleanup;
}
ret = kv_index_iterator(store, "myTable", "DoB",
key, // Key to use for the lookup
KV_FALSE, // Whether only primary keys
// are returned
rangep, // Field range
NULL, // Included tables
KV_DIRECTION_UNORDERED,
NULL, // Read options
0, // max iterator results, 0 - use default
&iter);
int nRows = 0;
while (kv_iterator_next(iter) == KV_SUCCESS) {
const kv_result_t *result;
kv_row_t *retRow;
const char *surname = NULL;
const char *familiarName = NULL;
const char *userID = NULL;
const char *phonenumber = NULL;
const char *address = NULL;
const char *email = NULL;
const char *dateOfBirth = NULL;
result = kv_iterator_get_result(iter);
retRow = kv_result_get_row(result);
nRows++;
kv_row_get_string(retRow, "surname", &surname);
kv_row_get_string(retRow, "familiarName", &familiarName);
kv_row_get_string(retRow, "userID", &userID);
kv_row_get_string(retRow, "phonenumber", &phonenumber);
kv_row_get_string(retRow, "address", &address);
kv_row_get_string(retRow, "email", &email);
kv_row_get_string(retRow, "dateOfBirth", &dateOfBirth);
printf("Row %d:\n", nRows);
printf("\t%s, %s (%s):\n", familiarName, surname, userID);
printf("\t\tPhone: %s\n", phonenumber);
printf("\t\tEmail: %s\n", email);
printf("\t\tAddress: %s\n", address);
printf("\t\tDoB: %s\n", dateOfBirth);
}
cleanup:
if (key) {
kv_release_row(&key);
}
if (rangep) {
kv_release_field_range(&rangep);
}
if (iter) {
kv_release_iterator(&iter);
}
} 実行の順序付け
書込み操作の順序を保持するkv_operations_t構造体を作成するにはkv_create_operations()を使用します。すべての書込み操作は、すべての操作が同じshardキーを共有するかぎり、単一の原子的構造体として実行されます。
一連の1つ以上のkv_create_table_xxxx_op()関数を使用して、操作をkv_operations_t構造体に移入します。xxxxは、操作リストに挿入する操作のタイプを示します。たとえば、kv_create_table_delete_op()は行の削除操作を順序に挿入します。
操作の順序付けはkv_table_execute_operations()を使用して実行されます。
たとえば、「複数の表の行の読取り」で説明されているようなデータが移入されている表がある場合は、表の各行の価格および在庫値を次のような原子的操作で更新できます。
int main(void) {
kv_error_t ret;
kv_store_t *store = NULL;
kv_operations_t *op = NULL;
kv_operation_results_t *resultp = NULL;
open_store(&store);
if (!store) {
goto ERROR;
}
op = kv_create_operations();
// Causes all rows to be released when op is released.
kv_operations_set_donate(op);
ret = add_op_list(op, "Hats", "baseball", "longbill",
"red", "small", 13.07, 107);
if (ret != KV_SUCCESS) {
printf("adding to op list failed.\n");
return -1;
}
ret = add_op_list(op, "Hats", "baseball", "longbill",
"red", "medium", 14.07, 198);
if (ret != KV_SUCCESS) {
printf("adding to op list failed.\n");
return -1;
}
ret = add_op_list(op, "Hats", "baseball", "longbill",
"red", "large", 15.07, 140);
if (ret != KV_SUCCESS) {
printf("adding to op list failed.\n");
return -1;
}
ret = kv_table_execute_operations(store, op, NULL, &resultp);
if (ret != KV_SUCCESS) {
printf("operation execution failed.\n");
} else {
printf("operation execution succeeded.\n");
}
ERROR:
/* Close the store handle. */
if (store) {
kv_close_store(&store);
}
if (resultp) {
kv_release_operation_results(&resultp);
}
if (op) {
kv_release_operations(&op);
}
return 0;
}
int
add_op_list(kv_operations_t *op,
const char *itemType, const char *itemCategory,
const char *itemClass, const char *itemColor,
const char *itemSize, float price, int inventoryCount)
{
kv_error_t ret;
kv_row_t *row = NULL;
row = kv_create_row();
if (!row) {
printf("row creation failed.\n");
return -1;
}
ret = kv_row_put_string(row, "itemType", itemType);
if (ret != KV_SUCCESS) {
printf("row put 'itemType' failed.\n");
return -1;
}
ret = kv_row_put_string(row, "itemCategory", itemCategory);
if (ret != KV_SUCCESS) {
printf("row put 'itemCategory' failed.\n");
return -1;
}
ret = kv_row_put_string(row, "itemClass", itemClass);
if (ret != KV_SUCCESS) {
printf("row put 'itemClass' failed.\n");
return -1;
}
ret = kv_row_put_string(row, "itemColor", itemColor);
if (ret != KV_SUCCESS) {
printf("row put 'itemColor' failed.\n");
return -1;
}
ret = kv_row_put_string(row, "itemSize", itemSize);
if (ret != KV_SUCCESS) {
printf("row put 'itemSize' failed.\n");
return -1;
}
ret = kv_row_put_float(row, "price", price);
if (ret != KV_SUCCESS) {
printf("row put 'price' failed.\n");
return -1;
}
ret = kv_row_put_int(row, "inventoryCount", inventoryCount);
if (ret != KV_SUCCESS) {
printf("row put 'inventoryCount' failed.\n");
return -1;
}
ret = kv_create_table_put_op(op, "myTable", row,
KV_RETURN_ROW_NONE, // kv_return_row_version_enum
0); // Abort on failure?
if (ret != KV_SUCCESS) {
printf("Store put op failed.\n");
return -1;
} else {
printf("Store put op succeeded.\n");
}
// Do not release the row at the end of this, as doing so will
// cause the operation execution to core dump. The row must be
// saved for the future operation.
//
return KV_SUCCESS;
} 一貫性保証の設定
デフォルトでは、読取り操作はKV_CONSISTENCY_NONEの一貫性保証で実行されます。次のいずれかの関数を使用して、このデフォルトをオーバーライドする一貫性保証を作成します。
-
kv_create_simple_consistency() -
kv_create_time_consistency() -
kv_create_version_consistency()
これらは、kv_release_consistency()を使用して解放する必要のあるkv_consistency_t構造体の割当てと移入を行います。
次に、kv_consistency_t構造体をkv_create_read_options()とともに使用して、kv_read_options_t構造体の作成、割当ておよび移入を行います。kv_release_read_options()を使用して、この構造体を解放します。
最後に、ストアからの読取り操作を実行する場合はkv_read_options_t構造体を使用します。
たとえば、「単一の表の行の読取り」に示すコード・フラグメントは、次の方法でデフォルトの一貫性ポリシーを使用するようにリライトできます。
void
do_store_ops(kv_store_t *store)
{
kv_consistency_t *consis = NULL;
kv_error_t ret;
kv_read_options_t *readopts = NULL;
kv_result_t *results = NULL;
kv_row_t *key = NULL;
ret = kv_create_simple_consistency(KV_CONSISTENCY_ABSOLUTE,
&consis);
if (ret != KV_SUCCESS) {
printf("consistency creation failed\n");
goto cleanup;
}
ret = kv_create_read_options(consis, // consistency
0, // timeout value.
// 0 means use the default.
&readopts);
if (ret != KV_SUCCESS) {
printf("readoptions creation failed\n");
return;
}
key = kv_create_row();
if (!key) {
printf("key creation failed.\n");
goto cleanup;
}
ret = kv_row_put_string(key, "item", "Bolts");
if (ret != KV_SUCCESS) {
printf("row put 'item' failed.\n");
goto cleanup;
}
ret = kv_table_get_with_options(store,
"myTable",
key,
readopts,
&results);
if (ret != KV_SUCCESS) {
printf("Retrieval failed.\n");
goto cleanup;
}
kv_row_t *retRow = kv_result_get_row(results);
const char *retItem = NULL, *retDescription = NULL;
int retCount = 0;
float retPercentage = 0.0;
kv_row_get_string(retRow, "item", &retItem);
kv_row_get_string(retRow, "description", &retDescription);
kv_row_get_int(retRow, "count", &retCount);
kv_row_get_float(retRow, "percentage", &retPercentage);
printf("Item: %s. Desc: %s. Count is %i. Percent is %f\n",
retItem, retDescription, retCount, retPercentage);
cleanup:
if (key) {
kv_release_row(&key);
}
if (retRow) {
kv_release_row(&retRow);
}
// kv_release_read_options also releases the
// kv_consistency_t structure.
if (readopts) {
kv_release_read_options(&readopts);
}
} 永続性保証の設定
デフォルトでは、書込み操作はKV_DURABILITY_COMMIT_NO_SYNCの永続性保証で実行されます。これは、永続性保証を作成および使用することでオーバーライドできます。
kv_create_durability()を使用してkv_durability_t構造体を初期化します。次に、kv_durability_t構造体をkv_create_write_options()とともに使用して、kv_write_options_t構造体の割当てと移入を行います。kv_release_write_options()を使用して、この構造体を解放します。
最後に、ストアへの書込み操作を実行する場合はkv_write_options_t構造体を使用します。
たとえば、「表の行への書込み」に示すコード・フラグメントは、次の方法で永続性ポリシーを使用するようにリライトできます。
void
do_store_ops(kv_store_t *store)
{
kv_error_t ret;
kv_row_t *row = NULL;
kv_durability_t durability;
kv_write_options_t *writeopts;
kv_result_t *results;
row = kv_create_row();
if (!row) {
printf("row creation failed.\n");
goto cleanup;
}
ret = kv_row_put_string(row, "item", "Bolts");
if (ret != KV_SUCCESS) {
printf("row put 'item' failed.\n");
goto cleanup;
}
ret = kv_row_put_string(row, "description", "Hex head, stainless");
if (ret != KV_SUCCESS) {
printf("row put 'description' failed.\n");
goto cleanup;
}
ret = kv_row_put_int(row, "count", 5);
if (ret != KV_SUCCESS) {
printf("row put 'count' failed.\n");
goto cleanup;
}
ret = kv_row_put_float(row, "percentage", 0.2173913);
if (ret != KV_SUCCESS) {
printf("row put 'percentage' failed.\n");
goto cleanup;
}
durability = kv_create_durability(
KV_SYNC_FLUSH, // Master sync
KV_SYNC_NONE, // Replica sync
KV_ACK_MAJORITY); // Ack policy
ret = kv_create_write_options(durability,
0, // 0 is default timeout
&writeopts);
if (ret != KV_SUCCESS) {
printf("Write options creation failed.\n");
return;
}
ret = kv_table_put_with_options(store,
"myTable",
row,
writeopts,
// Whether the new row should be
// returned in the results
// parameter.
KV_RETURN_ROW_NONE,
&results);
if (ret != KV_SUCCESS) {
printf("Store put failed.\n");
goto cleanup;
} else {
printf("Store put succeeded.\n");
}
cleanup:
if (row) {
kv_release_row(&row);
}
if (writeopts) {
kv_release_write_options(&writeopts);
}
if (results) {
kv_release_result(&results);
}
} プロキシ・サーバー・リファレンス
プロキシ・サーバーのコマンドライン・オプションを次に示します。
nohup java -cp KVHOME/lib/kvclient.jar:kvproxy/lib/kvproxy.jar
oracle.kv.proxy.KVProxy -help
-port <port-number> Port number of the proxy server. Default: 5010
-store <store-name> Required KVStore name. No default.
-helper-hosts <host:port,host:port,...> Required list of KVStore
hosts and ports (comma separated).
-security <security-file-path> Identifies the security file used
to specify properties for login. Required for connecting to
a secure store.
-username <user> Identifies the name of the user to login to the
secured store. Required for connecting to a secure store.
-read-zones <zone,zone,...> List of read zone names.
-max-active-requests <int> Maximum number of active requests towards
the store.
-node-limit-percent <int> Limit on the number of requests, as a
percentage of the requested maximum active requests.
-request-threshold-percent <int> Threshold for activating request
limiting, as a percentage of the requested maximum active
requests.
-request-timeout <long> Configures the default request timeout in
milliseconds.
-socket-open-timeout <long> Configures the open timeout in
milliseconds used when establishing sockets to the store.
-socket-read-timeout <long> Configures the read timeout in
milliseconds associated with the underlying sockets to the
store.
-max-iterator-results <long> A long representing the maximum
number of results returned in one single iterator call.
Default: 100
-iterator-expiration <long> Iterator expiration interval in
milliseconds.
-max-open-iterators <int> Maximum concurrent opened iterators.
Default: 10000
-num-pool-threads <int> Number of proxy threads. Default: 20
-max-concurrent-requests <int> The maximum number of
concurrent requests per iterator. Default: <num_cpus * 2>
-max-results-batches <int> The maximum number of results
batches that can be held in the proxy per iterator.
Default: 0
-help Usage instructions.
-version Print KVProxy server version number.
-verbose Turn verbose flag on. プロキシ・サーバーを起動する前に必ずOracle NoSQL Databaseストアを起動します。
非セキュア・ストアに接続するときは次のパラメータが必要です。
-
-helper-hostsここで指定したホスト名はDNSまたはローカルの
/etc/hostsファイルを使用して解決可能である必要があります。 -
-port -
-store
セキュア・ストアに接続するときは次のパラメータも必要です。
-
-security -
-username
注意:
ドライバは、正しく構成されている場合にローカル・ホスト上のプロキシ・サーバーを開始および停止できます。詳細は、「プロキシ・サーバーの自動的な起動」を参照してください。
Oracle NoSQL Databaseプロキシ・サーバーの保護
プロキシは、正しく構成されている場合は、Oracle NoSQL Databaseのセキュアなインストールにアクセスできます。プロキシ・サーバー自体ではOracle NoSQL Databaseクライアントからのセキュアな接続はサポートされていないということに注意してください。これらの接続は、常に、暗号化されていない状態で、認証なしで実行されます。ただし、プロキシ・サーバーはセキュアなストアに接続でき、その接続は認証され暗号化されます。
これを行うには、プロキシ・サーバーの起動時に-usernameおよび-securityプロキシ・オプションを指定する必要があります。Oracle NoSQL Database Enterprise Editionを使用している場合は、Oracleウォレットを使用できます(これは、Enterprise Editionパッケージからのその取得時にkvliteによって使用されます)。その場合は、プロキシ・サーバーの起動時にoraclepki.jarファイルも使用する必要があります。
プロキシ・サーバーを起動するときには、-securityオプションによって、使用するセキュリティ・ファイルを指定します。kvliteを使用している場合は、それによって、新しいKVROOTディレクトリが作成されるときにセキュリティ・ファイルが作成されます。この場合は、KVROOT/security/user.securityを使用します。kvliteを使用せず、かわりにOracle NoSQL Databaseの保護されたフル・インストールを実行している場合は、KVROOT/security/client.securityのコピーを作成し、クライアントがストアに安全に接続するために必要なパラメータをさらに追加します。セキュリティ・ガイド内のSSLモデルを参照してください。
どちらの場合も、ファイルを同じホストに格納する必要があります。これは、プロキシ・サーバーが次のように動作するためです(このインストールではOracleウォレットが使用されていることに注意してください)。
oracle.kv.ssl.trustStore=client.trust
oracle.kv.transport=ssl
oracle.kv.auth.username=admin
oracle.kv.ssl.protocols=TLSv1.2,TLSv1.1,TLSv1
oracle.kv.ssl.hostnameVerifier=dnmatch(CN\=NoSQL)
oracle.kv.auth.wallet.dir=user.wallet KVProxyを実行し、セキュアなOracle NoSQL Databaseデプロイメントにアクセスするには、次のようにします(この例では、Oracleウォレットを使用しているため、oraclepki.jarが指定されています)。
java -cp <KVHOME>/lib/kvclient.jar: \
<KVPROXY>/lib/kvproxy.jar:<KVHOME>/lib/oraclepki.jar \
oracle.kv.proxy.KVProxy -helper-hosts node01:5000 -port 5010 \
-store mystore -username admin -security mylogin
Nov 21, 2014 12:59:12 AM oracle.kv.proxy.KVProxy <init>
INFO: PS: Starting KVProxy server
Nov 21, 2014 12:59:12 AM oracle.kv.proxy.KVProxy <init>
INFO: PS: Connect to Oracle NoSQL Database mystore nodes : localhost:5000
Nov 21, 2014 12:59:13 AM oracle.kv.proxy.KVProxy <init>
INFO: PS: ... connected successfully
Nov 21, 2014 12:59:13 AM oracle.kv.proxy.KVProxy startServer
INFO: PS: Starting listener ( Half-Sync/Half-Async server - 20
no of threads on port 5010) 注意:
このプロキシ・サーバーはセキュアなストアで使用されているため、プロキシ・サーバーに対して、認可されたクライアントを実行しているホストのみがプロキシ・サーバーのリスニング・ポート(前の例ではポート5010)にアクセスできるようにファイアウォールを構成する必要があります。
プロキシ・サーバーのトラブル・シューティング
クライアントがストアに接続できない場合、クライアント・コード、プロキシとその構成、またはストアに問題がある可能性があります。何が問題になるかを判断するためには、クライアント・コードがストアに接続するときに何が起きるかをよく理解することが役立ちます。
-
まず、クライアント・コードはプロキシで指定された
ip:portペアに接続しようとします。 -
接続の試行が失敗し、プロキシが自動的に起動する必要があるとクライアント・コードによって通知された場合:
-
クライアント・ドライバは、ローカル・ホストでプロキシを起動するコマンドラインを準備します。このコマンドラインに含まれるのは、
javaコマンドのパス、プロキシの起動に必要な2つのjarファイルのクラスパス、プロキシを起動しストアに接続するために必要なパラメータ(リスニングするプロキシのローカル・ポートやストアの接続情報が含まれる)です。 -
ドライバがコマンドラインを実行します。問題が発生した場合、問題の正確な特徴によって異なりますが、関連するエラー情報をドライバが提供できる場合があります。
-
コマンドを実行すると、ドライバは接続が完了するまで数秒間待機します。この間にプロキシが起動を試行します。この時点では、クラスパスの問題が示されることがあります。
次に、
kvclient.jarのバージョンをチェックし、適合していない場合は知らせます。その後、接続パラメータをチェックし、問題があれば知らせます。
次に、プロキシが
helper-hostsパラメータを使用して実際にストアに接続します。この時点では、ストアにアクセスできない、セキュリティ資格証明がない、またはセキュリティ資格証明が正しくないといった、接続エラーが報告されることがあります。最後に、プロキシは指定のポートのリスニングを試行します。ポートのリスニング中にエラー(別のプロセスで使用中など)が発生すると、プロキシによって報告されます。
-
直前のステップでエラーが発生すると、ドライバは自動的にプロセス全体を繰り返します。正常に接続を取得するか、再試行回数に到達するまで、プロセスを繰り返し続けます。
最終的にドライバが接続を正常に確立できない場合、エラーを返します。
-
-
ドライバが正常にプロキシに接続した場合、プロキシに確認メッセージを送信します。この確認メッセージには、helper-hostリスト、ストア名、ユーザー名(セキュア・ストアを使用している場合)、読取りゾーン(ストアで使用される場合)が含まれます。
確認メッセージの情報に問題がある場合、プロキシがエラー・メッセージを返します。これにより、ドライバが正しいストアに接続していることを確認するために、プロキシがパラメータをチェックします。
-
確認メッセージにエラーがない場合は、接続が確立され、ストアの操作を実行することができます。
接続の問題をトラブルシューティングする際に最適なエラー情報を取得するには、-verboseコマンドライン・オプションを使用してプロキシを起動します。また、java -eaコマンドライン・オプションを使用するとプロキシJavaコードのアサーションを有効化できます。
これら2つのメカニズムによりプロキシは豊富な情報を提供します。分析するためにファイルへのロギングを有効にすることができます。その手順を次に示します。
次のパラメータを使用してプロキシを起動します。
java -cp KVHOME/lib/kvclient.jar:KVPROXY/lib/kvproxy.jar
-Djava.util.logging.config.file=logger.properties
oracle.kv.proxy.KVProxy -helper-hosts node01:5000 -port 5010
-store mystore -verbose ファイルlogger.propertiesには次のような内容が含まれます。
# Log to file and console
handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler
## ConsoleHandler ##
java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter =
java.util.logging.SimpleFormatter
## FileHandler ##
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
# Limit the size of the file to x bytes
java.util.logging.FileHandler.limit = 100000
# Number of log files to rotate
java.util.logging.FileHandler.count = 1
# Location and log file name
# %g is the generation number to distinguish rotated logs
java.util.logging.FileHandler.pattern = ./kvproxy.%g.log 構成パラメータにより、使用されるローテーション・ログ・ファイルのサイズと数が制御されます(javaロギング同様、java.util.logging.FileHandlerを参照)。ローテーションのある一連のファイルの場合、各ファイルは指定されているサイズ制限に達すると閉じられ、ローテーションが行われ、新しいファイルが開かれます。古いファイルにはファイル名に"0"、"1"、"2"などを追加することで連続的に名前が付けられます。
サードパーティ・ライセンス
Oracle NoSQL Databaseクライアントは、Apache License、Version 2.0 (以下、「ライセンス」)に基づいてライセンス付与されます。このライセンスに準拠していないと、このファイルを使用できない場合があります。ライセンスのコピーは、次から入手できます:
http://www.apache.org/licenses/LICENSE-2.0
適用法により求められた場合、または書面をもって同意された場合を除き、ライセンスに基づいて配布されたソフトウェアは、明示的、黙示的を問わず一切の保証または条件なしに「現状のまま」で提供されています。特定の言語下のライセンス許諾事項および制限事項については、ライセンスを確認してください。
次の条件は、このOracle NoSQLクライアントと、Apache 2.0ライセンスの対象となる他のすべての製品に適用されます。
Apache License Version 2.0、2004年1月
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
Definitions
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity.For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship.For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner.For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
-
Grant of Copyright LicenseSubject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
-
Grant of Patent LicenseSubject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted.If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
-
Redistribution.You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
-
You must give any other recipients of the Work or Derivative Works a copy of this License; and
-
You must cause any modified files to carry prominent notices stating that You changed the files; and
-
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
-
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear.The contents of the NOTICE file are for informational purposes only and do not modify the License.You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions or use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
-
-
Submission of Contributions.Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions.Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
-
Trademarks.This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file
-
Disclaimer of Warranty.Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
-
Limitation of Liability.In no event and under no legal theory whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
-
Accepting Warranty or Additional LiabilityWhile redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License.However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information.(Don't include the brackets!)The text should be enclosed in the appropriate comment syntax for the file format.We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.ライセンスのコピーは、次から入手できます
http://www.apache.org/licenses/LICENSE-2.0
適用法により求められた場合、または書面をもって同意された場合を除き、ライセンスに基づいて配布されたソフトウェアは、明示的、黙示的を問わず一切の保証または条件なしに「現状のまま」で提供されています。特定の言語下のライセンス許諾事項および制限事項については、ライセンスを確認してください。
SLF4Jのライセンス条件
SLF4J source code and binaries are distributed under the MIT license.
Copyright © 2004, 2013 QOS.ch.All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
前述の著作権表示およびこの許諾表示は、このソフトウェアのすべてのコピーまたは大部分に含めることができるものとします。
-
このソフトウェアは、明示または黙示を問わず、商品性、特定の目的に対する適合性、および知的所有権を侵害していないことに関する保証を含め(これらのみというわけではない)、いかなる保証もなしで、現状のまま提供されます。IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Oracle NoSQL Database C表ドライバ開発者ガイド, リリース20.2
F33796-02
2020年8月
Copyright © 2011, 2020, Oracle and/or its affiliates.
このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。
ここに記載された情報は予告なしに変更される場合がありますまた、誤りが無いことの保証はいたしかねます。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクル社までご連絡ください。
このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。
U.S. GOVERNMENT END USERS: Oracle programs (including any operating system, integrated software, any programs embedded, installed or activated on delivered hardware, and modifications of such programs) and Oracle computer documentation or other Oracle data delivered to or accessed by U.S. Government end users are "commercial computer software" or “commercial computer software documentation” pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.As such, the use, reproduction, duplication, release, display, disclosure, modification, preparation of derivative works, and/or adaptation of i) Oracle programs (including any operating system, integrated software, any programs embedded, installed or activated on delivered hardware, and modifications of such programs), ii) Oracle computer documentation and/or iii) other Oracle data, is subject to the rights and limitations specified in the license contained in the applicable contract.The terms governing the U.S. Government’s use of Oracle cloud services are defined by the applicable contract for such services.No other rights are granted to the U.S. Government.
このソフトウェアまたはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアもしくはハードウェアは、危険が伴うアプリケーション(人的傷害を発生させる可能性があるアプリケーションを含む)への用途を目的として開発されていません。このソフトウェアまたはハードウェアを危険が伴うアプリケーションで使用する際、このソフトウェアまたはハードウェアを安全に使用するために、適切な安全装置、バックアップ、冗長性(redundancy)、その他の対策を講じることは使用者の責任となります。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、オラクル社およびその関連会社は一切の責任を負いかねます。
OracleおよびJavaはOracle およびその関連企業の登録商標です。その他の名称は、他社の商標の可能性があります。
Intel、Intel Insideは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Epyc、AMDロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXは、The Open Groupの登録商標です。
このソフトウェアまたはハードウェア、そしてドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。オラクル社との間で該当する取決めにて別途規定しないかぎり、オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。オラクル社との間で該当する取決めにて別途規定する場合を除き、オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても、一切の責任を負いかねます。