モデルとデータベース
TubePress のデータ層について解説します。モデルクラス、PDO Database ヘルパー、プリペアドステートメント、データベーススキーマ、そしてバージョン管理された SQL マイグレーションを説明します。
TubePressはMySQL/MariaDBとの通信に2つの薄いレイヤーを使用します:モデル(エンティティごとに1つのスタティッククラス)とDatabaseヘルパー(PDOの小さなラッパー)。ORMもクエリビルダーも学ぶ必要はありません — プリペアドステートメントと予測可能なメソッド名だけです。
モデルレイヤー
各コアエンティティにはsrc/Models/にスタティックメソッドを公開するモデルがあります。利用可能なモデルはVideo、Category、Tag、Performer、Channel、Comment、Page、User、Setting、Favorite、History、Report、ContactMessage、MenuConfig、FooterConfigです。
$video = Video::find($id); // one row (or null)
$latest = Video::all(['status' => 'published', 'limit' => 20]);
$id = Video::create($data); // returns new id
Video::update($id, ['title' => 'New title']);
Video::delete($id);モデルはエンティティ固有の結合とフィルターをカプセル化します — たとえばVideo::find()はカテゴリー、タグ、パフォーマー、チャンネルを含んだビデオを返すため、コントローラーとテンプレートをシンプルに保てます。
Databaseヘルパー
モデルがカバーしていない処理には、Databaseヘルパーを直接使用してください。すべてのメソッドはプリペアドステートメントを使用します — ユーザー入力をSQLに直接連結しないでください。
| メソッド | 戻り値 | 目的 |
|---|---|---|
Database::fetchOne($sql, $params) | array|null | 最初に一致する行。 |
Database::fetchAll($sql, $params) | array | 一致するすべての行。 |
Database::insert($table, $data) | int | 連想配列を挿入し、新しいidを返します。 |
Database::update($table, $data, $where, $whereParams) | int | 更新し、影響を受けた行数を返します。 |
Database::delete($table, $where, $params) | int | 削除し、影響を受けた行数を返します。 |
Database::count($table, $where, $params) | int | 行数。 |
Database::query($sql, $params) | PDOStatement | 任意のステートメント(完全な制御に使用)。 |
Database::transaction($callback) | mixed | クロージャーをトランザクション内で実行します(自動コミット/ロールバック)。 |
$rows = Database::fetchAll(
"SELECT * FROM videos WHERE status = ? ORDER BY id DESC LIMIT ?",
['published', 20]
);
$newId = Database::insert('categories', [
'name' => 'Amateur',
'slug' => 'amateur',
]);utf8mb4、実際のプリペアドステートメント(エミュレーションなし)、例外エラーモードを使用し、真の「server has gone away」エラー発生時には自動的に一度再接続します — これにより長時間実行されるワーカーがMySQLのアイドルタイムアウト後も動作し続けます。トランザクション
複数ステップの書き込みをすべて成功するかすべてロールバックするようにラップします:
Database::transaction(function () use ($videoId, $catIds) {
Database::delete('video_categories', 'video_id = ?', [$videoId]);
foreach ($catIds as $cid) {
Database::insert('video_categories', [
'video_id' => $videoId, 'category_id' => $cid,
]);
}
});スキーマ
データベースはクリーンで正規化されたMySQLスキーマを使用します。コアテーブルにはusers、settings、categories、tags、performers、channels、videosと結合テーブルvideo_categories、video_tags、video_performersが含まれます — さらにcomments、user_favorites、user_history、video_likes、pages、plugins、themes、migrationsも含まれます。オプションのサブシステムは有効化すると独自のテーブルを追加します(インポートジョブ、メディアストレージ、トランスコードジョブ/サーバー、広告ゾーン/スポット、レポート、フィードソース、翻訳テーブルなど)。
マイグレーション
スキーマの変更はsql/に番号付きファイルとして存在します — 001_users.sql、002_settings.sql、… — インストール時および各更新後にMigrator::run()によって順番に適用されます。各マイグレーションは追加的でmigrationsテーブルに記録されるため、二度実行されることはありません。
- プラグインからスキーマを拡張するには、
CREATE TABLEステートメントをプラグインのinstall()メソッドで実行してください(Hooks & pluginsを参照)。 - 適用済みのマイグレーションの番号を変更したり編集したりしないでください — より大きな番号の新しいマイグレーションを追加してください。
モデルの作成
モデルは1つのテーブルに対してDatabaseヘルパーをラップするスタティッククラスです:
class Promo
{
public static function current(): ?array
{
return Database::fetchOne(
"SELECT * FROM promos WHERE active = 1
ORDER BY id DESC LIMIT 1"
);
}
}