2019年12月14日 (土)

Windowsでmatn/go-oci8を使おうとしてとても苦労している話

0. 唐突にOracle Databaseを使おうと思い立った

Oracle Databaseを使ったシステムなど、お仕事くらいでしか使うことはなかったんだけど、Oracle Cloud Free Tierとして使えるDBのPaaSがOracle Databaseだけ、というので、かなり仕方なく使う、というネガティブな話だったりする。

Javaや.NETには公式のデータベースドライバが出ているので、それらを使えば簡単にDBを利用できるけど、せっかくなので今回はGoでやってみることにした。

なお、結論から書くとこの話、実現できてないorz

1. 環境

ビルドには以下が必要。

  • C/C++コンパイラ
  • pkg-config
  • プラットフォームとバージョンに応じたOracle InstantClient

このほか、当然のことながらGitやGoが必要。

1-1. MSYS2

僕のWindows PC(Windows 10 pro version 1909)にはSphinxでPDFをビルドするため、MSYS由来のGNU Makeとshが入っていたので、GCCを入れるためpacmanを起動。
しかしながら、なぜか何もフィードバックを出さずpacmanが途中で終了してしまい、パッケージのインストールもアップデートもできずハマる。

おかしい、version 1809のころはふつうにpacmanが動いていたはずなのに。

これでは何もできないので、MSYS2はあきらめることに。

1-2. Cygwin

ならば、ということでMSYS2をアンインストールしてCygwin x64を入れてみた。

Baseパッケージグループのほか、makeやGCCをCygwin Installerで一とおりインストールし、C:\cygwin64\binなどをWindowsのPath環境変数に追加していった。

Cygwin shellではなくDOS窓からgo get github.com/mattn/go-oci8とやったところ、

  # runtime/cgo
  gcc_libinit_windows.c: 関数 ‘x_cgo_sys_thread_create’ 内:
  gcc_libinit_windows.c:57:12: エラー: implicit declaration of function ‘_beginthread’; did you mean ‘OpenThread’? [-Werror=implicit-function-declaration]
    thandle = _beginthread(func, 0, arg);
              ^~~~~~~~~~~~
              OpenThread
  cc1: all warnings being treated as errors
  go: failed to remove work dir: GetFileInformationByHandle C:\cygwin64\tmp\go-build601027150\NUL: Incorrect function.

と出てビルドできず。後でググると本体のGitHub WikiInstallFromSource

Go does not support the Cygwin toolchain.

などど書かれていた。なん....だと....?

1-3. WSL

最近のエディションにはWSL(Windows Subsystem for Linux)という、読んで字のごとくLinux互換環境を提供するサブシステムが標準搭載されている。デーモンを常駐させられない以外はほぼLinuxそのままなので、こいつで頑張ってみることに。

僕は普段UbuntuのWSLを使っているけど、GCCもpkg-configもapt installで導入できるのでお手軽だ。

ということでapt installでGCCやらpkg-configやらをインストールしてgo getしてみる。
結果、エラー表示は出ず。

いけた、のか? ということで付属のexampleで動作確認。

  $ cd $GOPATH/src/github.com/mattn/go-oci8/_example/nls
  $ GO_OCI8_CONNECT_STRING=system/Orcl19cAdmin@//localhost:1521/ORCLCDB go run main.go
  ORA-12571: TNS:packet writer failure

パケット到達不能、だと....? まぁ、Oracle Databaseは親環境のDockerで動かしているとはいえ、WSLからDockerを制御できているので、親環境とは通信できているはずだが。

てなわけで、この方法もダメということに。

1-4. TDM-GCC

Goの公式としてはTDM-GCCを推奨しているようなので、Cygwin GCCをアンインストールしてこちらに切り替えてみた。

パッケージマネージャは付属していないので、pkg-configを自力でセットアップしなければならない。やり方自体はStackOverflowの記事を参考にやってみた。

一応、直リンクを置いておく。

準備自体はGistを残してくれている方がいたので、それを使わせてもらうことに。

  > go get github.com/mattn/go-oci8
  # pkg-config --cflags  -- oci8
  pkg-config: exit status 3221225595

3221225595をWindowsの電卓に通すと0xC000007Bになるのだが、pkg-configが正常起動できていない、ということのようだ。どうやらABIが違うようなので、win64ではなくwin32に変えることで正常起動するようになった。

で、再挑戦。

  > go get github.com/mattn/go-oci8
  # github.com/mattn/go-oci8
  In file included from GOPATH\src\github.com\mattn\go-oci8\cHelpers.go:3:0:
  ./oci8.go.h:1:17: fatal error: oci.h: No such file or directory
  compilation terminated.

....pkg-configがインクルードパスを正常に処理できていないようだ。もちろん、oci.hの場所は-Iオプションの行で指定しているんだが。

おわりに

最後のTDM-GCCパターンではあと一歩なような気もする。

そんな気はするんだが、MySQLやPostgreSQLのドライバだったり、GoではなくJavaを選択していた場合だと、もっと簡単にデータアクセスを実装できていたであろう、と考えると、「なぜ僕はこんな苦行を....?」などと考えてしまう。

| | コメント (0)

2019年7月20日 (土)

DockerにSQL Serverを追い出す件

追い出したい

僕のPCには開発用と称して

  • PostgreSQL 9.6
  • MySQL 8
  • Microsoft SQL Server 2017 Developer

をセットアップしているんだが、ホスト環境にそのままセットアップしているとこういった不満が出てくる(という私見)。

  • アップグレードは簡単にしたい
  • DBMSはアプリと1対1対応させたい
  • 開発していないときは、DBMSのプロセスを下げたい

こんなところか。
ということで、手始めにSQL ServerをDockerに追い出してみることにする。

SQL Server on Docker

いまどきのSQL ServerはLinux上でも動かせるエディションがリリースされているので、Microsoftも公式Dockerイメージを公開している。
今回はホスト環境にデータを永続化しておきたいので、Docker Hubの記載をもとにdocker-compose.ymlをかいてみた。

まだホスト環境でSQL Serverが稼働中なので、ホスト環境からの接続ポートを1433から14330に変更している。

version: '3'

 

services:
# Microsoft SQL Server 2017 Linux (Developer Edition)
db:
image: mcr.microsoft.com/mssql/server:2017-latest
container_name: mssql2017dev
environment:
ACCEPT_EULA: Y
# If you runs in production environment, you should change sa password.
SA_PASSWORD: P@ssw0rd2017
# If you have valid Product ID, set MSSQL_PID valiable.
# See : https://hub.docker.com/_/microsoft-mssql-server
#MSSQL_PID: Express
volumes:
- ./data/data:/var/opt/mssql/data
- ./data/log:/var/opt/mssql/log
ports:
- 14330:1433

docker-compose.ymlを置いているディレクトリで、PowerShellからこう叩くとDocker上にSQL Serverが立ち上がる。

PS> mkdir .\data\data
PS> mkdir .\data\log
PS> docker-compose up -d

 

ツールで接続する

 

立ち上がったら、ホスト環境のsqlcmdで接続して動作確認。

PS> sqlcmd -S localhost,14330 -U sa -P P@ssw0rd2017

注意点としては、ポートの指定がよくあるコロン(:)ではなくカンマ(,)だということ。MSDNにはちゃんと書かれているけれど、これは初見殺しだよなぁ。

接続ができたら、今度はSQL Server Management Studioを使えるようにしてみる。接続ダイアログのサーバ名は、sqlcmdの時同様の書き方でよい。

Connwithssms

これでSQL ServerをDockerに追い出せたので、データ移行をこなせば追い出しが完了する見込み。

 

プロジェクト的なもの

GitHubにプロジェクト的なものを上げてます。
ご参考あれ。

続きを読む "DockerにSQL Serverを追い出す件"

| | コメント (0)