プログラミング言語SML#解説 3.7.1版
22 SQL式とコマンド

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

    SQL.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.connectAndCreateCREATE 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を文字列化する.