PHPのためのADOdbライブラリ

original document  ADOdb関連文書

V4.62 2 Apr 2005 (c) 2000-2005 John Lim (jlim#natsoft.com)

このソフトウェアはBSDスタイルとLGPLを使いデュアルライセンスされています。これはコンパイルされて所有権のある市販製品で使えることを意味しています。

役に立つADOdbのリンク: Download   Other Docs

序文
ユニークな特徴
どんなふうに人々はADOdbを使っているか
機能要望とバグ報告
インストール
最小インストール
コードの初期化とデータベースへの接続
  データソース名(DSN)   接続例
高速ADOdb - チューニングTips
安全なADOdbのハッキングと変更
PHP5の機能

foreach iterators exceptions
サポートしているデータベース
チュートリアル
Example 1: Select
Example 2: 進歩したSelect
Example 3: Insert
Example 4: デバッグ  rs2html
Example 5: MySQLとMenus
Example 6: 複数のデータベースへの同時接続
Example 7: UpdateとInsert SQL文生成
Example 8: Next、Previousのあるスクローリング実装
Example 9: CSV、Tab区切りフォーマットへのエクスポート
Example 10: カスタムフィルタ
Example 11: スマートトランザクション

カスタムエラーハンドラとPEAR_Errorの利用
Data Source Names
キャッシング
Pivotテーブル

リファレンス

変数: $ADODB_COUNTRECS $ADODB_ANSI_PADDING_OFF $ADODB_CACHE_DIR
        $ADODB_FORCE_TYPE $ADODB_FETCH_MODE $ADODB_LANG
定数:
ADODB_ASSOC_CASE
ADOConnection
接続: Connect PConnect NConnect IsConnected
SQL実行: Execute CacheExecute SelectLimit CacheSelectLimit Param Prepare PrepareSP InParameter OutParameter AutoExecute
              GetOne CacheGetOne GetRow CacheGetRow GetAll CacheGetAll GetCol CacheGetCol GetAssoc CacheGetAssoc Replace
               ExecuteCursor (oci8のみ)
SQL文字列生成: GetUpdateSQL GetInsertSQL Concat IfNull length random substr qstr Param OffsetDate SQLDate DBDate DBTimeStamp
BLOB: UpdateBlob UpdateClob UpdateBlobFile BlobEncode BlobDecode
ページング/スクローリング: PageExecute CachePageExecute
クリーンアップ: CacheFlush Close
トランザクション: StartTrans CompleteTrans FailTrans HasFailedTrans BeginTrans CommitTrans RollbackTrans
データ取得様式:
SetFetchMode
文字列: concat length qstr quote substr
日付: DBDate DBTimeStamp UnixDate UnixTimeStamp OffsetDate SQLDate
行管理: Affected_Rows Insert_ID RowLock GenID CreateSequence DropSequence
エラーハンドリング: ErrorMsg ErrorNo MetaError MetaErrorMsg
データ辞書(メタデータ): MetaDatabases MetaTables MetaColumns MetaColumnNames MetaPrimaryKeys MetaForeignKeys ServerInfo
統計とクエリー書き直し: LogSQL fnExecute and fnCacheExecute
非推奨: Bind BlankRecordSet Parameter
ADORecordSet

1フィールド取得: Fields
1行取得: FetchRow FetchInto FetchObject FetchNextObject FetchObj FetchNextObj GetRowAssoc
全行取得: GetArray GetRows GetAssoc
スクロール:Move MoveNext MoveFirst MoveLast AbsolutePosition CurrentRow AtFirstPage AtLastPage AbsolutePage

メニュー生成: GetMenu GetMenu2
日付: UserDate UserTimeStamp UnixDate UnixTimeStamp
レコードセット情報: RecordCount PO_RecordSet NextRecordSet
フィールド情報: FieldCount FetchField MetaType
クリーンアップ: Close

rs2html  example
ADOdbとADOの違い
データベース ドライバ ガイド
変更履歴

序文

PHPのデータベースアクセスの機能は標準化されていません。このため様々なデータベースAPI間の差異を隠してくれる(差異を隠蔽してくれる)データベースクラスライブラリの必要が生まれています。そうすれば簡単にデータベースを切り替えることができるようになります。(配列に基づくstr_replaceを使っているので)現在はPHP 4.0.5 以降が必要です。

私たちは現在次の製品をサポートしています。MySQL、Oracle、Microsoft SQL Server、Sybase、Sybase SQL Anywhere、Informix、PostgreSQL、FrontBase、SQLite、Interbase(FirebirdやBorlandなど)、Foxpro、 Access、ADO、DB2、SAP DB、それにODBC。ODBC 経由で Progress と CacheLite への接続に成功したとの報告も受けてます。もっと多くの人が他のデータベースをサポートするドライバーに貢献してくれるだろうと希望をもっています。

PHP4 はセッション変数をサポートしています。真の移植性と拡張性のために、ADOdbを使ってセッション情報を保存しておくことができます。より詳細はadodb-session.phpを見てください。

また 移植性のあるSQLを記述するためのTipsとして tips_portable_sql.htm

ADOdbのユニークな特徴

どんなふうに人々はADOdbは使っているか

どんなふうに人々はADOdbは使っているか、いくつかの例をここで紹介します。 (もっと長いリストを見たければ adodb-cool-appsを訪ねてください。):

機能要望とバグ報告

jlim#natsoft.com.my にメールしたり、 http://phplens.com/lens/lensforum/topics.php?id=4 の ADOdb ヘルプ フォーラムにポストできます。

インストールガイド

PHP 4.0.5 以上を走らせていることを確かめてください。 あなたのWebサーバからアクセスできるディレクトリに全てのファイルを展開してください。

テストとして、チュートリアルの例をいくつか変更して試してみてください。接続設定が正しくされていることを確かめてください。 以下のように $conn->debug = true を使えばデバッグができます。

<?php
include('adodb/adodb.inc.php');
$conn = ADONewConnection($dbdriver); # つまり 'mysql' とか 'postgres' とか
$conn->debug = true;
$conn->Connect($server, $user, $password, $database);
$rs = $conn->Execute('select * from some_small_table');
print "<pre>";
print_r($rs->GetRows());
print "</pre>";
?>

最小インストール

ADOdbの最小インストールをリリースしたい開発者に必要なのは次のファイルになります。

以下は任意に選べます。

コード初期化の例

ADOdb が動いているとき、少なくとも2つのファイルがロードされています。最初のものは adodb/adodb.inc.php で、すべてのデータベース クラスから使われるすべての関数をもっています。データベース固有のコードは adodb/driver/adodb-????.inc.php ファイルに入っています。

例えば、MySQL データベースに接続するためには:

include('/path/to/set/here/adodb.inc.php');
$conn = &ADONewConnection('mysql');

データベース接続が必要なときにはいつでも、ADONewConnection($driver) 関数を使って接続(Connection)オブジェクトを生成しなければなりません。 NewADOConnection($driver) は同じ関数の別名です。

この時点では、データベースに接続していません。(dsn を渡す場合には接続します。)永続(persistent)非永続(non-persistent)接続を使うかを最初に決定する必要があります。永続接続の利点は、(たとえClose()を呼んだにしろ)データベース接続が閉じられないのでより高速なことです。しかし非永続接続はリソース消費が少なくてすむので、データベースとWebサーバが高負荷になるリスクを軽減してくれます。

永続接続には$conn->PConnect()を、非永続接続には$conn->Connect()を使ってください。データベースドライバの中にはNConnect() をサポートしているものもあります。これはそのつど新しい接続を生成します。

接続にかんする困った振る舞い:もし2つの接続を生成して、両方が同じuseridとpasswordを使うと、PHPは同一の接続を共有しようとします。接続が異なるデータベースに対してのものであれば、これが問題を引き起こす可能性があります。問題を解消するには、常に異なるデータベースには異なるuseridを使うか、NConnect()を使うことです。

データソース名(DSN)サポート

ADOdb 4.51から、dsnをNewADOConnection()(あるいは同一の関数である ADONewConnection)に渡すことで接続できます。dsnフォーマットは次のとおり。

	$driver://$username:$password@hostname/$database?options[=value]

NewADOConnection()はあなたに代わって内部でConnect()あるいはPConnect()をコールします。接続が失敗するとfalse が返ります。

	# 非永続接続
	$dsn = 'mysql://root:pwd@localhost/mydb'; 
	$conn = NewADOConnection($dsn);
	if (!$conn) die("Connection failed");   
	
	# connect/pconnectをコールする必要なし!
	$arr = $conn->GetArray("select * from table");
	
	# 永続接続
	$dsn2 = 'mysql://root:pwd@localhost/mydb?persist'; 

もしdsnに/:?のような特殊文字があれば、最初にrawurlencodeする必要があります。

	$pwd = rawurlencode($pwd);
$dsn = "mysql://root:$pwd@localhost/mydb";

正規オプションは次のとおり。

すべてのドライバに対して 'persist', 'persistent', 'debug', 'fetchmode'
Interbase/Firebird 'dialect','charset','buffers','role'
M'soft ADO 'charpage'
MySQL 'clientflags'
MySQLi 'port', 'socket', 'clientflags'
Oci8 'nls_date_format'

すべてのドライバで、persistあるいはpersistentが設定されると、強制的に永続接続となります。 debugオプションでデバッグできるようになります。fetchmodeSetFetchMode()をコールします。オプションになにも値が指定されなければ、1が設定されます。

ADOdb DSNはPEAR DBのDSN フォーマット version 1.0と互換です。

データベース接続例

MySQLと他の大部分のデータベースドライバ

MySQL接続はひじょうに直接的で、パラメタはmysql_connectと一緒です。

	$conn = &ADONewConnection('mysql'); 
$conn->PConnect('localhost','userid','password','database');

# あるいは dsn だと $dsn = 'mysql://user:pwd@localhost/mydb'; $conn = ADONewConnection($dsn); # no need for Connect() # あるいは永続的 dsn だと $dsn = 'mysql://user:pwd@localhost/mydb?persist'; $conn = ADONewConnection($dsn); # no need for PConnect() # あるいはもっと複雑なものだと $pwd = urlencode($pwd); $flags = MYSQL_CLIENT_COMPRESS; $dsn = "mysql://user:$pwd@localhost/mydb?persist&clientflags=$flags"; $conn = ADONewConnection($dsn); # no need for PConnect()

たいていのドライバに対して、標準的な関数Connect($server, $user, $password, $database)を、あるいはADOdb 4.51以降DSNを用いることができます。この例外については以下に示します。

PostgreSQL

PostgreSQL 7と8とでは接続文字列を使うことができます。

a. 標準的な接続文字列

	$conn = &ADONewConnection('postgres');  
$conn->PConnect('host=localhost port=5432 dbname=mary');

b. 古典的な4つのパラメタ

	$conn->PConnect('localhost','userid','password','database');

c. dsn:

	$dsn = 'postgres://user:pwd@localhost/mydb?persist';  # persist は任意
	$conn = ADONewConnection($dsn);  # Connect/PConnect は不要

LDAP

ここにあるのはLDAPサーバ検索の例です。ドライバとこのサンプルはJosh Eldridgeのおかげです。

require('/path/to/adodb.inc.php');

/* Connect()を呼び出すまえに、この設定を確実に */
$LDAP_CONNECT_OPTIONS = Array(
	Array ("OPTION_NAME"=>LDAP_OPT_DEREF, "OPTION_VALUE"=>2),
	Array ("OPTION_NAME"=>LDAP_OPT_SIZELIMIT,"OPTION_VALUE"=>100),
	Array ("OPTION_NAME"=>LDAP_OPT_TIMELIMIT,"OPTION_VALUE"=>30),
	Array ("OPTION_NAME"=>LDAP_OPT_PROTOCOL_VERSION,"OPTION_VALUE"=>3),
	Array ("OPTION_NAME"=>LDAP_OPT_ERROR_NUMBER,"OPTION_VALUE"=>13),
	Array ("OPTION_NAME"=>LDAP_OPT_REFERRALS,"OPTION_VALUE"=>FALSE),
	Array ("OPTION_NAME"=>LDAP_OPT_RESTART,"OPTION_VALUE"=>FALSE)
);
$host = 'ldap.baylor.edu';
$ldapbase = 'ou=People,o=Baylor University,c=US';

$ldap = NewADOConnection( 'ldap' );
$ldap->Connect( $host, $user_name='', $password='', $ldapbase );

echo "<pre>";

print_r( $ldap->ServerInfo() );
$ldap->SetFetchMode(ADODB_FETCH_ASSOC);
$userName = 'eldridge';
$filter="(|(CN=$userName*)(sn=$userName*)(givenname=$userName*)(uid=$userName*))";

$rs = $ldap->Execute( $filter );
if ($rs)
	while ($arr = $rs->FetchRow()) {
	     print_r($arr);	
	}

$rs = $ldap->Execute( $filter );
if ($rs) 
	while (!$rs->EOF) {
 		print_r($rs->fields);	
		$rs->MoveNext();
	} 
	
print_r( $ldap->GetArray( $filter ) );
print_r( $ldap->GetRow( $filter ) );

$ldap->Close();
echo "</pre>";

あるいはdsnだと

$dsn = "ldap://ldap.baylor.edu/ou=People,o=Baylor University,c=US";
$db = NewADOConnection($dsn);

Interbase/Firebird

$hostパラメタの中でデータベースを定義します。
	$conn = &ADONewConnection('ibase'); 
$conn->PConnect('localhost:c:\ibase\employee.gdb','sysdba','masterkey');

あるいはdsnだと

	$dsn = 'firebird://user:pwd@localhost/mydb?persist&dialect=3';  # persist は任意
$conn = ADONewConnection($dsn); # Connect/PConnect は不要

SQLite

Sqliteはデータベースファイルが存在していなければ、ファイルを作成します。
	$conn = &ADONewConnection('sqlite');
	$conn->PConnect('c:\path\to\sqlite.db'); # 存在しなければ sqlite が作成します

あるいはdsnだと

	$path = urlencode('c:\path\to\sqlite.db');
	$dsn = "sqlite://$path/?persist";  # persist は任意
	$conn = ADONewConnection($dsn);  # Connect/PConnect は不要

Oracle (oci8)

oci8 では、複数の方法で接続が可能です。oci8はOracleの9iや10gなど新しいバージョンでもきちんと動作します。

a. PHPとOracle が同一マシーン上にあれば、デフォルトのSIDを使います。

	$conn->Connect(false, 'scott', 'tiger');

b. tnsnames.ora (あるいは ONAMES や HOSTNAMES)に定義されているTNS名。例えば 'myTNS'

	$conn->PConnect(false, 'scott', 'tiger', 'myTNS');

あるいは

 	$conn->PConnect('myTNS', 'scott', 'tiger');

c. Hostアドレスと SID

	$conn->Connect('192.168.0.1', 'scott', 'tiger', 'SID');

d. Hostアドレスとサービス名

	$conn->Connect('192.168.0.1', 'scott', 'tiger', 'servicename');

e. Oracle接続文字列

	$cstr = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$host)(PORT=$port))
(CONNECT_DATA=(SID=$sid)))";
$conn->Connect($cstr, 'scott', 'tiger');

f. ADOdb dsn

	$dsn = 'oci8://user:pwd@tnsname/?persist';  # persist は任意
$conn = ADONewConnection($dsn); # Connect/PConnect は不要

$dsn = 'oci8://user:pwd@host/sid';
$conn = ADONewConnection($dsn);

$dsn = 'oci8://user:pwd@/'; # ローカルマシーン上のoracle
$conn = ADONewConnection($dsn);

またcharSetをOracle 9.2以降に設定できます。PHP 4.3.2、ADOdb 4.54からサポートです。

	$conn->charSet = 'we8iso8859p1';
$conn->Connect(...);

# or
$dsn = 'oci8://user:pwd@tnsname/?charset=WE8MSWIN1252';
$db = ADONewConnection($dsn);

DSN無し ODBC ( Access, MSSQL と DB2 の例)

ODBC DSN 接続は ODBCコントロールパネルで作成することができます。あるいは、DSN無し接続を使うこともできます。ODBCのDSN無し接続を使うには PHP 4.3以降が必要です。

Microsoft Access

	$db =& ADONewConnection('access');
$dsn = "Driver={Microsoft Access Driver (*.mdb)};Dbq=d:\\northwind.mdb;Uid=Admin;Pwd=;"; $db->Connect($dsn);
Microsoft SQL Server
	$db =& ADONewConnection('odbc_mssql');
$dsn = "Driver={SQL Server};Server=localhost;Database=northwind;";
$db->Connect($dsn,'userid','password');
あるいは mssql extension を使いたければ(mssql 6.5の機能に限定されてしまいますが)
	$db =& ADONewConnection('mssql');
$db->Execute('localhost', 'userid', 'password', 'northwind');
DB2
	$db =& ADONewConnection('db2');
$dsn = "driver={IBM db2 odbc DRIVER};Database=sample;hostname=localhost;port=50000;protocol=TCPIP;".
"uid=root; pwd=secret";
$db->Connect($dsn);
ADOを使ったDSN無し接続
PHP 4.3.0以前のPHPバージョンを使っているばあい、DSN無し接続はMicrosoftのCOMベースAPIであるADOでのみ動作します。ADOdbライブラリとMicrosoftのADOを使った例
<?php
include('adodb.inc.php');
$db = &ADONewConnection("ado_mssql");
print "<h1>Connecting DSN-less $db->databaseType...</h1>";

$myDSN="PROVIDER=MSDASQL;DRIVER={SQL Server};"
. "SERVER=flipper;DATABASE=ai;UID=sa;PWD=;" ;
$db->Connect($myDSN); $rs = $db->Execute("select * from table"); $arr = $rs->GetArray(); print_r($arr); ?>

高速 ADOdb - チューニング Tips

ADOdbは大きなクラスライブラリです。けれどパフォーマンスにおいて他のPHPクラスにずっと勝ち続けています。その理由は玉葱のように階層的に設計されているからです。最も速い関数はもっとも内部の層にあります。最良のパフォーマンスを得るには、以下の関数に執心してください。

もっとも内部の層

Connect, PConnect, NConnect
Execute, CacheExecute
SelectLimit, CacheSelectLimit
MoveNext, Close
qstr, Affected_Rows, Insert_ID

フィールドデータアクセスの最速の方法は$recordset->fields 配列に直接アクセスすることです。またデータベースに接続する前に、グローバル変数$ADODB_FETCH_MODE = ADODB_FETCH_NUM とし、(oci8、ibase/firebirdとodbcの場合には)$ADODB_COUNTRECS = falseとします。

データベースでサポートされていれば、クエリープランの再利用を改善する、結合引数(bind parameter)の利用も考えてください。迅速にボトルネックを見つけ出すため、ADOdb のパフォーマンスチューニングシステムを使ってください。これを書いている時点(Dec 2003)では、oci8とodbcドライバが該当します。

最後に APC、Turck MMCache、Zend Accelerator、ionCube のような PHPアクセラレーター キャッシュがインストールされていることを確かめてください。

いくつかの例

PHPを使った最速のデータ取得ADOdb 拡張を使った最速のデータ取得
$rs =& $conn->Execute($sql);
while (!$rs->EOF) {
var_dump($rs->fields);
$rs->MoveNext();
}
$rs =& $conn->Execute($sql);
$array = adodb_getall($rs);
var_dump($array);


上級 Tips

もし ADOdb C拡張をインストールしているなら、$rs->MoveNext()の呼出しをadodb_movenext($rs)で置き換えることができます。 これは操作の速度を倍加させます。一度にレコードセット全体を取得するには GetArray() を使います。GetArray()は内部的に高速拡張関数 adodb_getall($rs)を使っています。

Execute()はクエリーを実行するデフォルトの方法です。低レベル関数_Execute()と_query()を使えばクエリーのオーバーヘッドを軽減することができます。この両方の関数はExecute()と同じパラメタを使います。

もし(擬似的にではなく)結合引数やデータベースが結合をサポートがなければ、_Execute()を直接コールすることができます。擬似的な結合をせずにこの関数を呼び出すこと。 _Execute()においてもデバッグ機能はサポートされます。

デバッグ機能や擬似的な結合を必要としなければ、そしてレコードセットの戻りも必要なければ、 _query をコールできます。この関数はinserts、update、deleteで効力を発揮します。擬似的な結合、デバッグ、レコードセットのハンドリングをせずに、この関数を呼び出すこと。_query()はresultidとしてtureかfalesを返します。

Informixでは、スクロール可能カーソルを$db->cursorType = 0とすることで無効にできます。

ADOdbを安全にハッキング

ADOdbを自分自身の目的にあうよう変更したいことがあるかもしれません。幸いにも、ADOdbをサブクラス化し$ADODB_NEWCONNECTION変数を使って、下位互換性を確保することができます。$ADODB_NEWCONNECTIONはADONewConnection()の振る舞いを上書きしてくれます。ADOConnection()はこの変数をチェックして、それが定義されていれば、この変数に格納されている関数名をコールします。

以下の例では、hack_mysqlhack_postgres7クラスの中で接続オブジェクトの新しい機能が盛り込まれています。レコードセットクラスの命名規則は$rsPrefixを使って制御することができます。ここでは'hack_rs_'と設定しています。そうすることで、ADOdbはhack_rs_mysqlhack_rs_postgres7をレコードセットクラスとして使うようになります。

class hack_mysql extends adodb_mysql {
var $rsPrefix = 'hack_rs_';
/* あなたのモジュールをここに */
}

class hack_rs_mysql extends ADORecordSet_mysql {
/* あなたのモジュールをここに */
}

class hack_postgres7 extends adodb_postgres7 {
var $rsPrefix = 'hack_rs_';
/* あなたのモジュールをここに */
}

class hack_rs_postgres7 extends ADORecordSet_postgres7 {
/* あなたのモジュールをここに */
}

$ADODB_NEWCONNECTION = 'hack_factory';

function& hack_factory($driver)
{
if ($driver !== 'mysql' && $driver !== 'postgres7') return false;

$driver = 'hack_'.$driver;
$obj = new $driver();
return $obj;
}

include_once('adodb.inc.php');

自分のコンストラクタのなかで親クラスのコンストラクタを呼ぶのを忘れないでください。デフォルトのADOdドライバを使いたければ、上のhack_factory()関数のなかでfalseを返してください。

PHP5機能

4.02以降のADOdbは透過的にどのバージョンのPHPが使われているかを判断します。もしPHP5が検知されれば、以下の機能が利用可能となります。

サポートされるデータベース

以下の名前はデータベースに対する接続オブジェクトを生成するためNewADOConnection($name)にわたされる値です。

名前 テスト データベース RecordCount() 使用可否 必要条件 オペレーティングシステム
access B Microsoft Access/Jet。ODBC DSNの作成が必要。 Y/N ODBC Windowsのみ
ado B

汎用ADOで、特定データベースに最適化されていない。DSN無し接続が可能。最高のパフォーマンスのためにはOLEDBプロバイダを使うこと。これはすべてのadoドライバのベースクラス。

接続前に$db->codePageの設定が可能。

? depends on database ADO or OLEDB provider Windowsのみ
ado_access B ADOを使ったMicrosoft Access/Jet。DSN無し接続が可能。最高のパフォーマンスのためにはOLEDBプロバイダを使うこと。 Y/N ADO or OLEDB provider Windowsのみ
ado_mssql B ADOを使ったMicrosoft SQL Server。DSN無し接続が可能。最高のパフォーマンスのためにはOLEDBプロバイダを使うこと。 Y/N ADO or OLEDB provider Windowsのみ
db2 A DB2。ODBCドライバをベースに確実に動作すべき。 Y/N DB2 CLI/ODBC interface

UnixとWindows。 Unixインストールヒント。CLIインタフェースを使うとき、Connect()で$hostと$databaseパラメタは逆にならなければならいと私はレポートしました。

vfp A Microsoft Visual FoxPro。ODBC DSNの作成が必要。 Y/N ODBC Windowsのみ
fbsql C FrontBase Y ?

UnixとWindows

ibase B Interbase 6以前。なんにんかのユーザが接続するにはこうしなければならないかもとレポートしています。
$db->PConnect('localhost:c:/ibase/employee.gdb', "sysdba", "masterkey") 現在Affected_Rowsはありません。

接続前に$db->role、$db->dialect、$db->buffers、$db->charSetを設定できます。
Y/N Interbase client UnixとWindows
firebird C InterbaseのFirebirdバージョン Y/N Interbase client UnixとWindows
borland_ibase C Interbase 6.5以降のBorlandバージョン。フォークが違うのはとても残念。 Y/N Interbase client UnixとWindows
informix C 汎用informixドライバ。Informix 7.3以降を使っているばあいこれを用いること。 Y/N Informix client UnixとWindows
informix72 C 7.3以前のInformixデータベースはSELECT FIRSTをサポートしていません。 Y/N Informix client UnixとWindows
ldap C LDAPドライバ。利用方法はサンプルを参照。   LDAP extension ?
mssql A

Microsoft SQL Server 7以降。Microsoft SQL Server 2000でも動きます。このドライバにかんしては日付フォーマットに問題があることに注意。例えば、PHP mssql拡張はdatetimeの秒を返しません。

Y/N Mssql client

UnixとWindows。
Unix install howtoもうひとつ別の

mssqlpo A

移植性のあるmssqlドライバ。結合演算子'||'が'+'に変換される点以外は、上のmssqlドライバと同じです。||を使っているほかのおおくのSQL異種からスクリプトを移植するのに便利です。

Y/N Mssql client

UnixとWindows
Unix install howto
.

mysql A トランザクションサポートのないMySQL。接続前に$db->clientFlagsを設定することができます。 Y MySQL client UnixとWindows
mysqlt or maxsql A

トランザクションサポートのあるMySQL。最良の移植性のために結合演算子として||を使うことを推奨します。これはMySQLを次のように実行すればできます。
mysqld --ansi or mysqld --sql-mode=PIPES_AS_CONCAT

Y/N MySQL client UnixとWindows
oci8 A Oracle 8/9。oracleドライバよりも多くの機能をもっています(例えばAffected_Rows)。 Connect/PConnectする前にputenv('ORACLE_HOME=...')しなければならないかもしれません。

サーバIPとサーバ名を使った、接続する2つの方法があります。
PConnect('serverip:1521','scott','tiger','service')
あるいは、TNSNAMES.ORAか、ONAMESか、HOSTNAMESのエントリを使って、
PConnect(false, 'scott', 'tiger', $oraname).

2.31から、Oracle REF cursor変数を直接サポートしています(ExecuteCursor参照)。

Y/N Oracle client UnixとWindows
oci805 C Oracle 8.0.5に対して少ないOracle機能をサポートしています。SelectLimitはoci8やoci8poドライバほど有能ではありません。 Y/N Oracle client UnixとWindows
oci8po A Oracle 8/9の移植性のあるドライバ。次の点をのぞきoci8ドライバと同じです。(a) Prepare()の結合変数は :bindvarの代わりに ? 規約を使う、(b) フィールド名は小文字名のより一般的なPHP規約を使う。

他のデータベースからの移植が重要ならこのドライバを使ってください。そうでなければoci8ドライバがより良いパフォーマンスを提供します。

Y/N Oracle client UnixとWindows
odbc A 汎用ODBCで、特定データベースに対して最適化されていません。接続するには、
PConnect('DSN','user','pwd')とします。これはほかのすべてのodbc派生ドライバのベースクラスです。
? depends on database ODBC UnixとWindows Unix hints.
odbc_mssql C MSSQL接続にODBCを使います。 Y/N ODBC UnixとWindows
odbc_oracle C Oracle接続にODBCを使います。 Y/N ODBC UnixとWindows
odbtp C 汎用odbtpドライバ。Odbtpは、他のオペレーティングシステムからWindows ODBCデータソースへアクセスするためのソフトウェアです。 Y/N odbtp UnixとWindows
odbtp_unicode C UNICODEサポートのあるOdtbp Y/N odbtp UnixとWindows
oracle C 古いOracle 7 client APIを実装しています。より良いパフォーマンスのためにはoci8を使ってください。 Y/N Oracle client UnixとWindows
netezza C Netezzaドライバ。Netezzaはpostgres code-baseをベースにしています。 Y ? ?
pdo C PHP5の汎用PDOドライバ Y PDO拡張とデータベース固有ドライバ UnixとWindows
postgres A 汎用PostgreSQLドライバ。今のところpostgres7ドライバと同じです。 driver. Y PostgreSQL client UnixとWindows
postgres64 A 内部的にLIMITをサポートしていないPostgreSQL 6.4以前用。 Y PostgreSQL client UnixとWindows
postgres7 A LIMITとバージョン7の他の機能をサポートしたPostgreSQL。 Y PostgreSQL client UnixとWindows
postgres8 A バージョン8機能をサポートしたPostgreSQL。 Y PostgreSQL client UnixとWindows
sapdb C SAP DB。ODBCドライバをベースにして確実に動作すべきです。 Y/N SAP ODBC client

?

sqlanywhere C Sybase SQL Anywhere。ODBCドライバをベースにして確実に動作すべきです。 Y/N SQL Anywhere ODBC client

?

sqlite B SQLite Y -

UnixとWindows

sqlitepo B 移植性のあるSQLiteドライバ。sqliteでは他のドライバのように連想モードが機能しないため。つまり、複数テーブルを選択(結合)すると、テーブル名が"sqlite"ドライバの連想キーに含まれます。

"sqlitepo"ドライバでは、テーブル名は返されたカラム名から取り除かれます。この結果が衝突したとき、最初のフィールドが優先されます。

Y -

UnixとWindows

sybase C Sybase. Y/N Sybase client

UnixとWindows

sybase_ase C Sybase ASE. Y/N Sybase client

UnixとWindows

"テスト"カラムはコードがどれだけ広範にテストされ使われたかを示しています。
A = よくテストされ多くの人に使用されている。
B = テストされ利用可能。しかし、いくつかの機能が実装されていない可能性があります。
C = ユーザ貢献あるいは実験的なドライバ。十全にADOdbの最新機能をサポートしていない可能性があります。

"RecordCount() 利用可否"カラムは、SELECT文が実行されたときRecordCount()が行数を返すかあるいは-1を返すかを示します。もしこのカラムがY/Nであれば、グローバル変数$ADODB_COUNTRECS=true(これはデフォルトです)のとき、RecordCount()はエミュレートされます。大きなレコードセットに対しては、RecordCount()のエミュレーションを無効にしておいたほうがよいかもしれません。カウントのためにレコードセットをキャッシュするため、かなりのメモリ量が必要となるからです。またスピードの点でもエミュレーションが要求されると40-50%のペナルティがあります。PostgreSQLとMySQLをのぞくほとんどのデータベースでエミュレートが行われます。変数はクエリーが実行されるたびにチェックされます。このためどのレコードをカウントするかを選択することができます。


チュートリアル

Example 1: Select文

タスク: Northwind DSNで Access に接続し、各行の最初の2カラムを表示する。

この例では、データベースへの接続を表すADO接続オブジェクトを生成します。接続は永続接続のPConnectで開始されます。データベースを検索をしたいときにはいつでも、 ADOConnection.Execute()関数をコールします。この関数 ADORecordSetオブジェクトを返します。ADORecordSet オブジェクトは実際にはfields[]配列の現在の行を保持しているカーソルです。 行から行への移動には MoveNext()を使います。

注意: この例では使われていない便利な関数としてSelectLimitがあります。この関数を使うと行数を制限できます。

<?
include('adodb.inc.php'); # ADOdb共通コードをロード
$conn = &ADONewConnection('access'); # connectionを生成
$conn->PConnect('northwind'); # MS-Access、 northwind DSNに接続
$recordSet = &$conn->Execute('select * from products');
if (!$recordSet)
print $conn->ErrorMsg();
else
while (!$recordSet->EOF) {
print $recordSet->fields[0].' '.$recordSet->fields[1].'<BR>';
$recordSet->MoveNext();
}
$recordSet->Close(); # 任意
$conn->Close(); # 任意
?>

返される $recordSetは、(0から開始する)カラムの番号で示される$recordSet->fields 配列の現在の行を格納しています。次の行に移動するにはMoveNext()関数を使います。ファイルの最後まで来ると、EOFプロパティがtrueに設定されます。Execute()でエラーが発生すると、レコードセットではなくfalseが返されます。

$recordSet->fields[]配列はPHPデータベース拡張によって生成されます。データベース拡張のなかには番号によってのみインデックスし、フィールド名で配列をインデックスしないものがあります。名前によるインデックス、すなわち連想配列を強制するには、SetFetchMode関数を使います。各レコードセットは、Execute() あるいは SelectLimit()で生成されたときに、設定されているフェッチモードを使って格納されます。

	$db->SetFetchMode(ADODB_FETCH_NUM);
$rs1 = $db->Execute('select * from table');
$db->SetFetchMode(ADODB_FETCH_ASSOC);
$rs2 = $db->Execute('select * from table');
print_r($rs1->fields); # shows array([0]=>'v0',[1] =>'v1') print_r($rs2->fields); # shows array(['col1']=>'v0',['col2'] =>'v1')

select結果の行数を得るには、$recordSet->RecordCount()を使います。結果の行数が不明のばあい-1が返されます。

Example 2: Field Objectsを使った進んだSelect

テーブルをselectして、最初2つのカラムを表示します。第2カラムがdate型かtimestamp型であれば、日付をUSフォーマットに整形します。

<?
include('adodb.inc.php'); # ADOdb共通コードをロード
$conn = &ADONewConnection('access'); # connectionを生成
$conn->PConnect('northwind'); # MS-Access、 northwind DSNに接続
$recordSet = &$conn->Execute('select CustomerID,OrderDate from Orders');
if (!$recordSet)
print $conn->ErrorMsg();
else
while (!$recordSet->EOF) {
$fld = $recordSet->FetchField(1); $type = $recordSet->MetaType($fld->type);

if ( $type == 'D' || $type == 'T')
print $recordSet->fields[0].' '.
$recordSet->UserDate($recordSet->fields[1],'m/d/Y').'<BR>';
else print $recordSet->fields[0].' '.$recordSet->fields[1].'<BR>';

$recordSet->MoveNext();
}
$recordSet->Close(); # 任意
$conn->Close(); # 任意
?>

この例では、FetchField()を使って、第2カラムのフィールドの型をチェックしています。これは少なくとも3つのフィールドをもったオブジェクトを返します。

ネイティブな型を汎用型へ翻訳するのに MetaType() を使います。現在以下の汎用 型が定義されています。

メタタイプが date型 か timestamp型のばあい、UserDate()を使って、ユーザ定義の日付フォーマットでprintします。UserDate()はPHP SQL日付文字列をユーザ定義のフォーマットに変換します。MetaType()の別の用途はSQL insertやupdateをする前にデータの有効性を確認することです。

Example 3: Insert

Ordersテーブルに行を追加するばあい、データベースに受け入れられるためには、日付と文字列をクオートする(引用符で囲む)必要があります。つまりJohn'sという言葉はシングルクオートで。

<?
include('adodb.inc.php'); # ADOdb共通コードをロード
$conn = &ADONewConnection('access'); # connectionを生成

$conn->PConnect('northwind'); # MS-Access、 northwind DSNに接続
$shipto = $conn->qstr("John's Old Shoppe");

$sql = "insert into orders (customerID,EmployeeID,OrderDate,ShipName) ";
$sql .= "values ('ANATR',2,".$conn->DBDate(time()).",$shipto)";

if ($conn->Execute($sql) === false) {
print 'error inserting: '.$conn->ErrorMsg().'<BR>';
}
?>

この例に、ADOdbの進歩した日付とクオートのハンドリング技能を見ることができます。unix timestamp (これはlong integerです)がDBDate()を使ってAccessに対して適切にフォーマットされます。正しいエスケープ文字列 John's Old Shoppeをクオートするのに使われます。John''s Old Shoppeであって、qstr()を使ったPHPのデフォルトJohn's Old Shoppeではありません。

Execute文のエラーハンドリングをよく見てください。なにかエラーが発生すれば、Execute()からfalseが返ります。発生した最後のエラーについてのエラーメッセージがErrorMsg()で表示されます。 注意: エラーメッセージを保存するにはphp_track_errorsを有効にしなければならない場合があります。

Example 4: デバッグ

<?
include('adodb.inc.php'); # ADOdb共通コードをロード
$conn = &ADNewConnection('access'); # connectionを生成
$conn->PConnect('northwind'); # MS-Access、 northwind DSNに接続
$shipto = $conn->qstr("John's Old Shoppe");
$sql = "insert into orders (customerID,EmployeeID,OrderDate,ShipName) ";
$sql .= "values ('ANATR',2,".$conn->FormatDate(time()).",$shipto)";
$conn->debug = true; if ($conn->Execute($sql) === false) print 'error inserting';
?>

上の例では、debug = trueでデバッグ機能を有効にしています。実行前にSQL文が表示されます。またエラーメッセージを表示します。ErrorMsg()を呼び出す必要はありません。レコードセットを表示するは、rs2html()の例を見てください。

Custom Error Handlersのセクションも見てください。

Example 5: MySQL とメニュー

MySQLデータベースのagoraに接続して、SQL文から<select>メニューを生成します。最初のカラムが<option>キャプションで、サーバに返される値は第二カラムとなります。

<?
include('adodb.inc.php'); # ADOdb共通コードをロード
$conn = &ADONewConnection('mysql'); # connectionを生成
$conn->PConnect('localhost','userid','','agora');# MySQLのagora dbに接続
$sql = 'select CustomerName, CustomerID from customers';
$rs = $conn->Execute($sql);
print $rs->GetMenu('GetCust','Mary Rosli');
?>

選択肢の'Mary Rosli'が選択状態のGetCustという名前のメニューを定義しています。GetMenu()を見てください。レコードセットを配列として返すGetArray()、第一カラムがキーとなる連想配列を返すGetAssoc()もあります。

Example 6: 2つのデータベースへの同時接続

<?
include('adodb.inc.php'); # ADOdb共通コードをロード
$conn1 = &ADONewConnection('mysql'); # mysql接続を生成
$conn2 = &ADONewConnection('oracle'); # oracle接続を生成

$conn1->PConnect($server, $userid, $password, $database);
$conn2->PConnect(false, $ora_userid, $ora_pwd, $oraname);

$conn1->Execute('insert ...');
$conn2->Execute('update ...');
?>

Example 7: UpdateとInsert SQL文の生成

ADOdb 4.56以降、AutoExecute()をサポートしています。AutoExecute()はGetInsertSQL()とGetUpdateSQL()に進歩したラッパーを提供することで、ものごとを単純化しています。例えば、INSERTは次のようにすることで可能です。

    $record["firstname"] = "Bob"; 
    $record["lastname"] = "Smith"; 
    $record["created"] = time(); 
    $insertSQL = $conn->AutoExecute($rs, $record, 'INSERT'); 
またUPDATEは次のようにして
    $record["firstname"] = "Caroline"; 
    $record["lastname"] = "Smith"; # Update Caroline's lastname from Miranda to Smith 
    $insertSQL = $conn->AutoExecute($rs, $record, 'UPDATE', 'WHERE id = 1'); 

このセクションの残りの部分は今では古めかしいものとなっています。

ADOdb 1.31以降、2つの新しいレコードセット関数GetUpdateSQL()とGetInsertSQL()をサポートしています。"SELECT * FROM table query WHERE..."を実行し、$rs->fieldsをコピーして、フィールドを変更し、そして自動的にテーブルへのUPDATEとINSERTを行うSQLを生成することができます。

この関数がどのように使うことができるかを示しましょう。次のフィールドをもったテーブルにアクセスしてみます。(ID, FirstName, LastName, Created)

これらの関数がコールできるようになる前に、テーブルにSELECTを実行してレコードセットを初期化する必要があります。これはJonathan Younger jyounger#unilab.coのアイデアでありコードです。ADOdb 2.42から、レコードセットの代わりにテーブル名をGetInsertSQL(in $rs)にわたすことができます。こうすることでそのテーブルへのINSERT文が生成されます。

<?
#==============================================
# SAMPLE GetUpdateSQL() and GetInsertSQL() code
#==============================================
include('adodb.inc.php');
include('tohtml.inc.php');

#==========================
# This code tests an insert

$sql = "SELECT * FROM ADOXYZ WHERE id = -1";
# Select an empty record from the database

$conn = &ADONewConnection("mysql"); # connectionを生成
$conn->debug=1;
$conn->PConnect("localhost", "admin", "", "test"); # connect to MySQL, testdb
$rs = $conn->Execute($sql); # Execute the query and get the empty recordset

$record = array(); # Initialize an array to hold the record data to insert

# Set the values for the fields in the record
# Note that field names are case-insensitive
$record["firstname"] = "Bob";
$record["lastNamE"] = "Smith";
$record["creaTed"] = time();

# Pass the empty recordset and the array containing the data to insert
# into the GetInsertSQL function. The function will process the data and return
# a fully formatted insert sql statement.
$insertSQL = $conn->GetInsertSQL($rs, $record);

$conn->Execute($insertSQL); # Insert the record into the database

#==========================
# This code tests an update

$sql = "SELECT * FROM ADOXYZ WHERE id = 1";
# Select a record to update

$rs = $conn->Execute($sql); # Execute the query and get the existing record to update

$record = array(); # Initialize an array to hold the record data to update

# Set the values for the fields in the record
# Note that field names are case-insensitive
$record["firstname"] = "Caroline";
$record["LasTnAme"] = "Smith"; # Update Caroline's lastname from Miranda to Smith

# Pass the single record recordset and the array containing the data to update
# into the GetUpdateSQL function. The function will process the data and return
# a fully formatted update sql statement with the correct WHERE clause.
# If the data has not changed, no recordset is returned
$updateSQL = $conn->GetUpdateSQL($rs, $record);

$conn->Execute($updateSQL); # Update the record in the database
$conn->Close();
?>
$ADODB_FORCE_TYPE

AutoExecute()、GetUpdateSQL()、GetInsertSQL()の振る舞いは、空っぽあるいはnullのPHP変数をSQLに変換するとき、グローバル変数$ADODB_FORCE_TYPE変数によって制御されます。以下の値のどれかを設定してください。デフォルトはADODB_FORCE_VALUE (3)です。

0 = 空フィールドを無視します。配列のすべてのからフィールドは無視されます。
1 = nullを強制します。すべての空白、PHPのnullと'null'文字列のフィールドがsqlのNULL値に変更されます。
2 = 空白を強制します。すべての空白、PHPのnullと'null'文字列のフィールドが''あるいは値0に変更されます。
3 = 値を強制します。値がそのまま残ります。PHPのnullと'null'文字列はSQLのNULL値に設定されます。そして
空白フィールド''はSQLの空白''に設定されます。

define('ADODB_FORCE_IGNORE',0);
define('ADODB_FORCE_NULL',1);
define('ADODB_FORCE_EMPTY',2);
define('ADODB_FORCE_VALUE',3);

$ADODB_FORCE_TYPEのコードをありがとうNiko (nuko#mbnet.fi)。

注意: ADODB_FORCE_NULLSは4.52以降でもはや使われず、無視されます。同等の振る舞いをさせるには$ADODB_FORCE_TYPE = ADODB_FORCE_NULLと設定してください。

4.62から、AutoExecute()、GetInsertSQL()、GetUpdateSQL()をコールする前に$rs->tableNameを設定することで、使用されるテーブル名は上書きすることができます。

Example 8: Next、Previousのあるスクローリングの実装

次のコードはとても簡単なレコードセットのページャを作ります。レコードセットをページからページへとスクロールさせることができます。

include_once('../adodb.inc.php');
include_once('../adodb-pager.inc.php');
session_start();

$db = NewADOConnection('mysql');

$db->Connect('localhost','root','','xphplens');

$sql = "select * from adoxyz ";

$pager = new ADODB_Pager($db,$sql);
$pager->Render($rows_per_page=5);

次のような基本的なレコードページャができます。

|<   <<   >>   >|  
ID First Name Last Name Date Created
36  Alan  Turing  Sat 06, Oct 2001 
37  Serena  Williams  Sat 06, Oct 2001 
38  Yat Sun  Sun  Sat 06, Oct 2001 
39  Wai Hun  See  Sat 06, Oct 2001 
40  Steven  Oey  Sat 06, Oct 2001 
Page 8/10

一度に表示する行数はRender($rows)で制御できます。Render()になにも値を渡さなければ、ADODB_Pagerはデフォルトの1ページ10レコードとします。

カラムのタイトルはSQL文を変更することで可能です。(これはたいていのデータベースでサポートされています。)

$sql = 'select id as "ID", firstname as "First Name", 
lastname as "Last Name", created as "Date Created"
from adoxyz';

上記のコードはこのリリースで収録されているadodb/tests/testpaging.phpに見つかります。またADODB_Pagerクラスはadodb/adodb-pager.inc.phpに見つかります。 ADODB_Pagerのコードはプログラマがカスタマイズできるので、テキストのリンクはイメージで置き換えたり、味気のない白い背景色を他の色にすることもできます。

$pager->htmlSpecialChars = falseとすればHTMLを表示できます。

ここで用いられているコードの一部はIván OlivaとCornel Gの貢献によります。

Example 9: CSV、タグ区切りフォーマットでエクスポート

CSV、タグ区切りへエクスポートするヘルパー関数を提供しています。

include_once('/path/to/adodb/toexport.inc.php');
include_once('/path/to/adodb/adodb.inc.php');
$db = &NewADOConnection('mysql');
$db->Connect($server, $userid, $password, $database);

$rs = $db->Execute('select fname as "First Name", surname as "Surname" from table');

print "<pre>";
print rs2csv($rs); # CSVフォーマットの文字列を返す

print '<hr>';

$rs->MoveFirst(); # 注意、データベースの中にはMoveFirstをサポートしないものあり
print rs2tab($rs,false); # tab区切りの文字列を返す
# falseで先頭行のフィールドを省略

print '<hr>';
$rs->MoveFirst();
rs2tabout($rs); # stdoutに直接送信(rs2csvout関数もあり)
print "</pre>";

$rs->MoveFirst();
$fp = fopen($path, "w");
if ($fp) {
rs2csvfile($rs, $fp); # ファイルに書き出し(rs2tabfileという関数もあり)
fclose($fp);
}

キャリッジリターンあるいは改行はスペースに変換されます。フィールド名は先頭行で返されます。区切り文字を含む文字列はダブルクオートで囲まれます。ダブルクオートはダブルクオートで囲まれます。これはExcelのインポートとエクスポートのガイドラインに沿うものです。

上の関数すべてに任意の最後のパラメタ$addtitlesがあります。これはデフォルトではtrueで、falseを設定すると、先頭行のフィールド名が省略されます。

Example 10: レコードセットフィルタ

ときおりレコードセットを使用するまえにすべての行を前処理したいことがあります。例えば、レコードセット中のすべてのテキストを大文字にしたいなど。

include_once('adodb/rsfilter.inc.php');
include_once('adodb/adodb.inc.php');

// レコードセットのすべての要素をucwords()
function do_ucwords(&$arr,$rs)
{
foreach($arr as $k => $v) {
$arr[$k] = ucwords($v);
}
}

$db = NewADOConnection('mysql');
$db->PConnect('server','user','pwd','db');

$rs = $db->Execute('select ... from table');
$rs = RSFilter($rs,'do_ucwords');

RSFilter関数は、レコードセットとfilter関数の名前の2つのパラメタをとります。そして最初のレコードに移動された処理済のレコードセットを返します。 filter関数は、配列になっているカレント行と、レコードセットのオブジェクトの2つのパラメタをとります。将来の互換性のため、オリジナルのレコードセットオブジェクトを使うべきではありません。

Example 11: スマートトランザクション

トランザクションの昔のやりかたでは次のようにしなければなりませんでした。
$conn->BeginTrans();
$ok = $conn->Execute($sql);
if ($ok) $ok = $conn->Execute($sql2);
if (!$ok) $conn->RollbackTrans();
else $conn->CommitTrans();
これは大きなプロジェクトにはひじょうに複雑です。エラーの状態を追跡しなければならないからです。スマートトランザクションはずっと単純です。StartTrans()をコールしてスマートトランザクションを開始します。
$conn->StartTrans();
$conn->Execute($sql);
$conn->Execute($Sql2);
$conn->CompleteTrans();
CompleteTrans()はSQLエラーが発生するとそれを検知して、適切にRollbackかCommitを実行します。エラーが発生しない場合でも、rollbackを強制したければFailTrans()を使います。 注意してください。CompleteTrans()の中でrollbackされます。FailTrans()の中ではありません。
$conn->StartTrans();
$conn->Execute($sql);
if (!CheckRecords()) $conn->FailTrans();
$conn->Execute($Sql2);
$conn->CompleteTrans();

HasFailedTrans()を使えばトランザクションが失敗したかどうかチェックできます。これはFailTrans()が呼ばれたり、SQL実行でエラーがあればtrueを返します。 CompleteTrans()をコールする前に、HasFailedTrans()をコールしてください。StartTrans/CompleteTransの間でだけ機能するからです。

最後に、StartTrans/CompleteTransはネストすることができます。そしていちばん外側のブロックだけが実行されます。対照的に、BeginTrans/CommitTrans/RollbackTransではネストはできません。

$conn->StartTrans();
$conn->Execute($sql);
$conn->StartTrans(); # 無視されます if (!CheckRecords()) $conn->FailTrans(); $conn->CompleteTrans(); # 無視されます $conn->Execute($Sql2); $conn->CompleteTrans();

注意: savepointは現在未サポートです。

カスタムエラーハンドラとPEAR_Errorの利用

ADOdbはPHP5拡張をサポートします。adodb-exceptions.inc.phpをインクルードするだけで、例外発生時に例外をキャッチすることができます。

	include("../adodb-exceptions.inc.php"); 
include("../adodb.inc.php");
try {
$db = NewADOConnection("oci8://scott:bad-password@mytns/");
} catch (exception $e) {
var_dump($e);
adodb_backtrace($e->gettrace());
}

ADOdbはまた自分のニーズに合わせて変更できる2つのカスタムハンドラを提供します。最初のものはadodb-errorhandler.inc.phpファイルに収められています。これは標準的なPHP関数error_reportingを使って、どのえらメッセージを表示するかを制御します。またデフォルトのPHPエラーハンドラをコールするtrigger_errorを使います。

上記のファイルをインクルードすると、trigger_error($errorstring,E_USER_ERROR)が次のばあいにコールされるようになります。
(a) Connect()あるいはPConnect()が失敗したとき
(b) Execute()あるいはSelectLimit()のようなSQL文実行関数でエラーが起きたとき
(c) GenID()が無限ループに陥ったと思われるとき

$errorstringがADOdbにより生成され、以下で生成されるerror.logデータに似たデバッグに役立つ情報を含むようになります。 ADO接続オブジェクトを生成するまえに、このadodb-errorhandler.inc.phpファイルをインクルードしなければなりません。

error_reporting(0)を定義すると、エラーが一つもエラーハンドラに渡らなくなります。error_reporting(E_ALL)を設定すると、すべてのエラーがエラーハンドラに渡るようになります。エラー表示を制御するには、ini_set("display_errors", "0" or "1")を使う必要があります。

<?php
error_reporting(E_ALL); # 発生したどんなエラーでもエラーハンドラーへ
include('adodb-errorhandler.inc.php');
include('adodb.inc.php'); include('tohtml.inc.php'); $c = NewADOConnection('mysql'); $c->PConnect('localhost','root','','northwind'); $rs=$c->Execute('select * from productsz'); # productszは不正なテーブル名'); if ($rs) rs2html($rs); ?>

エラーメッセージをロギングしたければ、以下の任意の定数ADODB_ERROR_LOG_TYPEとADODB_ERROR_LOG_DESTを定義することで可能です。ADODB_ERROR_LOG_TYPEはエラーログメッセージタイプです(PHPマニュアルのerror_logを見てください)。ここでは3に設定しているので、定数ADODB_ERROR_LOG_DESTで定義されたファイルにロギングされることになります。

<?php
error_reporting(E_ALL); # すべてのエラーを報告
ini_set("display_errors", "0"); # けれどエラーをechoさせない
define('ADODB_ERROR_LOG_TYPE',3);
define('ADODB_ERROR_LOG_DEST','C:/errors.log');
include('adodb-errorhandler.inc.php');
include('adodb.inc.php'); include('tohtml.inc.php'); $c = NewADOConnection('mysql'); $c->PConnect('localhost','root','','northwind'); $rs=$c->Execute('select * from productsz'); ## productszは不正なテーブル名 if ($rs) rs2html($rs); ?>
以下のメッセージがerror.logファイルにロギングされることになります。
(2001-10-28 14:20:38) mysql error: [1146: Table 'northwind.productsz' doesn't exist] in
EXECUTE("select * from productsz")

PEAR_ERROR

二番目のエラーハンドラはadodb-errorpear.inc.phpです。これはエラーが発生すればいつでもPEAR_Errorを継承したオブジェクトを生成します。最後に生成されたPEAR_ErrorオブジェクトはADODB_Pear_Error()を使って取得することができます。
<?php
include('adodb-errorpear.inc.php'); include('adodb.inc.php'); include('tohtml.inc.php'); $c = NewADOConnection('mysql'); $c->PConnect('localhost','root','','northwind'); $rs=$c->Execute('select * from productsz'); # productszは不正なテーブル名'); if ($rs) rs2html($rs); else { $e = ADODB_Pear_Error();
echo '<p>',$e->message,'</p>';
} ?>

adodb-errorpear.inc.phpファイルをインクルードする前に、定数ADODB_PEAR_ERROR_CLASSを定義することでPEAR_Error継承クラスを使うことができます。デバッグを容易にするには、PHPスクリプトの先頭でにデフォルトのエラーハンドラとしてPEAR_ERROR_DIEを設定します。PEAR_ERROR_DIEはエラーメッセージを出力させ、スクリプトの実行を停止します。

include('PEAR.php');
PEAR::setErrorHandling('PEAR_ERROR_DIE');

エラーが発生したとき、明示的にPEAR_Errorオブジェクトを返さないことに注意願います。その代わりにfalseを返します。最後のエラーを取得するにはADODB_Pear_Error()をコールしなければならないか、PEAR_ERROR_DIEのテクニックを使わなければなりません。

MetaErrorとMetaErrorMsg

複数のデータベースで有効なエラーメッセージが必要であれば、MetaError()を使います。これはPEAR DBのエラー番号システムにもとづく仮想的なエラー番号を返します。そしてMetaErrorMsg()です。

エラーメッセージ

エラーメッセージはスタティックメソッドADOConnnection::outp($msg,$newline=true)を使って出力されます。デフォルトではクライアントにメッセージを送信します。エラーをロギングするようにこれをオーバーライドすることができます。

データソース名(Data Source Names)

現在PEARスタイルのDSNを使った接続をサポートしています。DSNは次の形式の接続文字列です。

$dsn = "$driver://$username:$password@$hostname/$databasename";

例:

   $username = 'root';
$password = '';
$hostname = 'localhost';
$databasename = 'xphplens';
$driver = 'mysql';
$dsn = "$driver://$username:$password@$hostname/$databasename"
$db = NewADOConnection();
# 'adodb/adodb-pear.inc.php'を先頭でインクルードすればDB::Connect($dsn)も機能します
$rs = $db->query('select firstname,lastname from adoxyz');
$cnt = 0;
while ($arr = $rs->fetchRow()) {
print_r($arr); print "<br>";
}

DSNフォーマットについての詳細情報と接続サンプルexamples

PEARとの互換性

DSN(上を見てください)と以下の関数をサポートしています。
 DB_Common
 	query - エラー発生時PEAR_Errorを返します
	limitQuery - エラー発生時PEAR_Errorを返します
	prepare - エラー発生時PEAR_Errorを返しません
	execute - エラー発生時PEAR_Errorを返しません
	setFetchMode - ASSOCとORDEREDをサポート
	errorNative
	quote
	nextID
	disconnect
	
	getOne
	getAssoc
	getRow
	getCol
	
 DB_Result
 	numRows - サポートされてなければ-1を返します
	numCols
	fetchInto - fetchmode渡しは未サポート
	fetchRows - fetchmode渡しは未サポート
	free

レコードセットのキャッシング

ADOdbは現在、CacheExecute()、CachePageExecute()、CacheSelectLimit()関数を使ってレコードセットのキャッシングをサポートしています。キャッシュしない関数に似ていて、違いは第一パラメタ$secs2cacheをとる点です。

例:

include('adodb.inc.php'); # ADOdb共通コードをロード
$ADODB_CACHE_DIR = '/usr/ADODB_cache';
$conn = &ADONewConnection('mysql'); # connectionを生成
$conn->PConnect('localhost','userid','','agora');# MySQLのagora dbに接続
$sql = 'select CustomerName, CustomerID from customers';
$rs = $conn->CacheExecute(15,$sql);

第一パラメタはクエリーをキャッシュする秒数です。2回目以降のクエリー呼び出しでは、 $ADODB_CACHE_DIRに格納されているキャッシュされたバージョンを使うことになります。強制的にクエリーの実行しキャッシュをフラッシュするには、第一パラメタに0を設定してCacheExecute()をコールします。あるいは別の方法として、CacheFlush($sql)をコールします。

セキュリティのため、$ADODB_CACHE_DIRを使用する場合、php.iniでregister_globals=offと設定することを推奨します。

ADOdb 1.80以降、CacheSelectLimit()とCacheExecute()でsecs2cacheパラメタは任意です。指定しないでおくと$connection->cacheSecs(デフォルト値60秒)を使います。

	$conn->Connect(...);
$conn->cacheSecs = 3600*24; # 24時間のキャッシュ
$rs = $conn->CacheExecute('select * from table');

magic_quotes_runtimeはoffにしておくべきことに注意してください。詳細情報。それからクエリーが実行されるときキャッシュされたレコードセットが$ADODB_FETCH_MODEを使うのであれば、$ADODB_FETCH_MODE(あるいはSetFetchMode)を変更しないでください。

Pivotテーブル

ADOdb 2.30から、pivotテーブルあるいはクロス集計表(cross-tabulations)として知られるものを作成するSQLの生成をサポートしています。より詳細な説明にはDevShedのクロス集計表入門を読んでください。使用するデータベースがcase-when expressionをサポートしていることが前提になります。

ここで取り上げる例では、MicrosoftのNorthwindデータベースを使います。データベースには、productsテーブルがあり、このテーブルをsuppliers対product categoriesで分析したいと思っています。suppliersを各行に置き、categoriesでpivotします。左側のテーブルから、右側のpivotテーブルを生成します。

Supplier Category
supplier1 category1
supplier2 category1
supplier2 category2
-->
  category1 category2 total
supplier1 1 0 1
supplier2 1 1 2

以下のコードはクロス集計表のためのSQLを生成します。

# Query the main "product" table
# Set the rows to CompanyName
# and the columns to the values of Categories
# and define the joins to link to lookup tables
# "categories" and "suppliers"
#
include "adodb/pivottable.php";
$sql = PivotTableSQL(
$gDB, # adodb connection
'products p ,categories c ,suppliers s', # tables
'CompanyName', # rows (multiple fields allowed)
'CategoryName', # column to pivot on
'p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID' # joins/where
);

以下のSQLが生成されます。

SELECT CompanyName,
SUM(CASE WHEN CategoryName='Beverages' THEN 1 ELSE 0 END) AS "Beverages",
SUM(CASE WHEN CategoryName='Condiments' THEN 1 ELSE 0 END) AS "Condiments",
SUM(CASE WHEN CategoryName='Confections' THEN 1 ELSE 0 END) AS "Confections",
SUM(CASE WHEN CategoryName='Dairy Products' THEN 1 ELSE 0 END) AS "Dairy Products",
SUM(CASE WHEN CategoryName='Grains/Cereals' THEN 1 ELSE 0 END) AS "Grains/Cereals",
SUM(CASE WHEN CategoryName='Meat/Poultry' THEN 1 ELSE 0 END) AS "Meat/Poultry",
SUM(CASE WHEN CategoryName='Produce' THEN 1 ELSE 0 END) AS "Produce",
SUM(CASE WHEN CategoryName='Seafood' THEN 1 ELSE 0 END) AS "Seafood",
SUM(1) as Total
FROM products p ,categories c ,suppliers s WHERE p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID
GROUP BY CompanyName

範囲を使って数値カラム生成された合計でpivotできます。このコードはADODB 2.41のときに変更されていて、下位互換性はありません。二番目の例は次のとおりです。

 $sql = PivotTableSQL(
$gDB, # adodb connection
'products p ,categories c ,suppliers s', # tables
'CompanyName', # rows (multiple fields allowed) array( # column ranges ' 0 ' => 'UnitsInStock <= 0', "1 to 5" => '0 < UnitsInStock and UnitsInStock <= 5', "6 to 10" => '5 < UnitsInStock and UnitsInStock <= 10', "11 to 15" => '10 < UnitsInStock and UnitsInStock <= 15', "16+" => '15 < UnitsInStock' ), ' p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID', # joins/where 'UnitsInStock', # sum this field 'Sum ' # sum label prefix );

次のSQLが生成されます。

SELECT CompanyName,
SUM(CASE WHEN UnitsInStock <= 0 THEN UnitsInStock ELSE 0 END) AS "Sum 0 ",
SUM(CASE WHEN 0 < UnitsInStock and UnitsInStock <= 5 THEN UnitsInStock ELSE 0 END) AS "Sum 1 to 5",
SUM(CASE WHEN 5 < UnitsInStock and UnitsInStock <= 10 THEN UnitsInStock ELSE 0 END) AS "Sum 6 to 10",
SUM(CASE WHEN 10 < UnitsInStock and UnitsInStock <= 15 THEN UnitsInStock ELSE 0 END) AS "Sum 11 to 15",
SUM(CASE WHEN 15 < UnitsInStock THEN UnitsInStock ELSE 0 END) AS "Sum 16+",
SUM(UnitsInStock) AS "Sum UnitsInStock",
SUM(1) as Total,
FROM products p ,categories c ,suppliers s WHERE p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID
GROUP BY CompanyName


Classリファレンス

[ ] 付きの関数パラメタは任意です。

グローバル変数

$ADODB_COUNTRECS

もしそのデータベースドライバAPIがSELECT文で返されるレコード数のカウントをサポートしていなければ、グローバル変数$ADODB_COUNTRECSがデフォルトのtrueに設定されているとき、RecordCount()関数がエミュレートされます。レコードをバッファリングすることでエミュレートします。このため大きなレコードセットには大量のメモリを消費することになります。最善のパフォーマンスのためにはこの変数をfalseに設定します。この変数はクエリーが実行されるたびにチェックされるので、カウントすべきレコードセットを選択することができます。

$ADODB_CACHE_DIR

レコードセットキャッシングを使用するばあい、この変数はレコードセットを格納するディレクトリを示します。CacheExecute()のようなどんなキャッシング関数を呼ぶ前にも、この変数を定義してください。この機能をセキュリティの理由で採用するのであれば、php.iniではregister_globals=offと設定することを推奨します。

Unixとapacheの組合せで使用するばあい、キャッシュディレクトリに以下のようなパーミッション設定をする必要があるかもしれません。

chown -R apache /path/to/adodb/cache
chgrp -R apache /path/to/adodb/cache

$ADODB_ANSI_PADDING_OFF

CHARフィールド(ibase/firebirdではVARCHARも)をright trimするかどうかを決定します。trueに設定されているとtrimします。デフォルトはfalse。現在oci8po、ibase、firebirdのドライバで機能します。 ADOdb 4.01で追加されました。

$ADODB_LANG

MetaErrorMsg()で使われる言語を決定します。デフォルトはEnglishで'en'です。どの言語がサポートされているかは、adodb/lang/adodb-$lang.inc.phpのファイルを見てください。そこにある$langがサポートされている言語です。

$ADODB_FETCH_MODE

これはレコードセットによってどのように配列がとられるかを決定するグローバル変数です。レコードセットはこの値を生成時に(例えば、Execute( )やSelectLimit()のなかで)保存します。$ADODB_FETCH_MODEに対する以降の変更は既存のレコードセットに影響を与えません。これから生成されるレコードセットにのみ影響を与えます

以下の定数が定義されています。

define('ADODB_FETCH_DEFAULT',0);
define('ADODB_FETCH_NUM',1);
define('ADODB_FETCH_ASSOC',2);
define('ADODB_FETCH_BOTH',3);

例:

	$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$rs1 = $db->Execute('select * from table');
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$rs2 = $db->Execute('select * from table');
print_r($rs1->fields); # array([0]=>'v0',[1] =>'v1')を表示 print_r($rs2->fields); # array(['col1']=>'v0',['col2'] =>'v1')を表示

上記の例に見えるように、両レコードセットはExecute()によってレコードセットが生成されたときに $ADODB_FETCH_MODE設定にもとづく異なるフェッチモードを使って保存されます。

どんなフェッチモードもあらかじめ定義されていなければ、フェッチモードはデフォルトのADODB_FETCH_DEFAULTとなります。このデフォルトモードの振る舞いはドライバによって変わります。このためADODB_FETCH_DEFAULTに依存しないでください。移植性のためには、ADODB_FETCH_NUMかADODB_FETCH_ASSOCのどちらかを決めて使い続けることを推奨します。多くのドライバはADODB_FETCH_BOTHをサポートしていません。

SetFetchMode関数

複数の接続オブジェクトがあって、別個のフェッチモードとしたいばあいには、SetFetchModeを使います。接続オブジェクトに対していちどこの関数が呼ばれると、接続オブジェクトはグローバル変数$ADODB_FETCH_MODEを無視して、排他的に内部のフェッチモードを使うようになります。

	$db->SetFetchMode(ADODB_FETCH_NUM);
$rs1 = $db->Execute('select * from table');
$db->SetFetchMode(ADODB_FETCH_ASSOC);
$rs2 = $db->Execute('select * from table');
print_r($rs1->fields); # array([0]=>'v0',[1] =>'v1')を表示 print_r($rs2->fields); # array(['col1']=>'v0',['col2'] =>'v1')を表示

以前のフェッチモードを取得するには、$db->fetchMode属性をチェックするか、SetFetchMode()の戻り値を使います。

ADODB_ASSOC_CASE

異なる振る舞いをもついくつかのドライバに対して連想フェッチを制御することができます。sybase、 oci8po、mssql、odbc、ibaseとこれらから派生したドライバに対して、ADODB_ASSOC_CASEはデフォルトでフィールド名キーが小文字のレコードセットを生成します。キーの大文字小文字を変更するには定数ADODB_ASSOC_CASEを使ってください。3つの値が可能です。

0 = 連想小文字フィールド名 $rs->fields['orderid']
1 = 連想大文字フィールド名 $rs->fields['ORDERID']
2 = ネイティブのフィールド名 $rs->fields['OrderID'] -- ADOdb 2.90からのデフォルト

これを使うには、adodb.inc.phpをインクルードする前に、宣言してください。

define('ADODB_ASSOC_CASE', 2); # ADODB_FETCH_ASSOCにネイティブケースを使用
include('adodb.inc.php');

$ADODB_FORCE_TYPE

GetUpdateSQLチュートリアルを見てください。


ADOConnection

データベースへ接続し、SQL文を実行するオブジェクトです。また、文字列結合や日付フォーマットの問題に対してSQL文のフォーマットを標準化するユーティリティ関数もそろえています。

ADOConnectionフィールド

databaseType: 接続しようとするデータベースシステム名。例えば、odbcmssqlmysql

dataProvider: データベース接続に使われる下位の機構。odbcadoを使わないのであれば、通常はnative

host: 接続するサーバの名前、あるいはデータソース名(DSN)

database: 接続するデータベースの名前。adoが使われるばあい、adoデータプロバイダを保持します。

user: データベースに接続するログインID。Passwordはセキュリティの理由から保存されません。

raiseErrorFn: エラーハンドリング関数を定義できます。例はadodb-errorhandler.inc.phpを参照。

debug: trueに設定するとデバッグ文が表示されます。

concat_operator: 通常は'+'か'||'を設定。SQLで文字列を結合するときに使うオペレータ。Concat関数で使われます。

fmtDate: 日付をデータベースに送信するDBDate関数で使われるフォーマット。Microsoft Accessに対しては'#Y-m-d#'、MySQLに対しては''Y-m-d''。

fmtTimeStamp: タイムスタンプをデータベースに送信するDBTimeStampで使われるフォーマット。

true: trueを表現する値。例、Foxproでは'.T.'、Microsoft SQLでは'1'。

false: falseを表現する値。 Foxproでは'.F.'、Microsoft SQLでは'0'。

replaceQuote: クオートでエスケープする文字列。例えば、Microsoft SQLはダブルシングルクオート、MySQLはバックスラッシュクオート。qstrによって使われます。

autoCommit: 自動コミットするようになっているかどうかを示す。デフォルトはtrueです。

charSet: 使用するデフォルトの文字セット。今のところはinterbase/firebirdのみサポート。

dialect: 使用するデフォルトのSQL方言を設定。set the default sql dialect to use. 今のところはinterbase/firebirdのみサポート。

role: ロールを設定。今のところはinterbase/firebirdのみサポート。

metaTablesSQL: 利用可能なテーブルの一覧を返すSQL文。例えば、MySQLではSHOW TABLES

genID: データベースがサポートしていればGenID()によって生成される直近のID。

cacheSecs: CacheExecute()あるいはCacheSelectLimit()に$secs2cacheがわたされなかったばあい、レコードセットをキャッシュする秒数。デフォルトは60秒です。

sysDate: 現在の日付を取得するため呼び出すデータベース関数名を保持する文字列。INSERTとUPDATEで有用です。

sysTimeStamp:現在のタイムスタンプ/日付時刻の値を取得するため呼び出すデータベース関数名を保持する文字列。

leftOuter: 分かっていれば、LEFT OUTER JOINのための演算子を保持する文字列。さもなくばfalseを設定。

rightOuter: 分かっていれば、RIGHT OUTER JOINのための演算子を保持する文字列。さもなくばfalseを設定。

ansiOuter: trueであればANSIスタイルのOUTER JOINが許されていることを示すBoolean。例えば、select * from table1 left join table2 on p1=p2.

connectSID: oci8ドライバに対して接続で$databaseをSIDとして扱うかどうかを示すBoolean。デフォルトはfalseです。Oracle 8.0.5とそれ以前のバージョンで利用できます。

autoRollback: trueに設定されていれば、永続接続はPConnect()で自動ロールバックされます。デフォルトはfalseです。


ADOConnection主要関数

ADOConnection()

コンストラクタ関数。直接これをコールしないでください。代わりにADONewConnection()を使ってください。

Connect($host,[$user],[$password],[$database])

データソースあるいはサーバ$hostに、ユーザID$user、パスワード$passwordで、非永続接続。サーバが複数のデータベースをサポートしているばあい、データベース$databaseに接続します。

接続の成功かどうかでtrueまたはfalseを返します。4.23以降、データベース拡張がロードされないばあいにはnullが返ります。

ADOにかんして、OLEDBではなくMicrosoftのADOを使っているばあい、$databaseパラメタをあなたが使用しているOLEDBデータプロバイダに設定することができます。

PostgreSQLにかんして、データベース接続の他の方法として、標準的なPostgreSQL接続文字列を第一パラメタ$hostでわたすことがでいます。このときそれ以外のパラメタは無視されることになります。

OracleとOci8に対しては、接続する2つの方法があります。最初のものは、ローカルのtnsnames.ora(あるいはONAMESあるいはHOSTNAMES)で定義されているTNS名を使う方法です。もう一つの方法は、$hostをサーバに設定し、$databaseをデータベースSIDに設定するやりかたです。こうするとtnsnames.oraがバイパスされます。

Examples:

 # tnsnames.ora/ONAMES/HOSTNAMESの$oraname
$conn->Connect(false, 'scott', 'tiger', $oraname);
$conn->Connect('server:1521', 'scott', 'tiger', 'ServiceName'); # tnsnames.oraをバイパス

データベースへのたくさんの接続例があります。接続例を見てください。

PConnect($host,[$user],[$password],[$database])

データソースあるいはサーバ$hostに、ユーザID$user、パスワード$passwordで、永続接続。サーバが複数のデータベースをサポートしているばあい、データベース$databaseに接続します。

PHPマニュアルでアドバイスされているやり方で、2.21以降選択されたデータベースへの永続接続でロールバックが実行されます。どのデータベースが影響を受けるかは変更履歴またはソースコードを見てください。

接続が成功かどうかでtrueまたはfalseを返します。4.23以降、データベース拡張がロードされないばあいにはnullが返ります。詳細は先のConnect()を見てください。

ADOdb 2.21から、設定していれば、autoRollbackもサポートしています。

 $conn = &NewADOConnection('mysql');
$conn->autoRollback = true; # デフォルトはfalse
$conn->PConnect(...); # ここでrollback

PConnect()で永続接続をするとき、ADOdbは最初にロールバックを行います。これは次のように説明されているからです。永続接続が使われるとき、PHPは既存の失敗しているトランザクションをロールバックすることを保証されていない。これは現在Oracle、MySQL、PgSQL、MSSQL、ODBCで実装されています。

ADOdb 3.11から、たとえPConnectをコールするまえに定数ADODB_NEVER_PERSISTを定義してPConnectが呼ばれても、非永続接続を強制することができます。

4.23以降、データベース拡張がロードされないばあいにはnullが返ります。

NConnect($host,[$user],[$password],[$database])

つねに新しい接続を強制します。対照的に、Connect()あるいはPConnect()を使うとき、PHPは接続を再利用します。今のところ、mysql(PHP 4.3.0以降)、postgresql、oci8系のドライバで有効です。それ以外のドライバに対しては、NConnect()はConnect()と同じように機能します。

IsConnected( )

データベースに接続されていればtrueを返します。4.53で追加されました。

Execute($sql,$inputarr=false)

$sqlで指定されたSQLステートメントを実行します。成功したばあい、ADORecordSetの継承クラスが返されます。INSERTやUPDATEを実行したばあいにも、つねにADORecordSetが返されます。Prepare()で作成できる準備済みステートメントを$sqlに渡すこともできます。

リターンはADORecordSetの継承クラスです。例えば、mysqlの接続の場合には、ADORecordSet_mysqlが返されます。SQLの実行中にエラーがあれば、falseが返ります。

$inputarrパラメタは変数をパラメタに結合するために使うことができます。以下はOracleの例です。

 $conn->Execute("SELECT * FROM TABLE WHERE COND=:val", array('val'=> $val));

ODBCを使った別の例では?規約を使います。

  $conn->Execute("SELECT * FROM TABLE WHERE COND=?", array($val));
結合変数

変数の結合はSQL文のコンパイルとキャッシュを効率化し、高いパフォーマンスにつながります。現状、Oracle、Interbase、ODBCが変数の結合をサポートしています。結合をサポートしていないデータベースでは、Interbase/ODBCスタイルの ? がエミュレートされます。結合を使うばあい、文字列をクオートする必要がないことに注意してください。

ODBC、Interbase、oci8poドライバにおける変数の結合

$rs = $db->Execute('select * from table where val=?', array('10'));
oci8ドライバにおける変数の結合
$rs = $db->Execute('select name from table where val=:key', array('key' => 10));
一括結合

ADOdb 3.80から、Execute()で一括結合をサポートしています。2次元配列を結合するINSERT、UPDATE、DELETE文にわたせます。

$arr = array(
array('Ahmad',32),
array('Zulkifli', 24),
array('Rosnah', 21)
);
$ok = $db->Execute('insert into table (name,age) values (?,?)',$arr);

これはSQL文が最初に準備されるので、としてひじょうに高速なパフォーマンスを提供します。全ての行が完了するまで、あるいはエラーが発生するまで、準備済み文が各配列の行に対して繰り返し実行されます。データをインポートするのにひじょうに役立ちます。

CacheExecute([$secs2cache,]$sql,$inputarr=false)

レコードセットが$secs2cache秒のあいだ$ADODB_CACHE_DIRディレクトリにキャッシュされ、また$inputarrは1次元配列のみを受け付けるという点をのぞきExecuteと同じです。同一の$sqlと$inputarrで、また同一のデータベース、同一のuseridでCacheExecute()が呼び出され、キャッシュされているレコードセットが有効期限切れでなければ、キャッシュされているレコードセットが返されます。

  include('adodb.inc.php'); 
include('tohtml.inc.php');
$ADODB_CACHE_DIR = '/usr/local/ADOdbcache';
$conn = &ADONewConnection('mysql');
$conn->PConnect('localhost','userid','password','database');
$rs = $conn->CacheExecute(15, 'select * from table'); # 15秒キャッシュ
rs2html($rs); /* recordsetをhtmlテーブルに */

あるいは、ADOdb 1.80から$secs2cacheパラメタが任意になっています。

	$conn->Connect(...);
$conn->cacheSecs = 3600*24; // 24時間キャッシュ
$rs = $conn->CacheExecute('select * from table');
$secs2cacheが省略されていれば、$connection->cacheSecs(デフォルト3600秒、すなわち1時間)の値を使います。SELECT文でのみCacheExecute()を使用してください。

パフォーマンスノート: 私はいくつかのベンチマークを実施して次のことが分かりました。状況によって結果が大きくことなるので、キャッシングがいつ有益であるかを話しておくのがよいでしょう。データベースサーバがWebサーバよりもずっと遅いか、あるいはデータベースにひじょうに大きな負荷がかかっているとき、ADOdbのキャッシングは有効です。なぜならデータベースの付加を軽減してくれますから。もしデータベースサーバの付加が軽いか、Webサーバよりも速ければ、キャッシングは実際にはパフォーマンスを損ねてしまいます。

ExecuteCursor($sql,$cursorName='rs',$parameters=false)

Oracleのストアドプロシージャを実行して、正規のADOdbレコードセットとしてOracleのREFカーソル変数を返します。oci8以外のデータベースでは機能しません。設計してくれたRobert Tuttleに感謝します。

    $db = ADONewConnection("oci8"); 
$db->Connect("foo.com:1521", "uid", "pwd", "FOO");
$rs = $db->ExecuteCursor("begin :cursorvar := getdata(:param1); end;",
'cursorvar',
array('param1'=>10));
# このとき$rsは他のADOdbレコードセットとそっくりです
rs2html($rs);

ExecuteCursor()はヘルパー関数で、内部的には以下を実行しています。

	$stmt = $db->Prepare("begin :cursorvar := getdata(:param1); end;", true); 
$db->Parameter($stmt, $cur, 'cursorvar', false, -1, OCI_B_CURSOR);
$rs = $db->Execute($stmt,$bindarr);

ExecuteCursorは1つのoutパラメタしか受け付けません。それで2つのoutパラメタがあるばあいには、次のようにしてください。

	$vv = 'A%';
$stmt = $db->PrepareSP("BEGIN list_tabs(:crsr,:tt); END;");
$db->OutParameter($stmt, $cur, 'crsr', -1, OCI_B_CURSOR);
$db->OutParameter($stmt, $vv, 'tt', 32); # return varchar(32)
$arr = $db->GetArray($stmt);
print_r($arr);
echo " val = $vv"; ## outputs 'TEST'
以下が対応するPL/SQLです。
	TYPE TabType IS REF CURSOR RETURN TAB%ROWTYPE;

PROCEDURE list_tabs(tabcursor IN OUT TabType,tablenames IN OUT VARCHAR) IS
BEGIN
OPEN tabcursor FOR SELECT * FROM TAB WHERE tname LIKE tablenames;
tablenames := 'TEST';
END list_tabs;

SelectLimit($sql,$numrows=-1,$offset=-1,$inputarr=false)

成功すればレコードセットを返します。そうでなければfalseを返します。PostgreSQLのSELECT文をシミュレートして、LIMIT $numrows OFFSET $offset 節で、SELECT文を実行します。

PostgreSQLでは、SELECT * FROM TABLE LIMIT 3 は最初の3レコードだけを返すことになります。ADOdbでこれと等しいのが$connection->SelectLimit('SELECT * FROM TABLE',3)です。この機能をもっていないデータベースでは機能がシミュレートされます。

またSELECT * FROM TABLE LIMIT 3 OFFSET 2は3、4、5のレコードを返すことになります(つまり2レコードの後の3行)。ADOdbでこれと等しいのが$connection->SelectLimit('SELECT * FROM TABLE',3,2)です。

これはMySQLのLIMIT節とは反対という点に注意してください。また11行目から最後の行までを取得するには、$connection->SelectLimit('SELECT * FROM TABLE',-1,10)とします。

最後のパラメタ$inputarrは変数結合をサポートしているOracle oci8のようなデータベースに対するものです。これはSQLのコンパイルオーバーヘッドを大いに下げてくれます。以下はOracleの例です。

 $conn->SelectLimit("SELECT * FROM TABLE WHERE COND=:val", 100,-1,array('val'=> $val));

oci8poドライバ(oracleのポータブルドライバ)はもっと標準的な ? の結合変数を使います。

 $conn->SelectLimit("SELECT * FROM TABLE WHERE COND=?", 100,-1,array('val'=> $val));

Ron WilsonがSelectLimitはUNIONでは機能しないことを報告しています。

CacheSelectLimit([$secs2cache,] $sql, $numrows=-1,$offset=-1,$inputarr=false)

レコードセットが$ADODB_CACHE_DIRディレクトリに$secs2cache秒のあいだキャッシュされるという点をのぞき、SelectLimitと同じです。

1.80から、$secs2cacheは任意になりました。キャッシング時間を$connection->cacheSecs.で定義することができます。

$conn->Connect(...);
$conn->cacheSecs = 3600*24; // 24時間キャッシュ
$rs = $conn->CacheSelectLimit('select * from table',10);

CacheFlush($sql=false,$inputarr=false)

$ADODB_CACHE_DIRにそのSQL文に対してキャッシュされているどんなレコードセットもフラッシュ(削除)します。

パラメタがわたされなければ、すべてのadodb_*.cacheファイルが削除されます。

キャッシュされているすべてのレコードセットをマニュアルで削除したければ、以下のPHPコードを実行してください(Unix環境でのみ有効です)。
  system("rm -f `find ".$ADODB_CACHE_DIR." -name adodb_*.cache`");

すべての有効期限切れファイルを消去するには、Unixではcrontabを、Windowsではat.exeを使うべきでしょう。それは以下のようシェルスクリプトになるでしょう。
#------------------------------------------------------
# この例では名前に".cache"という文字列をもつTMPPATH
# ディレクトリにあるファイルで7日以上経過したものを
# 削除します。
#------------------------------------------------------
AGED=7
find ${TMPPATH} -mtime +$AGED | grep "\.cache" | xargs rm -f

MetaError($errno=false)

PEAR DBのエラー番号システムにもとづく仮想エラー番号を返します。この関数を呼ぶ前にadodb-error.inc.phpをインクルードしておく必要があります。パラメタの$errnoは変換したいネイティブのエラー番号です。パラメタをわたさなければ、MetaErrorはあなたに代わってErrorNo()をコールしてそれを変換します。エラー番号か仮想化できないばあい、MetaErrorは-1(DB_ERROR)を返します。

MetaErrorMsg($errno)

MetaError()から返されるエラー番号をわたして対応するテキストのエラーメッセージを取得します。

ErrorMsg()

最後の状態あるいはエラーメッセージを返します。エラーメッセージはExecute()がコールされるたびにリセットされます。

エラーが発生していなくても文字列を返します。ADOdb関数がエラー発生時にfalseを返さなければ、通常はこの関数をコールする必要はありません。

注意: debugが有効になっているばあい、Execute関数がコールされるとき、そのSQLエラーメッセージはつねに表示されます。

ErrorNo()

最後のエラー番号を返します。エラー番号はExecute()がコールされるたびにリセットされます。エラーがなければ、0が返ってきます。

4.0.6以前のPHPではODBCのエラー番号をサポートしていないことに注意してください。ADOdb関数がエラー発生時にfalseを返さなければ、通常この関数をコールする必要はありません。

SetFetchMode($mode)

接続に対する現在のフェッチモードを設定し、$conn->fetchModeに格納します。正規のモードはADODB_FETCH_ASSOCとADODB_FETCH_NUMです。詳細は$ADODB_FETCH_MODEを参照。

これまでSetFetchMode()が呼ばれていなくてfalseでありうるばあい、以前のフェッチモードが返ります。

CreateSequence($seqName = 'adodbseq',$startID=1)

シーケンスを作ります。次にGenID()がコールされると、その値は$startIDとなります。2.60で追加されました。

DropSequence($seqName = 'adodbseq')

シーケンスを削除します。2.60で追加されました。

GenID($seqName = 'adodbseq',$startID=1)

シーケンス番号を生成します。今のところinterbase、mysql、postgresql、oci8、oci8po、mssql、ODBCベース(access、vfp、db2、など)のドライバで機能します。シーケンスの名前として$seqNameを使ってください。シーケンスが存在していなければ、GenID()は自動的にシーケンスを作ります(そのuseridにそうする権限があることが条件)。そうでなければ自分自身でシーケンスを作らなければならなくなります。

データベースドライバがシーケンスをエミュレートするなら、テーブル名がシーケンス名です。テーブルは"id"というカラムを1つもち、それはintegerか、あるいはより大きいのであればnumeric(16)であるべきです。

ネイティブにシーケンスをサポートしていないODBCとデータベースに対して(つまりmssqlやmysql)、各シーケンスのためのテーブルを作ります。そのシーケンスがそれまでに定義されていなければ、開始値に$startIDが設定されて作成されます。

1.90以前、mssqlドライバのGenID()は16バイトのGUIDを生成していました。

UpdateBlob($table,$column,$val,$where)

($valで指定される)BLOBを$tableの$whereで指定された行の$columnに格納することができます。

使用方法:

	# Oracle
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, empty_blob())');
$conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1');

# Oracle以外のデータベース
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
$conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1');

成功したらtrueが、失敗したらfalseが返ります。MySQL、PostgreSQL、Oci8、Oci8po、Interbaseでサポートされます。開発状況に応じて、他のドライバでも機能するかもしれません。

InterbaseのBLOBがSELECTを使って取得されるとき、4.1.0以前のPHPバージョンで元の値を取得するには$connection->DecodeBlob($blob);を使ってデコードされる必要があることに注意してください。

PostgreSQLでは、BLOB oidあるいはバイトフィールドを使ってBLOBを保存できます。UpdateBlob()では今のところバイトフィールドは使えますが、BLOB oidは使えません。反対にUpdateBlobFile()ではoidをサポートしていて、バイトデータをサポートしていません。

oidをわたさなければ、UpdateBlob()はバイトフィールドに格納されていると想定します。

BLOBフィールドがなにもなければ、$connection->disableBlobs = trueでBLOBハンドリングを無効にして、SQLクエリーの一般的なパフォーマンスを向上することができます。

UpdateClob($table,$column,$val,$where)

($valの)CLOBを$tableの$whereで指定された行の$columnに格納することができます。先のUpdateBlobとの相違は、Character Large OBjectsを扱うという点です。

使用方法:

	# Oracle
$conn->Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, empty_clob())');
$conn->UpdateBlob('clobtable','clobcol',$clobvalue,'id=1');

# Ooracle以外のデータベース
$conn->Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, null)');
$conn->UpdateBlob('clobtable','clobcol',$clobvalue,'id=1');

UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')

BLOBの存在場所としてファイルのパスをわたすという点以外、UpdateBlobと同じです。

PostgreSQLでは、BLOB oidを使うのであれば、このインタフェースを使用してください。このインタフェースはバイトフィールドをサポートしていません。

成功したらtrue、それ以外はfalseを返します。

BlobEncode($blob)

データベースの中にはアップロードされる前に手動でエンコードすることを要求するものがあります。もしUpdateBlob()あるいはUpdateBlobFile()を使っているのであれば、その変換は自動的にされるので、あなたがこの関数をコールする必要はありません。PostgreSQLでは、今のところ、BlobEncode()はバイトフィールドに対してのみ使うことができます。

エンコードされたBLOBの値が返されます。

次の3つの合法な値をもつblobEncodeTypeと呼ばれる接続プロパティがあるので留意してください。

false - エンコードやデコードの必要なし
'I' - BLOBのエンコードが必要で、戻りのエンコードされたBLOBは数値(クオートが不要)
'C' - BLOBのエンコードが必要で、戻りのエンコードされたBLOBは文字(クオートが必要)

これは純粋に文書化のためであって、複数のデータベースドライバを受け付けるプログラムはBLOBを処理するときになにをなすべきかを知っています。

BlobDecode($blob, $maxblobsize = false)

データベースの中にはSELECT文を実行した後に手動でデコードすることを要求するものがあります。もしデータベースがデコードを必要としないのであれば、この関数は変更されないBLOBを返します。今のところBlobDecodeはPostgreSQLで、BLOB oidを使っているときのみ要求します。(バイトフィールドを使っているばあいは、自動的にデコードが行われます。) デフォルトの最大BLOBサイズは$connection->maxblobsizeに設定されていて、ADOdb 4.54では256Kになっています。

$rs = $db->Execute("select bloboid from postgres_table where id=$key");
$blob = $db->BlobDecode( reset($rs->fields) );

Replace($table, $arrFields, $keyCols,$autoQuote=false)

レコードのUPDATEを試み、レコードが見つからなければ、INSERT文を生成して実行します。失敗時には0が、UPDATE文が成功したときには1 が、レコードが見つからずにINSERT文の実行が成功したなら2が返ります。これはMySQLのreplace機能とは違ってます。(MySQLの replaceはレコードをDELETEしてから新しいレコードを追加します。)これはまた主キーを更新できないことを意味しています。これに対する唯一の例外は、Interbaseとその派生製品で、Interbase APIの制約からDELETEしてINSERTを使います。

$tableはテーブル名、$arrFieldsは連想配列でkeyがフィールド名、$keyColsは主キーの名前か複合キーであればフィールド名の配列。$autoQuoteがtrueになっていなければ、Replace()は数値以外のすべての値をクオートします。自動クオートはnullをクオートしません。SQLの関数や演算子を使っているばあい、自動クオートは機能しません。

例:

# 単一フィールドの主キー
$ret = $db->Replace('atable',
array('id'=>1000,'firstname'=>'Harun','lastname'=>'Al-Rashid'),
'id',$autoquote = true);
# UPDATE atable SET firstname='Harun',lastname='Al-Rashid' WHERE id=1000 を生成するか
# INSERT INTO atable (id,firstname,lastname) VALUES (1000,'Harun','Al-Rashid') を生成

# 複合キー
$ret = $db->Replace('atable2',
array('firstname'=>'Harun','lastname'=>'Al-Rashid', 'age' => 33, 'birthday' => 'null'),
array('lastname','firstname'),
$autoquote = true);

# 自動クオート機能なし
$ret = $db->Replace('atable2',
array('firstname'=>"'Harun'",'lastname'=>"'Al-Rashid'", 'age' => 'null'),
array('lastname','firstname'));

AutoExecute($table, $arrFields, $mode, $where=false, $forceUpdate=true,$magicq=false)

ADOdb 4.56から、この関数を使って任意のテーブルにINSERTとUPDATEを自動生成して実行することができます。この関数はGetInsertSQL()とGetUpdateSQL()のラッパーです。

AutoExecute()は任意の$arrFields配列で$tableにINSERTもしくはUPDATEを行います。諸々のキーはフィールド名で、配列の値は格納するフィールドの値です。いくらかのオーバーヘッドのあることに留意してください。これはSQL文の生成に先立ち、諸キーの情報を抽出するため最初にクエリーが実行されるからです。INSERTあるいはUPDATEは$modeにもとづいて生成されます。(下記を参照)

$modeに対する合法な値

定数DB_AUTOQUERY_UPDATEとDB_AUTOQUERY_INSERTを自分で定義するか、adodb-pear.inc.phpをインクルードする必要があります。

$mode == 'UPDATE'であれば、$where節が必要です。$forceUpdate=falseであれば、最初にデータベースをクエリーして、クエリーで返るフィールドの値が現在のフィールドの値と一致するかどうかをチェックします。値が違っているときのみ、フィールドの更新を行います。

成功時にはtrue、エラー発生時はfalseです。

利用例:

$record["firstName"] = "Carol";
$record["lasTname"] = "Smith"; 
$conn->AutoExecute($table,$record,'INSERT');
# "INSERT INTO $table (firstName,lasTname) values ('Carol',Smith')";を実行

$record["firstName"] = "Carol";
$record["lasTname"] = "Jones"; 
$conn->AutoExecute($table,$record,'UPDATE', "lastname like 'Sm%'");
# "UPDATE $table SET firstName='Carol',lasTname='Jones' WHERE lastname like 'Sm%'";を実行

注意: ADOdb AutoExecute()の強みは、$tableの妥当なフィールド名のみ更新されることです。もし$arrFieldsに含まれている諸キーが$tableに対して不当なフィールド名のばあい、それらは無視されます。これを行うためにいくぶんのオーバーヘッドがあります。フィールド名を取得するためデータベースにクエリーを投げるからです。しかし、SQLを自分で直接コーディングするのでなければ、おそらく速度には全く関心がなくて、むしろ利便性に関心があるのではないでしょうか。

4.62から、AutoExecute()、GetInsertSQL()、GetUpdateSQL()がコールされる前に、$rs->tableNameを設定することで使用するテーブル名は上書き可能です。

GetUpdateSQL(&$rs, $arrFields, $forceUpdate=false,$magicq=false, $force=null)

任意のレコードセット$rsでテーブルを更新するSQLを生成します。配列$arrFields(カラム名と新しい値を保持する連想配列でなければなりません)の変更されたフィールドが現在のレコードセットと比較されます。もし$forceUpdateがtrueであれば、$arrFieldsが$rs->fieldsと同じであってもSQLを生成します。レコードセットは連想であることが必要です。マジッククオートが有効かどうかを示すのに$magicqが使われます(qstr()参照)。配列のフィールド名は大文字小文字の区別はありません。

4.52から、$forceパラメタをわたすことができるようになっています。これはグローバル変数$ADODB_FORCE_TYPEを上書きします。

4.62から、使用されるテーブル名が、 AutoExecute()、GetInsertSQL()、GetUpdateSQL()がコールされる前に、$rs->tableNameを設定することで上書きできるようにています。

GetInsertSQL(&$rs, $arrFields,$magicq=false,$force_type=false)

任意のレコードセット$rsをテーブルに追加するSQLを生成します。レコードセットは連想であることが必要です。マジッククオートが有効かどうかを示すのに$magicqが使われます(qstr()参照)。配列のフィールド名は大文字小文字の区別はありません。

2.42から、GetInsertSQL()の$rsでレコードセットの代わりにテーブル名をわたすことができます。そのテーブルへのINSERT文を生成します。

4.52から、$forceパラメタをわたすことができるようになっています。これはグローバル変数$ADODB_FORCE_TYPEを上書きします。

4.62から、使用されるテーブル名が、 AutoExecute()、GetInsertSQL()、GetUpdateSQL()がコールされる前に、$rs->tableNameを設定することで上書きできるようにています。

PageExecute($sql, $nrows, $page, $inputarr=false)

レコードセットのページングで使われます。$pageは1からはじまります。Example 8を参照。

CachePageExecute($secs2cache, $sql, $nrows, $page, $inputarr=false)

レコードセットのページングで使われます。$pageは1からはじまります。Example 8を参照。PageExecuteのキャッシングバージョンです。

Close( )

データベース接続をクローズします。PHP4は誇らかに述べています。わたしたちはもはや接続の終わりでクリーンアップする必要がありません。なぜならPHP4の参照カウントの機構が自動的にクリーンアップをしてくれるからです。

StartTrans( )

モニタされたトランザクションを開始します。SQL文が実行されるとき、ADOdbはSQLエラーをモニタし、もしなんらかのエラーを検知すると、CompleteTrans()がコールされるときに自動ロールバックします。

なぜStartTrans()がBeginTrans()に勝っているかを理解するため、BeginTrans()のいくつかの用法を吟味してみましょう。以下はトランザクションの使い方としては間違ったものです。

$DB->BeginTrans();
$DB->Execute("update table1 set val=$val1 where id=$id");
$DB->Execute("update table2 set val=$val2 where id=$id");
$DB->CommitTrans();

というのはどんなエラーチェックもされていないからです。table1を更新して、table2の更新で失敗する可能性があります。このためもっとましな方法は次となります。

$DB->BeginTrans();
$ok = $DB->Execute("update table1 set val=$val1 where id=$id");
if ($ok) $ok = $DB->Execute("update table2 set val=$val2 where id=$id");
if ($ok) $DB->CommitTrans();
else $DB->RollbackTrans();

あるいは次です。(ADOdb 2.0から)

$DB->BeginTrans();
$ok = $DB->Execute("update table1 set val=$val1 where id=$id");
if ($ok) $ok = $DB->Execute("update table2 set val=$val2 where id=$id");
$DB->CommitTrans($ok);

さて、すべての場所で$okをモニタするといのは頭の痛いことです。StartTrans()はこの点を改善してくれています。なぜならすべてのSQLエラーをあなたに代わってモニタしてくるのです。これはとくにその中でSQLクエリーが実行される可能性のあるブラックボックスの関数をコールするときに役立ちます。またStartTransブロックの内側でのBeginTrans、CommitTrans、RollbackTransの呼び出しすべて無効です。たとえブラックボックス関数がコミットしても、それは無視されることになります。

$DB->StartTrans();
CallBlackBox();
$DB->Execute("update table1 set val=$val1 where id=$id");
$DB->Execute("update table2 set val=$val2 where id=$id");
$DB->CompleteTrans($ok);

StartTransブロックはネスト可能で、その内部ブロックは無視されることに注意してください。

CompleteTrans($autoComplete=true)

StartTrans()で開始されたトランザクションを完了します。この関数はSQLエラーをモニタし、エラーがなければコミットし、エラーが発生していればロールバックします。コミット時にはtrueを、ロールバック時にはfalseを返します。パラメタ$autoCompleteがtrueなら、SQLエラーをモニタし適切にコミットかロールバックを行います。$autoCompleteをfalseに設定すると、SQLエラーが発生しないばあいにもロールバックを強制的に行います。

FailTrans( )

StartTrans()で開始されたトランザクションを失敗させます。CompleteTrans()がコールされたときだけロールバックされます。

HasFailedTrans( )

スマートトランザクションが失敗したかどうかをチェックします。つまり、SQL実行でエラーがあるかFailTrans()がコールされたかをチェックします。スマートトランザクション内で失敗していなければ、falseを返します。

BeginTrans( )

トランザクションを開始します。autoCommitをオフにします。成功時にはtrueを返します。トランザクションをサポートしていないデータベースではつねにfalseが返ります。接続が閉じられたときには、オープンしていたどんなトランザクションもロールバックされます。トランザクションをサポートするデータベースは、Oracle、 PostgreSQL、Interbase、MSSQL、MySQLのある種のバージョン、DB2、Informix、Sybase、などです。

StartTrans()とCompleteTrans()はトランザクションをハンドリングする勝った方法で、ADOdb 3.40から利用可能になっている点に注意してください。説明は、StartTrans()のドキュメントを見てください。

透過的にトランザクションを失敗させたりロールバックするのにADOdbのエラーハンドラを使うこともできます。いくつかのバグの混在したデータベース拡張では、すべての重要なトランザクションがコミットされてしまうことが確認されています。このためエラーハンドラーの中で安全に明示的に$DB->RollbackTrans()をしたいことがあるかもしれません。

Detecting Transactions

ADOdb 2.50から、トランザクションの内部にいることを検知できます。$connection->transCnt > 0をチェックしてください。この変数はBeginTrans()が呼ばれるたびにインクリメントされ、RollbackTrans()かCommitTrans()がコールされるたびにデクリメントされます。

CommitTrans($ok=true)

トランザクションを成功で終了させます。成功時にはtrueが返ります。もしデータベースがトランザクションをサポートしていなければ、常にデータがコミットされるのでtrueが返ることになります。

パラメタ$ok=falseをわたせば、データはロールバックされます。BeginTrans()の例を参照。

RollbackTrans( )

トランザクションを終了させ、すべての変更をロールバックします。成功すればtrueが返ります。データベースがトランザクションをサポートしていないばあい、データがロールバックされることがないためfalseが返ります。

GetAssoc($sql,$inputarr=false,$force_array=false,$first2cols=false)

$sqlクエリーに対して連想配列を返します。オプションで$inputarrにパラメタを結合します。もし返されるカラム数が2より大きいばあい、レコードセットの最初のカラムが残りの行の諸キーになる2次元配列が返されます。(配列がそれぞれの値に対して作られるとき、$force_arrayがtrueに設定されていないという条件で)カラムが2と等しければ、1次元配列が作られ、諸キーが直接値にマップされます。

例:

レコードセットに以下のデータがあるとします。

行1: Apple, Fruit, Edible
行2: Cactus, Plant, Inedible
行3: Rose, Flower, Edible

GetAssocは次の2次元の連想配列を生成します。

Apple => array[Fruit, Edible]
Cactus => array[Plant, Inedible]
Rose => array[Flower,Edible]

もしデータが次の場合には

行1: Apple, Fruit
行2: Cactus, Plant
行3: Rose, Flower

GetAssocは($force_array==falseで)次の1次元の連想配列を生成します。

Apple => Fruit
Cactus=>Plant
Rose=>Flower

関数の戻りは連想配列か、エラーが発生したならfalseとなります。

CacheGetAssoc([$secs2cache,] $sql,$inputarr=false,$force_array=false,$first2cols=false)

上記GetAssoc関数のキャッシング版です。

GetOne($sql,$inputarr=false)

SQLを実行して、最初の行の最初のフィールドの値を返します。レコードセットと残りの行は自動的に切捨てられます。エラーが発生したばあい、falseが返ります

GetRow($sql,$inputarr=false)

SQLを実行して、最初の行を配列として返します。レコードセットと残りの行は自動的に切捨てられます。エラーが発生したばあい、falseが返ります。

GetAll($sql)

SQLを実行して、すべての行を2次元配列として返します。レコードセットと残りの行は自動的に切捨てられます。エラーが発生したばあい、falseが返ります。

GetCol($sql,$inputarr=false,$trim=false)

SQLを実行して、最初のカラムの値を1次元配列として返します。レコードセットは自動的に切捨てられます。エラーが発生したばあい、falseが返ります。

CacheGetOne([$secs2cache,] $sql,$inputarr=false), CacheGetRow([$secs2cache,] $sql,$inputarr=false), CacheGetAll([$secs2cache,] $sql,$inputarr=false), CacheGetCol([$secs2cache,] $sql,$inputarr=false,$trim=false)

レコードセットが$secs2cache秒のあいだ$ADODB_CACHE_DIRディレクトリにキャッシュされるという点をのぞき、上記のGet*関数と同じです。あまり変更されないデータのクエリーに有効です。$secs2cacheパラメタが任意であることに注意してください。省略されたばあい、$connection->cacheSecs(デフォルト3600秒、すなわち1時間)の値が使われます。

Prepare($sql )

反復実行のためにSQLクエリーを準備(コンパイル)します。結合変数は ? で指示されます。oci8ドライバは例外で、伝統的Oracleの :varname を使います。

最初の配列要素にもとのSQL文を含む配列を返します。配列の残りの要素はドライバに依存します。もしエラーがあったり、あるいはPrepare()をエミュレートしているばあい、もとの$sql文字列を返します。これはすべてのエラーハンドリングがExecute()に集約されているためです。

Prepare()は、PageExecute()やSelectLimit()などのSQLクエリーのリライティング技術を使う関数と併用することはできません。

例:

$stmt = $DB->Prepare('insert into table (col1,col2) values (?,?)');
for ($i=0; $i < $max; $i++)
$DB->Execute($stmt,array((string) rand(), $i));

また下記のInParameter()、OutParameter()、PrepareSP()を参照してください。Interbase、oci8 、所定のODBCベースのドライバだけでサポートされています。それ以外のドライバではエミュレートされます。エミュレーションではパフォーマンス上の利点はありません。

重要: PHPの制約あるいはバグのために、準備済みクエリーを使うときにエラーが起こるばあいは、この関数を使う前に$ADODB_COUNTRECS = falseの設定を試みてください。この振る舞いはODBCで観察されています。

IfNull($field, $nullReplacementValue)

移植性のあるIFNULL関数です(OracleではNVLが該当)。$fieldがnullかどうかをチェックする関数を表す文字列を返します。もしnullであれば、返される値を$nullReplacementValueの値に変更します。

$sql = 'SELECT '.$db->IfNull('name', "'- unknown -'"). ' FROM table';

length

これは関数ではなくプロパティです。文字列の長さを測る関数として、あるデータベースでは"length"、また別のデータベースでは"len"となっていてまちまちです。このプロパティは次のように使います。

  $sql = "SELECT ".$db->length."(field) from table";
$rs = $db->Execute($sql);

random

これは関数ではなくプロパティです。これは0.0から1.0までのあいだの乱数を生成するSQLを保持する文字列です。

substr

これは関数ではなくプロパティです。sub-stringを取得する関数として、あるデータベースでは"substr"、また別のデータベースでは"substring"となっていてまちまちです。このプロパティは次のように使います。

  $sql = "SELECT ".$db->substr."(field, $offset, $length) from table";
$rs = $db->Execute($sql);

すべてのデータベースに対して、substrの第一パラメタはフィールド、第二パラメタはsub-stringが開始されるところまでの(1ベースの)オフセット、第三パラメタはsub-stringの長さです。

Param($name)

移植性があるように結合のプレースホルダを生成します。多くのデータベースでは、結合プレースホルダは"?"です。けれどOracleのようにデータベースのなかにはバンド変数として":somevar"を使うものがあります。この関数で結合変数のあるSQL文を移植性があるように定義することができます。

$sql = 'insert into table (col1,col2) values ('.$DB->Param('a').','.$DB->Param('b').')';
# generates 'insert into table (col1,col2) values (?,?)'
# or 'insert into table (col1,col2) values (:a,:b)
'
$stmt = $DB->Prepare($sql);
$stmt = $DB->Execute($stmt,array('one','two'));

PrepareSP($sql, $cursor=false )

mssqlとoci8(oracle)でストアドプロシージャをコールするとき、戻り値を直接パラメタに結合したっかたり、とくべつなLOBハンドリングがしたいことがあるかもしれません。PrepareSP()はそうすることを可能にします。

先のPrepare()と同じ配列あるいは$sqlを返します。戻り値を結合する必要がなければ、この関数の代わりにPrepare()を使うべきです。

第二パラメタ$cursorはoci8では使用されません。trueに設定するとOCINewCursorが呼ばれるよう強制することができます。これはoutput REF CURSORをサポートするためです。

PrepareSP()の利用例は、下記のInParameter()を参照してください。

注意:mssqlドライバでは、ストアドプロシージャの準備は特別の関数mssql_init()のコールを必要とします。mssql_init()はPrepare()からコールされます。PrepareSP()はその他すべてのドライバで利用可能で、Prepare()呼び出しでエミュレートされます。

InParameter($stmt, $var, $name, $maxLen = 4000, $type = false )

PHP変数を入力としてストアドプロシージャ変数に結合します。パラメタ$stmtはPrepareSP()が返す値で、$varは結合したいPHP変数、$nameはストアドプロシージャ変数名です。$maxLenは任意で、結合するデータの最大長。$typeの合法な値にかんする詳細情報はphp.netのmssql_bindocibindbyname文書を参照してください。

InParameter()は、$isOutput=falseで、Parameter()をコールするラッパー関数です。この関数の有利な点は、$isOutputパラメタがもはや必要ないので、自己記述的であることです。mssqlとoci8に対してのみ今のところサポートされています。

これはoci8を使った例です。

# oracleではPrepareとPrepareSPは同じものです。
$stmt = $db->PrepareSP(
	"declare RETVAL integer; 
begin
:RETVAL :=
SP_RUNSOMETHING(:myid,:group);
end;"
);
$db->InParameter($stmt,$id,'myid');
$db->InParameter($stmt,$group,'group',64);
$db->OutParameter($stmt,$ret,'RETVAL');
$db->Execute($stmt);

mssqlを使った同じ例です。

# @RETVAL = SP_RUNSOMETHING @myid,@group
$stmt = $db->PrepareSP('SP_RUNSOMETHING'); 
# パラメタ名が頭に@がないことに注意! $db->InParameter($stmt,$id,'myid'); $db->InParameter($stmt,$group,'group',64); # mssqlでのリターン値 - RETVALはハードコードされた名前
$db->OutParameter($stmt,$ret,'RETVAL');
$db->Execute($stmt);

oci8とmssqlの実装の違いは$sqlだけだという点留意してください。

$typeパラメタがfalseに設定されていると、mssqlでは$typeがわたされたPHP変数のタイプにもとづき動的に決定されます。(string => SQLCHAR, boolean =>SQLINT1, integer =>SQLINT4 あるいは float/double=>SQLFLT8).

oci8では、$typeにOCI_B_FILE (Binary-File)、OCI_B_CFILE (Character-File)、OCI_B_CLOB (Character-LOB)、OCI_B_BLOB (Binary-LOB)、OCI_B_ROWID (ROWID)を設定することができます。nullをわたすには、 $db->Parameter($stmt, $null=null, 'param')を使います。

OutParameter($stmt, $var, $name, $maxLen = 4000, $type = false )

PHP変数をストアドプロシージャ変数からのoutputとして結合します。パラメタ$stmtはPrepareSP()から返される値、$varは結合したいPHP変数、$nameはストアドプロシージャ変数です。結合するデータの最大長$maxLenと、データベースに依存する$typeは任意です。

OutParameter()は$isOutput=trueでParameter()をコールするラッパー関数です。この関数の利点は自己記述的であることです。なぜなら$isOutputパラメタは現在では使われていないからです。現在mssqlとoci8でサポートしています。

例としてはInParameterを見てください。

Parameter($stmt, $var, $name, $isOutput=false, $maxLen = 4000, $type = false )

注意:新しいInParameter()とOutParameter()があるので、この関数は非推奨です。新しい関数は、Parameter()とは違って、自己記述的なために優れています。

PrepareSP()を使ってステートメントが準備されたあとで、結合パラメタを返り値あるいは特別のデータハンドリング(例えばLOB)に適応するように追加します。現在mssqlとoci8でサポートしています。パラメタは次のとおりです。

$stmt Prepare()あるいはPrepareSP()から返されるステートメント。
$var 結合するPHP変数。先に初期化していることを確実にしてください。
$name 結合するストアドプロシージャ変数名の名前。
[$isOutput] パラメタの方向を示します。0/false=IN 1=OUT 2= IN/OUT。これは方向を自動認識するoci8ドライバでは無視されます。
[$maxLen] パラメタ変数の最大長。
[$type] typeの合法な値にかんする詳細については、php.netでmssql_bindocibindbyname文書を調べてみてください。

最後に、oci8では、結合パラメタはPrepareSP()やParametersをふたたび呼び出すことなく再利用可能です。これはmssqlではできません。次はoci8の例です。

$id = 0; $i = 0;
$stmt = $db->PrepareSP( "update table set val=:i where id=:id");
$db->Parameter($stmt,$id,'id');
$db->Parameter($stmt,$i, 'i');
for ($cnt=0; $cnt < 1000; $cnt++) {
$id = $cnt;
$i = $cnt * $cnt; # oci8で動きます! $db->Execute($stmt);
}

Bind($stmt, $var, $size=4001, $type=false, $name=false)

これはoci8ドライバでのみサポートされる低レベル関数です。Oracleだけサポートするのでなければ利用を避けてください。結合変数を使うのであればParameter()関数が推奨される方法です。

Bind()はSQL文で結合変数を使えるようにします。これはPHP変数をPrepare()を使って準備されたOracleのSQL文のなかで定義されている名前に結合します。Oracleの名前付き変数はコロンで始まります。またADOdbは名前付き変数が:0、:1、:2、:3と呼ばれることを要求します。Bind()の最初の呼び出しは:0にマッチし、第二の呼び出しは:1にマッチします。結合はINSERT、SELECT、UPDATE文に対して100%のスピードアップを提供します。

それ以外の変数、$sizeはデータストレージに対してバッファサイズを設定します。$typeは任意の記述タイプ OCI_B_FILE (Binary-File)、OCI_B_CFILE (Character-File)、OCI_B_CLOB (Character-LOB)、OCI_B_BLOB (Binary-LOB)、OCI_B_ROWID (ROWID)です。最後に、デフォルトの:0、:1などの名前を使う代わりに、$nameを使って自分で結合名を定義することもできます。

次の例では3つの結合変数p1、p2、p3が使われています。これらの変数は:0、:1、:2に結合されます。

$stmt = $DB->Prepare("insert into table (col0, col1, col2) values (:0, :1, :2)");
$DB->Bind($stmt, $p1);
$DB->Bind($stmt, $p2);
$DB->Bind($stmt, $p3);
for ($i = 0; $i < $max; $i++) {
$p1 = ?; $p2 = ?; $p3 = ?;
$DB->Execute($stmt);
}

名前付き変数を使うこともできます。

$stmt = $DB->Prepare("insert into table (col0, col1, col2) values (:name0, :name1, :name2)");
$DB->Bind($stmt, $p1, "name0");
$DB->Bind($stmt, $p2, "name1");
$DB->Bind($stmt, $p3, "name2");
for ($i = 0; $i < $max; $i++) {
$p1 = ?; $p2 = ?; $p3 = ?;
$DB->Execute($stmt);
}

LogSQL($enable=true)

SQLロギングと(fnExecuteを使う)タイミング関数をインストールするためにこのメソッドをコールします。そるとすべてのSQL文はデータベースのadodb_logsqlテーブルにロギングされることになります。もしadodb_logsqlが存在しなければ、適切な権限があればADOdbはそのテーブルを作成します。前回のロギングの値を返します(有効であればtrue、無効であればfalse)。以下はデータベースのためのDDLサンプルです。

		mysql:
		CREATE TABLE adodb_logsql (
		  created datetime NOT NULL,
		  sql0 varchar(250) NOT NULL,
		  sql1 text NOT NULL,
		  params text NOT NULL,
		  tracer text NOT NULL,
		  timer decimal(16,6) NOT NULL
		)
		
		postgres:
		CREATE TABLE adodb_logsql (
		  created timestamp NOT NULL,
		  sql0 varchar(250) NOT NULL,
		  sql1 text NOT NULL,
		  params text NOT NULL,
		  tracer text NOT NULL,
		  timer decimal(16,6) NOT NULL
		)
		
		mssql:
		CREATE TABLE adodb_logsql (
		  created datetime NOT NULL,
		  sql0 varchar(250) NOT NULL,
		  sql1 varchar(4000) NOT NULL,
		  params varchar(3000) NOT NULL,
		  tracer varchar(500) NOT NULL,
		  timer decimal(16,6) NOT NULL
		)
		
		oci8:
		CREATE TABLE adodb_logsql (
		  created date NOT NULL,
		  sql0 varchar(250) NOT NULL,
		  sql1 varchar(4000) NOT NULL,
		  params varchar(4000),
		  tracer varchar(4000),
		  timer decimal(16,6) NOT NULL
		)
使い方:
	$conn->LogSQL(); // ロギングを有効に
:
$conn->Execute(...);
:
$conn->LogSQL(false); // ロギングを無効に

# SQLロギング結果の要約を出力
$perf = NewPerfMonitor($conn);
echo $perf->SuspiciousSQL();
echo $perf->ExpensiveSQL();

ロギングの1つの制限はロールバックがロギングされないことです。

SQLを格納するために使うテーブル名を別なものにしたければ、adodb_perf::table($tablename)を読んで上書きすることができます。$tablenameが新しいテーブル名になります。(テーブルは自分で手動で作成する必要があります。)

例:
	include('adodb.inc.php');
include('adodb-perf.inc.php');
adodb_perf::table('my_logsql_table');
Performance Monitorも参照のこと。

fnExecuteとfnCacheExecuteプロパティ

この2つのプロパティはADOdbで処理されるすべてのSQL文に対してボトルネック関数を突き止めることを可能にしてくれます。これを使えば統計分析とあたなのSQLクエリーの書き直しができます。

fnExecuteの例

これはfnExecuteを使った例で、すべてのキャッシュされたクエリーとキャッシュされていないクエリーをカウントするために、次のようにできます。

# $dbは接続オブジェクト
function CountExecs($db, $sql, $inputarray)
{
global $EXECS;

if (!is_array(inputarray)) $EXECS++;
# 2次元インプット配列のハンドル
else if (is_array(reset($inputarray))) $EXECS += sizeof($inputarray);
else $EXECS++;
}

# $dbは接続オブジェクト
function CountCachedExecs($db, $secs2cache, $sql, $inputarray)
{
global $CACHED; $CACHED++;
}

$db = NewADOConnection('mysql');
$db->Connect(...);
$db->fnExecute = 'CountExecs';
$db->fnCacheExecute = 'CountCachedExecs';
:
:
# たくさんのSQL文の後
printf("<p>Total queries=%d; total cached=%d</p>",$EXECS+$CACHED, $CACHED);

fnExecute関数はSQLが解析されて実行されるまえにコールされます。このためクエリーを書き直すことができます。もし準備ステートメントがわたされれば、$sqlは配列です(Prepare参照)。fnCacheExecute関数は返されるレコードセットがキャッシャされたばあいのみコールされます。 $this(接続オブジェクト)が第一パラメタとして渡される以外は、関数パラメタはExecuteとCacheExecute関数にそれぞれ合致しています。

ADOdb 3.91から、fnExecuteの振る舞いが定義された関数が返す値に依存して変化するようになっています。もし値を返さなければ、$sqlは事前に実行されます。これはクエリーの書き換えやSQLクエリーをカウントするのに役立ちます。

他方、Execute関数を自分自身で設計したものに置き換えたい場合があるかもしれません。そういう場合には、あなたの関数が値を返すようにしてください。もし値が返るのなら、その値は即座に返されます。それ以降の処理はありません。これはADOdbで内部的にLogSQL()の機能を実装するのに使っています。


ADOConnectionユーティリティ関数

BlankRecordSet([$queryid])

もう利用できません。1.99から削除されました。

Concat($s1,$s2,....)

$s1、$s2などを結合するのに使われるSQL文字列を生成します。文字列結合を生成するにはconcat_operatorフィールドの文字列を使ってください。MySQLのように文字列結合演算子が使われなければ、この関数をオーバーライドしてください。

結合された文字列を返します。

DBDate($date)

$dateをそのデータベースが受け付けるフォーマットにします。これはINSERT/UPDATE文で使われます。SELECT文では、SQLDateを使います。$dateパラメタはUnixのinteger timestampか、Y-m-dのISOフォーマットです。使われるフォーマットを保持しているfmtDateフィールドを使います。nullあるいはfalseあるいは''がわたされると、SQL nullに変換されます。

クオートされた文字列として日付が返されます。

DBTimeStamp($ts)

タイムスタンプ$tsをそのデータベースが受け付けるフォーマットにします。これはUnixのinteger timestampか、Y-m-dのISOフォーマットが可能です。使われるフォーマットを保持しているfmtTimeStampフィールドを使います。nullあるいはfalseあるいは''がわたされると、SQL nullに変換されます。

クオートされた文字列としてタイムスタンプが返されます。

qstr($s,[$magic_quotes_enabled=false])

データベースに送信される文字列をクオートします。$magic_quotes_enabledパラメタは妙に思われるかもしれませんが、POST/GET変数から抽出された文字列をクオートするばあい、第二パラメタとしてget_magic_quotes_gpc()がわたされるということです。一度はqstrで、もう一度はmagic_quotes_gpcで、変数が二度クオートされないことを確かにしてくれます。

例えば、 $s = $db->qstr(HTTP_GET_VARS['name'],get_magic_quotes_gpc());

クオートされた文字列が返ります。

Quote($s)

$sをクオートして、適切にデータベース固有のクオート文字をエスケープします。以前はmagic quotesの設定がチェックされていましたが、これはPEAR DBとの互換性のため3.31から無効です。

Affected_Rows( )

UPDATEやDELETEで影響を受けた行数を返します。機能がサポートされていなければfalseが返ります。

interbase/firebirdでは現在サポートされていません。

Insert_ID( )

最後に自動挿入されたIDを返します。機能がサポートされていなければfalseを返します。

現在PostgreSQL、MySQL、MS SQL Serverのような自動インクリメントやオブジェクトIDをサポートしているデータベースでのみサポートされています。PostgreSQLはOIDを返しますが、これはデータベースリロード時に変わることができます。

RowLock($table,$where)

トランザクションのあいだテーブルの行をロックします。たとえば次のように、table1の$idのレコードをロックします。

	$DB->StartTrans();
$DB->RowLock("table1","rowid=$id");
$DB->Execute($sql1);
$DB->Execute($sql2);
$DB->CompleteTrans();

db2、interbase、informix、mssql、oci8、postgres、sybaseでサポートされます。

MetaDatabases()

サーバで利用可能なデータベースのリストを配列で返します。最初にサーバに接続している必要があります。ODBC、MySQL、ADOでのみ利用可能です。

MetaTables($ttype = false, $showSchema = false, $mask=false)

現在のデータベースのテーブルとビューを配列で返します。可能であれば配列はシステムカタログテーブルを取り除きます。テーブルだけを表示するには$db->MetaTables('TABLES')を使います。ビューだけを表示するには$db->MetaTables('VIEWS')を使います。$showSchemaパラメタは今のところDB2に対してのみ有効です。これがtrueに設定されると、"SCHEMA.TABLE"とテーブルにスキーマ名を追加します。

マッチングに対してマスクを定義することができます。例えば、$mask = 'TMP%'の設定は'TMP'ではじまるすべてのテーブルにマッチします。mssql、oci8、odbc_mssql、postgres*が今のところ$maskをサポートしています。

MetaColumns($table,$toupper=true)

$tableのすべてのカラムに対するフィールドオブジェクトADOFieldObjectの配列を返します。フィールドオブジェクトは(名前name、型type、最大長max_lengthで)定義されたクラスのインスタンスです。現在Sybaseは日付型を認識しません。またADOは正確なデータ型を突き止めることができません(このためvarcharにしています)。

$toupperパラメタはテーブル名を大文字にするかどうかを決めます(いくつかのデータベースでは必要です)。

"$schema.$tablename"とスキーマサポートのためには$tableパラメタをわたします。所定のデータベースでサポートされます。

MetaColumnNames($table,$numericIndex=false)

$tableのカラム名の配列を返します。ADOdb 4.22から、これはキーが大文字の連想配列です。(since 4.2から)昔の数値インデックスがよければ、$numericIndex=trueとします。

つまり array('FIELD1' => 'Field1', 'FIELD2'=>'Field2')

MetaPrimaryKeys($table, $owner=false)

$tableの主キーであるカラム名の配列を返します。現在、mysql、odbc(db2、odbc_mssqlなどを含みます)、mssql、postgres、interbase/firebird、oci8でサポートされています。

ビュー(そしていくつかのテーブル)に主キーがあっても、ときどきのこ情報はデータベースから利用できないことがあります。ADODB_View_PrimaryKeys($databaseType, $database, $view, $owner)関数を定義することができます。この関数は主キーを構成するフィールド配列を返すべきです。この関数が存在すると、MetaPrimaryKeys()がテーブルやビューの主キーを見つけられなかったときコールされます。

// この例では: dbtype = 'oci8', $db = 'mydb', $view = 'dataView', $owner = false 
function ADODB_View_PrimaryKeys($dbtype,$db,$view,$owner)
{
switch(strtoupper($view)) {
case 'DATAVIEW': return array('DATAID');
default: return false;
}
}

$db = NewADOConnection('oci8');
$db->Connect('localhost','root','','mydb');
$db->MetaPrimaryKeys('dataView');

ServerInfo($table)

'description'と'version'の2つの要素の配列を返します。'description'要素はデータベースの説明文字列が入っています。'version'にはバージョン番号が入っています(これもまた文字列です)。

MetaForeignKeys($table, $owner=false, $upper=false)

外部参照キーの配列を返します。サポートされていないばあいはfalseが返ります。例えば、employeeテーブルにemployee.deptkeyがdept_table.deptidをポイントする外部参照キーがあって、employee.posn=posn_table.postionidでemployee.poscategory=posn_table.categoryのばあい、$conn->MetaForeignKeys('employee')は次の配列を返します。

	array(
'dept_table' => array('deptkey=deptid'),
'posn_table' => array('posn=positionid','poscategory=category')
)

$ownerで任意のスキーマもしくは所有者を定義することができます。$upperがtrueなら、テーブル名(配列キー)は大文字になります。


ADORecordSet

SQL文がADOConnection->Execute($sql),で実行が成功したとき、ADORecordSetオブジェクトが返されます。このオブジェクトは仮想カーソルを持っているので、行から行へ移動できます。また、カラムとカラムの型についての情報を取得する諸々の関数、ユーザに見せるために結果をフォーマットする諸々のヘルパー関数があります。

ADORecordSetフィールド

fields: 現在の行の配列を返します。これは連想配列ではありません。1番目のカラムが0からはじまるインデックス配列です。連想配列のように振舞うFields関数も見てください。

dataProvider: データベースに接続する下部の機構。odbcadoが使われるのでなければ、通常はnativeが設定されます。

blobSize: BLOBとして扱われない、char、string、varcharオブジェクトの最大サイズ。(BLOBはtextareaに表示されるべきです。)MetaType関数を参照。

sql: このレコードセットを生成するのに使われたSQL分を保持。

canSeek: Move()関数を使うにはこれをtrueに設定。

EOF: レコードの最後までスクロールしたばあいtrue。

ADORecordSet関数

ADORecordSet( )

コンストラクタ。通常はこの関数をけして自分自身で呼び出しません。

GetAssoc([$force_array])

レコードセットから連想配列を生成します。この機能は接続オブジェクトでも利用可能な点注意してください。より詳細は接続オブジェクトで見つかります。

GetArray([$number_of_rows])

現在のカーソルの位置から2次元配列を生成します。インデックスは0から$number_of_rows - 1となります。もし$number_of_rowsが定義されていなければ、EOFまでとなります。

GetRows([$number_of_rows])

現在のカーソルの位置から2次元配列を生成します。Microsoft ADO互換のためのGetArray()の同義語になります。

GetMenu($name, [$default_str=''], [$blank1stItem=true], [$multiple_select=false], [$size=0], [$moreAttr=''])

HTMLメニュー(<select><option><option></select>)を生成します。レコードセット最初のカラム(fields[0])はoptionタグに表示する文字列を保持しています。レコードセットに1つ以上のカラムがあるばあい、第二カラム(fields[1])はWebサーバに送り返される値になります。$nameがメニューの名前になります。

もし$default_strが定義されていれば、そして$default_str == fields[0]であれば、そのフィールドがselectedになります。$blank1stItemがtrueであれば、最初のoptionは空となります。最初のoptionを$blank1stItem = "$value:$text"で設定することも可能です。

$Default_strは複数選択リストボックスの配列になることができます。

リストボックスを取得するには、$sizeに0以外の値を設定します(あるいは配列として$default_strをわたします)。$multiple_selectがtrueであれば、リストボックスは$sizeの項目が(あるいは$size==0であれば5項目が)見えるように生成されて、サーバに配列を返します。最後にjavascriptやstyleのような付加的な属性を追加するには、$moreAttr を使います。

Menuの例1: GetMenu('menu1','A',true)はデータ(A,1), (B,2), (C,3)に対してこのメニューを生成します。example 5も参照してください。

Menuの例2: 同一のデータに対して、GetMenu('menu1',array('A','B'),false)はAtoBが選択されたメニューを生成します。

GetMenu2($name, [$default_str=''], [$blank1stItem=true], [$multiple_select=false], [$size=0], [$moreAttr=''])

これはほとんどGetMenuと同じです。違う点は、$default_strがfields[1](optionの値)に一致するところです。

Menuの例3: Menuの例2のデータが与えられると、GetMenu2('menu1',array('1','2'),false)はMenuの例2のAtoBの両方が選択されたメニューを生成します。しかし今回はWebサーバに返される値を保持した選択が二番目のカラムにもとづいて行われます。

UserDate($str, [$fmt])

日付文字列$strを他のフォーマットに変換します。データフォーマットはY-m-dかUnixのtimestampフォーマットです。デフォルトの$fmtはY-m-dです。

UserTimeStamp($str, [$fmt])

timestamp文字列$strを他のフォーマットに変換します。timestampフォーマットは'2002-02-28 23:00:12'のようにY-m-d H:i:sかUnix timestampフォーマットです。UserTimeStampは$strを解析するためUnixTimeStampをコールし、$fmtにフォーマットします。定義されていなければデフォルトY-m-d H:i:sになります。

UnixDate($str)

日付文字列$strを解析して、Unixのmktimeフォーマットで返します(つまり1970年1月1日からの秒数で)。日付はY-m-d H:i:sフォーマットであることが期待されます。ただしSybaseとMicrosoft SQL Serverにおいては、M d Yも受け付けられます(3文字の月文字列はローカライズされている必要があるかもしれないグローバル配列で制御されます)。

1.91からこの関数はADORecordSetとADOConnectionの両方で利用可能です。

UnixTimeStamp($str)

タイムスタンプ文字列$strを解析して、Unixのmktimeフォーマットで返します(つまり1970年1月1日からの秒数で)。日付が"Y-m-d, H:i:s" (1970-12-24, 00:00:00)か"Y-m-d H:i:s" (1970-12-24 00:00:00)あるいは"YmdHis" (19701225000000)のフォーマットであることが期待されます。ただしSybaseとMicrosoft SQL Serverにおいては、"M d Y h:i:sA" (Dec 25 1970 00:00:00AM)も受け付けられます(3文字の月文字列はローカライズされている必要があるかもしれないグローバル配列で制御されます)。

1.91からこの関数はADORecordSetとADOConnectionの両方で利用可能です。

OffsetDate($dayFraction, $basedate=false)

移植可能な様式で$basedateにもとづき未来や過去の日付を計算するためのネイティブのSQL関数をもった文字列を返します。$basedateが定義されていなければ、現在の日付(も夜中の12時)が使われます。Execute()にわたされたとき

たとえば、Oracleで、今日から2.5日の日付と時間をみつけるため、使うことができます。

# 今から1週間を取得
$fld = $conn->OffsetDate(7); // returns "(trunc(sysdate)+7")
# 今から60時間後の日付と時刻を取得
$fld = $conn->OffsetDate(2.5, $conn->sysTimeStamp); // returns "(sysdate+2.5)"

$conn->Execute("UPDATE TABLE SET dodate=$fld WHERE ID=$id");

2.13からこの関数はmysql、mssql、oracle、oci8、postgresqlのドライバで利用可能です。それ以外のドライバでも日付数値演算の実行が可能であれば、使えるかもしれません。

SQLDate($dateFormat, $basedate=false)

日付あるいは日付カラムの$basedateをフォーマットするネイティブなSQL関数をもった文字列を返します。この関数はSELECT文で使用されます。INSERT/UPDATE文に対しては、DBDateを使ってください。大文字小文字の区別のある$dateFormatを使い、以下をサポートしています。
 
  Y: 4-桁 年
  Q: 四半期 (1-4)
  M: 月 (Jan-Dec)
  m: 月 (01-12)
  d: 日 (01-31)
  H: 時間 (00-23)
  h: 時間 (1-12)
  i: 分 (00-59)
  s: 秒 (00-60)
  A: AM/PM指示
  w: 曜日 (DBに依存して0-6か1-7)
  l: 曜日 (文字列で - 小文字はL)
  

上記以外の文字は文字列として扱われます。文字をエスケープするのに\を使うこともできます。mysql、 postgresql、mssql、oci8、DB2を含む所定のデータベースで利用可能です。

これは移植性のある日付でGROUP BYするSQL文を書くのに役立ちます。例えば、四半期毎の商品売り上げの合計を表示するのに(日付はpostdateと呼ばれるフィールドに格納されます)。

 $sqlfn = $db->SQLDate('Y-\QQ','postdate'); # 2002-Q1と出力するためpostdateをフォーマットするSQLを取得
$sql = "SELECT $sqlfn,SUM(cogs) FROM table GROUP BY $sqlfn ORDER BY 1 desc";

MoveNext( )

内部カーソルを次の行に移動します。$this->fields配列は自動的に更新されます。もしそうすることができなかったときにはfalseを返します(通常はEOFに到達して)。それ以外ではtrueが返ります。

EOFに到達すると、$this->fields配列がfalseに設定されます。(これはADOdb 3.30で一貫して実装されてきました。)3.30以前の$this->fields(EOFでの)では、グローバル変数$ADODB_COMPAT_FETCH = trueとなります。

例:

$rs = $db->Execute($sql);
if ($rs)
while (!$rs->EOF) {
ProcessArray($rs->fields);
$rs->MoveNext();
}

Move($to)

内部カーソルを指定行$toに移動します。行は0からはじまりますので、0だと最初の行です。fields配列は自動的に更新されます。内部的にスクローリングをサポートしないデータベースに対して、ADOdbはフォワードスクロールをシミュレートします。いくつかのデータベースは後方スクロールをサポートしていません。もし$toの位置がEOFよりもあとであれば、たいていのデータベースでは$toはレコードセットの最後に移動することになります。odbdを使ういくつかの曖昧なデータベースではこのようにはならないかもしれません。

注意: この関数は絶対的なポジショニングをします。この点MicrosoftのADOと違っています。

trueかfalseを返します。falseのばあい、内部カーソルは多くの実装では動きません。このためAbsolutePosition()はMove()の前の最後のカーソル位置を返します。

MoveFirst()

内部的にMove(0)をコールします。データベースの中にはこの機能をサポートしていないものもあります。

MoveLast()

内部的にMove(RecordCount()-1)をコールします。データベースの中にはこの機能をサポートしていないものもあります。

GetRowAssoc($toUpper=true)

現在の行を含む連想配列を返します。配列のキーはカラム名です。カラム名はアクセスが容易なので大文字です。次の行を取得するには、MoveNext()をコールする必要があります。

例:
Array ( [ID] => 1 [FIRSTNAME] => Caroline [LASTNAME] => Miranda [CREATED] => 2001-07-05 )

注意:$ADODB_FETCH_MODE = ADODB_FETCH_ASSOCでGetRowAssoc()を使わないように。なぜなら同一の機能をもっているので、互いに干渉するからです。

AbsolutePage($page=-1)

現在のページを返します。PageExecute()/CachePageExecute()がコールされる必要があります。Example 8参照。

AtFirstPage($status='')

最初のページ(1から始まる)であればtrueを返します。PageExecute()/CachePageExecute()がコールされる必要があります。Example 8参照。

AtLastPage($status='')

最後のページ(1から始まる)であればtrueを返します。Requires PageExecute()/CachePageExecute() to be called. See Example 8.

Fields($colname)

現在の行の連想カラム$colnameを返します。カラム名は大文字小文字の区別がありません。

これは便利な機能です。より高いパフォーマンスのためには、$ADODB_FETCH_MODEを使ってください。

FetchRow()

現在行を含んだ配列を返します。EOFであればfalseを返します。FetchRow()は内部的に現在の行を取得したら次の行に移動します。

警告: FetchRow()とMoveNext()を混ぜて使わないでください。

使い方:

$rs = $db->Execute($sql);
if ($rs)
while ($arr = $rs->FetchRow()) {
  # $arrを処理
}

FetchInto(&$array)

$arrayを現在の行に設定します。EOFであればPEAR_Errorオブジェクトが返り、ok(DB_OK定数)なら1が返ります。もしPEARが定義されていなければ、EOFのときfalseが返ります。FetchInto()はは内部的に現在の行を取得したら次の行に移動します。

FetchRow()の使い方はとても簡単です。先の例を見てください。

FetchField($column_number)

関連するフィールドのnametypemax_lengthを含んだオブジェクトを返します。max_lengthの長さが信頼できないばあいには、-1にセットされます。カラム数は0ベースです。example 2を参照。

FieldCount( )

レコードセットのフィールド(カラム)数を返します。

RecordCount( )

レコードセットの行数を返します。返されたレコード数がデータベースドライバAPIから決められないばあい、全ての行をバッファリングして全行取得後に行数を返します。(パフォーマンスのために)グローバル変数$ADODB_COUNTRECS = falseを設定すれば、このバッファリングは無効にすることができます。無効のばあい、いくつかのデータベースではRecordCount()は-1を返すことになります。より詳細は先のサポートされているデータベースリストを見てください。

RowCountはRecordCountの同義語です。

PO_RecordCount($table, $where)

レコードセットの行数を返します。データベースがこれをサポートしていないばあい、レコードセットの見積りを返すため、任意の$where条件で$tableテーブルに$SELECT COUNT(*)を実行します。

$numrows = $rs->PO_RecordCount("articles_table", "group=$group");

NextRecordSet()

1つのクエリーで複数レコードセットを返すことのできるデータベースに対して、この関数は次のレコードセットに移動することを可能にしてくれます。現在mssqlドライバでのみサポートされています。

$rs = $db->Execute('execute return_multiple_rs');
$arr1 = $rs->GetArray();
$rs->NextRecordSet();
$arr2 = $rs->GetArray();

FetchObject($toupper=true)

現在行をオブジェクトとして返します。$toupperをtrueに設定すると、オブジェクトのフィールドが大文字になります。注意:新しいFetchNextObject()はオブジェクトとして行にアクセスする推奨方法です。下記を参照。

FetchNextObject($toupper=true)

現在行をオブジェクトとして取得し自動的に次の行へ移動します。EOFであればfalseを返します。$toupperをtrueに設定すると、オブジェクトフィールドは大文字になります。

$rs = $db->Execute('select firstname,lastname from table');
if ($rs) {
while ($o = $rs->FetchNextObject()) {
print "$o->FIRSTNAME, $o->LASTNAME<BR>";
}
}

FetchNextObject()を使うばあい実行速度のトレードオフがあります。パフォーマンスが重要であれば、fields[]で行にアクセスすべきです。FetchObj()

現在の行をオブジェクトとして返します。FetchObjectとは違い、フィールドは大文字ではありません。

FetchNextObj()

現在の行をオブジェクトとして返し次のレコードに移動します。IOFであれば、falseが返ります。FetctNextObjectとは違い、フィールドは大文字ではありません。

CurrentRow( )

レコードセットの現在の行を返します。0が最初の行です。

AbsolutePosition( )

ADOとの互換性のためで、CurrentRowの同義語です。レコードセットの現在行を返します。0は最初の行です。

MetaType($nativeDBType[,$field_max_length],[$fieldobj])

データベースフィールドタイプたして文字列でわたされたネイティブタイプ$nativeDBTypeとフィールド長$field_max_lengthが、どのgenericメタタイプであるかを決定します。field_max_lengthが不明であれば、field_max_lengthが-1となることに注意。FetchField()で返されるフィールドオブジェクトは$fieldobjあるいは最後のパラメタ$nativeDBTypeでわたされます。これはフィールドオブジェクトにprimary_keyのような付加的なプロパティをもつmysqlのようなデータベースで役に立ちます。

フィールドblobSizeを使い、それを$field_max_lengthと比較して、characterフィールドがほんとうにBLOBかどうか決定します。

例えば、$db->MetaType('char')は'C'を返します。

返り値:

  • C: <input type="text"> タグに表示されるべき character フィールド
  • X: CLOB(Character Large Objects)、<textarea> タグに表示されるべきlarge text フィールド
  • D: Date フィールド
  • T: Timestamp フィールド
  • L: Logical フィールド (boolean か bitフィールド)
  • N: Numeric フィールド。autoincrement、numeric、floating point、real、integerが含まれます。
  • I: Integer フィールド
  • R: カウンタあるいは自動インクリメントフィールド。数値でなければなりません。
  • B: BLOB、すなわち Binary Large Object。

ADOdb 3.0から、MetaTypeは最初のパラメタとして$nativeDBTypeではなく$fieldobjを受け付けます。

Close( )

レコードセットに関係するすべてのメモリやリソースをきれいにして、レコードセットを閉じます。

もしメモリ管理が問題でなければ、レコードセットが閉じられるときにこの関数をコールする必要はありません。というのは、PHPがスクリプトの最後で閉じてくれるからです。INSERT/UPDATE/DELETEのようなSQL文は実際にはレコードセットを返しません。このためこのようなSQL文に対してはClose()を呼ぶ必要はないのです。


function rs2html($adorecordset,[$tableheader_attributes], [$col_titles])

これはスタンドアロンの関数です(rs2html = recordset to htmlの意味)。これはPHPのodbc_result_all関数に似ています。ADORecordSet $adorecordsetをHTMLテーブルとしてプリントします。$tableheader_attributescellpaddingcellspacingborderの属性を制御することができます。最後にデータベースのカラム名は$col_titles配列を使って自分の好きなカラムタイトルに置き換えることができます。これは製品のテーブルレコードセットビューアとしてではなく、素早いデバッグ機構のために設計されています。

tohtml.inc.phpファイルをインクルードする必要があります。

rs2htmlの例:

<?
include('tohtml.inc.php')
; # ADOdb共通コードをロード
include('adodb.inc.php'); # ADOdb共通コードをロード
$conn = &ADONewConnection('mysql'); # connectionを生成
$conn->PConnect('localhost','userid','','agora');# MySQLのagora dbに接続
$sql = 'select CustomerName, CustomerID from customers';
$rs = $conn->Execute($sql);
rs2html($rs,'border=2 cellpadding=3',array('Customer Name','Customer ID'));
?>

このADOdbライブラリとMicrosoft ADOのちがい

  1. ADOdbは接続オブジェクトが生成したレコードセットのみサポートします。レコードセットをそれだけで生成することはできません。
  2. ADOプロパティはADOdbの中で関数として実装されています。これは将来ADOに高い機能を実装することをとても容易にしてくれます。
  3. ADOdbのADORecordSet->Move()は相対ではなく絶対ポジショニングを使います。ブックマークはサポートされていません。
  4. ADORecordSet->AbsolutePosition() はレコードセットカーソルを移動するために使うことはできません。
  5. ADOパラメタオブジェクトはサポートされていません。そのかわり準備パラメタあるいはストアドプロシージャを呼び出すもっと簡単なインタフェースを提供しているADOConnection::Parameter()関数を使います。
  6. レコードをページングするためのレコードセットプロパティが利用可能です。しかし実装はExample 8のようになっています。

データベース ドライバ ガイド

ここでは新しいデータベースへ接続するクラスの作り方を記述しています。あなたが新しいそのようなクラスを作成しようと決めたなら、作業の重複が発生しないために、jlim#natsoft.com.myにどうかメールしてください。

最初にデータベースタイプをコールする小文字の名前を決めます。それをxbaseとしてみましょう。

次にadodb-xbase.inc.phpファイルのなかに、ADODB_xbaseとADORecordSet_xbaseの2つのクラスを作る必要があります。

データベースドライバのもっとも単純な形は既存のODBCドライバの採用です。それからADODB_odbcを拡張したADODB_xbaseクラス(class ADODB_xbase extends ADODB_odbc)を作る必要があります。このクラスは新しいdatetimestampフォーマット、使用されるconcatenation操作、truefalseをサポートします。ADORecordSet_xbase extends ADORecordSet_odbcのために、MetaType関数を変更する必要があります。例としてadodb-vfp.inc.phpを見てください。

新しいPHP拡張に接続する全く新しいデータベースドライバはもっと複雑です。このばあい幾つかの関数を実装することが必要になるでしょう。幸いに、大部分の複雑なコードを変更する必要はありません。いくつかのスタブ関数をオーバーライドする必要があるだけです。例としてadodb-mysql.inc.phpを見てください。

内部的なADOdbのデフォルト日付フォーマットはYYYY-MM-DD(Ansi-92)です。すべての日付はADOdb関数にわたされるときこのフォーマットに変換されるべきです。例としてはOracleを見てください。_pconnect、_connectのなかでデフォルトの日付フォーマットを変更するためどのようにALTER SESSIONを使っているか。

オーバーライドするADOConnection関数

ADOConnection派生関数のコンストラクタを定義することは任意です。ベースクラスのコンストラクタをコールする必要はありません。

_connect: Connectの低レベル実装。trueかfalseを返します。_connectionIDを設定すべきです。

_pconnect: PConnectの低レベル実装。trueかfalseを返します。_connectionIDを設定すべきです。

_query: クエリーを実行します。queryIDかfalseを返します。

_close: 接続を閉じます。 -- PHPがすべてのレコードセットをクリーンアップすべきです。

ErrorMsg: プライベート変数_errorMsgにエラーメッセージを格納します。

設定するADOConnectionフィールド

_bindInputArray: SQLのINSERTとUPDATEでパラメタの結合の使用が許されていれば、つまりODBCのようであれば、trueを設定。

fmtDate

fmtTimeStamp

true

false

concat_operator

replaceQuote

hasLimit MySQLのSELECT * FROM TABLE LIMIT 10をサポートしている。

hasTop MicrosoftスタイルのSELECT TOP 10 * FROM TABLEをサポートしている。

オーバーライドするADORecordSet関数

親クラスのコンストラクタをコールするADORecordSet派生クラスのコンストラクタを定義する必要があります。

FetchField: ADORecordSetで先に文書化したとおりです。

_initrs: レコードセットの低レベルの初期化です。numOfRowsnumOfFieldsフィールドを設定します。コンストラクタから呼ばれます。

_seek: 特定の行をseekします。フィールド配列にデータをロードしないでください。これは_fetchによって尾こなれます。trueかfalseを返します。Interbaseのようないくつかの実装ではseekをサポートしてません。canSeekをfalseと設定してください。

_fetch: データベース拡張関数を使って行をfetchし、それから次の行へ移動します。fields配列を設定してください。もしパラメタ$ignore_fieldsがtrueであれば、fields配列にデータを充填する必要はなく、たんに次の行に移動します。それからtrueかfalseを返します。

_close: レコードセットを閉じます。

Fields: もしPHP拡張によって返される配列行が連想配列でないばあい、これをオーバーライドしなければなりません。例としてadodb-odbc.inc.phpを見てください。連想配列が返されるMySQLやMSSQLのようなデータベースに対しては、この関数をオーバーライドする必要はありません。

設定するADOConnectionフィールド

canSeek: _seek関数が機能するならtrue。

ToDo:

ロードマップ記事を見てください。

またhttpリモートプロシージャコールを使ってWindowsとUnixデータベースをブリッジするためには、ADOdb proxy記事を見てください。 勉強のため、データベースの情報についてはpalslib.comを訪れてください。またOptimizing PHPでこの記事を読んでください。

変更履歴

4.62 2 Apr 2005

Added 'w' (dow as 0-6 or 1-7) and 'l' (dow as string) for SQLDate for oci8, postgres and mysql.

Rolled back MetaType() changes for mysqli done in prev version.

Datadict change by chris, cblin#tennaxia.com data mappings from:

oci8:  X->varchar(4000) XL->CLOB
mssql: X->XL->TEXT
mysql: X->XL->LONGTEXT
fbird: X->XL->varchar(4000)

to:

oci8:  X->varchar(4000) XL->CLOB
mssql: X->VARCHAR(4000) XL->TEXT
mysql: X->TEXT          XL->LONGTEXT
fbird: X->VARCHAR(4000) XL->VARCHAR(32000)

Added $connection->disableBlobs to postgresql to improve performance when no bytea is used (2-5% improvement).

Removed all HTTP_* vars.

Added $rs->tableName to be set before calling AutoExecute().

Alex Rootoff rootoff#pisem.net contributed ukrainian language file.

Added new mysql_option() support using $conn->optionFlags array.

Added support for ldap_set_option() using the $LDAP_CONNECT_OPTIONS global variable. Contributed by Josh Eldridge.

Added LDAP_* constant definitions to ldap.

Added support for boolean bind variables. We use $conn->false and $conn->true to hold values to set false/true to.

We now do not close the session connection in adodb-session.inc.php as other objects could be using this connection.

We now strip off \0 at end of Ixora SQL strings in $perf->tohtml() for oci8.

4.61 23 Feb 2005

MySQLi added support for mysqli_connect_errno() and mysqli_connect_error().

Massive improvements to alpha PDO driver.

Quote string bind parameters logged by performance monitor for easy type checking. Thx Jason Judge.

Added support for $role when connecting with Interbase/firebird.

Added support for enum recognition in MetaColumns() mysql and mysqli. Thx Amedeo Petrella.

The sybase_ase driver contributed by Interakt Online. Thx Cristian Marin cristic#interaktonline.com.

Removed not_null, has_default, and default_value from ADOFieldObject.

Sessions code, fixed quoting of keys when handling LOBs in session write() function.

Sessions code, added adodb_session_regenerate_id(), to reduce risk of session hijacking by changing session cookie dynamically. Thx Joe Li.

Perf monitor, polling for CPU did not work for PHP 4.3.10 and 5.0.0-5.0.3 due to PHP bugs, so we special case these versions.

Postgresql, UpdateBlob() added code to handle type==CLOB.

4.60 24 Jan 2005

Implemented PEAR DB's autoExecute(). Simplified design because I don't like using constants when strings work fine.

_rs2serialize will now update $rs->sql and $rs->oldProvider.

Added autoExecute().

Added support for postgres8 driver. Currently just remapped to postgres7 driver.

Changed oci8 _query(), so that OCIBindByName() sets the length to -1 if element size is > 4000. This provides better support for LONGs.

Added SetDateLocale() support for netherlands (Nl).

Spelling error in pivot code ($iff should be $iif).

mysql insert_id() did not work with mysql 3.x. Fixed.

"\r\n" not converted to spaces correctly in exporting data. Fixed.

_nconnect() in mysqli did not return value correctly. Fixed.

Arne Eckmann contributed danish language file.

Added clone() support to FetchObject() for PHP5.

Removed SQL_CUR_USE_ODBC from odbc_mssql.

4.55 5 Jan 2005

Found bug in Execute() with bind params for db's that do not support binding natively.

DropSequence() now correctly uses default parameter.

Now Execute() ignores locale for floats, so 1.23 is NEVER converted to 1,23.

SetFetchMode() not properly saved in adodb-perf, suspicious sql and expensive sql. Fixed.

Added INET to postgresql metatypes. Thx motzel.

Allow oracle hints to work when counting with _adodb_getcount in adodb-lib.inc.php. Thx Chris Wrye.

Changed mysql insert_id() to use SELECT LAST_INSERT_ID().

If alter col in datadict does not modify col type/size of actual col, then it is removed from alter col code. By Mark Newham. Not perfect as MetaType() !== ActualType().

Added handling of view fields in metacolumns() for postgresql. Thx Renato De Giovanni.

Added to informix MetaPrimaryKeys and MetaColumns fixes for null bit. Thx to Cecilio Albero.

Removed obsolete connection_timeout() from perf code.

Added support for arrayClass in adodb-csv.inc.php.

RSFilter now accepts methods of the form $array($obj, 'methodname'). Thx to blake#near-time.com.

Changed CacheFlush to $cmd = 'rm -rf '.$ADODB_CACHE_DIR.'/[0-9a-f][0-9a-f]/';

For better cursor concurrency, added code to free ref cursors in oci8 when $rs->Close() is called. Note that CLose() is called internally by the Get* functions too.

Added IIF support for access when pivoting. Thx Volodia Krupach.

Added mssql datadict support for timestamp. Thx Alexios.

Informix pager fix. By Mario Ramirez.

ADODB_TABLE_REGEX now includes ':'. By Mario Ramirez.

Mark Newnham contributed MetaIndexes for oci8 and db2.

4.54 5 Nov 2004

Now you can set $db->charSet = ?? before doing a Connect() in oci8.

Added adodbFetchMode to sqlite.

Perf code, added a string typecast to substr in adodb_log_sql().

Postgres: Changed BlobDecode() to use po_loread, added new $maxblobsize parameter, and now it returns the blob instead of sending it to stdout - make sure to mention that as a compat warning. Also added $db->IsOID($oid) function; uses a heuristic, not guaranteed to work 100%.

Contributed arabic language file by "El-Shamaa, Khaled" k.el-shamaa#cgiar.org

PHP5 exceptions did not handle @ protocol properly. Fixed.

Added ifnull handling for postgresql (using coalesce).

Added metatables() support for Postgresql 8.0 (no longer uses pg_% dictionary tables).

Improved Sybase ErrorMsg() function. By Gaetano Giunta.

Improved oci8 SelectLimit() to use Prepare(). By Cristiano Duarte.

Type-cast $row parameter in ifx_fetch_row() to int. Thx stefan bodgan.

Ralf becker contributed improvements in postgresql, sapdb, mysql data dictionary handling:
- MySql and Postgres MetaType was reporting every int column which was part of a primary key and unique as serial
- Postgres was not reporting the scale of decimal types
- MaxDB was padding the defaults of none-string types with spaces
- MySql now correctly converts enum columns to varchar

Ralf also changed Postgresql datadict:
- you cant add NOT NULL columns in postgres in one go, they need to be added as NULL and then altered to NOT NULL
- AlterColumnSQL could not change a varchar column with numbers into an integer column, postgres need an explicit conversation
- a re-created sequence was not set to the correct value, if the name was the old name (no implicit sequence), now always the new name of the implicit sequence is used

Sergio Strampelli added extra $intoken check to Lens_ParseArgs() in datadict code.

4.53 28 Sept 2004

FetchMode cached in recordset is sometimes mapped to native db fetchMode. Normally this does not matter, but when using cached recordsets, we need to switch back to using adodb fetchmode. So we cache this in $rs->adodbFetchMode if it differs from the db's fetchMode.

For informix we now set canSeek = false driver because stefan bodgan tells me that seeking doesn't work.

SetDateLocale() never worked till now ;-) Thx david#tomato.it

Set $_bindInputArray = true in sapdb driver. Required for clob support.

Fixed some PEAR::DB emulation issues with isError() and isWarning. Thx to Gert-Rainer Bitterlich.

Empty() used in getupdatesql without strlen() check. Fixed.

Added unsigned detection to mysql and mysqli drivers. Thx to dan cech.

Added hungarian language file. Thx to Halászvári Gábor.

Improved fieldname-type formatting of datadict SQL generated (adding $widespacing parameter to _GenField).

Datadict oci8 DROP CONSTRAINTS misspelt. Fixed. Thx Mark Newnham.

Changed odbtp to dynamically change databaseType based on connection, eg. from 'odbtp' to 'odbtp_mssql' when connecting to mssql database.

In datadict, MySQL I4 was wrongly mapped to MEDIUMINT, which is actually I3. Fixed.

Fixed mysqli MetaType() recognition. Mysqli returns numeric types unlike mysql extension. Thx Francesco Riosa.

VFP odbc driver curmode set wrongly, causing problems with memo fields. Fixed.

Odbc driver did not recognize odbc version 2 driver date types properly. Fixed. Thx Bostjan.

ChangeTableSQL() fixes to datadict-db2.inc.php by Mark Newnham.

Perf monitoring with odbc improved. Now we try in perf code to manually set the sysTimeStamp using date() if sysTimeStamp is empty.

All ADO errors are thrown as exceptions in PHP5. So we added exception handling to ado in PHP5 by creating new adodb-ado5.inc.php driver.

Added IsConnected(). Returns true if connection object connected. By Luca.Gioppo.

"Ralf Becker" RalfBecker#digitalROCK.de contributed new sapdb data-dictionary driver and a large patch that implements field and table renaming for oracle, mssql, postgresql, mysql and sapdb. See the new RenameTableSQL() and RenameColumnSQL() functions.

We now check ExecuteCursor to see if PrepareSP was initially called.

Changed oci8 datadict to use MODIFY for $dd->alterCol. Thx Mark Newnham.

4.52 10 Aug 2004

Bug found in Replace() when performance logging enabled, introduced in ADOdb 4.50. Fixed.

Replace() checks update stmt. If update stmt fails, we now return immediately. Thx to alex.

Added support for $ADODB_FORCE_TYPE in GetUpdateSQL/GetInsertSQL. Thx to niko.

Added ADODB_ASSOC_CASE support to postgres/postgres7 driver.

Support for DECLARE stmt in oci8. Thx Lochbrunner.

4.51 29 July 2004

Added adodb-xmlschema 1.0.2. Thx dan and richard.

Added new adorecordset_ext_* classes. If ADOdb extension installed for mysql, mysqlt and oci8 (but not oci8po), we use the superfast ADOdb extension code for movenext.

Added schema support to mssql and odbc_mssql MetaPrimaryKeys().

Patched MSSQL driver to support PHP NULL and Boolean values while binding the input array parameters in the _query() function. By Stephen Farmer.

Added support for clob's for mssql, UpdateBlob(). Thx to gfran#directa.com.br

Added normalize support for postgresql (true=lowercase table name, or false=case-sensitive table names) to MetaColumns($table, $normalize=true).

PHP5 variant dates in ADO not working. Fixed in adodb-ado.inc.php.

Constant ADODB_FORCE_NULLS was not working properly for many releases (for GetUpdateSQL). Fixed. Also GetUpdateSQL strips off ORDER BY now - thx Elieser Leão.

Perf Monitor for oci8 now dynamically highlights optimizer_* params if too high/low.

Added dsn support to NewADOConnection/ADONewConnection.

Fixed out of page bounds bug in _adodb_pageexecute_all_rows() Thx to "Sergio Strampelli" sergio#rir.it

Speedup of movenext for mysql and oci8 drivers.

Moved debugging code _adodb_debug_execute() to adodb-lib.inc.php.

Fixed postgresql bytea detection bug. See http://phplens.com/lens/lensforum/msgs.php?id=9849.

Fixed ibase datetimestamp typo in PHP5. Thx stefan.

Removed whitespace at end of odbtp drivers.

Added db2 metaprimarykeys fix.

Optimizations to MoveNext() for mysql and oci8. Misc speedups to Get* functions.

4.50 6 July 2004

Bumped it to 4.50 to avoid confusion with PHP 4.3.x series.

Added db2 metatables and metacolumns extensions.

Added alpha PDO driver. Very buggy, only works with odbc.

Tested mysqli. Set poorAffectedRows = true. Cleaned up movenext() and _fetch().

PageExecute does not work properly with php5 (return val not a variable). Reported Dmytro Sychevsky sych#php.com.ua. Fixed.

MetaTables() for mysql, $showschema parameter was not backward compatible with older versions of adodb. Fixed.

Changed mysql GetOne() to work with mysql 3.23 when using with non-select stmts (e.g. SHOW TABLES).

Changed TRIG_ prefix to a variable in datadict-oci8.inc.php. Thx to Luca.Gioppo#csi.it.

New to adodb-time code. We allow you to define your own daylights savings function, adodb_daylight_sv for pre-1970 dates. If the function is defined (somewhere in an include), then you can correct for daylights savings. See http://phplens.com/phpeverywhere/node/view/16#daylightsavings for more info.

New sqlitepo driver. This is because assoc mode does not work like other drivers in sqlite. Namely, when selecting (joining) multiple tables, in assoc mode the table names are included in the assoc keys in the "sqlite" driver. In "sqlitepo" driver, the table names are stripped from the returned column names. When this results in a conflict, the first field get preference. Contributed by Herman Kuiper herman#ozuzo.net

Added $forcenull parameter to GetInsertSQL/GetUpdateSQL. Idea by Marco Aurelio Silva.

More XHTML changes for GetMenu. By Jeremy Evans.

Fixes some ibase date issues. Thx to stefan bogdan.

Improvements to mysqli driver to support $ADODB_COUNTRECS.

Fixed adodb-csvlib.inc.php problem when reading stream from socket. We need to poll stream continiously.

4.23 16 June 2004

New interbase/firebird fixes thx to Lester Caine. Driver fixes a problem with getting field names in the result array, and corrects a couple of data conversions. Also we default to dialect3 for firebird. Also ibase sysDate property was wrong. Changed to cast as timestamp.

The datadict driver is set up to give quoted tables and fields as this was the only way round reserved words being used as field names in TikiWiki. TikiPro is tidying that up, and I hope to be able to produce a build of THAT which uses what I consider proper UPPERCASE field and table names. The conversion of TikiWiki to ADOdb helped in that, but until the database is completely tidied up in TikiPro ...

Modified _gencachename() to include fetchmode in name hash. This means you should clear your cache directory after installing this release as the cache name algorithm has changed.

Now Cache* functions work in safe mode, because we do not create sub-directories in the $ADODB_CACHE_DIR in safe mode. In non-safe mode we still create sub-directories. Done by modifying _gencachename().

Added $gmt parameter (true/false) to UserDate and UserTimeStamp in connection class, to force conversion of input (in local time) to be converted to UTC/GMT.

Mssql datadict did not support INT types properly (no size param allowed). Added _GetSize() to datadict-mssql.inc.php.

For borland_ibase, BeginTrans(), changed:

   $this->_transactionID = $this->_connectionID;
to
   $this->_transactionID = ibase_trans($this->ibasetrans, $this->_connectionID);

Fixed typo in mysqi_field_seek(). Thx to Sh4dow (sh4dow#php.pl).

LogSQL did not work with Firebird/Interbase. Fixed.

Postgres: made errorno() handling more consistent. Thx to Michael Jahn, Michael.Jahn#mailbox.tu-dresden.de.

Added informix patch to better support metatables, metacolumns by "Cecilio Albero" c-albero#eos-i.com

Cyril Malevanov contributed patch to oci8 to support passing of LOB parameters:

	$text = 'test test test';
$sql = "declare rs clob; begin :rs := lobinout(:sa0); end;";
$stmt = $conn -> PrepareSP($sql);
$conn -> InParameter($stmt,$text,'sa0', -1, OCI_B_CLOB);
$rs = '';
$conn -> OutParameter($stmt,$rs,'rs', -1, OCI_B_CLOB);
$conn -> Execute($stmt);
echo "return = ".$rs."<br>";
As he says, the LOBs limitations are:
 - use OCINewDescriptor before binding
- if Param is IN, uses save() before each execute. This is done automatically for you.
- if Param is OUT, uses load() after each execute. This is done automatically for you.
- when we bind $var as LOB, we create new descriptor and return it as a
Bind Result, so if we want to use OUT parameters, we have to store
somewhere &$var to load() data from LOB to it.
- IN OUT params are not working now (should not be a big problem to fix it)
- now mass binding not working too (I've wrote about it before)

Simplified Connect() and PConnect() error handling.

When extension not loaded, Connect() and PConnect() will return null. On connect error, the fns will return false.

CacheGetArray() added to code.

Added Init() to adorecordset_empty().

Changed postgres64 driver, MetaColumns() to not strip off quotes in default value if :: detected (type-casting of default).

Added test: if (!defined('ADODB_DIR')) die(). Useful to prevent hackers from detecting file paths.

Changed metaTablesSQL to ignore Postgres 7.4 information schemas (sql_*).

New polish language file by Grzegorz Pacan

Added support for UNION in _adodb_getcount().

Added security check for ADODB_DIR to limit path disclosure issues. Requested by postnuke team.

Added better error message support to oracle driver. Thx to Gaetano Giunta.

Added showSchema support to mysql.

Bind in oci8 did not handle $name=false properly. Fixed.

If extension not loaded, Connect(), PConnect(), NConnect() will return null.

4.22 15 Apr 2004

Moved docs to own adodb/docs folder.

Fixed session bug when quoting compressed/encrypted data in Replace().

Netezza Driver and LDAP drivers contributed by Josh Eldridge.

GetMenu now uses rtrim() on values instead of trim().

Changed MetaColumnNames to return an associative array, keys being the field names in uppercase.

Suggested fix to adodb-ado.inc.php affected_rows to support PHP5 variants. Thx to Alexios Fakos.

Contributed bulgarian language file by Valentin Sheiretsky valio#valio.eu.org.

Contributed romanian language file by stefan bogdan.

GetInsertSQL now checks for table name (string) in $rs, and will create a recordset for that table automatically. Contributed by Walt Boring. Also added OCI_B_BLOB in bind on Walt's request - hope it doesn't break anything :-)

Some minor postgres speedups in _initrs().

ChangeTableSQL checks now if MetaColumns returns empty. Thx Jason Judge.

Added ADOConnection::Time(), returns current database time in unix timestamp format, or false.

4.21 20 Mar 2004

We no longer in SelectLimit for VFP driver add SELECT TOP X unless an ORDER BY exists.

Pim Koeman contributed dutch language file adodb-nl.inc.php.

Rick Hickerson added CLOB support to db2 datadict.

Added odbtp driver. Thx to "stefan bogdan" sbogdan#rsb.ro.

Changed PrepareSP() 2nd parameter, $cursor, to default to true (formerly false). Fixes oci8 backward compat problems with OUT params.

Fixed month calculation error in adodb-time.inc.php. 2102-June-01 appeared as 2102-May-32.

Updated PHP5 RC1 iterator support. API changed, hasMore() renamed to valid().

Changed internal format of serialized cache recordsets. As we store a version number, this should be backward compatible.

Error handling when driver file not found was flawed in ADOLoadCode(). Fixed.

4.20 27 Feb 2004

Updated to AXMLS 1.01.

MetaForeignKeys for postgres7 modified by Edward Jaramilla, works on pg 7.4.

Now numbers accepts function calls or sequences for GetInsertSQL/GetUpdateSQL numeric fields.

Changed quotes of 'delete from $perf_table' to "". Thx Kehui (webmaster#kehui.net)

Added ServerInfo() for ifx, and putenv trim fix. Thx Fernando Ortiz.

Added addq(), which is analogous to addslashes().

Tested with php5b4. Fix some php5 compat problems with exceptions and sybase.

Carl-Christian Salvesen added patch to mssql _query to support binds greater than 4000 chars.

Mike suggested patch to PHP5 exception handler. $errno must be numeric.

Added double quotes (") to ADODB_TABLE_REGEX.

For oci8, Prepare(...,$cursor), $cursor's meaning was accidentally inverted in 4.11. This causes problems with ExecuteCursor() too, which calls Prepare() internally. Thx to William Lovaton.

Now dateHasTime property in connection object renamed to datetime for consistency. This could break bc.

Csongor Halmai reports that db2 SelectLimit with input array is not working. Fixed..

4.11 27 Jan 2004

Csongor Halmai reports db2 binding not working. Reverted back to emulated binding.

Dan Cech modifies datadict code. Adds support for DropIndex. Minor cleanups.

Table misspelt in perf-oci8.inc.php. Changed v$conn_cache_advice to v$db_cache_advice. Reported by Steve W.

UserTimeStamp and DBTimeStamp did not handle YYYYMMDDHHMMSS format properly. Reported by Mike Muir. Fixed.

Changed oci8 Prepare(). Does not auto-allocate OCINewCursor automatically, unless 2nd param is set to true. This will break backward compat, if Prepare/Execute is used instead of ExecuteCursor. Reported by Chris Jones.

Added InParameter() and OutParameter(). Wrapper functions to Parameter(), but nicer because they are self-documenting.

Added 'R' handling in ActualType() to datadict-mysql.inc.php

Added ADOConnection::SerializableRS($rs). Returns a recordset that can be serialized in a session.

Added "Run SQL" to performance UI().

Misc spelling corrections in adodb-mysqli.inc.php, adodb-oci8.inc.php and datadict-oci8.inc.php, from Heinz Hombergs.

MetaIndexes() for ibase contributed by Heinz Hombergs.

4.10 12 Jan 2004

Dan Cech contributed extensive changes to data dictionary to support name quoting (with `), and drop table/index.

Informix added cursorType property. Default remains IFX_SCROLL, but you can change to 0 (non-scrollable cursor) for performance.

Added ADODB_View_PrimaryKeys() for returning view primary keys to MetaPrimaryKeys().

Simplified chinese file, adodb-cn.inc.php from cysoft.

Added check for ctype_alnum in adodb-datadict.inc.php. Thx to Jason Judge.

Added connection parameter to ibase Prepare(). Fix by Daniel Hassan.

Added nameQuote for quoting identifiers and names to connection obj. Requested by Jason Judge. Also the data dictionary parser now detects `field name` and generates column names with spaces correctly.

BOOL type not recognised correctly as L. Fixed.

Fixed paths in ADODB_DIR for session files, and back-ported it to 4.05 (15 Dec 2003)

Added Schema to postgresql MetaTables. Thx to col#gear.hu

Empty postgresql recordsets that had blob fields did not set EOF properly. Fixed.

CacheSelectLimit internal parameters to SelectLimit were wrong. Thx to Nio.

Modified adodb_pr() and adodb_backtrace() to support command-line usage (eg. no html).

Fixed some fr and it lang errors. Thx to Gaetano G.

Added contrib directory, with adodb rs to xmlrpc convertor by Gaetano G.

Fixed array recordset bugs when _skiprow1 is true. Thx to Gaetano G.

Fixed pivot table code when count is false.

4.05 13 Dec 2003

Added MetaIndexes to data-dict code - thx to Dan Cech.

Rewritten session code by Ross Smith. Moved code to adodb/session directory.

Added function exists check on connecting to most drivers, so we don't crash with the unknown function error.

Smart Transactions failed with GenID() when it no seq table has been created because the sql statement fails. Fix by Mark Newnham.

Added $db->length, which holds name of function that returns strlen.

Fixed error handling for bad driver in ADONewConnection - passed too few params to error-handler.

Datadict did not handle types like 16.0 properly in _GetSize. Fixed.

Oci8 driver SelectLimit() bug &= instead of =& used. Thx to Swen Thümmler.

Jesse Mullan suggested not flushing outp when output buffering enabled. Due to Apache 2.0 bug. Added.

MetaTables/MetaColumns return ref bug with PHP5 fixed in adodb-datadict.inc.php.

New mysqli driver contributed by Arjen de Rijke. Based on adodb 3.40 driver. Then jlim added BeginTrans, CommitTrans, RollbackTrans, IfNull, SQLDate. Also fixed return ref bug.

$ADODB_FLUSH added, if true then force flush in debugging outp. Default is false. In earlier versions, outp defaulted to flush, which is not compat with apache 2.0.

Mysql driver's GenID() function did not work when when sql logging is on. Fixed.

$ADODB_SESSION_TBL not declared as global var. Not available if adodb-session.inc.php included in function. Fixed.

The input array not passed to Execute() in _adodb_getcount(). Fixed.

4.04 13 Nov 2003

Switched back to foreach - faster than list-each.

Fixed bug in ado driver - wiping out $this->fields with date fields.

Performance Monitor, View SQL, Explain Plan did not work if strlen($SQL)>max($_GET length). Fixed.

Performance monitor, oci8 driver added memory sort ratio.

Added random property, returns SQL to generate a floating point number between 0 and 1;

4.03 6 Nov 2003

The path to adodb-php4.inc.php and adodb-iterators.inc.php was not setup properly.

Patched SQLDate in interbase to support hours/mins/secs. Thx to ari kuorikoski.

Force autorollback for pgsql persistent connections - apparently pgsql did not autorollback properly before 4.3.4. See http://bugs.php.net/bug.php?id=25404

4.02 5 Nov 2003

Some errors in adodb_error_pg() fixed. Thx to Styve.

Spurious Insert_ID() error was generated by LogSQL(). Fixed.

Insert_ID was interfering with Affected_Rows() and Replace() when LogSQL() enabled. Fixed.

More foreach loops optimized with list/each.

Null dates not handled properly in ADO driver (it becomes 31 Dec 1969!).

Heinz Hombergs contributed patches for mysql MetaColumns - adding scale, made interbase MetaColumns work with firebird/interbase, and added lang/adodb-de.inc.php.

Added INFORMIXSERVER environment variable.

Added $ADODB_ANSI_PADDING_OFF for interbase/firebird.

PHP 5 beta 2 compat check. Foreach (Iterator) support. Exceptions support.

4.01 23 Oct 2003

Fixed bug in rs2html(), tohtml.inc.php, that generated blank table cells.

Fixed insert_id() incorrectly generated when logsql() enabled.

Modified PostgreSQL _fixblobs to use list/each instead of foreach.

Informix ErrorNo() implemented correctly.

Modified several places to use list/each, including GetRowAssoc().

Added UserTimeStamp() to connection class.

Added $ADODB_ANSI_PADDING_OFF for oci8po.

4.00 20 Oct 2003

Upgraded adodb-xmlschema to 1 Oct 2003 snapshot.

Fix to rs2html warning message. Thx to Filo.

Fix for odbc_mssql/mssql SQLDate(), hours was wrong.

Added MetaColumns and MetaPrimaryKeys for sybase. Thx to Chris Phillipson.

Added autoquoting to datadict for MySQL and PostgreSQL. Suggestion by Karsten Dambekalns

3.94 11 Oct 2003

Create trigger in datadict-oci8.inc.php did not work, because all cr/lf's must be removed.

ErrorMsg()/ErrorNo() did not work for many databases when logging enabled. Fixed.

Removed global variable $ADODB_LOGSQL as it does not work properly with multiple connections.

Added SQLDate support for sybase. Thx to Chris Phillipson

Postgresql checking of pgsql resultset resource was incorrect. Fix by Bharat Mediratta bharat#menalto.com. Same patch applied to _insertid and _affectedrows for adodb-postgres64.inc.php.

Added support for NConnect for postgresql.

Added Sybase data dict support. Thx to Chris Phillipson

Extensive improvements in $perf->UI(), eg. Explain now opens in new window, we show scripts which call sql, etc.

Perf Monitor UI works with magic quotes enabled.

rsPrefix was declared twice. Removed.

Oci8 stored procedure support, eg. "begin func(); end;" was incorrect in _query. Fixed.

Tiraboschi Massimiliano contributed italian language file.

Fernando Ortiz, fortiz#lacorona.com.mx, contributed informix performance monitor.

Added _varchar (varchar arrays) support for postgresql. Reported by PREVOT Stéphane.


0.10 Sept 9 2000 First release

Old change log history moved to old-changelog.htm.