Edited at

D言語ネイティブのMySQLドライバーmysql-nativeの基本的な使い方

More than 1 year has passed since last update.


はじめに

D-man botで使われているmysql-dはlibmysqlに依存しています。

今回、読んで字のごとくD言語ネイティブなmysql-nativeに変更するため、基本的な使い方をまとめます。


基本的な使い方

READMEのBasic exampleに書かれています。

import std.variant;

import mysql;

void main(string[] args)
{
// Connect
auto connectionStr = args[1];
Connection conn = new Connection(connectionStr);
scope(exit) conn.close();

// Insert
auto rowsAffected = exec(conn,
"INSERT INTO `tablename` (`id`, `name`) VALUES (1, `Ann`), (2, `Bob`)");

// Query
ResultRange range = query(conn, "SELECT * FROM `tablename`");
Row row = range.front;
Variant id = row[0];
Variant name = row[1];
assert(id == 1);
assert(name == "Ann");

range.popFront();
assert(range.front[0] == 2);
assert(range.front[1] == "Bob");

// Prepared statements
Prepared prepared = prepare(conn, "SELECT * FROM `tablename` WHERE `name`=? OR `name`=?");
prepared.setArgs("Bob", "Bobby");
ResultRange bobs = prepared.query();
bobs.close(); // Skip them

prepared.setArgs("Bob", "Ann");
ResultSet rs = prepared.querySet();
assert(rs.length == 1);
assert(rs[0][0] == 1);
assert(rs[0][1] == "Ann");
assert(rs[1][0] == 2);
assert(rs[1][1] == "Bob");

// Nulls
Prepared insert = prepare(conn, "INSERT INTO `tablename` (`id`, `name`) VALUES (?,?)");
insert.setArgs(null, "Cam"); // Also takes Nullable!T
insert.exec();
range = query(conn, "SELECT * FROM `tablename` WHERE `name`='Cam'");
assert( range.front[0][0].type == typeid(typeof(null)) );
}


// Connect

auto connectionStr = args[1];

Connection conn = new Connection(connectionStr);
scope(exit) conn.close();

例ではconnectionStrとして文字列でMySQLの接続情報を取得しています。"host=localhost;port=3306;user=joe;pwd=pass123;db=myappsdb"のように;で値を連結したものを用います。

それ以外にもいくつかのコンストラクタが利用できます。


// Insert

auto rowsAffected = exec(conn,

"INSERT INTO `tablename` (`id`, `name`) VALUES (1, `Ann`), (2, `Bob`)");

execで直接SQLを実行します。返り値は変更された行数がulongで返ります。


// Query

ResultRange range = query(conn, "SELECT * FROM `tablename`");

Row row = range.front;
Variant id = row[0];
Variant name = row[1];
assert(id == 1);
assert(name == "Ann");

range.popFront();
assert(range.front[0] == 2);
assert(range.front[1] == "Bob");

queryはSQLを実行し、結果をResultRangeで返します。

Rowrangeなので、frontなどでRowとして取り出すことができます。

RowVariantで各カラムの値を持ちます。また、toStructで構造体に変換できます。


// Prepared statements

Prepared prepared = prepare(conn, "SELECT * FROM `tablename` WHERE `name`=? OR `name`=?");

prepared.setArgs("Bob", "Bobby");
ResultRange bobs = prepared.query();
bobs.close(); // Skip them

prepared.setArgs("Bob", "Ann");
ResultSet rs = prepared.querySet();
assert(rs.length == 1);
assert(rs[0][0] == 1);
assert(rs[0][1] == "Ann");
assert(rs[1][0] == 2);
assert(rs[1][1] == "Bob");

Preparedでプリペアドステートメントを利用できます。

setArgsで値をセット、queryResultRangequerySetResultSetを返します。


// Nulls

Prepared insert = prepare(conn, "INSERT INTO `tablename` (`id`, `name`) VALUES (?,?)");

insert.setArgs(null, "Cam"); // Also takes Nullable!T
insert.exec();
range = query(conn, "SELECT * FROM `tablename` WHERE `name`='Cam'");
assert( range.front[0][0].type == typeid(typeof(null)) );

null値の扱いです。


さいごに

コミットしました。


注意


This package supports both Phobos sockets and Vibe.d sockets. Vibe.d support is disabled by default, to avoid unnecessary depencency on Vibe.d. To enable Vibe.d support, use:

(このパッケージはPhobosのソケットとVibe.dのソケット両方をサポートしています。デフォルトでは不必要な依存を避けるためにVibe.dは無効になっていますが、下記で有効にすることができます。)

-version=Have_vibe_d_core


とありますが、DUBのバグのためVibe.dは常に有効になります。