Ground Sunlight

Windowsで作る - PHPプログラミングの開発環境

ユーザ用ツール

サイト用ツール


apricot:app:db-model

差分

このページの2つのバージョン間の差分を表示します。

この比較画面にリンクする

両方とも前のリビジョン 前のリビジョン
次のリビジョン
前のリビジョン
apricot:app:db-model [2020/05/11 21:05]
y2sunlight [テスト実行]
apricot:app:db-model [2020/05/23 14:58] (現在)
y2sunlight [モデルクラス]
行 1: 行 1:
->編集中 
- 
------ 
- 
 ====== Apricot データベースとモデル ====== ====== Apricot データベースとモデル ======
  --- //[[http://www.y2sunlight.com|y2sunlight]] 2020-05-06//  --- //[[http://www.y2sunlight.com|y2sunlight]] 2020-05-06//
行 18: 行 14:
     * Apricot データベースとモデル     * Apricot データベースとモデル
     * [[apricot:app:user-list|Apricot ユーザ一覧画面]]     * [[apricot:app:user-list|Apricot ユーザ一覧画面]]
-    * [[apricot:app:user-edit|Apricot ユーザ編集画面]]+    * [[apricot:app:user-edit|Apricot ユーザ登録画面]]
     * [[apricot:app:validation|Apricot バリデーション]]     * [[apricot:app:validation|Apricot バリデーション]]
     * [[apricot:app:transaction|Apricot トランザクション]]     * [[apricot:app:transaction|Apricot トランザクション]]
-  * [[apricot:ext:top|Apricot 拡張]]+  * [[apricot:ext:middleware|Apricot 拡張]]
  
 \\ \\
行 258: 行 254:
 ===== テスト実行 ===== ===== テスト実行 =====
  
-データベースファイル(apricot.sqlite)を作ってみましょう。 +データベースファイル(apricot.sqlite)を作ってみましょう。ブラウザ上で以下のURLにアクセス、Apricotのホーム画面を表示して下さい。
- +
-ブラウザ上で以下のURLにアクセス、Apricotのホーム画面を表示して下さい。+
  
 <code> <code>
行 266: 行 260:
 </code> </code>
  
-まだユーザ登録機能を実装していないので、ユーザテーブルの内容を見る事はできませんが、以下の場所にデータベースファイルが作成されていることを確認して下さい。+まだユーザ登録機能を実装していないので、アプリからユーザテーブルの内容を見る事はできませんが、以下の場所にデータベースファイルが作成されていることを確認して下さい。
  
 {{fa>file-o}} ** /apricot/var/db/apricot.sqlite ** {{fa>file-o}} ** /apricot/var/db/apricot.sqlite **
行 297: 行 291:
  
 ===== モデルクラス ===== ===== モデルクラス =====
->TODO+ 
 +ORマッパーが使えるようになったので、モデルのベースクラス( Model )を作ります。Modelクラスは必ず継承して使い、以下のメソッドを持ちます。詳しくはソースコードを参照して下さい。 
 + 
 +^メソッド名^機能^ 
 +|tableName()\\ :string|テーブル名の取得\\ テーブル名(snake_case)はクラス名(UpperCamelCase)から自動判定します。| 
 +|for_table()\\ :ORM|ORMオブジェクトの取得| 
 +|findAll()\\ :array|全件検索\\ ORMの配列を返します。| 
 +|findOne\\ (int $id):mixed|主キー検索\\ 見つかった場合は ORM を、それ以外は false を返します。| 
 +|create\\ (array $inputs=null):ORM|モデルの新規作成| 
 +|insert\\ (array $inputs):ORM|レコードの挿入| 
 +|update\\ ($id, array $inputs):ORM|レコードの更新\\ レコードが存在しない時、ApplicationExceptionが発生します。\\ 楽観的ロック例外を検知した時、OptimissticLockExceptionが発生します。| 
 +|delete\\ ($id):ORM|レコードの削除\\ レコードが存在しない時、ApplicationExceptionが発生します。| 
 +|isSuccess()\\ :bool|最新の更新結果を取得します(insert/update/delete)| 
 + 
 +ソースコードを以下に示します。 
 + 
 +{{fa>folder-open-o}} ** /apricot/app/Foundation ** 
 +<code php Model.php> 
 +<?php 
 +namespace App\Foundation; 
 + 
 +use ORM; 
 +use App\Exceptions\OptimissticLockException; 
 +use App\Exceptions\ApplicationException; 
 + 
 +/** 
 + * モデル 
 + */ 
 +class Model 
 +
 +    /** 
 +     * 最新の更新結果(insert/update/delete) 
 +     * @var bool 
 +     */ 
 +    private $success = false; 
 + 
 +    /** 
 +     * テーブル名の取得 
 +     * @return string 
 +     */ 
 +    public function tableName():string 
 +    { 
 +        return snake_case(get_short_class_name($this)); 
 +    } 
 +     
 +    /** 
 +     * テーブルの取得 
 +     * @return \ORM 
 +     */ 
 +    public function for_table():ORM 
 +    { 
 +        return ORM::for_table(snake_case(get_short_class_name($this))); 
 +    } 
 + 
 +    /** 
 +     * 全件検索 
 +     * @return array|\IdiormResultSet 
 +     */ 
 +    public function findAll() 
 +    { 
 +        return $this->for_table()->find_many(); 
 +    } 
 + 
 +    /** 
 +     * 主キー検索 
 +     * @param int $id 
 +     * @return \ORM|false returna single instance of the ORM class, or false if norows were returned. 
 +     */ 
 +    public function findOne(int $id) 
 +    { 
 +        return $this->for_table()->find_one($id); 
 +    } 
 + 
 +    /** 
 +     * 新規作成 
 +     * @return \ORM 
 +     */ 
 +    public function create(array $inputs=null):ORM 
 +    { 
 +        return $this->for_table()->create($inputs); 
 +    } 
 + 
 +    /** 
 +     * 新規保存 
 +     * @param array $inputs 
 +     * @return \ORM 
 +     */ 
 +    public function insert(array $inputs):ORM 
 +    { 
 +        $row = $this->for_table()->create($inputs); 
 +        $row->set_expr('created_at', "datetime('now','localtime')"); 
 +        $row->set_expr('updated_at', "datetime('now','localtime')"); 
 +        $this->success = $row->save(); 
 +        return $row; 
 +    } 
 + 
 +    /** 
 +     * データ更新 
 +     * @param mixed $id 
 +     * @param array $inputs 
 +     * @return \ORM 
 +     */ 
 +    public function update($id, array $inputs):ORM 
 +    { 
 +        // ApricotではSQLite3.0.8以上の使用を前提としており、トランザクション分離レベルはデフォルト値がDEFERREDです。 
 +        // DEFERRED は最初の読み取り時に共有ロックが掛かります(SQLiteのロックはデータベースロックです)。 
 +        // 従って、version_no読み取り後はトランザクション終了まで他の更新は発生しません。 
 +        // NOTE: 他のデータベースの場合は、ここで行ロックを取得してレコードの検索を行います(select for update) 
 +        $row = $this->for_table()->find_one($id); 
 +        if ($row===false) 
 +        { 
 +            throw new ApplicationException(__('messages.error.db.update')); 
 +        } 
 + 
 +        // 楽観的ロックの検証 
 +        if ($row->version_no != $inputs['version_no']) 
 +        { 
 +            throw new OptimissticLockException(); 
 +        } 
 + 
 +        // データ更新 
 +        $row->set($inputs); 
 +        $row->set_expr('updated_at', "datetime('now','localtime')"); 
 +        $row->set_expr('version_no', "version_no+1"); 
 +        $this->success = $row->save(); 
 +        return $row; 
 +    } 
 + 
 +    /** 
 +     * データ削除 
 +     * @param mixed $id 
 +     * @return \ORM 
 +     */ 
 +    public function delete($id):ORM 
 +    { 
 +        $row = $this->for_table()->find_one($id); 
 +        if ($row===false) 
 +        { 
 +            throw new ApplicationException(__('messages.error.db.delete')); 
 +        } 
 +        $this->success = $row->delete(); 
 +        return $row; 
 +    } 
 + 
 +    /** 
 +     * 最新の更新結果の取得(insert/update/delete) 
 +     * @return bool 
 +     */ 
 +    public function isSuccess():bool 
 +    { 
 +        return $this->success; 
 +    } 
 +
 +</code> 
 + 
 +ORMオブジェクトについては、以下のIdiormのドキュメントを参照して下さい: 
 + 
 +  * https://idiorm.readthedocs.io/en/latest/
  
 \\ \\
  
apricot/app/db-model.1589198719.txt.gz · 最終更新: 2020/05/11 21:05 by y2sunlight