NodeでRealmに触れてみる(その２)

今回もNodeでrealmに触れていきます。

[前回](http://qiita.com/yamayamasan/items/86eab74bc97dcbd1ba63)は登録と取得だけだったので、今回は「削除」「更新」と「条件を指定して取得」をやります。

今回のソースは[こちら](https://github.com/yamayamasan/realm-first-sample)にあります。


### 環境

環境は[前回](http://qiita.com/yamayamasan/items/86eab74bc97dcbd1ba63)と同じです。


| module  | version |
|:---:|:----:|
| node | 6.1.0 |
| commander  | 2.9.0 |
| realm | 0.15.0 | 

### ソース(追加分)

* 新たに、roleキーを追加しています。

```js:user.js
function User() {
  if (!(this instanceof User)) return new User();
  this.schema = {
    name: 'Users',
    primaryKey: 'uuid',
    properties: {
      uuid: 'string',
      username: 'string',
      age: 'int',
      role: 'string', // 追加
      created_at: 'date'
    }
  };

  this.realm = new Realm({
    path: 'db/realm',
    schema: [this.schema]
  });
}

User.prototype.filteredRoleUser = function() {
  const datas = this.realm.objects(this.schema.name);
  return datas.filtered('role == "user"');
}

User.prototype.delete = function(object) {
  this.realm.write(() => {
    this.realm.delete(object);
  });
}

User.prototype.update = function(uuid, inputs) {
  const data = this.filtered(`uuid == '${uuid}'`);
 
  this.realm.write(() => {
    Object.keys(inputs).forEach((key) => {
      data[0][key] = inputs[key];
    });
  });
}

```

### 解説

**更新**

* トランザクション内で、プロパティに値を設定します。

```js
  const datas = this.realm.objects(this.schema.name);
  const object = data[0];
  /*
  const object = this.realm.create('Users', {});
  */
  this.realm.write(() => {
    object.age = 22;
  });
```

**削除**

* 削除はトランザクション内(write)でやります。deleteの引数にはrealmオブジェクトを指定します。今回はrealm.objectsで取得したオブジェクト（1件）を指定してますが、realm.createでオブジェクトを作成し、指定する事もできます。

```js:user.js
  const datas = this.realm.objects(this.schema.name);
  const object = data[0];
  /*
  const object = this.realm.create('Users', {});
  */
  this.realm.write(() => {
    this.realm.delete(object);
  });
```

**条件取得**

```js
User.prototype.filteredRoleUser = function() {
  const datas = this.realm.objects(this.schema.name);
  return datas.filtered('role == "user"');
}
```

* objectsで全て取得し、filteredで検索条件を指定します。

条件一覧

演算子に[c]を付加すると、大文字小文字を区別しない比較をします。
例： roler ==[c] 'R'

| 演算子| 有効な型 | 備考 | [c] |
|:------:|:------:|:------:|:----:|
| == | 数値型, 文字列 |  | ○ |
| != | 数値型 |  |  |
| > | 数値型 |  |  |
| >= | 数値型 |  |  |
| < | 数値型 |  |  |
| <= | 数値型 |  |  |
| BEGINSWITH | 文字列 | 先頭にある文字列を検索 | ○ | 
| ENDSWITH |  文字列 | 末尾にある文字列を検索 | ○ |
| CONTAINS | 文字列 | 文字列内検索 |  ○ |



### 動作確認

上記に載せた[サンプル](https://github.com/yamayamasan/realm-first-sample)を落としてきます。
※前回とは違うディレクトリに新しく落としてきました

まず、事前にデータを3件ほど登録しておきます。

```shell-session
node main.js -a "username: root, age: 45, role: admin"
node main.js -a "username: yamada, age: 25, role: user"
node main.js -a "username: tanaka, age: 27, role: user"
```

こんな感じにデータが入ってます。

```shell-session
node main.js -g
// 結果
datas: Results {
  '0': 
   RealmObject {
     uuid: 'uuid_1480061997461',
     username: 'root',
     age: 45,
     role: 'admin',
     created_at: 2016-11-25T08:19:57.462Z },
  '1': 
   RealmObject {
     uuid: 'uuid_1480062020049',
     username: 'yamada',
     age: 25,
     role: 'user',
     created_at: 2016-11-25T08:20:20.050Z },
  '2': 
   RealmObject {
     uuid: 'uuid_1480062035389',
     username: 'tanaka',
     age: 27,
     role: 'user',
     created_at: 2016-11-25T08:20:35.389Z } }
```

roleが"user"のものだけを取得します。

```shell-session
node main.js -r
// 結果
Results {
  '0': 
   RealmObject {
     uuid: 'uuid_1480062020049',
     username: 'yamada',
     age: 25,
     role: 'user',
     created_at: 2016-11-25T08:20:20.050Z },
  '1': 
   RealmObject {
     uuid: 'uuid_1480062035389',
     username: 'tanaka',
     age: 27,
     role: 'user',
     created_at: 2016-11-25T08:20:35.389Z } }
```

今度は自由に条件を指定します。

①age = 25

```shell-session
node main.js -f "age = 25"
// 結果
Results {
  '0': 
   RealmObject {
     uuid: 'uuid_1480062020049',
     username: 'yamada',
     age: 25,
     role: 'user',
     created_at: 2016-11-25T08:20:20.050Z } }
```

②age >= 27

```shell-session
node main.js -f "age >= 27
// 結果
Results {
  '0': 
   RealmObject {
     uuid: 'uuid_1480061997461',
     username: 'root',
     age: 45,
     role: 'admin',
     created_at: 2016-11-25T08:19:57.462Z },
  '1': 
   RealmObject {
     uuid: 'uuid_1480062035389',
     username: 'tanaka',
     age: 27,
     role: 'user',
     created_at: 2016-11-25T08:20:35.389Z } }
```

③role BEGINSWITH[c] 'Ro'

```shell-session
node main.js -f "username BEGINSWITH[c] 'Ro'"
// 結果
Results {
  '0': 
   RealmObject {
     uuid: 'uuid_1480061997461',
     username: 'root',
     age: 45,
     role: 'admin',
     created_at: 2016-11-25T08:19:57.462Z } }
```

**データ更新**

```shell-session
node main.js -u "uuid: uuid_1480062035389, age: 22"
```    

**データ削除**

uuidを指定削除します。

```shell-session
node main.js -d uuid_1480062020049
```

削除後に、node main.js -gで、指定したデータが消えてる事が確認できます。


### おまけ（スキーマ編）

*オプショナルプロパティ*と*デフォルト値*

* 型の宣言方法には、前回書いたように「キーにカラム名、バリューに型」で定義出来ますが
他にもあります。

* その際に、optionalをtrueに設定するとNULL可となります。
また、default値も設定できます。


```

schema = {
    name: 'Users',
    primaryKey: 'uuid',
    properties: {
      uuid: {'type': 'string'},
      username: {'type': 'string'},
      age: {'type': 'int', optional: true},
      role: {'type': 'string', default: 'user'},
      created_at: {'type': 'date'}
    }
};
```

### まとめ

またまた、雑に書いてしまいました。。。

realmには他にも、マイグレーション機能や変更通知イベントを受け取る事ができるようです。
色々できそうなので、次こそは丁寧に書こうかなと思います。