sqlite3にmaxminddbを組み合わせて使っていたりしてます。sqlite3からmaxminddbを参照できるようにextentionを作ってます。*1GeoLite2のIPデータベースを使うということで察せられると思いますが、ここで集計しようとするsqlite3のデータベースはフローデータに関係するものです。
extension化はlinuxだと素直にできていたのですが、人に見せやすいよう*2にWindowsでも動かせるかどうか考えてみました。sqliteといってもExcelとかに比べると知ってる人はるかに少ないと思うのですが、すでにデータの入ったdbファイル渡して、SQL/selectの単純な組み方を知ってもらえるとsqliteなら結構簡単に使えると思うのです。で、GeoLite2との組み合わせを関数形式で使えるようになると結構作業の幅が広がるだろう、そう考えてみたのが動機です。
方針
maxminddbはWindowsではvc12でビルドできるそうです。Windowsの場合の開発環境というのは、自分が思うにヘッダーがそれぞれのプロジェクトに分散して参照設定がスパゲティになってしまうことが多いと思うので*3、今回試してみるのはmaxminddbのソース(*.c/*.h)を直接参照して一気にコンパイル・リンクしてひとつのextension DLLファイルを生成することにしました。
windowsだと文字列をunicodeかマルチバイトのいずれかとして認識してそれに沿って処理を書くことになっている*4と思います。libmaxminddbのwindowsコードはunicode派のようです。
Windows版extension構築に必要なもの
linuxだとヘッダーなどをパッケージシステムのインストールで参照できるようになりますが、windowsの場合はそれぞれを明示的に用意しないと話がかみ合わなくなります。
- sqlite3.h
- sqlite3ext.h
- src/maxminddb.c
- src/data-pool.c
- include/maxminddb.h
- include/data-pool.h
- projects/VS12/maxminddb_config.h
コンパイル・リンク
こういった単純なexe/dll程度であれば、Windowsのビルドも、コマンドラインからの生成が分かりやすい、と思っています。
今回の例だと、まず
C:\Users\nao86\source\repos\フォルダ配下に
- sqlite-maxminddb
さらにその下に
- libmaxminddb (githubから)
- sqlite (sqlite-amalgamation-32800から)
を並べておいたという前提です。
コンパイルリンクに32bit-nativeのコマンドツールを使います。*5*6*7
プロンプトを開いてこれで生成。
C:\Users\nao86\source\repos\sqlite-maxminddb>cl /D_USRDLL /D_WINDLL /I. /I..\sqlite3 sqsqlite3_maxminddb.c ..\libmaxminddb\maxminddb.c ..\libmaxminddb\data-pool.c Ws2_32.lib /link /DLL /OUT:maxminddb.dll Microsoft(R) C/C++ Optimizing Compiler Version 19.21.27702.2 for x86 Copyright (C) Microsoft Corporation. All rights reserved. sqlite3_maxminddb.c maxminddb.c data-pool.c コードを生成中... Microsoft (R) Incremental Linker Version 14.21.27702.2 Copyright (C) Microsoft Corporation. All rights reserved. /out:sqlite3_maxminddb.exe /DLL /OUT:maxminddb.dll sqlite3_maxminddb.obj maxminddb.obj data-pool.obj Ws2_32.lib ライブラリ maxminddb.lib とオブジェクト maxminddb.exp を作成中
windows用のsqlite3は、sqlite3.exeを使いました。これを起動して、extensionとしてロードします。定義関数経由でmaxminddbの機能をwindows上で動かすことができました。
C:\Users\nao86\source\repos\sqlite-maxminddb>sqlite3 SQLite version 3.28.0 2019-04-16 19:49:53 Enter ".help" for usage hints. Connected to a transient in-memory database. Use ".open FILENAME" to reopen on a persistent database. sqlite> .load maxminddb sqlite> select asn('1.1.1.1'),cc('1.1.1.1'),org('1.1.1.1'); 13335|AU|Cloudflare, Inc.