Realm基本操作

## CREATE TABLE
一般的なRDBではCREATE TABLE文でテーブルを物理的に作成しますが、Realmではモデルクラスを定義するだけで自動でテーブルが作成されます。
ここではたとえばこんなCREATE TABLEを想定します。

```sql
CREATE TABLE MyticketEntity (
  myticketNo varchar(n) PRIMARY KEY,
  ticketInfoKindAmountTitle varchar(n) DEFAULT 'no name'
)
```
 
RealmでのテーブルはRLMObjectクラスを継承したモデルクラスを定義し、列カラムをプロパティで定義します。

```objc
@interface MyticketEntity: RLMObject
  @property (nonatomic, retain) NSString *myticketNo;
  @property (nonatomic, retain) NSString *ticketInfoKindAmountTitle;
@end
 
@implementation MyticketEntity
  //プライマリキーはprimaryKey()メソッドをオーバライドし、対象カラムを文字列で返します。
  + (NSString *)primaryKey {
    return @"myticketNo";
  }
@end
```

## SELECT
レコードの取得です。プライマリキーで単一レコードを取得する場合はコンストラクタでプライマリキーの値を指定します。
（但しプライマリキーが設定されている場合のみ）

```objc
MyticketEntity *myticket = [MyticketEntity objectForPrimaryKey:@1];
```
 
複数レコードの取得には条件文としてNSPredicateでのクエリが記述可能です。
取得結果はRLMResultという独自の型インスタンスが返されますが、NSFastEnumerationプロトコルに準拠しているのでArrayと同等に扱えます。

```objc
//保存する暗号化Realmを取得する
RLMRealm *realm = [[TBDatabaseManager manager] getEncryptedRealmDb];
 
//対象の取得
RLMResults *allPerformancesForDelete = [PerformanceEntity objectsInRealm:realm where:@"deleteFlag =%@", @YES];
//保存する暗号化Realmを取得する
RLMRealm *realm = [[TBDatabaseManager manager] getEncryptedRealmDb];

//NSPredicateで条件文指定
NSPredicate *pred = [NSPredicate predicateWithFormat:@"deleteFlag =%@", @YES];
//対象の取得(対象となるRealmDBとNSPredicateを指定する)
RLMResults *allPerformancesForDelete = [MyticketEntity objectsInRealm:realm withPredicate:pred];
```

## INSERT
基本的な流れは下記の通りです。
オブジェクトを作成する
DBManagerの追加・更新メソッドにオブジェクトを投げる
(writeOrUpdateObjectメソッドの中でRealm内のプライマリキーの値の有無に応じて、追加か更新かを判別して処理を行います) 
 
```objc
//オブジェクトを作成する
MyticketEntity *myticket = [[MyticketEntity alloc] init]
myticket.key = @"aaaaaa";
myticket.name = @"太郎"; 
 
//DBManagerの追加・更新メソッドにオブジェクトを投げる
[[TBDatabaseManager manager] writeOrUpdateObject:myticketEntity];
```

もし、何らかの理由でDBManagerにメソッドを投げられない場合はそのままトランザクションを書くことも可能です。
ただし、 writeOrUpdateObjectメソッドの中で記載しているコードを書く分、長くなります。
その場合の流れは 
オブジェクトを作成する
保存するRealmを取得する
トランザクションを開始する
追加更新処理を行う
トランザクションを終了する

```objc
//オブジェクトを作成する
MyticketEntity *myticket = [[MyticketEntity alloc] init]
myticket.key = @"aaaaaa";
myticket.name = @"太郎"; 
 
//保存する暗号化Realmを取得する
RLMRealm *realm = [[TBDatabaseManager manager] getEncryptedRealmDb];
// トランザクションの開始
[realm beginWriteTransaction];

//追加更新処理を行う
[realm addOrUpdateObject:myticket];
// トランザクションの終了
[realm commitWriteTransaction];
```
 
また、トランザクションブロックを作成し、下記のようの記述することも可能です。
オブジェクトを作成する
保存するRealmを取得する
トランザクションブロックを作る
ブロック内で追加更新処理を行う

```
//オブジェクトを作成する
MyticketEntity *myticket = [[MyticketEntity alloc] init]
myticket.key = @"aaaaaa";
myticket.name = @"太郎"; 
 
//保存する暗号化Realmを取得する
RLMRealm *realm = [[TBDatabaseManager manager] getEncryptedRealmDb];
 
//トランザクションブロックを作る
[realm transactionWithBlock:^{
  //追加更新処理を行う
  [realm addOrUpdateObject:myticket]; 
}];
```
 
## UPDATE
UPDATE はモデルオブジェクトのプロパティを上書きするだけです。INSERT同様にトランザクションブロック内である必要があります。
SELECTの章とINSERTの章を組み合わせたような記述になります。 
保存するRealmを取得する
対象の取得(読み出し)
トランザクション張る
更新する
トランザクション外す

```
//保存する暗号化Realmを取得する
RLMRealm *realm = [[TBDatabaseManager manager] getEncryptedRealmDb];
 
//対象の取得
RLMResults *allPerformancesForDelete = [PerformanceEntity objectsInRealm:realm where:@"deleteFlag =%@", @YES];
RLMResults *allMyticketsForDelete = [MyticketEntity objectsInRealm:realm where:@"deleteFlag =%@", @YES];

//トランザクションを張る
[realm beginWriteTransaction];
 
//更新する
[allPerformancesForDelete setValue:@"NO" forKeyPath:@"deleteFlag"];
[allMyticketsForDelete setValue:@"NO" forKeyPath:@"deleteFlag"];

//トランザクションを外す
[realm commitWriteTransaction];
```
 
下記のようにトランザクションブロックで更新もOK
保存するRealmを取得する
対象の取得(読み出し)
トランザクションブロック作る
ブロック内で更新する

```objc
//保存する暗号化Realmを取得する
RLMRealm *realm = [[TBDatabaseManager manager] getEncryptedRealmDb];
 
//対象の取得
RLMResults *allPerformancesForDelete = [PerformanceEntity objectsInRealm:realm where:@"deleteFlag =%@", @YES];
RLMResults *allMyticketsForDelete = [MyticketEntity objectsInRealm:realm where:@"deleteFlag =%@", @YES];
 
//トランザクションブロックを作る
[realm transactionWithBlock:^{
  //更新する
  [allPerformancesForDelete setValue:@"NO" forKeyPath:@"deleteFlag"];
  [allMyticketsForDelete setValue:@"NO" forKeyPath:@"deleteFlag"];
}];
```

## DELETE
ほぼUPDATEと同様です。 
保存するRealmを取得する
対象の取得(読み出し)
トランザクション張る
削除する
トランザクション外す

```objc
//保存する暗号化Realmを取得する
RLMRealm *realm = [[TBDatabaseManager manager] getEncryptedRealmDb];
 
//対象の取得
RLMResults *allPerformancesForDelete = [PerformanceEntity objectsInRealm:realm where:@"deleteFlag =%@", @YES];
RLMResults *allMyticketsForDelete = [MyticketEntity objectsInRealm:realm where:@"deleteFlag =%@", @YES];

//トランザクションを張る
[realm beginWriteTransaction];
 
  //更新する
  [realm deleteObjects:allPerformancesForDelete];
  [realm deleteObjects:allMyticketsForDelete];

//トランザクションを外す
[realm commitWriteTransaction];
```

もしくは
保存するRealmを取得する
対象の取得(読み出し)
トランザクションブロック作る
ブロック内で削除する

```objc
//保存する暗号化Realmを取得する
RLMRealm *realm = [[TBDatabaseManager manager] getEncryptedRealmDb];
 
//対象の取得
RLMResults *allPerformancesForDelete = [PerformanceEntity objectsInRealm:realm where:@"deleteFlag =%@", @YES];
RLMResults *allMyticketsForDelete = [MyticketEntity objectsInRealm:realm where:@"deleteFlag =%@", @YES];
 
//トランザクションブロックを作る
[realm transactionWithBlock:^{
  //更新する
  [realm deleteObjects:allPerformancesForDelete];
  [realm deleteObjects:allMyticketsForDelete];
}];
```