3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

D言語くんAdvent Calendar 2017

Day 9

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

Last updated at Posted at 2017-12-09

はじめに

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は常に有効になります。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?