メインコンテンツまでスキップ

データベース API

データベース接続とクエリのヘルパーは ptool.dbp.db にあります。

ptool.db.connect

v0.1.0 - Introduced.

ptool.db.connect(url_or_options) はデータベース接続を開き、 Connection オブジェクトを返します。

サポートされるデータベース:

  • SQLite
  • PostgreSQL
  • MySQL

引数:

  • url_or_options (string|table, 必須):
    • 文字列が渡された場合は、データベース URL として扱われます。
    • テーブルが渡された場合、現在サポートされるのは次のとおりです:
      • url (string, 必須): データベース URL。

サポートされる URL の例:

local sqlite_db = ptool.db.connect("sqlite:test.db")
local pg_db = ptool.db.connect("postgres://user:pass@localhost/app")
local mysql_db = ptool.db.connect("mysql://user:pass@localhost/app")

SQLite に関する注意:

  • sqlite:test.dbsqlite://test.db がサポートされます。
  • 相対 SQLite パスは現在の ptool ランタイムディレクトリから解決される ため、ptool.cd(...) に従います。
  • mode= クエリパラメータが指定されていない場合、SQLite 接続のデフォルト は mode=rwc で、データベースファイルの自動作成が可能です。

例:

ptool.cd("workdir")
local db = ptool.db.connect({
url = "sqlite:data/app.db",
})

Connection

v0.1.0 - Introduced.

Connectionptool.db.connect() が返す開かれたデータベース接続を 表します。

これは Lua userdata として実装されています。

メソッド:

  • db:query(sql, params?) -> table
  • db:query_one(sql, params?) -> table|nil
  • db:scalar(sql, params?) -> boolean|integer|number|string|nil
  • db:execute(sql, params?) -> table
  • db:transaction(fn) -> any
  • db:close() -> nil

パラメータバインディング:

  • params は任意です。
  • params が配列テーブルの場合は位置パラメータとして扱われ、 SQL プレースホルダーには ? を使います。
  • params がキーと値のテーブルの場合は名前付きパラメータとして扱われ、 SQL プレースホルダーには :name を使います。
  • 位置パラメータと名前付きパラメータは同じ呼び出し内で混在できません。
  • サポートされるパラメータ値の型:
    • boolean
    • integer
    • number
    • string
  • v0.1.0 では、バインドパラメータとして nil はサポートされません。

戻り値のルール:

  • クエリ結果で保証される Lua 値型は次のものだけです:
    • boolean
    • integer
    • number
    • string
    • nil (SQL NULL 用)
  • テキスト列は Lua 文字列として返されます。
  • バイナリ/blob 列も Lua 文字列として返されます。
  • クエリ結果に重複した列名が含まれる場合はエラーになります。AS などの SQL エイリアスで区別してください。

query

v0.1.0 - Introduced.

Canonical API name: ptool.db.Connection:query.

db:query(sql, params?) はクエリを実行し、次を持つテーブルを返します:

  • rows (table): 行テーブルの配列。
  • columns (table): 列名の配列。
  • row_count (integer): 返された行数。

例:

local db = ptool.db.connect("sqlite:test.db")

db:execute("create table users (id integer primary key, name text)")
db:execute("insert into users(name) values (?)", {"alice"})
db:execute("insert into users(name) values (:name)", { name = "bob" })

local res = db:query("select id, name from users order by id")
print(res.row_count)
print(res.columns[1], res.columns[2])
print(res.rows[1].name)
print(res.rows[2].name)

query_one

v0.1.0 - Introduced.

Canonical API name: ptool.db.Connection:query_one.

db:query_one(sql, params?) は最初の 1 行をテーブルとして返します。 クエリ結果が 0 行なら nil を返します。

例:

local row = db:query_one("select id, name from users where name = ?", {"alice"})
if row then
print(row.id, row.name)
end

scalar

v0.1.0 - Introduced.

Canonical API name: ptool.db.Connection:scalar.

db:scalar(sql, params?) は最初の行の最初の列を返します。クエリ結果が 0 行なら nil を返します。

例:

local count = db:scalar("select count(*) from users")
print(count)

execute

v0.1.0 - Introduced.

Canonical API name: ptool.db.Connection:execute.

db:execute(sql, params?) は文を実行し、次を持つテーブルを返します:

  • rows_affected (integer): 影響を受けた行数。

例:

local res = db:execute("update users set name = ? where id = ?", {"alice-2", 1})
print(res.rows_affected)

transaction

v0.1.0 - Introduced.

Canonical API name: ptool.db.Connection:transaction.

db:transaction(fn) はデータベーストランザクション内で fn(tx) を 実行します。

挙動:

  • fn(tx) が正常に返れば、トランザクションはコミットされます。
  • fn(tx) がエラーを投げると、トランザクションはロールバックされ、 そのエラーが再送出されます。
  • ネストしたトランザクションはサポートされません。
  • コールバックが有効な間は外側の接続オブジェクトを使ってはいけません。 代わりに渡された tx オブジェクトを使ってください。

tx オブジェクトは Connection と同じクエリメソッドをサポートします:

  • tx:query(sql, params?)
  • tx:query_one(sql, params?)
  • tx:scalar(sql, params?)
  • tx:execute(sql, params?)

例:

db:transaction(function(tx)
tx:execute("insert into users(name) values (?)", {"charlie"})
tx:execute("insert into users(name) values (?)", {"dora"})
end)

local ok, err = pcall(function()
db:transaction(function(tx)
tx:execute("insert into users(name) values (?)", {"eve"})
error("stop")
end)
end)
print(ok) -- false
print(tostring(err))

close

v0.1.0 - Introduced.

Canonical API name: ptool.db.Connection:close.

db:close() は接続を閉じます。

挙動:

  • 閉じた後、その接続はもう使えません。
  • アクティブなトランザクションコールバックの最中に閉じるとエラーに なります。

例:

local db = ptool.db.connect("sqlite:test.db")
db:close()