BedrudはGORMをORMとして使用し、SQLiteとPostgreSQLの両方をサポートしています。
サポートされているデータベース
- SQLite: 開発の容易さと小規模なインストール用にデフォルトで使用されます。データベースはファイル(通常は
bedrud.db)に保存されます。 - PostgreSQL: 多くのユーザーがいる本番環境で推奨されます。
データベースの種類と接続の詳細は、config.yamlファイルのdatabase:セクションで設定できます。
SQLiteファイルレイアウト
SQLiteを使用する場合、Bedrudは同時読み取りパフォーマンスを向上させるためにWAL(Write-Ahead Log)モードを有効にします。これにより、メインのデータベースファイルと一緒に2つの追加ファイルが作成されます:
| ファイル | 目的 |
|---|---|
bedrud-local.db | メインのデータベースファイル |
bedrud-local.db-shm | 共有メモリファイル — 読み取りと書き込みのアクセスを調整 |
bedrud-local.db-wal | Write-Ahead Log — 新しい書き込みは最初にここに保存され、後でメインDBにチェックポイントされる |
これらのファイルは正常です。 サーバー起動時に自動的に作成され、正常なシャットダウン時にクリーンアップされます。サーバーがクラッシュしても、SQLiteは自動的に復旧します — データ損失はありません。
WALモードを無効にするには(推奨しません)、SQLite設定でPRAGMA journal_mode=DELETE;を設定しますが、同時読み取りが遅くなります。
コアモデル
モデルはinternal/models/に配置されています。以下は最も重要なものです:
User (user.go)
認証情報やロールを含むアカウント情報を保存します。
Room (room.go)
ミーティングセッションを表します。GORMの埋め込み構造体を使用して設定を整理しています。
別のテーブルやJSONブロブの代わりに、RoomSettingsフィールド(allow_chat、allow_videoなど)はsettings_プレフィックス(例: settings_allow_chat)付きでroomsテーブルに直接保存されます。これにより、Goではクリーンなモデルを維持しながら、フラットで高性能なデータベース構造を実現しています。
Passkey (passkey.go)
パスワードレスログイン用のFIDO2/WebAuthn公開鍵を保存します。
カスタム型: StringArray
標準SQLデータベースは配列の処理が異なります(PostgreSQLはネイティブ配列を持ち、SQLiteは持ちません)。互換性を維持するため、Bedrudはinternal/models/user.goでStringArray型を定義しています。
sql.Scannerとdriver.Valuerを実装しています。- PostgreSQLでは、ネイティブの
text[]型を使用します。 - SQLiteでは、配列を文字列(例:
{admin,user})にシリアライズして保存します。
外部キー管理
GORMのAutoMigrateは複合主キー(例: room_participants)を処理できません。
internal/database/migrations.goで、Bedrudは手動でALTER TABLEステートメントを実行し、外部キー制約(ON DELETE CASCADEなど)が本番環境(PostgreSQL)で正しく適用されるようにしています。
リポジトリパターン
バックエンドはデータベースアクセスにリポジトリパターンを使用しています。ハンドラはGORMを直接呼び出さず、リポジトリを使用します。
例:
// In handler:
user, err := h.userRepo.GetByEmail(email)
// In repository:
func (r *UserRepository) GetByEmail(email string) (*models.User, error) {
var user models.User
err := r.db.Where("email = ?", email).First(&user).Error
return &user, err
}自動マイグレーション
サーバー起動時に、自動的に「AutoMigrate」が実行されます。これにより、internal/modelsのGo構造体に基づいてデータベーステーブルが作成または更新されます。単純なスキーマ変更であれば、手動のCREATE TABLEステートメントは不要です。