2007/01/04

PDOでpgsqlのbyteaカラムにはどうやって格納するの

ポスト @ 4:57:55 , 修正 @ 2007/01/04 5:20:34 |     このエントリーを含むはてなブックマーク

「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

Post Your Comment


*は入力必須です。E-Mailは公開されません。

1 + 2 =