Skip to content

Commit 5d5b183

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

File tree

4 files changed

+149
-71
lines changed

4 files changed

+149
-71
lines changed

ext/pdo_firebird/firebird_driver.c

Lines changed: 76 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -460,16 +460,63 @@ 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+
zend_long sqlcode = -999;
469+
470+
if (einfo->errmsg) {
471+
pefree(einfo->errmsg, dbh->is_persistent);
472+
einfo->errmsg = NULL;
473+
}
474+
475+
if (H->isc_status && (H->isc_status[0] == 1 && H->isc_status[1] > 0)) {
476+
char buf[512];
477+
size_t buf_size = sizeof(buf), read_len = 0;
478+
ssize_t tmp_len;
479+
const ISC_STATUS *s = H->isc_status;
480+
sqlcode = isc_sqlcode(s);
481+
482+
while ((buf_size > (read_len + 1)) && (tmp_len = fb_interpret(&buf[read_len], (buf_size - read_len - 1), &s)) && tmp_len > 0) {
483+
read_len += tmp_len;
484+
strcpy(&buf[read_len++], " ");
485+
}
466486

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

471-
#define RECORD_ERROR(dbh) _firebird_error(dbh, NULL, __FILE__, __LINE__)
472-
473520
/* called by PDO to close a db handle */
474521
static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
475522
{
@@ -478,17 +525,17 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
478525
if (dbh->in_txn) {
479526
if (dbh->auto_commit) {
480527
if (isc_commit_transaction(H->isc_status, &H->tr)) {
481-
RECORD_ERROR(dbh);
528+
firebird_error(dbh);
482529
}
483530
} else {
484531
if (isc_rollback_transaction(H->isc_status, &H->tr)) {
485-
RECORD_ERROR(dbh);
532+
firebird_error(dbh);
486533
}
487534
}
488535
}
489536

490537
if (isc_detach_database(H->isc_status, &H->db)) {
491-
RECORD_ERROR(dbh);
538+
firebird_error(dbh);
492539
}
493540

494541
if (H->date_format) {
@@ -501,6 +548,11 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
501548
efree(H->timestamp_format);
502549
}
503550

551+
if (H->einfo.errmsg) {
552+
pefree(H->einfo.errmsg, dbh->is_persistent);
553+
H->einfo.errmsg = NULL;
554+
}
555+
504556
pefree(H, dbh->is_persistent);
505557
}
506558
/* }}} */
@@ -547,7 +599,7 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */
547599

548600
/* fill the output sqlda with information about the prepared query */
549601
if (isc_dsql_describe(H->isc_status, &s, PDO_FB_SQLDA_VERSION, &S->out_sqlda)) {
550-
RECORD_ERROR(dbh);
602+
firebird_error(dbh);
551603
break;
552604
}
553605

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

575627
} while (0);
576628

577-
RECORD_ERROR(dbh);
629+
firebird_error(dbh);
578630

579631
zend_hash_destroy(np);
580632
FREE_HASHTABLE(np);
@@ -612,15 +664,15 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /*
612664

613665
/* execute the statement */
614666
if (isc_dsql_execute2(H->isc_status, &H->tr, &stmt, PDO_FB_SQLDA_VERSION, &in_sqlda, &out_sqlda)) {
615-
RECORD_ERROR(dbh);
667+
firebird_error(dbh);
616668
ret = -1;
617669
goto free_statement;
618670
}
619671

620672
/* find out how many rows were affected */
621673
if (isc_dsql_sql_info(H->isc_status, &stmt, sizeof(info_count), const_cast(info_count),
622674
sizeof(result), result)) {
623-
RECORD_ERROR(dbh);
675+
firebird_error(dbh);
624676
ret = -1;
625677
goto free_statement;
626678
}
@@ -648,13 +700,13 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /*
648700

649701
/* commit if we're in auto_commit mode */
650702
if (dbh->auto_commit && isc_commit_retaining(H->isc_status, &H->tr)) {
651-
RECORD_ERROR(dbh);
703+
firebird_error(dbh);
652704
}
653705

654706
free_statement:
655707

656708
if (isc_dsql_free_statement(H->isc_status, &stmt, DSQL_drop)) {
657-
RECORD_ERROR(dbh);
709+
firebird_error(dbh);
658710
}
659711

660712
return ret;
@@ -746,7 +798,7 @@ static bool firebird_handle_begin(pdo_dbh_t *dbh) /* {{{ */
746798
}
747799
#endif
748800
if (isc_start_transaction(H->isc_status, &H->tr, 1, &H->db, (unsigned short)(ptpb-tpb), tpb)) {
749-
RECORD_ERROR(dbh);
801+
firebird_error(dbh);
750802
return false;
751803
}
752804
return true;
@@ -759,7 +811,7 @@ static bool firebird_handle_commit(pdo_dbh_t *dbh) /* {{{ */
759811
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
760812

761813
if (isc_commit_transaction(H->isc_status, &H->tr)) {
762-
RECORD_ERROR(dbh);
814+
firebird_error(dbh);
763815
return false;
764816
}
765817
return true;
@@ -772,7 +824,7 @@ static bool firebird_handle_rollback(pdo_dbh_t *dbh) /* {{{ */
772824
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
773825

774826
if (isc_rollback_transaction(H->isc_status, &H->tr)) {
775-
RECORD_ERROR(dbh);
827+
firebird_error(dbh);
776828
return false;
777829
}
778830
return true;
@@ -804,7 +856,7 @@ static int firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sql,
804856

805857
/* allocate the statement */
806858
if (isc_dsql_allocate_statement(H->isc_status, &H->db, s)) {
807-
RECORD_ERROR(dbh);
859+
firebird_error(dbh);
808860
return 0;
809861
}
810862

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

821873
/* prepare the statement */
822874
if (isc_dsql_prepare(H->isc_status, &H->tr, s, 0, new_sql, H->sql_dialect, out_sqlda)) {
823-
RECORD_ERROR(dbh);
875+
firebird_error(dbh);
824876
efree(new_sql);
825877
return 0;
826878
}
@@ -848,7 +900,7 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *
848900
if (bval) {
849901
/* turning on auto_commit with an open transaction is illegal, because
850902
we won't know what to do with it */
851-
H->last_app_error = "Cannot enable auto-commit while a transaction is already open";
903+
firebird_error_with_info(dbh, "HY000", "Cannot enable auto-commit while a transaction is already open");
852904
return false;
853905
} else {
854906
/* close the transaction */
@@ -992,21 +1044,11 @@ static int firebird_handle_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *v
9921044
static void pdo_firebird_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info) /* {{{ */
9931045
{
9941046
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));
1047+
if (H->einfo.sqlcode != IS_NULL) {
1048+
add_next_index_long(info, H->einfo.sqlcode);
1049+
}
1050+
if (H->einfo.errmsg) {
1051+
add_next_index_string(info, H->einfo.errmsg);
10101052
}
10111053
}
10121054
/* }}} */

0 commit comments

Comments
 (0)