2007/01/04
PDOでpgsqlのbyteaカラムにはどうやって格納するの
「PDOでpgsqlのbyteaカラムにはどうやって格納するの」という質問に詰まってしまったので、少し調べてみました。
bytea型なんてものを初めて聞いたのですが、マニュアルを覗いてみると「8.4. バイナリ列データ型」とありました。
"バイナリ"とあるので、実際試していないながらもPDO::PARAM_LOBでいいんじゃね。と答えてみましたが、少し心配になったのでpgsql_statement.cを見てみると
static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
{
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
struct pdo_column_data *cols = stmt->columns;
if (!S->result) {
return 0;
}
cols[colno].name = estrdup(PQfname(S->result, colno));
cols[colno].namelen = strlen(cols[colno].name);
cols[colno].maxlen = PQfsize(S->result, colno);
cols[colno].precision = PQfmod(S->result, colno);
S->cols[colno].pgsql_type = PQftype(S->result, colno);
switch(S->cols[colno].pgsql_type) {
case BOOLOID:
cols[colno].param_type = PDO_PARAM_BOOL;
break;
case INT2OID:
case INT4OID:
case OIDOID:
cols[colno].param_type = PDO_PARAM_INT;
break;
case INT8OID:
if (sizeof(long)>=8) {
cols[colno].param_type = PDO_PARAM_INT;
} else {
cols[colno].param_type = PDO_PARAM_STR;
}
break;
case BYTEAOID:
cols[colno].param_type = PDO_PARAM_LOB;
break;
default:
cols[colno].param_type = PDO_PARAM_STR;
}
return 1;
}
というような記述があるので、たぶんLOBで大丈夫でしょう。(今度PDO::PARAM_LOBで試してみます)
(ちなみに、PQftypeは問い合わせ関数らしく、OIDを返すらしいです)
また、mysql_statement.cはこんな感じ。
static int pdo_mysql_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
{
pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data;
struct pdo_column_data *cols = stmt->columns;
unsigned int i;
if (!S->result) {
return 0;
}
if (colno >= stmt->column_count) {
/* error invalid column */
return 0;
}
/* fetch all on demand, this seems easiest
** if we've been here before bail out
*/
if (cols[0].name) {
return 1;
}
for (i=0; i < stmt->column_count; i++) {
int namelen;
namelen = strlen(S->fields[i].name);
cols[i].precision = S->fields[i].decimals;
cols[i].maxlen = S->fields[i].length;
cols[i].namelen = namelen;
cols[i].name = estrndup(S->fields[i].name, namelen);
cols[i].param_type = PDO_PARAM_STR;
}
return 1;
}
んで、このpgsql_stmt_describeやpdo_mysql_stmt_describeってのは何かというと、php_pdo_driver.hで定義されている構造体(インタフェース)で、こんな風に定義されてます。
struct pdo_stmt_methods {
pdo_stmt_dtor_func dtor;
pdo_stmt_execute_func executer;
pdo_stmt_fetch_func fetcher;
pdo_stmt_describe_col_func describer;
pdo_stmt_get_col_data_func get_col;
pdo_stmt_param_hook_func param_hook;
pdo_stmt_set_attr_func set_attribute;
pdo_stmt_get_attr_func get_attribute;
pdo_stmt_get_column_meta_func get_column_meta;
pdo_stmt_next_rowset_func next_rowset;
pdo_stmt_cursor_closer_func cursor_closer;
};
ここで定義されているdescriberを通して色々なドライバがそのDBMSに合った型へ変換しているんですね(たぶん)。
ちなみに、pgsqlは型が多いのですが、infomixのinformix_statement.cは結構迫力あります。
また、describerが発行されるタイミングとしては、PDOStatement::getColumnMetaの時っぽいです。(::executeのときも?)
といってもソースを眺めただけでトレースしてませんので、深い部分(?)は識者の方に任せつつ、今後じっくりこの辺を追ってみます。
# それにしてもpgsqlの型は多すぎじゃないかしら
Trackback
No Trackbacks
Track from Your Website
http://blog.xole.net/trackback/tb.php?id=536

Comment
No Comments