1 module pgator.sql_transaction;
2 
3 import pgator.rpc_table;
4 import pgator.app;
5 import vibe.db.postgresql;
6 
7 struct TransactionQueryParams
8 {
9     QueryParams[] queryParams;
10     AuthorizationCredentials auth;
11 }
12 
13 struct SQLTransaction
14 {
15     private LockedConnection!__Conn conn;
16     private bool opened = false;
17 
18     @disable this(this){}
19 
20     this(PostgresClient client)
21     {
22         conn = client.lockConnection();
23     }
24 
25     void begin(bool isReadOnly)
26     {
27         execBuiltIn(isReadOnly ? BuiltInPrep.BEGIN_RO : BuiltInPrep.BEGIN);
28         opened = true;
29     }
30 
31     void resetStart()
32     {
33         import vibe.core.log;
34 
35         logDebugV(__FUNCTION__);
36 
37         opened = false;
38         conn.resetStart();
39     }
40 
41     void commit()
42     {
43         execBuiltIn(BuiltInPrep.COMMIT);
44         opened = false;
45     }
46 
47     ~this()
48     {
49         if(opened)
50             execBuiltIn(BuiltInPrep.ROLLBACK);
51 
52         delete conn;
53     }
54 
55     immutable(Answer)[] execMethod(in Method method, TransactionQueryParams qp)
56     {
57         assert(opened);
58 
59         if(method.needAuthVariablesFlag)
60         {
61             QueryParams q;
62             q.preparedStatementName = BuiltInPrep.SET_AUTH_VARS;
63             q.args = [qp.auth.username.toValue, qp.auth.password.toValue];
64 
65             conn.execPreparedStatement(q);
66         }
67 
68         immutable(Answer)[] ret;
69 
70         foreach(i, s; method.statements)
71         {
72             ret ~= conn.execPreparedStatement(qp.queryParams[i]);
73         }
74 
75         return ret;
76     }
77 
78     private void execBuiltIn(BuiltInPrep prepared)
79     {
80         QueryParams q;
81         q.preparedStatementName = prepared;
82 
83         conn.execPreparedStatement(q);
84     }
85 }
86 
87 enum BuiltInPrep : string
88 {
89     BEGIN = "#b#",
90     BEGIN_RO = "#r#",
91     COMMIT = "#C#",
92     ROLLBACK = "#R#",
93     SET_AUTH_VARS = "#a#"
94 }