Skip to content

Commit 9ae039c

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

File tree

4 files changed

+156
-71
lines changed

4 files changed

+156
-71
lines changed

ext/pdo_firebird/firebird_driver.c

Lines changed: 80 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -460,16 +460,67 @@ 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 size_t state_len,
464+
const char *msg, const size_t msg_len) /* {{{ */
464465
{
465466
pdo_error_type *const error_code = stmt ? &stmt->error_code : &dbh->error_code;
467+
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
468+
pdo_firebird_error_info *einfo = &H->einfo;
469+
int sqlcode = -999;
470+
471+
if (einfo->errmsg) {
472+
pefree(einfo->errmsg, dbh->is_persistent);
473+
einfo->errmsg = NULL;
474+
einfo->errmsg_length = 0;
475+
}
476+
477+
if (H->isc_status && (H->isc_status[0] == 1 && H->isc_status[1] > 0)) {
478+
char buf[512];
479+
size_t buf_size = sizeof(buf), read_len = 0;
480+
ssize_t 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)) && tmp_len > 0) {
485+
read_len += tmp_len;
486+
buf[read_len++] = ' ';
487+
}
466488

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

471-
#define RECORD_ERROR(dbh) _firebird_error(dbh, NULL, __FILE__, __LINE__)
472-
473524
/* called by PDO to close a db handle */
474525
static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
475526
{
@@ -478,17 +529,17 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
478529
if (dbh->in_txn) {
479530
if (dbh->auto_commit) {
480531
if (isc_commit_transaction(H->isc_status, &H->tr)) {
481-
RECORD_ERROR(dbh);
532+
firebird_error(dbh);
482533
}
483534
} else {
484535
if (isc_rollback_transaction(H->isc_status, &H->tr)) {
485-
RECORD_ERROR(dbh);
536+
firebird_error(dbh);
486537
}
487538
}
488539
}
489540

490541
if (isc_detach_database(H->isc_status, &H->db)) {
491-
RECORD_ERROR(dbh);
542+
firebird_error(dbh);
492543
}
493544

494545
if (H->date_format) {
@@ -501,6 +552,11 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
501552
efree(H->timestamp_format);
502553
}
503554

555+
if (H->einfo.errmsg) {
556+
pefree(H->einfo.errmsg, dbh->is_persistent);
557+
H->einfo.errmsg = NULL;
558+
}
559+
504560
pefree(H, dbh->is_persistent);
505561
}
506562
/* }}} */
@@ -547,7 +603,7 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */
547603

548604
/* fill the output sqlda with information about the prepared query */
549605
if (isc_dsql_describe(H->isc_status, &s, PDO_FB_SQLDA_VERSION, &S->out_sqlda)) {
550-
RECORD_ERROR(dbh);
606+
firebird_error(dbh);
551607
break;
552608
}
553609

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

575631
} while (0);
576632

577-
RECORD_ERROR(dbh);
633+
firebird_error(dbh);
578634

579635
zend_hash_destroy(np);
580636
FREE_HASHTABLE(np);
@@ -612,15 +668,15 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /*
612668

613669
/* execute the statement */
614670
if (isc_dsql_execute2(H->isc_status, &H->tr, &stmt, PDO_FB_SQLDA_VERSION, &in_sqlda, &out_sqlda)) {
615-
RECORD_ERROR(dbh);
671+
firebird_error(dbh);
616672
ret = -1;
617673
goto free_statement;
618674
}
619675

620676
/* find out how many rows were affected */
621677
if (isc_dsql_sql_info(H->isc_status, &stmt, sizeof(info_count), const_cast(info_count),
622678
sizeof(result), result)) {
623-
RECORD_ERROR(dbh);
679+
firebird_error(dbh);
624680
ret = -1;
625681
goto free_statement;
626682
}
@@ -648,13 +704,13 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /*
648704

649705
/* commit if we're in auto_commit mode */
650706
if (dbh->auto_commit && isc_commit_retaining(H->isc_status, &H->tr)) {
651-
RECORD_ERROR(dbh);
707+
firebird_error(dbh);
652708
}
653709

654710
free_statement:
655711

656712
if (isc_dsql_free_statement(H->isc_status, &stmt, DSQL_drop)) {
657-
RECORD_ERROR(dbh);
713+
firebird_error(dbh);
658714
}
659715

660716
return ret;
@@ -746,7 +802,7 @@ static bool firebird_handle_begin(pdo_dbh_t *dbh) /* {{{ */
746802
}
747803
#endif
748804
if (isc_start_transaction(H->isc_status, &H->tr, 1, &H->db, (unsigned short)(ptpb-tpb), tpb)) {
749-
RECORD_ERROR(dbh);
805+
firebird_error(dbh);
750806
return false;
751807
}
752808
return true;
@@ -759,7 +815,7 @@ static bool firebird_handle_commit(pdo_dbh_t *dbh) /* {{{ */
759815
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
760816

761817
if (isc_commit_transaction(H->isc_status, &H->tr)) {
762-
RECORD_ERROR(dbh);
818+
firebird_error(dbh);
763819
return false;
764820
}
765821
return true;
@@ -772,7 +828,7 @@ static bool firebird_handle_rollback(pdo_dbh_t *dbh) /* {{{ */
772828
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
773829

774830
if (isc_rollback_transaction(H->isc_status, &H->tr)) {
775-
RECORD_ERROR(dbh);
831+
firebird_error(dbh);
776832
return false;
777833
}
778834
return true;
@@ -804,7 +860,7 @@ static int firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sql,
804860

805861
/* allocate the statement */
806862
if (isc_dsql_allocate_statement(H->isc_status, &H->db, s)) {
807-
RECORD_ERROR(dbh);
863+
firebird_error(dbh);
808864
return 0;
809865
}
810866

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

821877
/* prepare the statement */
822878
if (isc_dsql_prepare(H->isc_status, &H->tr, s, 0, new_sql, H->sql_dialect, out_sqlda)) {
823-
RECORD_ERROR(dbh);
879+
firebird_error(dbh);
824880
efree(new_sql);
825881
return 0;
826882
}
@@ -848,7 +904,7 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *
848904
if (bval) {
849905
/* turning on auto_commit with an open transaction is illegal, because
850906
we won't know what to do with it */
851-
H->last_app_error = "Cannot enable auto-commit while a transaction is already open";
907+
firebird_error_with_info(dbh, "HY000", "Cannot enable auto-commit while a transaction is already open");
852908
return false;
853909
} else {
854910
/* close the transaction */
@@ -992,21 +1048,11 @@ static int firebird_handle_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *v
9921048
static void pdo_firebird_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info) /* {{{ */
9931049
{
9941050
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));
1051+
if (H->einfo.sqlcode != IS_NULL) {
1052+
add_next_index_long(info, H->einfo.sqlcode);
1053+
}
1054+
if (H->einfo.errmsg && H->einfo.errmsg_length) {
1055+
add_next_index_stringl(info, H->einfo.errmsg, H->einfo.errmsg_length);
10101056
}
10111057
}
10121058
/* }}} */

0 commit comments

Comments
 (0)