22.8 SQLライブラリ:SQLストラクチャ
SML#は,SQL関連の拡張構文と共に使用するための 関数や型をライブラリとして提供する. SQLに関連する全ての型と関数は, インターフェースファイルsql.smiがプロバイドする SQLストラクチャに含まれる. SQL機能を使用して書かれたSML#のソースファイルは, そのインターフェースファイルに以下の一行を加え, sql.smiを参照しなければならない.
_require "sql.smi"
SQLストラクチャのシグネチャは以下の通りである.
structure SQL : sig
type bool3
type numeric
type decimal = numeric
type backend
type ’a server
type ’a conn
type ’a cursor
type (’a, ’b) exp
type (’a, ’b) whr
type (’a, ’b) from
type (’a, ’b) orderby
type (’a, ’b, ’c) select
type (’a, ’b) query
type (’a, ’b) command
type (’a, ’b) db
exception Exec
exception Connect
exception Link
val postgresql : string -> backend
val mysql : string -> backend
val odbc : string -> backend
val sqlite3 : string -> backend
structure SQLite3 : (22.8.1節参照)
val connect : ’a server -> ’a conn
val connectAndCreate : ’a server -> ’a conn
val closeConn : ’a conn -> unit
val fetch : ’a cursor -> ’a option
val fetchAll : ’a cursor -> ’a list
val closeCursor : ’a cursor -> unit
val queryCommand : (’a list, ’b) query -> (’a cursor, ’b) command
val toy : ((’a, ’c) db -> (’b, ’c) query) -> ’a -> ’b
val commandToString : ((’a,’c) db -> (’b,’c) command) -> string
val queryToString : ((’a,’c) db -> (’b,’c) query) -> string
val expToString : (’a,’c) exp -> string
Structure Op : (22.9節参照)
Structure Numeric : (22.10節参照)
Structure Decimal = Numeric
end
以下, 22.1節で定義した型を除き, これらの定義を役割ごとに副節に分けて説明する.
22.8.1 データベースサーバーへの接続
-
•
exception Connect of string
データベースへの接続に関するエラーを表す例外. stringはエラーメッセージである.
-
•
exception Link of string
データベーススキーマの型チェックに関するエラーを表す例外. stringはエラーメッセージである.
-
•
type backend
_sqlserver構文に書く接続先情報の型 (22.3節参照). 以下の関数のいずれかを用いてこの型を持つ式を書く.
-
•
val postgresql : string -> backend
SQL.postgresql paramは, PostgreSQLサーバーへの接続情報を返す. 文字列paramは, PostgreSQLライブラリlibpqの接続文字列である. 接続文字列の詳細はPostgreSQLマニュアルを参照せよ. paramが適切でない場合はSQL.Connect例外が発生する.
サポートするPostgreSQLの型とSML#の型との対応は以下の通りである.
PostgreSQL SML# INT, INT4 int BOOLEAN bool TEXT, VARCHAR string FLOAT8 real FLOAT4 real32 -
•
val mysql : string -> backend
SQL.mysql paramは, MySQLサーバーへの接続情報を返す. 文字列paramには, “キー=値”という形式の指定を空白文字で区切って並べる. 指定可能なキーとその意味は以下の通りである.
キー 説明 host MySQLサーバーのホスト名 port MySQLサーバーのポート番号 user MySQLサーバーにログインするときのユーザー名 password MySQLサーバーにログインするときのパスワード dbname 接続先データベースの名前 unix_socket 接続先UNIXソケットのファイル名 flags 通信プロトコルのフラグ(10進数で指定) このうちdbnameは必ず指定しなければならない. これらのパラメタについて詳しくはMySQLのマニュアルを参照せよ. paramが適切でない場合はSQL.Connect例外が発生する.
サポートするMySQLの型とSML#の型との対応は以下の通りである.
MySQL SML# TINYINT, SMALLINT, MEDIUMINT, INT int TINYTEXT, TEXT, VARCHAR string DOUBLE real FLOAT real32 -
•
val sqlite3 : string -> backend
val sqlite3’ : SQL.SQLite3.flags * string -> backendSQL.sqlite3 filenameおよび SQL.sqlite3 (flags, filename)は, SQLite3データベースファイルへの接続情報を返す. 文字列filenameには, データベースファイルの名前を指定する. SQLite3は“:”で始まる名前を特別に解釈することに注意が必要である.
flagsは,以下の4つのフィールドからなるレコードである.
-
–
mode:ファイルをオープンするモードを表す. 以下のいずれかの値を取る.
-
*
SQL.SQLite3.SQLITE_OPEN_READONLY
-
*
SQL.SQLite3.SQLITE_OPEN_READWRITE
-
*
SQL.SQLite3.SQLITE_OPEN_READWRITE_CREATE
-
*
-
–
threading:マルチスレッドモードを表す. 以下のいずれかの値を取る.
-
*
SQL.SQLite3.SQLITE_OPEN_NOMUTEX
-
*
SQL.SQLite3.SQLITE_OPEN_FULLMUTEX
-
*
-
–
cache:キャッシュモードを表す. 以下のいずれかの値を取る.
-
*
SQL.SQLite3.SQLITE_OPEN_SHAREDCACHE
-
*
SQL.SQLite3.SQLITE_OPEN_PRIVATECACHE
-
*
-
–
uri:ファイル名の解釈の仕方を表す. 以下の値を取る.
-
*
SQL.SQLite3.SQLITE_OPEN_URI
-
*
これらのフラグについての詳細はSQLite3 C/C++ APIのマニュアルを 参照せよ. これらの定数は全て SQL.SQLite3ストラクチャに定義されている. また,SQL.SQLite3ストラクチャは flagsが未指定の場合に用いられるデフォルトのフラグ SQL.SQLite3.flagsを持つ. フィールドアップデート式と SQL.SQLite3.flagsを用いることで, デフォルトの設定を一部変更したフラグを作ることができる.
SQLite3のtype affinityとSML#の型が以下の通りに対応付け られている.
Type affinity SML# INT int REAL real STRING string NUMERIC numeric BLOB (未対応) CREATE TABLE時に各カラムに指定された型と type affinityとの対応は,SQLite3のマニュアルに記載されている通りである.
-
–
-
•
val odbc : string -> backen
SQL.odbc paramは, ODBCサーバーへの接続情報を返す. 文字列paramには, DSN名,ユーザー名,パスワードをこの順にスペースで区切って並べる. paramが適切でない場合はSQL.Connect例外が発生する.
サポートするODBCの型とSML#の型との対応は以下の通りである.
ODBC SML# CHAR string INTEGER, SMALLINT int FLOAT real32 DOUBLE real VARCHAR, LONGVARCHAR, NVARCHAR string -
•
val connect : ’a server -> ’a conn
SQL.connect serverは, 接続情報serverが表す接続先のサーバーとの接続を確立し, 実際のデータベーススキーマがserverが表すスキーマを包含することを 検査し,エラーが無ければ,サーバーへの接続ハンドルを返す. サーバーとの接続にエラーがあればSQL.Exec例外が発生する. スキーマの検査にエラーがあればSQL.Link例外が発生する.
接続情報serverの型は, この接続を通じて扱うテーブルおよびビューの型を表す. SQL.connectは,serverの型にある各テーブル名に ついて,同名のテーブルまたはビューが存在するかどうかを, データベースのシステムカタログを見てチェックする. 存在するならば,さらにそのテーブルまたはビューが, serverの型にあるカラムを全て持つことを検査する. チェックの際,名前の大文字小文字は区別しない. データベースは,serverの型に無いテーブルやビューを 含んでもよい. 一方,各テーブルは,serverの型に書かれているカラムを 正確に含まなければならない.
初めてデータベースサーバーと接続しようとしたとき, 接続先データベースの種類に応じて適切な 接続ライブラリが動的にリンクされる. デフォルトのライブラリ名が適切でない場合は, 環境変数を通じてライブラリ名を指定することができる. 接続先サーバー, デフォルトのライブラリ名, および環境変数の名前は以下の通りである.
データベース ライブラリ名 環境変数 PostgreSQL libpq.so.5 SMLSHARP_LIBPQ MySQL libmysqlclient.16.so SMLSHARP_LIBMYSQLCLIENT ODBC libodbc.so.2 SMLSHARP_LIBODBC SQLite3 libsqlite3.so.0 SMLSHARP_LIBSQLITE3 -
•
val connectAndCreate : ’a server -> ’a conn
以下の点を除いてSQL.connectと同じである. 引数の型で指示されたテーブルが 接続先データベースに存在しない場合, SQL.connectAndCreateは CREATE TABLEコマンドを発行し そのテーブルを作成する. サポートされない型を含むテーブルを作成しようとしたとき SQL.Link例外が発生する. CREATE TABLEコマンドの実行に失敗したとき SQL.Exec例外が発生する.
-
•
val closeConn : ’a conn -> unit
SQL.closeConn connは, SQL.connect関数が確立したデータベースサーバーへの接続を閉じる. SQL.connectで確立した接続は, SQL.closeConnで必ず閉じられなければならない.
22.8.2 SQLクエリの実行と結果の取得
-
•
exception Exec of string
SQLクエリの実行時にデータベースサーバーがエラーを報告したことを 表す例外. stringはエラーメッセージである.
-
•
val fetch : ’a cursor -> ’a option
SQL.fetch cursorは, カーソルcursorが指す行を一行読み込み, cursorを一行進める. もしカーソルがテーブルの終端に到達していた場合は NONEを返す. もしカーソルが閉じられているならば SQL.Exec例外が発生する.
-
•
val fetchAll : ’a cursor -> ’a list
SQL.fetchAll cursorは, カーソルcursorが指す行から最後の行までを読み込み, カーソルを閉じる. もしカーソルが閉じられているならば SQL.Exec例外が発生する.
-
•
closeCursor : ’a cursor -> unit
closeCursor cursorは, SQL実行関数が返したカーソルを閉じる. 全てのカーソルはこの関数かfetchAll関数で 閉じられなければならない.
22.8.3 SQLクエリの操作
-
•
val queryCommand : (’a list, ’b) query -> (’a cursor, ’b) command
SQL.queryCommand queryは, SELECTクエリqueryを SQLコマンドに変換する. この関数は, SQL実行関数式 _sql pat => select...(exp)が クエリexpに対して行うコマンド化(22.7節参照) と同じことをSQL実行関数を生成せずに行う.
-
•
val toy : ((’a, ’c) db -> (’b, ’c) query) -> ’a -> ’b
SQL.toy query dataは, SML#のデータ構造dataをデータベースに見立てて SELECTクエリqueryを評価する. クエリの評価はSML#の中で行われ,サーバーとのやり取りは 一切行われない. この関数は,SML#コンパイラがSQLの型付けのために生成した トイプログラムをそのまま実行する. クエリの実行効率は考慮されていないため, この関数は実用に適さないほど遅い可能性がある.
-
•
val commandToString : ((’a,’c) db -> (’b,’c) command) -> string
SQL.commandToString commandは, 関数commandの本体を評価して得られたSQLコマンドを文字列化して返す. この関数が返す文字列は,SQL実行関数が SQLコマンド実行時にサーバーに送信する文字列と 同じものである.
-
•
val queryToString : ((’a,’c) db -> (’b,’c) query) -> string
SQL.queryToString queryは, 関数queryの本体を評価して得られたSELECTクエリを文字列化する. この関数が返す文字列は,SQL実行関数が SELECTクエリ実行時にサーバーに送信する文字列と 同じものである.
-
•
val expToString : (’a,’c) exp -> string
SQL.expToString expは, SQL評価式expを文字列化する.