@@ -702,48 +702,36 @@ static zend_string* firebird_handle_quoter(pdo_dbh_t *dbh, const zend_string *un
702
702
static bool _firebird_begin_transaction (pdo_dbh_t * dbh ) /* {{{ */
703
703
{
704
704
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 [6 ] = { isc_tpb_version3 }, * ptpb = tpb + strlen (tpb );
706
+
707
+ switch (H -> txn_isolation_level ) {
708
+ case PDO_FB_READ_UNCOMMITTED :
710
709
* ptpb ++ = isc_tpb_read_committed ;
711
710
* 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 ) {
711
+ break ;
712
+ case PDO_FB_READ_COMMITTED :
714
713
* ptpb ++ = isc_tpb_read_committed ;
715
714
* 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 {
715
+ * ptpb ++ = isc_tpb_nowait ;
716
+ break ;
717
+
718
+ case PDO_FB_SERIALIZABLE :
721
719
* ptpb ++ = isc_tpb_consistency ;
722
- dbh -> transaction_flags &= ~(PDO_TRANS_ISOLATION_LEVEL ^PDO_TRANS_SERIALIZABLE );
723
- }
724
- }
720
+ break ;
725
721
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
- }
722
+ case PDO_FB_REPEATABLE_READ :
723
+ default :
724
+ * ptpb ++ = isc_tpb_concurrency ;
725
+ break ;
734
726
}
735
727
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
- }
728
+ if (H -> is_write_txn ) {
729
+ * ptpb ++ = isc_tpb_write ;
730
+ } else {
731
+ * ptpb ++ = isc_tpb_read ;
744
732
}
745
- #endif
746
- if (isc_start_transaction (H -> isc_status , & H -> tr , 1 , & H -> db , (unsigned short )(ptpb - tpb ), tpb )) {
733
+
734
+ if (isc_start_transaction (H -> isc_status , & H -> tr , 1 , & H -> db , (unsigned short )(ptpb - tpb ), tpb )) {
747
735
RECORD_ERROR (dbh );
748
736
return false;
749
737
}
@@ -884,6 +872,7 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *
884
872
{
885
873
pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
886
874
bool bval ;
875
+ zend_long lval ;
887
876
888
877
switch (attr ) {
889
878
case PDO_ATTR_AUTOCOMMIT :
@@ -964,6 +953,62 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *
964
953
zend_string_release_ex (str , 0 );
965
954
}
966
955
return true;
956
+
957
+ case PDO_FB_TRANSACTION_ISOLATION_LEVEL :
958
+ {
959
+ if (!pdo_get_long_param (& lval , val )) {
960
+ return false;
961
+ }
962
+ if (H -> txn_isolation_level != lval ) {
963
+ if (lval == PDO_FB_READ_UNCOMMITTED ||
964
+ lval == PDO_FB_READ_COMMITTED ||
965
+ lval == PDO_FB_REPEATABLE_READ ||
966
+ lval == PDO_FB_SERIALIZABLE
967
+ ) {
968
+ if (H -> tr && H -> in_manually_txn ) {
969
+ /* */
970
+ H -> last_app_error = "Cannot change isolation level while a transaction is already open" ;
971
+ return false;
972
+ }
973
+ H -> txn_isolation_level = lval ;
974
+ if (dbh -> auto_commit ) {
975
+ if (H -> tr && !_firebird_commit_transaction (dbh , false)) {
976
+ return false;
977
+ }
978
+ if (!_firebird_begin_transaction (dbh )) {
979
+ return false;
980
+ }
981
+ }
982
+ } else {
983
+ return false;
984
+ }
985
+ }
986
+ }
987
+ return true;
988
+
989
+ case PDO_FB_WRITE_TRANSACTION :
990
+ {
991
+ if (!pdo_get_bool_param (& bval , val )) {
992
+ return false;
993
+ }
994
+ if (H -> is_write_txn ^ bval ) {
995
+ if (H -> tr && H -> in_manually_txn ) {
996
+ /* */
997
+ H -> last_app_error = "Cannot change transaction mode while a transaction is already open" ;
998
+ return false;
999
+ }
1000
+ H -> is_write_txn = bval ;
1001
+ if (dbh -> auto_commit ) {
1002
+ if (H -> tr && !_firebird_commit_transaction (dbh , false)) {
1003
+ return false;
1004
+ }
1005
+ if (!_firebird_begin_transaction (dbh )) {
1006
+ return false;
1007
+ }
1008
+ }
1009
+ }
1010
+ }
1011
+ return true;
967
1012
}
968
1013
return false;
969
1014
}
@@ -1169,6 +1214,7 @@ static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /*
1169
1214
}
1170
1215
1171
1216
H -> in_manually_txn = 0 ;
1217
+ H -> is_write_txn = 1 ;
1172
1218
if (dbh -> auto_commit && !H -> tr ) {
1173
1219
ret = _firebird_begin_transaction (dbh );
1174
1220
}
0 commit comments