Skip to content

Commit 2ca4077

Browse files
committed
Changed to get sqlstatus and output appropriate error message
1 parent 500b0fe commit 2ca4077

File tree

4 files changed

+154
-71
lines changed

4 files changed

+154
-71
lines changed

ext/pdo_firebird/firebird_driver.c

Lines changed: 79 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -460,16 +460,66 @@ int preprocess(const zend_string* sql, char* sql_out, HashTable* named_params)
460460
}
461461

462462
/* map driver specific error message to PDO error */
463-
void _firebird_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char const *file, zend_long line) /* {{{ */
463+
void _firebird_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *state, const char *msg) /* {{{ */
464464
{
465465
pdo_error_type *const error_code = stmt ? &stmt->error_code : &dbh->error_code;
466+
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
467+
pdo_firebird_error_info *einfo = &H->einfo;
468+
int sqlcode = -999;
469+
470+
if (einfo->errmsg) {
471+
pefree(einfo->errmsg, dbh->is_persistent);
472+
einfo->errmsg = NULL;
473+
einfo->errmsg_length = 0;
474+
}
475+
476+
if (H->isc_status && (H->isc_status[0] == 1 && H->isc_status[1] > 0)) {
477+
char buf[512];
478+
size_t buf_size = sizeof(buf), read_len = 0;
479+
ssize_t tmp_len;
480+
const ISC_STATUS *s = H->isc_status;
481+
sqlcode = isc_sqlcode(s);
482+
483+
while ((buf_size > (read_len + 1)) && (tmp_len = fb_interpret(&buf[read_len], (buf_size - read_len - 1), &s)) && tmp_len > 0) {
484+
read_len += tmp_len;
485+
buf[read_len++] = ' ';
486+
}
466487

467-
strcpy(*error_code, "HY000");
488+
/* remove last space */
489+
if (read_len) {
490+
buf[read_len--] = '\0';
491+
}
492+
493+
einfo->errmsg_length = read_len;
494+
einfo->errmsg = pestrndup(buf, read_len, dbh->is_persistent);
495+
496+
#if FB_API_VER >= 25
497+
char sqlstate[sizeof(pdo_error_type)];
498+
fb_sqlstate(sqlstate, H->isc_status);
499+
if (sqlstate != NULL && strlen(sqlstate) < sizeof(pdo_error_type)) {
500+
strcpy(*error_code, sqlstate);
501+
goto end;
502+
}
503+
#endif
504+
} else if (msg) {
505+
einfo->errmsg_length = strlen(msg);
506+
einfo->errmsg = pestrndup(msg, einfo->errmsg_length, dbh->is_persistent);
507+
}
508+
509+
if (state) {
510+
strcpy(*error_code, state);
511+
} else {
512+
strcpy(*error_code, "HY000");
513+
}
514+
515+
end:
516+
einfo->sqlcode = sqlcode;
517+
if (!dbh->methods) {
518+
pdo_throw_exception(0, einfo->errmsg, error_code);
519+
}
468520
}
469521
/* }}} */
470522

471-
#define RECORD_ERROR(dbh) _firebird_error(dbh, NULL, __FILE__, __LINE__)
472-
473523
/* called by PDO to close a db handle */
474524
static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
475525
{
@@ -478,17 +528,17 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
478528
if (dbh->in_txn) {
479529
if (dbh->auto_commit) {
480530
if (isc_commit_transaction(H->isc_status, &H->tr)) {
481-
RECORD_ERROR(dbh);
531+
firebird_error(dbh);
482532
}
483533
} else {
484534
if (isc_rollback_transaction(H->isc_status, &H->tr)) {
485-
RECORD_ERROR(dbh);
535+
firebird_error(dbh);
486536
}
487537
}
488538
}
489539

490540
if (isc_detach_database(H->isc_status, &H->db)) {
491-
RECORD_ERROR(dbh);
541+
firebird_error(dbh);
492542
}
493543

494544
if (H->date_format) {
@@ -501,6 +551,11 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
501551
efree(H->timestamp_format);
502552
}
503553

554+
if (H->einfo.errmsg) {
555+
pefree(H->einfo.errmsg, dbh->is_persistent);
556+
H->einfo.errmsg = NULL;
557+
}
558+
504559
pefree(H, dbh->is_persistent);
505560
}
506561
/* }}} */
@@ -547,7 +602,7 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */
547602

548603
/* fill the output sqlda with information about the prepared query */
549604
if (isc_dsql_describe(H->isc_status, &s, PDO_FB_SQLDA_VERSION, &S->out_sqlda)) {
550-
RECORD_ERROR(dbh);
605+
firebird_error(dbh);
551606
break;
552607
}
553608

@@ -574,7 +629,7 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */
574629

575630
} while (0);
576631

577-
RECORD_ERROR(dbh);
632+
firebird_error(dbh);
578633

579634
zend_hash_destroy(np);
580635
FREE_HASHTABLE(np);
@@ -612,15 +667,15 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /*
612667

613668
/* execute the statement */
614669
if (isc_dsql_execute2(H->isc_status, &H->tr, &stmt, PDO_FB_SQLDA_VERSION, &in_sqlda, &out_sqlda)) {
615-
RECORD_ERROR(dbh);
670+
firebird_error(dbh);
616671
ret = -1;
617672
goto free_statement;
618673
}
619674

620675
/* find out how many rows were affected */
621676
if (isc_dsql_sql_info(H->isc_status, &stmt, sizeof(info_count), const_cast(info_count),
622677
sizeof(result), result)) {
623-
RECORD_ERROR(dbh);
678+
firebird_error(dbh);
624679
ret = -1;
625680
goto free_statement;
626681
}
@@ -648,13 +703,13 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /*
648703

649704
/* commit if we're in auto_commit mode */
650705
if (dbh->auto_commit && isc_commit_retaining(H->isc_status, &H->tr)) {
651-
RECORD_ERROR(dbh);
706+
firebird_error(dbh);
652707
}
653708

654709
free_statement:
655710

656711
if (isc_dsql_free_statement(H->isc_status, &stmt, DSQL_drop)) {
657-
RECORD_ERROR(dbh);
712+
firebird_error(dbh);
658713
}
659714

660715
return ret;
@@ -746,7 +801,7 @@ static bool firebird_handle_begin(pdo_dbh_t *dbh) /* {{{ */
746801
}
747802
#endif
748803
if (isc_start_transaction(H->isc_status, &H->tr, 1, &H->db, (unsigned short)(ptpb-tpb), tpb)) {
749-
RECORD_ERROR(dbh);
804+
firebird_error(dbh);
750805
return false;
751806
}
752807
return true;
@@ -759,7 +814,7 @@ static bool firebird_handle_commit(pdo_dbh_t *dbh) /* {{{ */
759814
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
760815

761816
if (isc_commit_transaction(H->isc_status, &H->tr)) {
762-
RECORD_ERROR(dbh);
817+
firebird_error(dbh);
763818
return false;
764819
}
765820
return true;
@@ -772,7 +827,7 @@ static bool firebird_handle_rollback(pdo_dbh_t *dbh) /* {{{ */
772827
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
773828

774829
if (isc_rollback_transaction(H->isc_status, &H->tr)) {
775-
RECORD_ERROR(dbh);
830+
firebird_error(dbh);
776831
return false;
777832
}
778833
return true;
@@ -804,7 +859,7 @@ static int firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sql,
804859

805860
/* allocate the statement */
806861
if (isc_dsql_allocate_statement(H->isc_status, &H->db, s)) {
807-
RECORD_ERROR(dbh);
862+
firebird_error(dbh);
808863
return 0;
809864
}
810865

@@ -820,7 +875,7 @@ static int firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sql,
820875

821876
/* prepare the statement */
822877
if (isc_dsql_prepare(H->isc_status, &H->tr, s, 0, new_sql, H->sql_dialect, out_sqlda)) {
823-
RECORD_ERROR(dbh);
878+
firebird_error(dbh);
824879
efree(new_sql);
825880
return 0;
826881
}
@@ -848,7 +903,7 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *
848903
if (bval) {
849904
/* turning on auto_commit with an open transaction is illegal, because
850905
we won't know what to do with it */
851-
H->last_app_error = "Cannot enable auto-commit while a transaction is already open";
906+
firebird_error_with_info(dbh, "HY000", "Cannot enable auto-commit while a transaction is already open");
852907
return false;
853908
} else {
854909
/* close the transaction */
@@ -992,21 +1047,11 @@ static int firebird_handle_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *v
9921047
static void pdo_firebird_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info) /* {{{ */
9931048
{
9941049
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
995-
const ISC_STATUS *s = H->isc_status;
996-
char buf[400];
997-
zend_long i = 0, l, sqlcode = isc_sqlcode(s);
998-
999-
if (sqlcode) {
1000-
add_next_index_long(info, sqlcode);
1001-
1002-
while ((sizeof(buf)>(i+2))&&(l = fb_interpret(&buf[i],(sizeof(buf)-i-2),&s))) {
1003-
i += l;
1004-
strcpy(&buf[i++], " ");
1005-
}
1006-
add_next_index_string(info, buf);
1007-
} else if (H->last_app_error) {
1008-
add_next_index_long(info, -999);
1009-
add_next_index_string(info, const_cast(H->last_app_error));
1050+
if (H->einfo.sqlcode != IS_NULL) {
1051+
add_next_index_long(info, H->einfo.sqlcode);
1052+
}
1053+
if (H->einfo.errmsg && H->einfo.errmsg_length) {
1054+
add_next_index_stringl(info, H->einfo.errmsg, H->einfo.errmsg_length);
10101055
}
10111056
}
10121057
/* }}} */

0 commit comments

Comments
 (0)