データベースシステム

Wippy は、PostgreSQL と MySQL 用の接続プール付き SQL データベースエントリ、および単一接続の SQLite エントリを提供します。

このページは設定リファレンスです。コードブロックに version、namespace、entries が含まれていない場合は、既存のエントリリスト内に配置する断片として扱ってください。

エントリ種別

種別 説明
db.sql.postgres PostgreSQL データベース
db.sql.mysql MySQL データベース
db.sql.sqlite SQLite データベース

設定

標準データベース(PostgreSQL、MySQL)

# src/data/_index.yaml
version: "1.0"
namespace: app.data

entries:
  - name: main_db
    kind: db.sql.postgres
    host: "localhost"
    port: 5432
    database: "myapp"
    username: "dbuser"
    password: ${env:app.secrets:db_password}
    pool:
      max_open: 25
      max_idle: 5
      max_lifetime: "1h"
    options:
      sslmode: "disable"
    lifecycle:
      auto_start: true

SQLite

  - name: cache_db
    kind: db.sql.sqlite
    file: "/var/data/cache.db"  # Use :memory: for in-memory
    pool:
      max_open: 4
      max_idle: 2
      max_lifetime: "1h"
    lifecycle:
      auto_start: true
プライベートなインメモリSQLiteデータベース(file: ":memory:")は1本の物理接続にスコープされるため、max_openとmax_idleは1に強制されます。ファイルベースのデータベースは設定されたpoolの値をそのまま使用します。CDCのスナップショット読み取りトランザクションが唯一のライター接続を占有しないために、これが必要です。ジャーナルモードは常にWALです。

接続フィールド

標準データベースフィールド

フィールド 型 説明
host string データベースホストのアドレス
port int データベースのポート番号
database string データベース名
username string データベースユーザー
password string データベースパスワード
pool object 接続プールの設定
options map データベース固有のオプション
lifecycle object ライフサイクル設定

SQLite フィールド

フィールド 型 デフォルト 説明
file string 必須 データベースファイルパスまたは:memory:
pool object - 接続プール設定。:memory:ではmax_openとmax_idleは1に強制される
max_mutation_changes int 100000 コミット済みミューテーションオブザーバーで1トランザクションが保持できる行数
max_mutation_bytes int 67108864 オブザーバーで1トランザクションが保持できる論理バイト数(64 MiB)
options map - 受け付けられるが無視される
lifecycle object - ライフサイクル設定

max_mutation_changesとmax_mutation_bytesは、db.cdc.sqliteソースに供給するインメモリのコミット済みミューテーションオブザーバーの上限を定めます。いずれのフィールドも0を指定するとデフォルトが選択され、負の値は拒否されます。この上限は厳密ではなく保守的なものです。SQLiteはpre-updateフックに行全体を渡すため、上限が候補を拒否する前に1行が実体化することがあります。

シークレットと環境変数の値

接続値は${env:NAME}プレースホルダで環境レジストリから取得され、デコード時に解決されます。NAMEは登録済み変数の公開名またはそのエントリID(例: app.secrets:db_password)であり、生のOS環境変数ではありません。

- name: prod_db
  kind: db.sql.postgres
  host: ${env:DB_HOST}
  port: ${env:DB_PORT}
  database: ${env:DB_NAME}
  username: ${env:DB_USER}
  password: ${env:app.secrets:db_password}
古い設定では、同じ方法で解決される兄弟の<field>_envディレクティブ(host_env、port_env、database_env、username_env、password_env)を使用します。この形式は非推奨です — 上記の${env:NAME}プレースホルダに移行してください。 設定にパスワードをハードコードしないでください。認証情報にはenv.variableエントリを使用してください。セキュアなシークレット管理については環境変数を参照してください。

接続プール

接続プールの動作を設定します。プール設定は Go の database/sql 接続プールに対応します。

フィールド 型 デフォルト 説明
max_open int 0 最大オープン接続数(0 = 無制限)
max_idle int 0 最大アイドル接続数(0 = アイドル接続を保持しない)
max_lifetime duration 1h 最大接続寿命
pool:
  max_open: 25      # Limit concurrent connections
  max_idle: 5       # Keep 5 connections ready
  max_lifetime: "30m"  # Recycle connections every 30 minutes
max_idle は max_open 以下に設定してください。max_lifetime を超えた接続は閉じられて置き換えられるため、古くなった接続からの回復に役立ちます。

DSN 形式

各データベースタイプは設定からDSNを構築します。optionsはすべて(キー順にソートして)付加されます。デフォルトで含まれるものはありません。

PostgreSQL {id="dsn-postgresql"}

host='host' port=port user='username' password='password' dbname='database' [option='value' ...]

ポート以外のすべての値はシングルクォートで囲まれ、埋め込まれた'と\はバックスラッシュでエスケープされます。そのため、スペースやクォートを含むホスト、パスワード、オプション値もそのまま渡されます。

MySQL {id="dsn-mysql"}

username:password@tcp(host:port)/database[?option=value&...]

SQLite {id="dsn-sqlite"}

file:/path/to/database.db?mode=rwc
:memory:

データベースオプション

一般的なデータベース固有のオプション:

PostgreSQL {id="options-postgresql"}

options:
  sslmode: "require"      # disable, require, verify-ca, verify-full
  connect_timeout: "10"   # Connection timeout in seconds
  application_name: "myapp"

MySQL {id="options-mysql"}

options:
  charset: "utf8mb4"
  parseTime: "true"       # Parse time values to time.Time
  loc: "Local"            # Timezone

SQLite {id="options-sqlite"}

SQLiteはoptionsマップをDSNに適用しません。ファイルデータベースは常にmode=rwcで開かれ、ジャーナルモードは常にWALに設定されます。optionsフィールドは受け付けられますが無視されます。

例

SSL を使用する PostgreSQL

- name: secure_postgres
  kind: db.sql.postgres
  host: "db.example.com"
  port: 5432
  database: "production"
  username: "app_user"
  password: ${env:app.secrets:db_password}
  pool:
    max_open: 50
    max_idle: 10
    max_lifetime: "1h"
  options:
    sslmode: "verify-full"
    sslcert: "/certs/client.crt"
    sslkey: "/certs/client.key"
    sslrootcert: "/certs/ca.crt"
  lifecycle:
    auto_start: true

MySQL 読み取りレプリカ

- name: mysql_replica
  kind: db.sql.mysql
  host: "replica.db.example.com"
  port: 3306
  database: "app"
  username: "readonly"
  password: ${env:app.secrets:replica_password}
  pool:
    max_open: 20
    max_idle: 5
    max_lifetime: "30m"
  options:
    charset: "utf8mb4"
    parseTime: "true"
    readTimeout: "30s"

SQLite インメモリ

- name: test_db
  kind: db.sql.sqlite
  file: ":memory:"

複数データベースの設定

entries:
  # Primary database
  - name: users_db
    kind: db.sql.postgres
    host: ${env:USERS_DB_HOST}
    port: 5432
    database: "users"
    username: ${env:USERS_DB_USER}
    password: ${env:app.secrets:users_db_password}
    lifecycle:
      auto_start: true

  # Analytics database
  - name: analytics_db
    kind: db.sql.mysql
    host: ${env:ANALYTICS_DB_HOST}
    port: 3306
    database: "analytics"
    username: ${env:ANALYTICS_DB_USER}
    password: ${env:app.secrets:analytics_db_password}
    lifecycle:
      auto_start: true

  # Local cache
  - name: cache
    kind: db.sql.sqlite
    file: "/var/cache/app.db"
    lifecycle:
      auto_start: true

ランタイム登録

データベースは、レジストリモジュールを使用して実行時に登録できます。

Lua API

クエリ、トランザクション、接続の操作については、SQL モジュールを参照してください。

関連項目

  • SQLモジュール - Lua APIリファレンス
  • ストア - db.sql.*データベースをバックエンドとするキーバリューストア
  • キュー - SQLバックエンドのキューハンドラ
  • 変更データキャプチャ - db.sql.sqliteまたはPostgresデータベースからの行レベル変更のストリーミング