Let me code again...

Welcome to ijokarumawak's blog :)

N1QLのDMLステートメントの書き込みモードはどうなってるの?

Couchbase Server 4.1.0からN1QLでDMLがサポートされたけど、更新のモードってどうなってるんでしょうね。ReplicateToとか使えるのでしょうか..?

4.1の公式ドキュメントではまだBetaラベルがついている状態。ここにはそれらしきパラメータは書いてないですね。

そんな時はソースを見よう!

N1QLのステートメントはQuery Serviceが解析して実行します。Query Serviceのプロジェクト名はズバリquery。Github上に公開されています。 N1QLの各キーワードは該当する実装がalgebraパッケージにxxx.goというファイルで作成されているので探すのも簡単です。

query/algebra/insert.go、そう、実装はGo言語です!

開いてfunctionをさらーっと眺めていたら気になる物が:

/*
Returns all required privileges.
*/
func (this *Insert) Privileges() (datastore.Privileges, errors.Error) {
	privs := datastore.NewPrivileges()
	privs[this.keyspace.Namespace()+":"+this.keyspace.Keyspace()] = datastore.PRIV_WRITE
  ...
}

これは、DML実行する際に権限チェックを行えるっぽいですね。さすがに無条件でDELETEされるようなことは起こってほしくないですから。でも今までBucketにはパスワードしか付けられなくて、接続するユーザの概念すらなかったのに、どうやって実装しているんでしょう。気になりますねー。このへんはまた次回!

今日はData Serviceにドキュメント挿入のリクエストを投げてるところを見つけるのがテーマでした。

insert.goはステートメントのinsert句を表現するオブジェクトで、ここにはあまり脳みそはないみたい。次行ってみよー。

Insertを使ってる箇所を検索してみると、

  • execution/insert_send.go
  • execution/visitor.go
  • plan/insert.go
  • plan/visitor.go

などがありました。algebra/insert.goではVisitorパターンの実装が入ってたので、visitor.goのあたりは複数命令の制御、単体のKVアクセスはinsert_send.goに記述されているような感じでしょうか。全く見てないからまだ何ともいえませんが。

planとかplannerというパッケージもあって、ここで実行計画を立てているのでしょう。これもまた別の機会に。

重要なことやってそうなexecution/insert_send.goを見てみましょう。

実装しているのはflushBatchというfunctionでしょう。

func (this *SendInsert) flushBatch(context *Context) bool { … }

名前から複数アイテムをバッチ形式でまとめて更新していることがわかりますが、どんな単位で実行しているのかは今回は深追いしません。

// Perform the actual INSERT
keys, e := this.plan.Keyspace().Insert(dpairs)

this.plan.Keyspace()はSendInsertのkeyspaceで、datastore.Keyspace型。

datastoreパッケージ見てたら、privilege.goとかあるー。みたいけど今回は我慢。。

datastore.goをみてみましょう。ん、Keyspaceはinterface。Goのinterfaceってimplementって書かなくて良いらしく、同一シグネチャの関数を実装していればそのinterfaceとして扱えるということみたい。こいつの実装はどこやねん!

plannerパッケージのbuild.goにそれらしき、namespace.KeyspaceByName(node.Keyspace())の記述が。

なるほどー。datastoreパッケージにはcouchbaseやfile、mockなど実際のdatastoreを切り替えられるようにしているのですな。 couchbaseパッケージのcouchbase.goに、insertありました。

var added bool
// add the key to the backend
added, err = b.cbbucket.Add(key, 0, val)

残念、ReplicateToとかのオプションは指定できない様子!今日のところはここで終わりますが、またの機会にもうちょい見てみたいですね。何かデフォルトのオプションとか隠れてるのかな。。。?