@@ -3,6 +3,7 @@ use crate::{
33 hrana:: { connection:: HttpConnection , hyper:: HttpSender } ,
44 local:: { self , impls:: LibsqlStmt } ,
55 params:: Params ,
6+ parser,
67 replication:: connection:: State ,
78 sync:: SyncContext ,
89 BatchRows , Error , Result , Statement , Transaction , TransactionBehavior ,
@@ -33,7 +34,68 @@ impl SyncedConnection {
3334
3435 let mut state = self . state . lock ( ) . await ;
3536
36- crate :: replication:: connection:: should_execute_local ( & mut state, stmts. as_slice ( ) )
37+ if !self . remote . is_autocommit ( ) {
38+ * state = State :: Txn ;
39+ }
40+
41+ {
42+ let predicted_end_state = {
43+ let mut state = state. clone ( ) ;
44+
45+ stmts. iter ( ) . for_each ( |parser:: Statement { kind, .. } | {
46+ state = state. step ( * kind) ;
47+ } ) ;
48+
49+ state
50+ } ;
51+
52+ dbg ! ( ( & state, sql, & predicted_end_state) ) ;
53+
54+ let should_execute_local = match ( * state, predicted_end_state) {
55+ ( State :: Init , State :: Init ) => stmts. iter ( ) . all ( parser:: Statement :: is_read_only) ,
56+
57+ ( State :: Init , State :: TxnReadOnly ) | ( State :: TxnReadOnly , State :: TxnReadOnly ) => {
58+ let is_read_only = stmts. iter ( ) . all ( parser:: Statement :: is_read_only) ;
59+
60+ if !is_read_only {
61+ return Err ( Error :: Misuse (
62+ "Invalid write in a readonly transaction" . into ( ) ,
63+ ) ) ;
64+ }
65+
66+ * state = State :: TxnReadOnly ;
67+ true
68+ }
69+
70+ ( State :: TxnReadOnly , State :: Init ) => {
71+ let is_read_only = stmts. iter ( ) . all ( parser:: Statement :: is_read_only) ;
72+
73+ if !is_read_only {
74+ return Err ( Error :: Misuse (
75+ "Invalid write in a readonly transaction" . into ( ) ,
76+ ) ) ;
77+ }
78+
79+ * state = State :: Init ;
80+ true
81+ }
82+
83+ ( init, State :: Invalid ) => {
84+ let err = Err ( Error :: InvalidParserState ( format ! ( "{:?}" , init) ) ) ;
85+
86+ // Reset state always back to init so the user can start over
87+ * state = State :: Init ;
88+
89+ return err;
90+ }
91+ _ => {
92+ * state = predicted_end_state;
93+ false
94+ } ,
95+ } ;
96+
97+ Ok ( should_execute_local)
98+ }
3799 }
38100}
39101
0 commit comments