Skip to content

Commit 43db908

Browse files
committed
Added transaction isolation level
1 parent 10b02c5 commit 43db908

File tree

3 files changed

+57
-36
lines changed

3 files changed

+57
-36
lines changed

ext/pdo_firebird/firebird_driver.c

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -702,48 +702,25 @@ static zend_string* firebird_handle_quoter(pdo_dbh_t *dbh, const zend_string *un
702702
static bool _firebird_begin_transaction(pdo_dbh_t *dbh) /* {{{ */
703703
{
704704
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
705-
char tpb[8] = { isc_tpb_version3 }, *ptpb = tpb+1;
706-
#ifdef abies_0
707-
if (dbh->transaction_flags & PDO_TRANS_ISOLATION_LEVEL) {
708-
if (dbh->transaction_flags & PDO_TRANS_READ_UNCOMMITTED) {
709-
/* this is a poor fit, but it's all we have */
705+
char tpb[5] = { isc_tpb_version3, isc_tpb_write }, *ptpb = tpb + strlen(tpb);
706+
707+
switch (H->txn_isolation_level) {
708+
case PDO_FB_READ_COMMITTED:
710709
*ptpb++ = isc_tpb_read_committed;
711710
*ptpb++ = isc_tpb_rec_version;
712-
dbh->transaction_flags &= ~(PDO_TRANS_ISOLATION_LEVEL^PDO_TRANS_READ_UNCOMMITTED);
713-
} else if (dbh->transaction_flags & PDO_TRANS_READ_COMMITTED) {
714-
*ptpb++ = isc_tpb_read_committed;
715-
*ptpb++ = isc_tpb_no_rec_version;
716-
dbh->transaction_flags &= ~(PDO_TRANS_ISOLATION_LEVEL^PDO_TRANS_READ_COMMITTED);
717-
} else if (dbh->transaction_flags & PDO_TRANS_REPEATABLE_READ) {
718-
*ptpb++ = isc_tpb_concurrency;
719-
dbh->transaction_flags &= ~(PDO_TRANS_ISOLATION_LEVEL^PDO_TRANS_REPEATABLE_READ);
720-
} else {
711+
break;
712+
713+
case PDO_FB_SERIALIZABLE:
721714
*ptpb++ = isc_tpb_consistency;
722-
dbh->transaction_flags &= ~(PDO_TRANS_ISOLATION_LEVEL^PDO_TRANS_SERIALIZABLE);
723-
}
724-
}
715+
break;
725716

726-
if (dbh->transaction_flags & PDO_TRANS_ACCESS_MODE) {
727-
if (dbh->transaction_flags & PDO_TRANS_READONLY) {
728-
*ptpb++ = isc_tpb_read;
729-
dbh->transaction_flags &= ~(PDO_TRANS_ACCESS_MODE^PDO_TRANS_READONLY);
730-
} else {
731-
*ptpb++ = isc_tpb_write;
732-
dbh->transaction_flags &= ~(PDO_TRANS_ACCESS_MODE^PDO_TRANS_READWRITE);
733-
}
717+
case PDO_FB_REPEATABLE_READ:
718+
default:
719+
*ptpb++ = isc_tpb_concurrency;
720+
break;
734721
}
735722

736-
if (dbh->transaction_flags & PDO_TRANS_CONFLICT_RESOLUTION) {
737-
if (dbh->transaction_flags & PDO_TRANS_RETRY) {
738-
*ptpb++ = isc_tpb_wait;
739-
dbh->transaction_flags &= ~(PDO_TRANS_CONFLICT_RESOLUTION^PDO_TRANS_RETRY);
740-
} else {
741-
*ptpb++ = isc_tpb_nowait;
742-
dbh->transaction_flags &= ~(PDO_TRANS_CONFLICT_RESOLUTION^PDO_TRANS_ABORT);
743-
}
744-
}
745-
#endif
746-
if (isc_start_transaction(H->isc_status, &H->tr, 1, &H->db, (unsigned short)(ptpb-tpb), tpb)) {
723+
if (isc_start_transaction(H->isc_status, &H->tr, 1, &H->db, (unsigned short)(ptpb - tpb), tpb)) {
747724
RECORD_ERROR(dbh);
748725
return false;
749726
}
@@ -884,6 +861,7 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *
884861
{
885862
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
886863
bool bval;
864+
zend_long lval;
887865

888866
switch (attr) {
889867
case PDO_ATTR_AUTOCOMMIT:
@@ -964,6 +942,37 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *
964942
zend_string_release_ex(str, 0);
965943
}
966944
return true;
945+
946+
case PDO_FB_TRANSACTION_ISOLATION_LEVEL:
947+
{
948+
if (!pdo_get_long_param(&lval, val)) {
949+
return false;
950+
}
951+
if (H->txn_isolation_level != lval) {
952+
if (lval == PDO_FB_READ_COMMITTED ||
953+
lval == PDO_FB_REPEATABLE_READ ||
954+
lval == PDO_FB_SERIALIZABLE
955+
) {
956+
if (H->tr && H->in_manually_txn) {
957+
/* */
958+
H->last_app_error = "Cannot change isolation level while a transaction is already open";
959+
return false;
960+
}
961+
H->txn_isolation_level = lval;
962+
if (dbh->auto_commit) {
963+
if (H->tr && !_firebird_commit_transaction(dbh, false)) {
964+
return false;
965+
}
966+
if (!_firebird_begin_transaction(dbh)) {
967+
return false;
968+
}
969+
}
970+
} else {
971+
return false;
972+
}
973+
}
974+
}
975+
return true;
967976
}
968977
return false;
969978
}

ext/pdo_firebird/pdo_firebird.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ PHP_MINIT_FUNCTION(pdo_firebird) /* {{{ */
5757
REGISTER_PDO_CLASS_CONST_LONG("FB_ATTR_DATE_FORMAT", (zend_long) PDO_FB_ATTR_DATE_FORMAT);
5858
REGISTER_PDO_CLASS_CONST_LONG("FB_ATTR_TIME_FORMAT", (zend_long) PDO_FB_ATTR_TIME_FORMAT);
5959
REGISTER_PDO_CLASS_CONST_LONG("FB_ATTR_TIMESTAMP_FORMAT", (zend_long) PDO_FB_ATTR_TIMESTAMP_FORMAT);
60+
REGISTER_PDO_CLASS_CONST_LONG("FB_TRANSACTION_ISOLATION_LEVEL", (zend_long) PDO_FB_TRANSACTION_ISOLATION_LEVEL);
61+
REGISTER_PDO_CLASS_CONST_LONG("FB_READ_COMMITTED", (zend_long) PDO_FB_READ_COMMITTED);
62+
REGISTER_PDO_CLASS_CONST_LONG("FB_REPEATABLE_READ", (zend_long) PDO_FB_REPEATABLE_READ);
63+
REGISTER_PDO_CLASS_CONST_LONG("FB_SERIALIZABLE", (zend_long) PDO_FB_SERIALIZABLE);
6064

6165
if (FAILURE == php_pdo_register_driver(&pdo_firebird_driver)) {
6266
return FAILURE;

ext/pdo_firebird/php_pdo_firebird_int.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ typedef struct {
8686

8787
unsigned _reserved:29;
8888

89+
/* transaction isolation level */
90+
zend_ulong txn_isolation_level;
8991
} pdo_firebird_db_handle;
9092

9193

@@ -132,6 +134,12 @@ enum {
132134
PDO_FB_ATTR_DATE_FORMAT = PDO_ATTR_DRIVER_SPECIFIC,
133135
PDO_FB_ATTR_TIME_FORMAT,
134136
PDO_FB_ATTR_TIMESTAMP_FORMAT,
137+
138+
/* transaction isolation level */
139+
PDO_FB_TRANSACTION_ISOLATION_LEVEL,
140+
PDO_FB_READ_COMMITTED,
141+
PDO_FB_REPEATABLE_READ,
142+
PDO_FB_SERIALIZABLE,
135143
};
136144

137145
#endif /* PHP_PDO_FIREBIRD_INT_H */

0 commit comments

Comments
 (0)