33
33
34
34
static int php_firebird_alloc_prepare_stmt (pdo_dbh_t * , const zend_string * , XSQLDA * , isc_stmt_handle * ,
35
35
HashTable * );
36
+ static bool php_firebird_rollback_transaction (pdo_dbh_t * dbh , bool retain );
36
37
37
38
const char CHR_LETTER = 1 ;
38
39
const char CHR_DIGIT = 2 ;
@@ -526,17 +527,14 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
526
527
{
527
528
pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
528
529
529
- if (dbh -> in_txn ) {
530
+ if (H -> tr ) {
530
531
if (dbh -> auto_commit ) {
531
- if (isc_commit_transaction (H -> isc_status , & H -> tr )) {
532
- php_firebird_error (dbh );
533
- }
532
+ php_firebird_commit_transaction (dbh , FB_TXN_RELEASE );
534
533
} else {
535
- if (isc_rollback_transaction (H -> isc_status , & H -> tr )) {
536
- php_firebird_error (dbh );
537
- }
534
+ php_firebird_rollback_transaction (dbh , FB_TXN_RELEASE );
538
535
}
539
536
}
537
+ H -> in_manually_txn = 0 ;
540
538
541
539
if (isc_detach_database (H -> isc_status , & H -> db )) {
542
540
php_firebird_error (dbh );
@@ -702,9 +700,8 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /*
702
700
}
703
701
}
704
702
705
- /* commit if we're in auto_commit mode */
706
- if (dbh -> auto_commit && isc_commit_retaining (H -> isc_status , & H -> tr )) {
707
- php_firebird_error (dbh );
703
+ if (dbh -> auto_commit && !H -> in_manually_txn ) {
704
+ php_firebird_commit_transaction (dbh , FB_TXN_RETAIN );
708
705
}
709
706
710
707
free_statement :
@@ -756,8 +753,8 @@ static zend_string* firebird_handle_quoter(pdo_dbh_t *dbh, const zend_string *un
756
753
}
757
754
/* }}} */
758
755
759
- /* called by PDO to start a transaction */
760
- static bool firebird_handle_begin (pdo_dbh_t * dbh ) /* {{{ */
756
+ /* php_firebird_begin_transaction */
757
+ static bool php_firebird_begin_transaction (pdo_dbh_t * dbh ) /* {{{ */
761
758
{
762
759
pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
763
760
char tpb [8 ] = { isc_tpb_version3 }, * ptpb = tpb + 1 ;
@@ -809,28 +806,84 @@ static bool firebird_handle_begin(pdo_dbh_t *dbh) /* {{{ */
809
806
}
810
807
/* }}} */
811
808
812
- /* called by PDO to commit a transaction */
813
- static bool firebird_handle_commit (pdo_dbh_t * dbh ) /* {{{ */
809
+ /* called by PDO to start a transaction */
810
+ static bool firebird_handle_manually_begin (pdo_dbh_t * dbh ) /* {{{ */
814
811
{
815
812
pdo_firebird_db_handle * H = (pdo_firebird_db_handle * )dbh -> driver_data ;
816
813
817
- if (isc_commit_transaction (H -> isc_status , & H -> tr )) {
818
- php_firebird_error (dbh );
814
+ if (dbh -> auto_commit && H -> tr && !php_firebird_commit_transaction (dbh , FB_TXN_RELEASE )) {
815
+ return false;
816
+ }
817
+
818
+ if (!php_firebird_begin_transaction (dbh )) {
819
+ return false;
820
+ }
821
+ H -> in_manually_txn = 1 ;
822
+ return true;
823
+ }
824
+ /* }}} */
825
+
826
+ /* php_firebird_commit_transaction */
827
+ bool php_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
+ php_firebird_error (dbh );
834
+ return false;
835
+ }
836
+ } else {
837
+ if (isc_commit_transaction (H -> isc_status , & H -> tr )) {
838
+ php_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 (!php_firebird_commit_transaction (dbh , dbh -> auto_commit )) {
819
851
return false;
820
852
}
853
+ H -> in_manually_txn = 0 ;
854
+ return true;
855
+ }
856
+ /* }}} */
857
+
858
+ /* php_firebird_rollback_transaction */
859
+ static bool php_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
+ php_firebird_error (dbh );
866
+ return false;
867
+ }
868
+ } else {
869
+ if (isc_rollback_transaction (H -> isc_status , & H -> tr )) {
870
+ php_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
- php_firebird_error (dbh );
883
+ if (!php_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 php_firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sq
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
php_firebird_error (dbh );
@@ -900,19 +943,21 @@ static bool pdo_firebird_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *val
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
php_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 && !php_firebird_begin_transaction (dbh )) {
955
+ return false;
956
+ }
957
+ } else {
958
+ /* close the transaction */
959
+ if (!H -> in_manually_txn && H -> tr && !php_firebird_commit_transaction (dbh , FB_TXN_RELEASE )) {
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 pdo_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
pdo_firebird_set_attribute ,
1070
1123
NULL , /* last_id not supported */
1071
1124
pdo_firebird_fetch_error_func ,
1072
1125
pdo_firebird_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
+ pdo_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 = php_firebird_begin_transaction (dbh );
1213
+ }
1214
+
1157
1215
if (!ret ) {
1158
1216
firebird_handle_closer (dbh );
1159
1217
}
0 commit comments