環境
- Opa compiler (c) MLstate -- version 1.1.1 -- build 4308
- MongoDB v2.6.0
方法
簡単なコードを書いてDBにデータを格納し、mongo クライアントから
結果を確認する。
simple
type x =
{
int foo,
string bar,
float baz,
bool hoge,
void fuga
}
database dbtest {
x /xs[{foo}]
/xs[_]/hoge = { false }
}
/dbtest/xs[{foo: 1}] <- {bar: "hello", baz: 3.14, hoge: true, fuga: {}}
> db.xs.find()
{
"_id" : ObjectId("539f3e9d68a84ebe3504cd4e"),
"foo" : NumberLong(1),
"bar" : "hello",
"hoge" : true,
"baz" : 3.14
}
- なんか bool のフィールドにはデフォルト値を設定しないとコンパイラに怒られた。
- えっ、void は入らないの?
- それ以外はフツー。
tuple
type x =
{
int foo,
(string, int) bar
}
database dbtest {
x /xs[{foo}]
}
/dbtest/xs[{foo: 1}] <- {bar: ("hello", 3)}
> db.xs.find()
{
"_id" : ObjectId("539f3e9d68a84ebe3504cd4e"),
"foo" : NumberLong(1),
"bar" : {
"f2" : NumberLong(3),
"f1" : "hello"
}
}
- タプルは自動的に "f1", "f2", ... というプロパティが作られて入る。
variant
type s = {Foo} or {int Bar} or {string Xyz} or {(int, string) Blah}
type x = {
s foo,
s bar
}
database dbtest {
x /xs[{foo}]
}
/dbtest/xs[{foo: {Foo}}] <- {bar: {Bar: 1}}
/dbtest/xs[{foo: {Xyz: "aaa"}}] <- {bar: {Blah: (3, "hoge")}}
> db.xs.find()
{
"_id" : ObjectId("539f524468a84ebe3504cd53"),
"foo" : {
"Foo" : null
},
"bar" : {
"Bar" : NumberLong(1)
}
}
{
"_id" : ObjectId("539f524468a84ebe3504cd54"),
"foo" : {
"Xyz" : "aaa"
},
"bar" : {
"Blah" : {
"f2" : "hoge",
"f1" : NumberLong(3)
}
}
}
- コンストラクタ名がオブジェクトのプロパティ名となる。
-
https://github.com/MLstate/opalang/wiki/The-type-system に "type color = { Red } or { Green } or { Blue } defines color as a sum with three cases, each of them implicitly of type void." と書かれているので、
"Foo" : null
は納得。
option
type x = {
int foo,
option(int) bar
}
database dbtest {
x /xs[{foo}]
}
/dbtest/xs[{foo: 1}] <- {bar: {some: 1} }
/dbtest/xs[{foo: 2}] <- {bar: {none} }
> db.xs.find()
{
"_id" : ObjectId("53a04f9568a84ebe3504cd67"),
"foo" : NumberLong(1),
"bar" : {
"some" : NumberLong(1)
}
}
{
"_id" : ObjectId("53a04f9568a84ebe3504cd68"),
"foo" : NumberLong(2),
"bar" : {
"none" : null
}
}
- option も variant として定義されてるだけなので、当然の結果ですねー。
foreign
type t = {
string foo,
int bar
}
type x = {
t first,
t second,
int third
}
database dbtest {
t /ts[{foo}]
x /xs[{first, second}]
}
s1 = {foo: "hello", bar: 100}
s2 = {foo: "world", bar: 200}
/dbtest/ts[{foo: "hello"}] <- s1
/dbtest/ts[{foo: "world"}] <- s2
/dbtest/xs[{first: s1, second: s2}] <- {third: 111}
> db.ts.find()
{
"_id" : ObjectId("539f563168a84ebe3504cd57"),
"foo" : "hello",
"bar" : NumberLong(100)
}
{
"_id" : ObjectId("539f563168a84ebe3504cd58"),
"foo" : "world",
"bar" : NumberLong(200)
}
> db.xs.find()
{
"_id" : ObjectId("539f563168a84ebe3504cd59"),
"first" : {
"foo" : "hello",
"bar" : NumberLong(100)
},
"second" : {
"foo" : "world",
"bar" : NumberLong(200)
},
"third" : NumberLong(111)
}
- _id で参照する形にはならず、first にも second にも展開されたオブジェクトがそのまま入ってます。
list
type x = {
int foo,
list(int) bar
}
database dbtest {
x /xs[{foo}]
}
/dbtest/xs[{foo: 1}] <- {bar: [1]}
/dbtest/xs[{foo: 2}] <- {bar: [1, 2, 3]}
/dbtest/xs[{foo: 3}] <- {bar: []}
> db.xs.find()
{
"_id" : ObjectId("53a046dd68a84ebe3504cd5e"),
"foo" : NumberLong(1),
"bar" : [
NumberLong(1)
]
}
{
"_id" : ObjectId("53a046dd68a84ebe3504cd5f"),
"foo" : NumberLong(2),
"bar" : [
NumberLong(3),
NumberLong(2),
NumberLong(1)
]
}
{
"_id" : ObjectId("53a046dd68a84ebe3504cd60"),
"foo" : NumberLong(3),
"bar" : [ ]
}
- list は配列として入る。
- [1, 2, 3] が NumberLong(3), NumberLong(2), NumberLong(1) の順序で入っているがなんだこれは?
- 空は空配列として入る。
map
type x = {
int foo,
map(string, float) bar
}
database dbtest {
x /xs[{foo}]
}
/dbtest/xs[{foo: 1}] <- {bar: Map.From.assoc_list([("pi", 3.14), ("e", 2.72)])}
> db.xs.find()
{
"_id" : ObjectId("53a049e068a84ebe3504cd62"),
"foo" : NumberLong(1),
"bar" : {
""pi"" : 3.14,
""e"" : 2.72
}
}
- map は object として入る。が、キーが文字列のときは二重にクォートされるんだな。
set
type x = {
int foo,
intset bar
}
database dbtest {
x /xs[{foo}]
}
/dbtest/xs[{foo: 1}] <- {bar: Set.From.list([1, 3, 1, 5])}
> db.xs.find()
{
"_id" : ObjectId("53a0538968a84ebe3504cd6e"),
"foo" : NumberLong(1),
"bar" : {
"5" : null,
"3" : null,
"1" : null
}
}
- set は value が null の map なのだな。
xhtml
type x = {
int foo,
xhtml bar
}
database dbtest {
x /xs[{foo}]
}
/dbtest/xs[{foo: 1}] <- {bar: <p>Hello</p>}
$ make run
### Building executable dbtest.exe
opa --opx-dir _build --import-package stdlib.database.mongo --conf opa.conf --conf-opa-files -o dbtest.exe --build-dir _build/dbtest.exe
Error: File "src/model.opa", line 7, characters 1-34, (7:1-9:1 | 39-72)
Elements of type Dom.event -> void cannot be stored in the database
make: *** [dbtest.exe] Error 1
- ほほーぅ。xhtml 型は DB には入れられない。というか、function 型がダメ?
function
type x = {
int foo,
(int -> int) bar
}
database dbtest {
x /xs[{foo}]
}
/dbtest/xs[{foo: 1}] <- {bar: function (x) { x * 2 } }
$ make run
### Building executable dbtest.exe
opa --opx-dir _build --import-package stdlib.database.mongo --conf opa.conf --conf-opa-files -o dbtest.exe --build-dir _build/dbtest.exe
Error: File "src/model.opa", line 7, characters 1-35, (7:1-10:1 | 46-80)
Elements of type int -> int cannot be stored in the database
make: *** [dbtest.exe] Error 1
- やはり関数はダメ、と。
以上、だいたいこんなもんですかね。