刹那(せつな)の瞬き

Willkömmen! Ich heiße Setsuna. Haben Sie etwas Zeit für mich?

UbuntuでnanodbcからSQLServerに接続する #1 - 導入編

C++ODBC 接続するのに便利な nanodbc (http://nanodbc.io/) という C++ wrapper が MIT ライセンスで公開されています。
nanodbc は Windows だけでなく LinuxmacOS 環境にも対応しています。
私も Ubuntu に環境を用意して試してみました。

1. 環境

  • Ubuntu Desktop 18.04.4 LTS 日本語Remix (Linux Kernel 5.3.0-46-generic)
  • SQL Server 2019 (RTM-CU4) (KB4548597) - 15.0.4033.1 (X64) on Linux
  • MS 版 ODBC ドライバ version 17.5.2
  • unixODBC 2.3.7
  • g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
  • git version 2.17.1
  • cmake version 3.17.20200324-gc98ec36

次の過去記事も前提としています。

2. 準備

(1) 作業ディレクト
$ cd ~
$ mkdir work
$ cd work
(2) リポジトリのクローン

GitHub に公開されているリポジトリを取得します。

$ git clone https://github.com/nanodbc/nanodbc.git
(3) ビルド用ディレクトリの準備
$ cd nanodbc
$ mkdir build
$ cd build
$ pwd
/home/dareka/work/nanodbc/build

以降の操作は、このディレクトリで作業します。

3. ビルド

(1) Makefile 生成

CMake のオプションで共有ライブラリの構築を指定します。

$ cmake -DBUILD_SHARED_LIBS=ON ..
-- The CXX compiler identification is GNU 7.5.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- nanodbc version: 2.13.0
-- nanodbc compile: C++14
-- Performing Test CXX_SUPPORTS_STDLIB
-- Performing Test CXX_SUPPORTS_STDLIB - Failed
-- nanodbc build: Disable linking libc++ - OFF
-- nanodbc feature: ODBC Version Override - OFF
-- nanodbc feature: Disable async features - OFF
-- nanodbc feature: Enable Unicode - OFF
-- nanodbc feature: Enable Boost - OFF
-- nanodbc feature: Enable SQL_NO_DATA bug workaround - OFF
-- nanodbc build: ODBC on Unix - unixODBC
-- ODBC compile flags: -I/usr/include -DHAVE_UNISTD_H -DHAVE_PWD_H -DHAVE_SYS_TYPES_H -DHAVE_LONG_LONG -DSIZEOF_LONG_INT=8
-- ODBC link flags: 
-- nanodbc build: Enable nanodbc target - SHARED
-- nanodbc build: Disable install target - OFF
-- nanodbc build: Disable tests target - OFF
-- nanodbc build: Disable examples target - OFF
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dareka/work/nanodbc/build
(2) 共有ライブラリ構築
$ make nanodbc
Scanning dependencies of target nanodbc
[ 50%] Building CXX object CMakeFiles/nanodbc.dir/nanodbc/nanodbc.cpp.o
[100%] Linking CXX shared library lib/libnanodbc.so
[100%] Built target nanodbc

後はインストールすれば完了ですが、念の為、テストを実行します。
テストが不要であれば、「5. インストール」に進みます。

4. テスト

SQL Server に接続してテストを実行します。
テスト内容の都合により、後述のテストは DSN-less で実施します。
なお、実際に nanodbc を使用する際は DSN 指定でも問題ありません。

(1) テスト実行ファイル生成

私が必要なのは mssql_tests だけですが、とりあえず対象をすべてビルドします。

$ make tests

テストを絞るなら~/work/nanodbc/test/CMakeLists.txtの44行目をset(test_list mssql)にしてから cmake すると幸せになれるかもしれません。

(2) テスト用データベース作成

nanodbc のテストでは、実行時に必要なテーブルを作成します。(多分48個)

対象は指定されたデータベースコンテキストになります。
特に指定しない場合、既定のデータベースコンテキストは master です。

データベースを汚したくなければ、テスト用データベースを用意した方が無難です。 
コマンドラインツールがインストール済みであれば、 sqlcmd コマンドでデータベース 'my_test_db' を作成します。

$ sqlcmd -Slocalhost -Usa -Pabcd1234$ -Q"IF DB_ID (N'my_test_db') IS NULL CREATE DATABASE my_test_db"

または、unixODBC の isql コマンドでも作成できます。

$ echo "IF DB_ID (N'my_test_db') IS NULL CREATE DATABASE my_test_db" | isql -b -k "DRIVER={ODBC Driver 17 for SQL Server};Server=localhost;UID=sa;PWD=abcd1234$"

なお、テスト中にCREATE DATABASEが存在しますが、すぐにDROP DATABASEするので流用はできません。

(3) テスト実行

SQLServer 用のテストだけ実行するように、環境変数を調整します。
接続先のデータベースには、先程作成した 'my_test_db' を指定します。

$ export NANODBC_TEST_CONNSTR_MSSQL='DRIVER={ODBC Driver 17 for SQL Server};Server=localhost;UID=sa;PWD=abcd1234$;Database=my_test_db'
$ export CTEST_OUTPUT_ON_FAILURE=1

続いてテストを実行します。
mssql_tests 以外の実行結果は無視します。

$ make test
Running tests...
Test project /home/dareka/work/nanodbc/build
    Start 1: utility_tests
1/6 Test #1: utility_tests ....................   Passed    0.00 sec
    Start 2: mssql_tests
2/6 Test #2: mssql_tests ......................***Failed   25.52 sec

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mssql_tests is a Catch v2.4.2 host application.
Run with -? for options

-------------------------------------------------------------------------------
test_datetimeoffset
-------------------------------------------------------------------------------
/home/dareka/work/nanodbc/test/mssql_test.cpp:765
...............................................................................

/home/dareka/work/nanodbc/test/mssql_test.cpp:792: FAILED:
  REQUIRE( t.day == 30 )
with expansion:
  31 == 30

===============================================================================
test cases:    53 |    52 passed | 1 failed
assertions: 17491 | 17490 passed | 1 failed


    Start 3: mysql_tests
〜(以下、省略)〜

mssql_test のテスト 53 項目中、失敗したテストが1つありますが、これは想定内です。

datetimeoffset 型の値が日本のタイムゾーンに従って変換される際、日付が変わる事を想定していないだけです。よって、このテストはパス済みと見なしました。

MS 版 ODBC ドライバは中々の成績です。

成績と表現しましたが、このテストはドライバの優劣を競うものではないです。
ドライバの特性を確認して、それを考慮した不具合のないコードを書くのが目的なので、想定の範囲や期待値を決定する為の一助だと思ってます。

5. インストール

共有ライブラリやヘッダ等をインストールします。

$ sudo make install
[  6%] Built target nanodbc
[ 17%] Built target mssql_tests

  〜(ざっくり省略)〜

[100%] Built target example_empty
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/lib/libnanodbc.so.2.13.0
-- Installing: /usr/local/lib/libnanodbc.so
-- Installing: /usr/local/include/nanodbc/nanodbc.h
-- Installing: /usr/local/cmake/nanodbc-config.cmake
-- Installing: /usr/local/cmake/nanodbc-config-noconfig.cmake

これで、nanodbc の共有ライブラリが使えるようになりました。

続きはこちら