Skip to content

Commit 9c2cc79

Browse files
committed
Changed to get sqlstatus and output appropriate error message
1 parent 490b808 commit 9c2cc79

File tree

4 files changed

+154
-72
lines changed

4 files changed

+154
-72
lines changed

ext/pdo_firebird/firebird_driver.c

Lines changed: 79 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -460,16 +460,65 @@ 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 *errState, const char *msg, char const *file, int line) /* {{{ */
464464
{
465-
pdo_error_type *const error_code = stmt ? &stmt->error_code : &dbh->error_code;
465+
pdo_error_type *const err_state = 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+
zend_long sqlcode = -999;
469+
470+
einfo->file = file;
471+
einfo->line = line;
472+
473+
if (einfo->errmsg) {
474+
pefree(einfo->errmsg, dbh->is_persistent);
475+
einfo->errmsg = NULL;
476+
}
477+
478+
if (H->isc_status && (H->isc_status[0] == 1 && H->isc_status[1] > 0)) {
479+
char buf[512];
480+
size_t buf_size = sizeof(buf), read_len = 0, tmp_len;
481+
const ISC_STATUS *s = H->isc_status;
482+
sqlcode = isc_sqlcode(s);
483+
484+
while ((buf_size > (read_len + 1)) && (tmp_len = fb_interpret(&buf[read_len], (buf_size - read_len - 1), &s))) {
485+
read_len += tmp_len;
486+
strcpy(&buf[read_len++], " ");
487+
}
488+
489+
/* remove last space */
490+
if (read_len) {
491+
buf[read_len - 1] = '\0';
492+
}
493+
494+
einfo->errmsg = pestrdup(buf, 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(*err_state, sqlstate);
501+
goto end;
502+
}
503+
#endif
504+
} else if (msg) {
505+
einfo->errmsg = pestrdup(msg, dbh->is_persistent);
506+
}
507+
508+
if (errState) {
509+
strcpy(*err_state, errState);
510+
} else {
511+
strcpy(*err_state, "HY000");
512+
}
466513

467-
strcpy(*error_code, "HY000");
514+
end:
515+
einfo->errcode = sqlcode;
516+
if (!dbh->methods) {
517+
pdo_throw_exception(0, einfo->errmsg, err_state);
518+
}
468519
}
469520
/* }}} */
470521

471-
#define RECORD_ERROR(dbh) _firebird_error(dbh, NULL, __FILE__, __LINE__)
472-
473522
/* called by PDO to close a db handle */
474523
static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
475524
{
@@ -478,17 +527,17 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
478527
if (dbh->in_txn) {
479528
if (dbh->auto_commit) {
480529
if (isc_commit_transaction(H->isc_status, &H->tr)) {
481-
RECORD_ERROR(dbh);
530+
firebird_error(dbh);
482531
}
483532
} else {
484533
if (isc_rollback_transaction(H->isc_status, &H->tr)) {
485-
RECORD_ERROR(dbh);
534+
firebird_error(dbh);
486535
}
487536
}
488537
}
489538

490539
if (isc_detach_database(H->isc_status, &H->db)) {
491-
RECORD_ERROR(dbh);
540+
firebird_error(dbh);
492541
}
493542

494543
if (H->date_format) {
@@ -501,6 +550,11 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
501550
efree(H->timestamp_format);
502551
}
503552

553+
if (H->einfo.errmsg) {
554+
pefree(H->einfo.errmsg, dbh->is_persistent);
555+
H->einfo.errmsg = NULL;
556+
}
557+
504558
pefree(H, dbh->is_persistent);
505559
}
506560
/* }}} */
@@ -547,7 +601,7 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */
547601

548602
/* fill the output sqlda with information about the prepared query */
549603
if (isc_dsql_describe(H->isc_status, &s, PDO_FB_SQLDA_VERSION, &S->out_sqlda)) {
550-
RECORD_ERROR(dbh);
604+
firebird_error(dbh);
551605
break;
552606
}
553607

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

575629
} while (0);
576630

577-
RECORD_ERROR(dbh);
631+
firebird_error(dbh);
578632

579633
zend_hash_destroy(np);
580634
FREE_HASHTABLE(np);
@@ -612,15 +666,15 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /*
612666

613667
/* execute the statement */
614668
if (isc_dsql_execute2(H->isc_status, &H->tr, &stmt, PDO_FB_SQLDA_VERSION, &in_sqlda, &out_sqlda)) {
615-
RECORD_ERROR(dbh);
669+
firebird_error(dbh);
616670
ret = -1;
617671
goto free_statement;
618672
}
619673

620674
/* find out how many rows were affected */
621675
if (isc_dsql_sql_info(H->isc_status, &stmt, sizeof(info_count), const_cast(info_count),
622676
sizeof(result), result)) {
623-
RECORD_ERROR(dbh);
677+
firebird_error(dbh);
624678
ret = -1;
625679
goto free_statement;
626680
}
@@ -648,13 +702,13 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /*
648702

649703
/* commit if we're in auto_commit mode */
650704
if (dbh->auto_commit && isc_commit_retaining(H->isc_status, &H->tr)) {
651-
RECORD_ERROR(dbh);
705+
firebird_error(dbh);
652706
}
653707

654708
free_statement:
655709

656710
if (isc_dsql_free_statement(H->isc_status, &stmt, DSQL_drop)) {
657-
RECORD_ERROR(dbh);
711+
firebird_error(dbh);
658712
}
659713

660714
return ret;
@@ -746,7 +800,7 @@ static bool firebird_handle_begin(pdo_dbh_t *dbh) /* {{{ */
746800
}
747801
#endif
748802
if (isc_start_transaction(H->isc_status, &H->tr, 1, &H->db, (unsigned short)(ptpb-tpb), tpb)) {
749-
RECORD_ERROR(dbh);
803+
firebird_error(dbh);
750804
return false;
751805
}
752806
return true;
@@ -759,7 +813,7 @@ static bool firebird_handle_commit(pdo_dbh_t *dbh) /* {{{ */
759813
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
760814

761815
if (isc_commit_transaction(H->isc_status, &H->tr)) {
762-
RECORD_ERROR(dbh);
816+
firebird_error(dbh);
763817
return false;
764818
}
765819
return true;
@@ -772,7 +826,7 @@ static bool firebird_handle_rollback(pdo_dbh_t *dbh) /* {{{ */
772826
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
773827

774828
if (isc_rollback_transaction(H->isc_status, &H->tr)) {
775-
RECORD_ERROR(dbh);
829+
firebird_error(dbh);
776830
return false;
777831
}
778832
return true;
@@ -804,7 +858,7 @@ static int firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sql,
804858

805859
/* allocate the statement */
806860
if (isc_dsql_allocate_statement(H->isc_status, &H->db, s)) {
807-
RECORD_ERROR(dbh);
861+
firebird_error(dbh);
808862
return 0;
809863
}
810864

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

821875
/* prepare the statement */
822876
if (isc_dsql_prepare(H->isc_status, &H->tr, s, 0, new_sql, H->sql_dialect, out_sqlda)) {
823-
RECORD_ERROR(dbh);
877+
firebird_error(dbh);
824878
efree(new_sql);
825879
return 0;
826880
}
@@ -848,7 +902,7 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *
848902
if (bval) {
849903
/* turning on auto_commit with an open transaction is illegal, because
850904
we won't know what to do with it */
851-
H->last_app_error = "Cannot enable auto-commit while a transaction is already open";
905+
firebird_error_with_info(dbh, "HY000", "Cannot enable auto-commit while a transaction is already open");
852906
return false;
853907
} else {
854908
/* close the transaction */
@@ -992,21 +1046,11 @@ static int firebird_handle_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *v
9921046
static void pdo_firebird_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info) /* {{{ */
9931047
{
9941048
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));
1049+
if (H->einfo.errcode != IS_NULL) {
1050+
add_next_index_long(info, H->einfo.errcode);
1051+
}
1052+
if (H->einfo.errmsg) {
1053+
add_next_index_string(info, H->einfo.errmsg);
10101054
}
10111055
}
10121056
/* }}} */

0 commit comments

Comments
 (0)