Let's start Scheme

2018-06-07

パイプライン アイデア編

MongoDBバインディングの使用例を書いている際に、アクターを繋げてパイプライン的に動かすようなのを書いたのだが、これうまくやるとパターンにできないかなぁと思えてきた。

イメージとしては以下のようなブロックをつなげていくような感じ
    +==============pipeline==============+
    |                                    |
    |    +-------+          +-------+    |
==input=>| pipe1 |=success=>| pipe2 |=success=>
    |    +-------+     |    +-------+    |
    |        |         |        |        |
    |      error       |      error      |
    |        |         |        |        |
    |    +-------+     |        |        |
    |    | pipe3 |==>>=+        |        |
    |    +-------+ (success)    |        |
    |        |                  |        |
    |      error----------------+        |
    +========+===========================+
             |
pipe1は入力を受け取って処理をし、成功すればpipe2に処理したデータを渡す。失敗すればerrorに渡す。errorの接続先は別のパイプでもよく、pipe3の処理が成功すれば(例、データ変換)すればpipe2に処理を渡す。失敗すればerrorに渡す。以下同様。 っで、全体のpiplelineとしての処理はpipe同様二本のチャンネルで得る。
最終的にはpipleline同士を繋げてより大きなパイプラインにするみたいな。

パイプ、パイプラインともにアクターの亜種として定義すれば、処理ごとにアトミックになるし、必要なら同一チャンネルを使うユニットを増やすことで処理の多重化もできそう。うまく書ければ使いではありそうな感じがする。ちと考えてみるか。

2018-06-04

MongoDBバインディング

ここ数週間R6RSな処理系で動くMongoDBバインディングを作っていたのだが、なんとなくお披露目してもいいかなぁという感じの出来になってきたのでお披露目してみる。

リポジトリはここ
こんな感じで使える。
(import (rnrs)
        (mongodb))

(define connection 
  (open-mongodb-connection! (make-mongodb-connection "localhost")))
(define database (make-mongodb-database connection "test"))

(define collection "testCollection")

(mongodb-database-insert database collection
  '#(
     (("id" 1) ("name" "R6RS MongoDB library") ("lang" "Scheme")))
     )
(mongodb-database-upsert database collection
  '(("name" "R7RS PostgreSQL library"))
  '(("$set"
     (("id" 2) ("name" "R7RS PostgreSQL library") ("lang" "Scheme")))))

(mongodb-database-update database collection
  '(("id" 1))
  '(("$set" (("lang" "R6RS Scheme")))))
(mongodb-database-update-all database collection
  '(("id" (("$gt" 0))))
  '(("$set" (("comment" "Portable Scheme library")))))

(mongodb-query-for-each (lambda (doc) (write doc) (newline))
  (mongodb-database-query database collection '()))

(mongodb-database-delete-all database collection '())

(display
 (mongodb-query-result-documents
  (mongodb-database-query database collection '()))) (newline)

(close-mongodb-connection! connection)
#|
;; prints
(("_id" (object-id "5b1110aa9614bc720de985b6"))
 ("id" 1)
 ("name" "R6RS MongoDB library")
 ("lang" "R6RS Scheme")
 ("comment" "Portable Scheme library"))
(("_id" (object-id "5b1110aa9614bc720de985b8"))
 ("id" 2)
 ("name" "R7RS PostgreSQL library") 
 ("lang" "Scheme")
 ("comment" "Portable Scheme library"))
#()
|#
BSONは手で書くには不便すぎるのでSBSON(S-expr BSON)という形式で書く。SBSONはalist形式(Gauche形式)のJSONによく似ているが、型をつけれるという点とBSONである必要がる(全てがJSONでいうObject等)で多少異なる。

現状でサポートしている処理系は3つだが、以下のSRFIを両方サポートしている処理系なら動くはず:
  • SRFI-39
  • SRFI-106
 もう少しドキュメントとサンプルを足したらリリースのアナウンスをしようかなぁと思っている。

余談
このライブラリのテストにScheme Envを使っているのだが、まぁ、便利に使えている。Bashの中にサポートしている処理系のリストを作れば後は共通でやってくれるので楽である。Bash内にリストせずにインストールしている処理系に対してというのをやれると便利かなぁと思っているので、処理系のメタデータ的なものを入れるといいかもしれないと思ってきた。サポートしている仕様とか。