最近のデータベースは、そのほとんどが複数のフレームワークとプログラミング言語をサポートしています。 一般的にサポートされている言語の中には、Java、C、Ruby、Pythonなどがあります。 GridDBも同様です。 GridDBは、C、Python、およびRubyプログラミング言語用のAPIを使用して、開発者にツールキットを提供するようになりました。
Setting Up the C API
GridDBのCクライアントAPIは、 CentOS 6.7 および CentOS 7.3 をサポートしています。 クライアントは互換性があり gcc version-4.8.5 で、コミュニティ版またはスタンダード版で使用できます。 CクライアントのStandard Editionのバージョンでは、ジオメトリの列や操作などをサポートするJava対応のすべての機能がサポートされています。Community Edition用のCクライアントをセットアップするためのファイルと説明は、 GridDB Githubページにあります。
何らかの理由で configure
スクリプトまたは bootstrap.sh
スクリプトのいずれかでエラーが発生した場合は、これらのコマンドを使用して次のライブラリをインストールします。
$ sudo yum groupinstall ‘Development Tools’ $ sudo yum makecache fast
make
コマンドを実行しているときに、 **recursive errorというエラーがスローされた場合は、上記のライブラリがインストールされていることを確認してください。 その後、Github Cリポジトリから新しいものを取得してクローニングして、 c_client ディレクトリを削除します。
そこから、クライアントとGridDB接続をテストするために、c_clientリポジトリに用意されているいくつかのサンプルプログラムを実行して、クライアントをテストできます。
CクライアントファイルをGridDBにコンパイルしてリンクする際に注意すべき点がいくつかあります。 gcc
でコンパイルする場合、インクルード(-I)
フラグは gridstore.h
を含む include
>ディレクトリを指します。ライブラリ、または(-L)
フラグは、.so
ファイルとシンボリックリンクを持つc-clientディレクトリの中にある bin ディレクトリを常に指します。
$ ls c_client/bin libgridstore.so libgridstore.so.0 libgridstore.so.0.0.0
ファイルを正常にコンパイルするには、 -lgridstore
オプションも使用する必要があります。
また、コンパイルされた実行ファイルが正常に実行されるためには、 LD_LIBRARY_PATH
という環境変数を設定する必要があります。 この変数は、GridDB Cクライアントディレクトリの bin
ディレクトリを指す必要があります。
Cソースコードファイルのコンパイル例
$ export LD_LIBRARY_PATH=/path/to/c_client/bin $ gcc -o cSample cSample.c -I./include -L./bin -lgridstore $ ./cSample 239.0.0.1 31999 defaultCluster admin admin
C APIリファレンスの詳細については、こちらを参照してください。
Python/Ruby API Setup
GridDBは、Python 2.6、2.7、そしてPython 3.6をサポートします。
Pythonライブラリをうまく構築するために重要なことの1つは、Cクライアントを正常に構築する必要があることです。 PythonとRuby用の開発キットも必要です。
$ sudo yum install ruby-devel $ sudo yum install python-devel
SWIGとpcreライブラリも必要です。 インストール手順とサンプルプログラムについては、 griddb_client ページを参照してください。
PythonやRubyライブラリを使うことについて知っておくべき重要なことは、クライアントの Makefile
の変数がc_clientライブラリを指しているため、Cクライアントをインストールしてセットアップする必要があることです。
Cクライアントを設定している場合は、環境変数 LD_LIBRARY_PATH
を設定する必要があります。 RubyとPythonの両方のクライアントライブラリファイルを正常に構築するには、この変数の値が必要です。
Makefile でこの行を編集してください。
LDFLAGS = -L/path/c_client/library/bin -lpthread -lrt -lgridstore
Makefileでは、使用されるPythonのデフォルトバージョンはPython 2.6です。 2.7またはPython 3.6を使用する場合は、 Makefile
の11行目を編集して make
コマンドを正常に実行できるようにします。
MakefileのPythonバージョンを2.6から2.7に変更する例:
Line 11 of Makefile
:
INCLUDES_PYTHON = $(INCLUDES) -I/usr/include/python2.6 ## Before Makefile used (Python 2.6) ## Change it to INCLUDES_PYTHON = $(INCLUDES) -I/usr/include/python2.7 ## After, now uses (Python 2.7)
ソースコードでは、 griddb_python_client
ファイルをインポートして、グリッドストア機能にアクセスしてください。
PythonのAPIのリファレンスは、こちらにあります。
Ruby API Features
GridDB Pythonクライアント用のリポジトリをクローンすると、Rubyクライアントのビルドと実行に必要なすべてのファイルも取得されます。 GridDBはRubyバージョン1.8とバージョン2.4をサポートします。 Rubyクライアントをビルドして実行する方法の詳細については、 griddb_clientページを参照してください。
PythonクライアントとしてRubyクライアントにも同様のルールが適用されます。 一つの違いは、Rubyクライアントライブラリを含む griddb_ruby_client.so
ファイルを参照する 'griddb_ruby_client'
をソースコードで単純に require
。
Ruby APIのリファレンスは、こちらにあります。
Connecting to your GridDB Cluster
ほとんどの場合、C/Python/Ruby APIのGridDBクラスタへの接続は、Java APIのGridDBへの接続に似ています。 Properties オブジェクトまたは同様のデータ構造を作成し、接続先のデータベースのホスト、ポート、および構成設定を入力します。 GridDBへの接続を表す Gridstore
インスタンスを取得するために、これらのプロパティとの接続をフェッチするために StoreFactory
オブジェクトを使用します。
C
#include "gridstore.h" // (snip) GSGridStore* gridstore; const GSPropertyEntry properties[] = { {"notificationAddress",host}, {"notificationPort",port}, {"clusterName",clusterName}, {"user",username}, {"password",password} }; size_t propertyCount = sizeof(properties) / sizeof(*properties); gsGetGridStore(gsGetDefaultFactory(),properties,propertyCount,&gridstore);
Python
#!/usr/bin/python import sys import griddb_python_client # (snip) griddb = griddb_python_client factory = griddb.StoreFactory.get_default() try: gridstore = factory.get_store({ "notificationAddress":host, "notificationPort": port, "clusterName":cluster, "user":user, "password":password })
Ruby
#!/usr/bin/ruby $:.unshift File.dirname(__FILE__) require 'griddb_ruby_client' Griddb = Griddb_ruby_client factory = Griddb::StoreFactory.get_default() gridstore = factory.get_store({ "notificationAddress"=> ARGV[0], "notificationPort"=> ARGV[1], "clusterName"=> ARGV[2], "user"=> ARGV[3], "password"=> ARGV[4] })
TQLクエリの発行
GridDBのC APIには、コンテナ内の行を照会および集約するためのさまざまな組み込み関数があります。ほとんどの場合、コンテナにクエリを作成して発行する最も簡単で簡単な方法は、TQL文字列を使用することです。 TQL は、GridDBのSQLクエリの簡略化された形式です。
クエリはTQL文字列として開始されます。 そこから、そのTQLをコンテナに発行することによってクエリオブジェクトが形成されます。このTQLを取得して結果の行セットを取得できます。 その結果得られる行セットを反復して、個々の行と列の値を取得できます。 集計結果も行セットから取得されます。 このフローは、C、Python、RubyのAPIとほぼ同じです。
TQL Query in C
他の多くのクエリ言語と同様に、GridDBのTQL を用いて、文字列の長さチェック、部分文字列スライシング、文字列認識のような
文字列操作が可能です。
Device nextDevice; GSQuery* generalQuery; GSRowSet* generalRowSet; gsQuery(collection, \ "select * where (SUBSTRING(name,8,3)='r12' OR name LIKE '%LUE%R55_') and CHAR_LENGTH(name) > 4", \ &generalQuery); gsFetch(generalQuery,GS_FALSE,&generalRowSet); printf("Performing a String Operation on Collection ampCollection151 in TQL\n\n"); while(gsHasNextRow(generalRowSet)){ GSChar timeString[GS_TIME_STRING_SIZE_MAX]; gsGetNextRow(generalRowSet,&nextDevice); // Obtain row object gsFormatTime(nextDevice.timestamp,timeString,sizeof(timeString)); // Format timestamp number printf("Row in collection ampMeter151: Name=%s",nextDevice.name); printf(" Amperage = %.2lf",nextDevice.amperage); printf(" Count = %d",nextDevice.count); printf(" Timestamp = %s\n",timeString);
アウトプット
TQLのコレクションampCollection151で文字列操作を実行する Row in collection ampMeter151: Name=ampMeter12 Amperage = 1.45 \ Count = 3 Timestamp = 2017-09-15T18:13:52.710Z Row in collection ampMeter151: Name=BLUESEAMETER555 Amperage = 2.43 \ Count = 5 Timestamp = 2017-09-15T18:13:52.710Z
Python
ジオメトリ固有のクエリと関数を除いて、TQLはPythonとRuby APIの両方でクエリを作成するために使用できます。 たとえば、PythonでTimeseries集計を実行する組み込み関数はありませんが、TQLで発行できます。 これには、タイムサンプリング、時間平均、および補間のような時間依存のクエリおよび関数が含まれます。
PythonでのTQL時間クエリ
query = timeseries.query(“select * where timestamp > TIMESTAMPADD(HOUR,NOW(),-12)”) rowSet = query.fetch(False) while rowSet.has_next(): rowSet.get_next(row) time = row.get_field_as_timestamp(0) voltage = row.get_field_as_double(2) print(“Voltage at timestamp: {0} is {1} volts in Timeseries voltmeter2.”.format(time,voltage)
Output
Voltage at timestamp: 1505398224644 is 12.34 volts in Timeseries voltmeter2
Ruby
特定の集約関数をTQLの時間特有の関数と組み合わせることもできます。
Rubyでの集計TQLクエリ
update = false timestamp = Griddb::Timestamp.current() aggCommand = "select AVG(voltage) from voltmeter502 where timestamp > TIMESTAMPADD(MINUTE, \ TO_TIMESTAMP_MS(#{timestamp}), -10) AND timestamp < TIMESTAMPADD(MINUTE, \ TO_TIMESTAMP_MS(#{timestamp}), 10)" aggQuery = timeseries.query(aggCommand) aggRowSet = aggQuery.fetch(update) while aggRowSet.has_next() aggResult = aggRowSet.get_next_aggregation() print "Aggregation Result from voltmeter502: Average voltage = #{aggResult.get_double()}\n" end
Output
Aggregation result from voltmeter502: Average voltage = 10.5
Inserting Collection into GridDB with C API
Cでは、静的スキーマまたは動的スキーマのいずれかを使用して、コンテナのスキーマを作成してGridDBに更新できます。 静的スキーマは、構造体バインディングの形式で提供されます。 動的スキーマは、コンテナを更新または挿入するために使用できる columnInfo
および containerInfo
オブジェクトの形式で提供されます。
C-Structを使用した静的スキーマの作成
typedef struct { const GSChar* name; double amperage; int count; GSTimestamp timestamp; } Device; // Static Column Schema in GridDB C API
構造体をGridDB内のコンテナのスキーマとして使用するには、行キーを定義し、各フィールドに型を明示的に割り当てるための構造体バインディングを作成する必要があります 構造体。
Creating a Column Schema from a Struct
GS_STRUCT_BINDING(Device, GS_STRUCT_BINDING_KEY(name,GS_TYPE_STRING) GS_STRUCT_BINDING_ELEMENT(amperage,GS_TYPE_DOUBLE) GS_STRUCT_BINDING_ELEMENT(count,GS_TYPE_INTEGER) GS_STRUCT_BINDING_ELEMENT(timestamp,GS_TYPE_TIMESTAMP));
そこから構造体がバインドされ、行スキーマになったら、コンテナで使用することができます。
コンテナへの構造体バインディングスキーマの挿入
GSCollection* collection; gsPutCollection(gridstore,"ampCollection151",GS_GET_STRUCT_BINDING(Device),NULL,GS_FALSE,&collection);
そこから Device
構造体を行オブジェクトとして使用して行をフェッチして挿入できます。
Inserting a Struct as a GSRow
Device insertionDevice; insertionDevice.name = "ampMeter12"; insertionDevice.amperage = 1.45; insertionDevice.count = 3; insertionDevice.timestamp = gsCurrentTime();
Having a Struct Represent a Row Schema
Device device; while(gsHasNextRow(rowSet)){ gsGetNextRow(rowSet,&device); GSChar timeStr[GS_TIME_STRING_SIZE_MAX]; gsFormatTime(device.timestamp,timeStr,sizeof(timeStr)); printf("Device in ampCollection151: "); printf("name=%s",device.name); printf(" amperage=%.2lf",device.amperage); printf(" count=%d",device.count); printf(" timestamp=%s\n",timeStr);
アウトプット
Device in ampCollection151: name=ampMeter12 amperage=1.45 count=3 \ timestamp=2017-09-14T20:05:06.285Z
Python
PythonとRubyの両方で、スキーマを作成してコンテナを挿入するアプローチは、C APIで示した動的アプローチに似ています。 列とコンテナに名前を付け、列の種類を定義するだけです。 それらがTimeSeriesかコレクションであるかどうか、およびそれらが持つべき索引を決定します。 使用可能な列の種類は、GridDBドキュメント および APIリファレンスを参照してください。
Pythonで時系列を挿入する
timeseries = gridstore.put_container("voltmeter2",[ ("timestamp",griddb.GS_TYPE_TIMESTAMP), ("active",griddb.GS_TYPE_BOOL), ("voltage",griddb.GS_TYPE_DOUBLE) ],griddb.GS_CONTAINER_TIME_SERIES)
Pythonでは、変数の型を明示的に記述する必要がないためです。 行フィールドは、より流動的に挿入して取り込むことができます。 知る必要があるのは、列のタイプとインデックスのみです。 作成された行オブジェクトは、それが基になっているコンテナによって設定された行スキーマを持ちます。 行を挿入するには以下のようにします。
Pythonで行を挿入する
## Create rows and set all Row Fields insertionRow = timeseries.create_row() insertionRow.set_field_by_timestamp(0,griddb.Timestamp_add_time(griddb.Timestamp_current(),-6, \ griddb.GS_TIME_UNIT_HOUR)) insertionRow.set_field_by_bool(1,True) insertionRow.set_field_by_double(2, 12.34) ## Insert Row into Timeseries timeseries.put_row(insertionRow)
Ruby
同じプロセスを使用して、Rubyで Python でスキーマやコンテナを作成します。 単に列に名前を付けて型を設定し、コンテナ、コレクション、またはtimeseriesのタイプを設定します。
Rubyにコレクションを挿入する
Collection = gridstore.put_container(“collection121”,[ {“name”=>Grid db::GS_TYPE_STRING}, {“status”=>Grid db::GS_TYPE_BOOL}, {“count”=>Grid db::GS_TYPE_LONG}, {“lob”=>Grid db::GS_TYPE_BLOB } ],CONTAINER_TYPE_COLLECTION)
そこから行は、Pythonと同じ方法でフェッチ、挿入、更新できます。
Rubyでの行の取得と更新
rowSet.get_next(row) name = row.get_field_as_string(0) status = row.get_field_as_bool(1) count = row.get_field_as_long(2) + 1 lob = row.get_field_as_blob(3) print "Row in Collection: collection121, Person: name=#{name} status=#{status} count=#{count} lob=" p lob.unpack("U*") row.set_field_as_long(2,count) rowSet.update_current(row)
アウトプット
Row in Collection: collection121, Person: name=secondRow status=false \ count=6 lob=[65, 66, 67, 68, 69, 70, 71, 72, 73, 74]
上記の例からわかるように、GridDBとのやりとりは多くの言語で理解され使用されています。 これは、GridDBがどのように使いやすいAPIを介して幅広いサポートを提供するかを示しています。さまざまなアプリケーションを作成するベースとして使用できます。
Source Code
ここに表示されているすべてのコードスニペットは、サンプルプログラムから入手でき、以下のリンクからダウンロードして実行できます。 Ruby、Python、C のサンプルコードがそれぞれ一つづつあります。
api_samples.tar.gz
ブログの内容について疑問や質問がある場合は Q&A サイトである Stack Overflow に質問を投稿しましょう。 GridDB 開発者やエンジニアから速やかな回答が得られるようにするためにも "griddb" タグをつけることをお忘れなく。 https://stackoverflow.com/questions/ask?tags=griddb
[…] GridDBのCクライアントの設定とインストールに関して詳しくは、CクライアントのGithubリポジトリの README.md ファイルか、またはGridDBの様々なAPIに関するブログを参照してください。 […]
[…] システムにGo clientを構築するには、 GridDB C clientを構築し、 インストールする必要があります。 C clientの設定とテストの方法については、このブログ記事を参照してください。 […]