@@ -475,7 +475,7 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
475
475
{
476
476
pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
477
477
478
- if (dbh -> in_txn ) {
478
+ if (H -> tr ) {
479
479
if (dbh -> auto_commit ) {
480
480
if (isc_commit_transaction (H -> isc_status , & H -> tr )) {
481
481
RECORD_ERROR (dbh );
@@ -486,6 +486,7 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
486
486
}
487
487
}
488
488
}
489
+ H -> in_manually_txn = 0 ;
489
490
490
491
if (isc_detach_database (H -> isc_status , & H -> db )) {
491
492
RECORD_ERROR (dbh );
@@ -647,8 +648,10 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /*
647
648
}
648
649
649
650
/* commit if we're in auto_commit mode */
650
- if (dbh -> auto_commit && isc_commit_retaining (H -> isc_status , & H -> tr )) {
651
- RECORD_ERROR (dbh );
651
+ if (dbh -> auto_commit && !H -> in_manually_txn ) {
652
+ if (isc_commit_retaining (H -> isc_status , & H -> tr )) {
653
+ RECORD_ERROR (dbh );
654
+ }
652
655
}
653
656
654
657
free_statement :
@@ -700,8 +703,8 @@ static zend_string* firebird_handle_quoter(pdo_dbh_t *dbh, const zend_string *un
700
703
}
701
704
/* }}} */
702
705
703
- /* called by PDO to start a transaction */
704
- static bool firebird_handle_begin (pdo_dbh_t * dbh ) /* {{{ */
706
+ /* firebird_begin_transaction */
707
+ static bool firebird_begin_transaction (pdo_dbh_t * dbh ) /* {{{ */
705
708
{
706
709
pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
707
710
char tpb [8 ] = { isc_tpb_version3 }, * ptpb = tpb + 1 ;
@@ -753,15 +756,42 @@ static bool firebird_handle_begin(pdo_dbh_t *dbh) /* {{{ */
753
756
}
754
757
/* }}} */
755
758
756
- /* called by PDO to commit a transaction */
757
- static bool firebird_handle_commit (pdo_dbh_t * dbh ) /* {{{ */
759
+ /* called by PDO to start a transaction */
760
+ static bool firebird_handle_begin (pdo_dbh_t * dbh ) /* {{{ */
758
761
{
759
762
pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
760
763
761
- if (isc_commit_transaction (H -> isc_status , & H -> tr )) {
764
+ if (dbh -> auto_commit && H -> tr && isc_commit_transaction (H -> isc_status , & H -> tr )) {
762
765
RECORD_ERROR (dbh );
763
766
return false;
764
767
}
768
+
769
+ if (!firebird_begin_transaction (dbh )) {
770
+ return false;
771
+ }
772
+
773
+ H -> in_manually_txn = 1 ;
774
+ return true;
775
+ }
776
+ /* }}} */
777
+
778
+ /* called by PDO to commit a transaction */
779
+ static bool firebird_handle_commit (pdo_dbh_t * dbh ) /* {{{ */
780
+ {
781
+ pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
782
+
783
+ if (dbh -> auto_commit ) {
784
+ if (isc_commit_retaining (H -> isc_status , & H -> tr )) {
785
+ RECORD_ERROR (dbh );
786
+ return false;
787
+ }
788
+ } else {
789
+ if (isc_commit_transaction (H -> isc_status , & H -> tr )) {
790
+ RECORD_ERROR (dbh );
791
+ return false;
792
+ }
793
+ }
794
+ H -> in_manually_txn = 0 ;
765
795
return true;
766
796
}
767
797
/* }}} */
@@ -771,10 +801,18 @@ static bool firebird_handle_rollback(pdo_dbh_t *dbh) /* {{{ */
771
801
{
772
802
pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
773
803
774
- if (isc_rollback_transaction (H -> isc_status , & H -> tr )) {
775
- RECORD_ERROR (dbh );
776
- return false;
804
+ if (dbh -> auto_commit ) {
805
+ if (isc_rollback_retaining (H -> isc_status , & H -> tr )) {
806
+ RECORD_ERROR (dbh );
807
+ return false;
808
+ }
809
+ } else {
810
+ if (isc_rollback_transaction (H -> isc_status , & H -> tr )) {
811
+ RECORD_ERROR (dbh );
812
+ return false;
813
+ }
777
814
}
815
+ H -> in_manually_txn = 0 ;
778
816
return true;
779
817
}
780
818
/* }}} */
@@ -792,16 +830,6 @@ static int firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sql,
792
830
return 0 ;
793
831
}
794
832
795
- /* start a new transaction implicitly if auto_commit is enabled and no transaction is open */
796
- if (dbh -> auto_commit && !dbh -> in_txn ) {
797
- /* dbh->transaction_flags = PDO_TRANS_READ_UNCOMMITTED; */
798
-
799
- if (!firebird_handle_begin (dbh )) {
800
- return 0 ;
801
- }
802
- dbh -> in_txn = true;
803
- }
804
-
805
833
/* allocate the statement */
806
834
if (isc_dsql_allocate_statement (H -> isc_status , & H -> db , s )) {
807
835
RECORD_ERROR (dbh );
@@ -844,19 +872,22 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *
844
872
845
873
/* ignore if the new value equals the old one */
846
874
if (dbh -> auto_commit ^ bval ) {
847
- if (dbh -> in_txn ) {
848
- if (bval ) {
875
+ if (bval ) {
876
+ if (H -> tr && H -> in_manually_txn ) {
849
877
/* turning on auto_commit with an open transaction is illegal, because
850
- we won't know what to do with it */
878
+ we won't know what to do with it */
851
879
H -> last_app_error = "Cannot enable auto-commit while a transaction is already open" ;
852
880
return false;
853
- } else {
854
- /* close the transaction */
855
- if (!firebird_handle_commit (dbh )) {
856
- break ;
857
- }
858
- dbh -> in_txn = false;
859
881
}
882
+ if (!H -> tr && !firebird_begin_transaction (dbh )) {
883
+ return false;
884
+ }
885
+ } else {
886
+ /* close the transaction */
887
+ if (!H -> tr && !firebird_handle_commit (dbh )) {
888
+ return false;
889
+ }
890
+ H -> in_manually_txn = 0 ;
860
891
}
861
892
dbh -> auto_commit = bval ;
862
893
}
@@ -1011,6 +1042,14 @@ static void pdo_firebird_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval
1011
1042
}
1012
1043
/* }}} */
1013
1044
1045
+ /* {{{ firebird_in_transaction */
1046
+ static bool firebird_in_transaction (pdo_dbh_t * dbh )
1047
+ {
1048
+ pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
1049
+ return H -> tr && H -> in_manually_txn ;
1050
+ }
1051
+ /* }}} */
1052
+
1014
1053
static const struct pdo_dbh_methods firebird_methods = { /* {{{ */
1015
1054
firebird_handle_closer ,
1016
1055
firebird_handle_preparer ,
@@ -1026,7 +1065,7 @@ static const struct pdo_dbh_methods firebird_methods = { /* {{{ */
1026
1065
NULL , /* check_liveness */
1027
1066
NULL , /* get driver methods */
1028
1067
NULL , /* request shutdown */
1029
- NULL , /* in transaction, use PDO's internal tracking mechanism */
1068
+ firebird_in_transaction ,
1030
1069
NULL /* get gc */
1031
1070
};
1032
1071
/* }}} */
@@ -1107,6 +1146,11 @@ static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /*
1107
1146
"HY000" , H -> isc_status [1 ], errmsg );
1108
1147
}
1109
1148
1149
+ H -> in_manually_txn = 0 ;
1150
+ if (dbh -> auto_commit && !H -> tr ) {
1151
+ ret = firebird_begin_transaction (dbh );
1152
+ }
1153
+
1110
1154
if (!ret ) {
1111
1155
firebird_handle_closer (dbh );
1112
1156
}
0 commit comments