[patch] add COPY functions to pdo_pgsql
| From: | Tim Ringenbach | Date: | Thu, 05 Nov 2009 18:37:23 +0000 |
| Subject: | [patch] add COPY functions to pdo_pgsql | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-45954@lists.php.net to get a copy of this message | ||
Here's a patch to add pgsqlGetCopyData, pgsqlPutCopyData, and
pgsqlEndCopyData
methods. I opened bug #50092 but I don't seem able to attach the patch,
so I attached it here.
--Tim
Index: ext/pdo_pgsql/pgsql_driver.c =================================================================== --- ext/pdo_pgsql/pgsql_driver.c (revision 290359) +++ ext/pdo_pgsql/pgsql_driver.c (working copy) @@ -292,7 +292,7 @@ return -1; } qs = PQresultStatus(res); - if (qs != PGRES_COMMAND_OK && qs != PGRES_TUPLES_OK) { + if (qs != PGRES_COMMAND_OK && qs != PGRES_TUPLES_OK && qs != PGRES_COPY_OUT && qs != PGRES_COPY_IN) { pdo_pgsql_error(dbh, qs, pdo_pgsql_sqlstate(res)); PQclear(res); return -1; @@ -603,11 +603,99 @@ } /* }}} */ +/* {{{ proto string PDO::pgsqlGetCopyData() + Receives data after issuing a COPY TO STDOUT query. */ +static PHP_METHOD(PDO, pgsqlGetCopyData) +{ + pdo_dbh_t *dbh; + pdo_pgsql_db_handle *H; + int res; + char *buffer; + + dbh = zend_object_store_get_object(getThis() TSRMLS_CC); + PDO_CONSTRUCT_CHECK; + H = (pdo_pgsql_db_handle *)dbh->driver_data; + + res = PQgetCopyData(H->server, &buffer, 0); + + if (res > 0) { + char *ret = emalloc(res); + memcpy(ret, buffer, res); + PQfreemem(buffer); + RETURN_STRINGL(ret, res, 0); + } else if (res == -1) { + /* Done copying */ + RETURN_FALSE; + } else { + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000"); + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto boolean PDO::pgsqlPutCopyData(string) + Send data to the postgresql server after issuing a COPY FROM STDIN. */ +static PHP_METHOD(PDO, pgsqlPutCopyData) +{ + pdo_dbh_t *dbh; + pdo_pgsql_db_handle *H; + int res; + char *buffer; + int bufferlen; + + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", + &buffer, &bufferlen)) { + RETURN_FALSE; + } + + dbh = zend_object_store_get_object(getThis() TSRMLS_CC); + PDO_CONSTRUCT_CHECK; + + H = (pdo_pgsql_db_handle *)dbh->driver_data; + + res = PQputCopyData(H->server, buffer, bufferlen); + + if (res == 1) { + RETURN_TRUE; + } else { + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000"); + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto boolean PDO::pgsqlPutCopyEnd() + End sending data to the postgresql server after issuing a COPY FROM STDIN. */ +static PHP_METHOD(PDO, pgsqlPutCopyEnd) +{ + pdo_dbh_t *dbh; + pdo_pgsql_db_handle *H; + int res; + + dbh = zend_object_store_get_object(getThis() TSRMLS_CC); + PDO_CONSTRUCT_CHECK; + + H = (pdo_pgsql_db_handle *)dbh->driver_data; + + res = PQputCopyEnd(H->server, NULL); + + if (res == 1) { + RETURN_TRUE; + } else { + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000"); + } + RETURN_FALSE; +} +/* }}} */ + static const zend_function_entry dbh_methods[] = { PHP_ME(PDO, pgsqlLOBCreate, NULL, ZEND_ACC_PUBLIC) PHP_ME(PDO, pgsqlLOBOpen, NULL, ZEND_ACC_PUBLIC) PHP_ME(PDO, pgsqlLOBUnlink, NULL, ZEND_ACC_PUBLIC) + PHP_ME(PDO, pgsqlGetCopyData, NULL, ZEND_ACC_PUBLIC) + PHP_ME(PDO, pgsqlPutCopyData, NULL, ZEND_ACC_PUBLIC) + PHP_ME(PDO, pgsqlPutCopyEnd, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; Index: ext/pdo_pgsql/pgsql_statement.c =================================================================== --- ext/pdo_pgsql/pgsql_statement.c (revision 290359) +++ ext/pdo_pgsql/pgsql_statement.c (working copy) @@ -215,7 +215,7 @@ } status = PQresultStatus(S->result); - if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) { + if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK && status != PGRES_COPY_OUT && status != PGRES_COPY_IN) { pdo_pgsql_error_stmt(stmt, status, pdo_pgsql_sqlstate(S->result)); return 0; } @@ -228,7 +228,7 @@ if (status == PGRES_COMMAND_OK) { stmt->row_count = (long)atoi(PQcmdTuples(S->result)); H->pgoid = PQoidValue(S->result); - } else { + } else if (status == PGRES_TUPLES_OK) { stmt->row_count = (long)PQntuples(S->result); } @@ -423,6 +423,11 @@ if (!S->result) { return 0; + } else { + ExecStatusType status = PQresultStatus(S->result); + if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) { + return 0; + } } cols[colno].name = estrdup(PQfname(S->result, colno));
Index: ext/pdo_pgsql/pgsql_driver.c =================================================================== --- ext/pdo_pgsql/pgsql_driver.c (revision 290359) +++ ext/pdo_pgsql/pgsql_driver.c (working copy) @@ -292,7 +292,7 @@ return -1; } qs = PQresultStatus(res); - if (qs != PGRES_COMMAND_OK && qs != PGRES_TUPLES_OK) { + if (qs != PGRES_COMMAND_OK && qs != PGRES_TUPLES_OK && qs != PGRES_COPY_OUT && qs != PGRES_COPY_IN) { pdo_pgsql_error(dbh, qs, pdo_pgsql_sqlstate(res)); PQclear(res); return -1; @@ -603,11 +603,99 @@ } /* }}} */ +/* {{{ proto string PDO::pgsqlGetCopyData() + Receives data after issuing a COPY TO STDOUT query. */ +static PHP_METHOD(PDO, pgsqlGetCopyData) +{ + pdo_dbh_t *dbh; + pdo_pgsql_db_handle *H; + int res; + char *buffer; + + dbh = zend_object_store_get_object(getThis() TSRMLS_CC); + PDO_CONSTRUCT_CHECK; + H = (pdo_pgsql_db_handle *)dbh->driver_data; + + res = PQgetCopyData(H->server, &buffer, 0); + + if (res > 0) { + char *ret = emalloc(res); + memcpy(ret, buffer, res); + PQfreemem(buffer); + RETURN_STRINGL(ret, res, 0); + } else if (res == -1) { + /* Done copying */ + RETURN_FALSE; + } else { + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000"); + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto boolean PDO::pgsqlPutCopyData(string) + Send data to the postgresql server after issuing a COPY FROM STDIN. */ +static PHP_METHOD(PDO, pgsqlPutCopyData) +{ + pdo_dbh_t *dbh; + pdo_pgsql_db_handle *H; + int res; + char *buffer; + int bufferlen; + + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", + &buffer, &bufferlen)) { + RETURN_FALSE; + } + + dbh = zend_object_store_get_object(getThis() TSRMLS_CC); + PDO_CONSTRUCT_CHECK; + + H = (pdo_pgsql_db_handle *)dbh->driver_data; + + res = PQputCopyData(H->server, buffer, bufferlen); + + if (res == 1) { + RETURN_TRUE; + } else { + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000"); + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto boolean PDO::pgsqlPutCopyEnd() + End sending data to the postgresql server after issuing a COPY FROM STDIN. */ +static PHP_METHOD(PDO, pgsqlPutCopyEnd) +{ + pdo_dbh_t *dbh; + pdo_pgsql_db_handle *H; + int res; + + dbh = zend_object_store_get_object(getThis() TSRMLS_CC); + PDO_CONSTRUCT_CHECK; + + H = (pdo_pgsql_db_handle *)dbh->driver_data; + + res = PQputCopyEnd(H->server, NULL); + + if (res == 1) { + RETURN_TRUE; + } else { + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000"); + } + RETURN_FALSE; +} +/* }}} */ + static const zend_function_entry dbh_methods[] = { PHP_ME(PDO, pgsqlLOBCreate, NULL, ZEND_ACC_PUBLIC) PHP_ME(PDO, pgsqlLOBOpen, NULL, ZEND_ACC_PUBLIC) PHP_ME(PDO, pgsqlLOBUnlink, NULL, ZEND_ACC_PUBLIC) + PHP_ME(PDO, pgsqlGetCopyData, NULL, ZEND_ACC_PUBLIC) + PHP_ME(PDO, pgsqlPutCopyData, NULL, ZEND_ACC_PUBLIC) + PHP_ME(PDO, pgsqlPutCopyEnd, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; Index: ext/pdo_pgsql/pgsql_statement.c =================================================================== --- ext/pdo_pgsql/pgsql_statement.c (revision 290359) +++ ext/pdo_pgsql/pgsql_statement.c (working copy) @@ -215,7 +215,7 @@ } status = PQresultStatus(S->result); - if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) { + if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK && status != PGRES_COPY_OUT && status != PGRES_COPY_IN) { pdo_pgsql_error_stmt(stmt, status, pdo_pgsql_sqlstate(S->result)); return 0; } @@ -228,7 +228,7 @@ if (status == PGRES_COMMAND_OK) { stmt->row_count = (long)atoi(PQcmdTuples(S->result)); H->pgoid = PQoidValue(S->result); - } else { + } else if (status == PGRES_TUPLES_OK) { stmt->row_count = (long)PQntuples(S->result); } @@ -423,6 +423,11 @@ if (!S->result) { return 0; + } else { + ExecStatusType status = PQresultStatus(S->result); + if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) { + return 0; + } } cols[colno].name = estrdup(PQfname(S->result, colno));