データベース API
データベース接続とクエリのヘルパーは ptool.db と p.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.dbとsqlite://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.
Connection は ptool.db.connect() が返す開かれたデータベース接続を
表します。
これは Lua userdata として実装されています。
メソッド:
db:query(sql, params?)->tabledb:query_one(sql, params?)->table|nildb:scalar(sql, params?)->boolean|integer|number|string|nildb:execute(sql, params?)->tabledb:transaction(fn)->anydb:close()->nil
パラメータバインディング:
paramsは任意です。paramsが配列テーブルの場合は位置パラメータとして扱われ、 SQL プレースホルダーには?を使います。paramsがキーと値のテーブルの場合は名前付きパラメータとして扱われ、 SQL プレースホルダーには:nameを使います。- 位置パラメータと名前付きパラメータは同じ呼び出し内で混在できません。
- サポートされるパラメータ値の型:
booleanintegernumberstring
v0.1.0では、バインドパラメータとしてnilはサポートされません。
戻り値のルール:
- クエリ結果で保証される Lua 値型は次のものだけです:
booleanintegernumberstringnil(SQLNULL用)
- テキスト列は 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()