@@ -526,17 +526,14 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
526
526
{
527
527
pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
528
528
529
- if (dbh -> in_txn ) {
529
+ if (H -> tr ) {
530
530
if (dbh -> auto_commit ) {
531
- if (isc_commit_transaction (H -> isc_status , & H -> tr )) {
532
- firebird_error (dbh );
533
- }
531
+ firebird_commit_transaction (dbh , FB_TXN_RELEASE );
534
532
} else {
535
- if (isc_rollback_transaction (H -> isc_status , & H -> tr )) {
536
- firebird_error (dbh );
537
- }
533
+ firebird_rollback_transaction (dbh , FB_TXN_RELEASE );
538
534
}
539
535
}
536
+ H -> in_manually_txn = 0 ;
540
537
541
538
if (isc_detach_database (H -> isc_status , & H -> db )) {
542
539
firebird_error (dbh );
@@ -702,9 +699,8 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /*
702
699
}
703
700
}
704
701
705
- /* commit if we're in auto_commit mode */
706
- if (dbh -> auto_commit && isc_commit_retaining (H -> isc_status , & H -> tr )) {
707
- firebird_error (dbh );
702
+ if (dbh -> auto_commit && !H -> in_manually_txn ) {
703
+ firebird_commit_transaction (dbh , FB_TXN_RETAIN );
708
704
}
709
705
710
706
free_statement :
@@ -756,8 +752,8 @@ static zend_string* firebird_handle_quoter(pdo_dbh_t *dbh, const zend_string *un
756
752
}
757
753
/* }}} */
758
754
759
- /* called by PDO to start a transaction */
760
- static bool firebird_handle_begin (pdo_dbh_t * dbh ) /* {{{ */
755
+ /* _firebird_begin_transaction */
756
+ static bool _firebird_begin_transaction (pdo_dbh_t * dbh ) /* {{{ */
761
757
{
762
758
pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
763
759
char tpb [8 ] = { isc_tpb_version3 }, * ptpb = tpb + 1 ;
@@ -809,28 +805,85 @@ static bool firebird_handle_begin(pdo_dbh_t *dbh) /* {{{ */
809
805
}
810
806
/* }}} */
811
807
812
- /* called by PDO to commit a transaction */
813
- static bool firebird_handle_commit (pdo_dbh_t * dbh ) /* {{{ */
808
+ /* called by PDO to start a transaction */
809
+ static bool firebird_handle_manually_begin (pdo_dbh_t * dbh ) /* {{{ */
814
810
{
815
811
pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
816
812
817
- if (isc_commit_transaction (H -> isc_status , & H -> tr )) {
818
- firebird_error (dbh );
813
+ if (dbh -> auto_commit && H -> tr && !firebird_commit_transaction (dbh , false)) {
814
+ return false;
815
+ }
816
+
817
+ if (!_firebird_begin_transaction (dbh )) {
819
818
return false;
820
819
}
820
+
821
+ H -> in_manually_txn = 1 ;
822
+ return true;
823
+ }
824
+ /* }}} */
825
+
826
+ /* firebird_commit_transaction */
827
+ bool _firebird_commit_transaction (pdo_dbh_t * dbh , bool retain ) /* {{{ */
828
+ {
829
+ pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
830
+
831
+ if (retain ) {
832
+ if (isc_commit_retaining (H -> isc_status , & H -> tr )) {
833
+ firebird_error (dbh );
834
+ return false;
835
+ }
836
+ } else {
837
+ if (isc_commit_transaction (H -> isc_status , & H -> tr )) {
838
+ firebird_error (dbh );
839
+ return false;
840
+ }
841
+ }
842
+ return true;
843
+ }
844
+ /* }}} */
845
+
846
+ /* called by PDO to commit a transaction */
847
+ static bool firebird_handle_manually_commit (pdo_dbh_t * dbh ) /* {{{ */
848
+ {
849
+ pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
850
+ if (!firebird_commit_transaction (dbh , dbh -> auto_commit )) {
851
+ return false;
852
+ }
853
+ H -> in_manually_txn = 0 ;
854
+ return true;
855
+ }
856
+ /* }}} */
857
+
858
+ /* firebird_rollback_transaction */
859
+ bool _firebird_rollback_transaction (pdo_dbh_t * dbh , bool retain ) /* {{{ */
860
+ {
861
+ pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
862
+
863
+ if (retain ) {
864
+ if (isc_rollback_retaining (H -> isc_status , & H -> tr )) {
865
+ firebird_error (dbh );
866
+ return false;
867
+ }
868
+ } else {
869
+ if (isc_rollback_transaction (H -> isc_status , & H -> tr )) {
870
+ firebird_error (dbh );
871
+ return false;
872
+ }
873
+ }
821
874
return true;
822
875
}
823
876
/* }}} */
824
877
825
878
/* called by PDO to rollback a transaction */
826
- static bool firebird_handle_rollback (pdo_dbh_t * dbh ) /* {{{ */
879
+ static bool firebird_handle_manually_rollback (pdo_dbh_t * dbh ) /* {{{ */
827
880
{
828
881
pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
829
882
830
- if (isc_rollback_transaction (H -> isc_status , & H -> tr )) {
831
- firebird_error (dbh );
883
+ if (!firebird_rollback_transaction (dbh , dbh -> auto_commit )) {
832
884
return false;
833
885
}
886
+ H -> in_manually_txn = 0 ;
834
887
return true;
835
888
}
836
889
/* }}} */
@@ -848,16 +901,6 @@ static int firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sql,
848
901
return 0 ;
849
902
}
850
903
851
- /* start a new transaction implicitly if auto_commit is enabled and no transaction is open */
852
- if (dbh -> auto_commit && !dbh -> in_txn ) {
853
- /* dbh->transaction_flags = PDO_TRANS_READ_UNCOMMITTED; */
854
-
855
- if (!firebird_handle_begin (dbh )) {
856
- return 0 ;
857
- }
858
- dbh -> in_txn = true;
859
- }
860
-
861
904
/* allocate the statement */
862
905
if (isc_dsql_allocate_statement (H -> isc_status , & H -> db , s )) {
863
906
firebird_error (dbh );
@@ -900,19 +943,21 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *
900
943
901
944
/* ignore if the new value equals the old one */
902
945
if (dbh -> auto_commit ^ bval ) {
903
- if (dbh -> in_txn ) {
904
- if (bval ) {
946
+ if (bval ) {
947
+ if (H -> in_manually_txn ) {
905
948
/* turning on auto_commit with an open transaction is illegal, because
906
949
we won't know what to do with it */
907
950
const char * msg = "Cannot enable auto-commit while a transaction is already open" ;
908
951
firebird_error_with_info (dbh , "HY000" , strlen ("HY000" ), msg , strlen (msg ));
909
952
return false;
910
- } else {
911
- /* close the transaction */
912
- if (!firebird_handle_commit (dbh )) {
913
- break ;
914
- }
915
- dbh -> in_txn = false;
953
+ }
954
+ if (!H -> tr && !_firebird_begin_transaction (dbh )) {
955
+ return false;
956
+ }
957
+ } else {
958
+ /* close the transaction */
959
+ if (!H -> in_manually_txn && H -> tr && !firebird_commit_transaction (dbh , false)) {
960
+ return false;
916
961
}
917
962
}
918
963
dbh -> auto_commit = bval ;
@@ -1058,22 +1103,30 @@ static void pdo_firebird_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval
1058
1103
}
1059
1104
/* }}} */
1060
1105
1106
+ /* {{{ firebird_in_manually_transaction */
1107
+ static bool firebird_in_manually_transaction (pdo_dbh_t * dbh )
1108
+ {
1109
+ pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
1110
+ return H -> in_manually_txn ;
1111
+ }
1112
+ /* }}} */
1113
+
1061
1114
static const struct pdo_dbh_methods firebird_methods = { /* {{{ */
1062
1115
firebird_handle_closer ,
1063
1116
firebird_handle_preparer ,
1064
1117
firebird_handle_doer ,
1065
1118
firebird_handle_quoter ,
1066
- firebird_handle_begin ,
1067
- firebird_handle_commit ,
1068
- firebird_handle_rollback ,
1119
+ firebird_handle_manually_begin ,
1120
+ firebird_handle_manually_commit ,
1121
+ firebird_handle_manually_rollback ,
1069
1122
firebird_handle_set_attribute ,
1070
1123
NULL , /* last_id not supported */
1071
1124
pdo_firebird_fetch_error_func ,
1072
1125
firebird_handle_get_attribute ,
1073
1126
NULL , /* check_liveness */
1074
1127
NULL , /* get driver methods */
1075
1128
NULL , /* request shutdown */
1076
- NULL , /* in transaction, use PDO's internal tracking mechanism */
1129
+ firebird_in_manually_transaction ,
1077
1130
NULL /* get gc */
1078
1131
};
1079
1132
/* }}} */
@@ -1154,6 +1207,11 @@ static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /*
1154
1207
"HY000" , H -> isc_status [1 ], errmsg );
1155
1208
}
1156
1209
1210
+ H -> in_manually_txn = 0 ;
1211
+ if (dbh -> auto_commit && !H -> tr ) {
1212
+ ret = _firebird_begin_transaction (dbh );
1213
+ }
1214
+
1157
1215
if (!ret ) {
1158
1216
firebird_handle_closer (dbh );
1159
1217
}
0 commit comments