LoginSignup
7
0

More than 3 years have passed since last update.

tiberiusを使ってRustでMSSQLに接続する

Posted at

はじめに

RustからMSSQLを操作したいと思い、いい感じのcrateがないか探していました。
色々調べるとDB操作関連に関してはDieselというORMがよく使われているようでした。
https://github.com/diesel-rs/diesel

「情報もある程度ありそうだしこれを使ってみよう!」
と思っていたら‥

Supported databases:

1. PostgreSQL
2. MySQL
3. SQLite

だめやん‥

というわけで他の方法を探すことにしました。

tiberius

tiberiusというcrateがありました。
https://crates.io/crates/tiberius

スター数があまり多くないのは気になりますが、検証ということでとりあえずこちらを使ってみることにします。

注意

「rust tiberius」でググるとgithubのページが二つ出てくると思います。

前者が最新のリポジトリのようなので気をつけてください。

確認環境

今回はそれぞれ以下のバージョンを使用しました。

  • rustc
    • 1.45.0-nightly(dockerの「rustlang/rust:nightly」を使用)
  • tiberius
    • 0.4.0-alpha.6
      • Crates.ioに公開されているバージョンを使いたかったのですが、いい感じのexampleが見つけられず現時点の最新版(2020/05/29 時点)を使っています。申し訳ありません‥

実装

ディレクトリ構造

今回作成したプロジェクトは以下の構造になっています。

├── Dockerfile
├── app
│   ├── Cargo.lock
│   ├── Cargo.toml
│   └── target ※このディレクトリ配下は省略
│   └── src
│       └── main.rs
└── docker-compose.yaml

それでは一つづつみていきましょう!

Dockerfile

今回はnightlyのバージョンを使います。

FROM rustlang/rust:nightly

docker-compose.yaml

docker-compose.yamlは以下の通りです。
接続するMSSQLは公式で配布されているdocker imageを使います。

また、あらかじめテスト用のデータを作成するためにアプリケーションとmssqlの他にmssqlのcliツールを使用するコンテナも作成します。


version: '3.7'
services:
  app:
    build: .
    volumes:
      - ./app:/app
    working_dir: /app
    tty: true
    depends_on: 
      - db
  db:
    image: microsoft/mssql-server-linux:2017-GA
    environment:
      ACCEPT_EULA: Y
      SA_PASSWORD: "P@ssw0rd!"
    volumes:
      - rust-mssql-data:/var/opt/mssql/
    ports:
      - "1433:1433"
  mssql_cil_client:
    image: node:alpine
    tty: true
volumes:
  rust-mssql-data:
    driver: local

Cargo.toml

「Cargo.toml」はdependenciesだけ抜粋しています。
サンプルを動かすにはtiberiusの他にも幾つか必要なcrateがあるので全て追加してください。

[dependencies]
tiberius = { git = "https://github.com/prisma/tiberius.git" }
tokio = { version = "0.2", features = ["macros"] }
anyhow = "1.0.31"
futures = "0.3.5"

tiberiusについては「動作確認環境」にも書きましたが最新版を使いたかったのでgithubから直接ダウンロードするようにしています。

サンプル用確認用のテーブル

サンプルを実装する前にテスト用のデータベースを作成してサンプルデータを登録しておきます。

コンテナの起動

docker-compose up -d

MSSQLが起動するので、データベースやテーブルを作成します。

cli用のコンテナにログイン


docker-compose exec mssql_cil_client /bin/sh

sql-cliのinstall


npm install -g sql-cli

mssqlにログイン


mssql -s db -u sa -p P@ssw0rd!

データベースの作成


create database test;
use test;

テーブルの作成


create table users \
( \
    id int not null, \
    name nvarchar(128), \
    constraint pk_users primary key (id) \
);

テストデータの登録


insert into users(id,name) values(1,'Taro');
insert into users(id,name) values(2,'Jiro');
insert into users(id,name) values(3,'Hanako');

テストデータの確認

想定通りにデータが登録されているか確認しましょう!


select * from users;

以下ように表示されればOKです!


id  name
--  ------
1   Taro
2   Jiro
3   Hanako

3 row(s) returned

Executed in 1 ms

問題なければ、mssqlおよびコンテナからログアウトしましょう


.quit
exit

main.rs

それでは先ほど作成したテストデータをRustから取得してみます!

以下にテーブルを作成するサンプルが格納されています。
今回はこれをベースにしました。
https://github.com/prisma/tiberius/blob/master/examples/new.rs


use tiberius::{AuthMethod, Client};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let mut builder = Client::builder();
    builder.host("db");
    builder.port(1433);
    builder.database("test");
    builder.authentication(AuthMethod::sql_server("SA", "P@ssw0rd!"));
    builder.trust_cert();

    let mut conn = builder.build().await?;
    let results = conn
        .simple_query("select id, name from Users;")
        .await?
        .into_results()
        .await?;

    for val in results.iter() {
        // 取得した件数分ループする
        for inner in val.iter() {
            // id列の情報を取得
            if let Some(id) = inner.get::<i32, _>("id") {
                print!("id = {} ", id);
            }
            // name列の情報を取得
            if let Some(name) = inner.get::<&str, _>("name") {
                println!("name = {}", name);
            }
        }
    }
    Ok(())
}

とりあえず使ってみるだけであれば、特に難しい点はなさそうです。
resultsが2次元配列になっている理由が今ひとつわからず気になりました。

細かいことは一旦気にせず上記コードを実行してみましょう!


docker-compose exec app cargo run

結果

id = 1 name = Taro
id = 2 name = Jiro
id = 3 name = Hanako

いい感じですね!

今回作ったサンプルは以下で公開しています。
https://github.com/shushutochako/tiberius_sample

さいごに

Rustでmssqlを操作するサンプルがあまり多くない印象で少し手こずってしまいました。
これから色々と実装例が増えてくることを切に願います(´·ω·`)

他にもRustからMSSQLを操作する場合はODBCのWrapperライブラリを使う方法などもあるようです。
ODBCクレートを使用する場合はこちらの記事が非常に参考になりました。
https://setsuna-no-matataki.hateblo.jp/entry/2020/04/30/182305


ZEROBILLBANKでは一緒に働く仲間を募集中です。
ZEROBILLBANK JAPAN Inc.

7
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
7
0