1 /*
2  * Copyright (C) 2009 Emweb bv, Herent, Belgium.
3  *
4  * See the LICENSE file for terms of use.
5  */
6 
7 #include "Wt/Dbo/DbAction.h"
8 #include "DbAction_impl.h"
9 #include "Wt/Dbo/Session.h"
10 #include "Wt/Dbo/SqlConnection.h"
11 #include "Wt/Dbo/SqlStatement.h"
12 
13 namespace Wt {
14   namespace Dbo {
15     namespace Impl {
16 
createJoinName(RelationType type,const char * c1,const char * c2)17     std::string createJoinName(RelationType type,
18                                const char *c1, const char *c2) {
19       if (type == ManyToOne) {
20         return c1;
21       } else {
22         std::string t1 = c1;
23         std::string t2 = c2;
24         if (t2 < t1)
25           std::swap(t1, t2);
26 
27         return t1 + "_" + t2;
28       }
29     }
30 }
31 
InitSchema(Session & session,Impl::MappingInfo & mapping)32 InitSchema::InitSchema(Session& session, Impl::MappingInfo& mapping)
33   : session_(session),
34     mapping_(mapping),
35     idField_(false),
36     fkFlags_(0)
37 { }
38 
actMapping(Impl::MappingInfo * mapping)39 void InitSchema::actMapping(Impl::MappingInfo *mapping)
40 {
41   if (!mapping->initialized_)
42     mapping->init(session_);
43 }
44 
getsValue()45 bool InitSchema::getsValue() const { return false; }
setsValue()46 bool InitSchema::setsValue() const { return false; }
isSchema()47 bool InitSchema::isSchema() const { return true; }
48 
DropSchema(Session & session,Impl::MappingInfo & mapping,std::set<std::string> & tablesDropped)49 DropSchema::DropSchema(Session& session,
50 		       Impl::MappingInfo& mapping,
51 		       std::set<std::string>& tablesDropped)
52   : session_(session),
53     mapping_(mapping),
54     tablesDropped_(tablesDropped)
55 {
56   tablesDropped_.insert(mapping.tableName);
57 }
58 
actMapping(Impl::MappingInfo * mapping)59 void DropSchema::actMapping(Impl::MappingInfo *mapping)
60 { }
61 
drop(const std::string & table)62 void DropSchema::drop(const std::string& table)
63 {
64   tablesDropped_.insert(table);
65 
66   if (table == mapping_.tableName && mapping_.surrogateIdFieldName) {
67       std::vector<std::string> sql = session_.connection(false)
68 	->autoincrementDropSequenceSql(Impl::quoteSchemaDot(table),
69 				       mapping_.surrogateIdFieldName);
70 
71       for (unsigned i = 0; i < sql.size(); i++)
72 	session_.connection(true)->executeSql(sql[i]);
73   }
74 
75   session_.connection(true)
76     ->executeSql("drop table \"" + Impl::quoteSchemaDot(table) + "\"");
77 }
78 
getsValue()79 bool DropSchema::getsValue() const { return false; }
setsValue()80 bool DropSchema::setsValue() const { return false; }
isSchema()81 bool DropSchema::isSchema() const { return true; }
82 
DboAction(Session * session)83 DboAction::DboAction(Session *session)
84   : session_(session),
85     dbo_(nullptr),
86     mapping_(nullptr),
87     setStatementIdx_(0),
88     setIdx_(0)
89 { }
90 
DboAction(MetaDboBase & dbo,Impl::MappingInfo & mapping)91 DboAction::DboAction(MetaDboBase& dbo, Impl::MappingInfo& mapping)
92   : session_(nullptr),
93     dbo_(&dbo),
94     mapping_(&mapping),
95     setStatementIdx_(0),
96     setIdx_(0)
97 { }
98 
actMapping(Impl::MappingInfo * mapping)99 void DboAction::actMapping(Impl::MappingInfo *mapping)
100 { }
101 
getsValue()102 bool DboAction::getsValue() const { return false; }
setsValue()103 bool DboAction::setsValue() const { return false; }
isSchema()104 bool DboAction::isSchema() const { return false; }
105 
LoadBaseAction(MetaDboBase & dbo,Impl::MappingInfo & mapping,SqlStatement * statement,int & column)106 LoadBaseAction::LoadBaseAction(MetaDboBase& dbo, Impl::MappingInfo& mapping,
107 			       SqlStatement *statement, int& column)
108   : DboAction(dbo, mapping),
109     statement_(statement),
110     column_(column)
111 { }
112 
start()113 void LoadBaseAction::start()
114 {
115   if (mapping().versionFieldName) {
116     int version;
117     statement_->getResult(column_++, &version);
118     dbo().setVersion(version);
119   }
120 }
121 
setsValue()122 bool LoadBaseAction::setsValue() const { return true; }
123 
SaveBaseAction(Session * session,SqlStatement * statement,int column)124 SaveBaseAction::SaveBaseAction(Session *session, SqlStatement *statement,
125 			       int column)
126   : DboAction(session),
127     statement_(statement),
128     column_(column),
129     bindNull_(false),
130     auxIdOnly_(false)
131 {
132   pass_ = Self;
133 }
134 
SaveBaseAction(MetaDboBase & dbo,Impl::MappingInfo & mapping,SqlStatement * statement,int column)135 SaveBaseAction::SaveBaseAction(MetaDboBase& dbo, Impl::MappingInfo& mapping,
136 			       SqlStatement *statement, int column)
137   : DboAction(dbo, mapping),
138     statement_(statement),
139     column_(column),
140     bindNull_(false),
141     auxIdOnly_(false)
142 {
143   pass_ = Self;
144 }
145 
startDependencyPass()146 void SaveBaseAction::startDependencyPass()
147 {
148   pass_ = Dependencies;
149 }
150 
startSelfPass()151 void SaveBaseAction::startSelfPass()
152 {
153   pass_ = Self;
154   needSetsPass_ = false;
155 
156   statement_->reset();
157   column_ = 0;
158 
159   if (mapping().versionFieldName)
160     statement_->bind(column_++, dbo().version() + 1);
161 }
162 
exec()163 void SaveBaseAction::exec()
164 {
165   statement_->execute();
166 
167   if (isInsert_ && mapping().surrogateIdFieldName)
168     dbo().setAutogeneratedId(statement_->insertedId());
169 
170   dbo().setTransactionState(MetaDboBase::SavedInTransaction);
171 }
172 
startSetsPass()173 void SaveBaseAction::startSetsPass()
174 {
175   pass_ = Sets;
176 }
177 
getsValue()178 bool SaveBaseAction::getsValue() const { return true; }
179 
TransactionDoneAction(MetaDboBase & dbo,Session & session,Impl::MappingInfo & mapping,bool success)180 TransactionDoneAction::TransactionDoneAction(MetaDboBase& dbo,
181 					     Session& session,
182 					     Impl::MappingInfo& mapping,
183 					     bool success)
184   : DboAction(dbo, mapping),
185     session_(session),
186     success_(success)
187 { }
188 
getsValue()189 bool TransactionDoneAction::getsValue() const { return true; }
190 
SessionAddAction(MetaDboBase & dbo,Impl::MappingInfo & mapping)191 SessionAddAction::SessionAddAction(MetaDboBase& dbo,
192 				   Impl::MappingInfo& mapping)
193   : DboAction(dbo, mapping)
194 { }
195 
getsValue()196 bool SessionAddAction::getsValue() const { return true; }
setsValue()197 bool SessionAddAction::setsValue() const { return false; }
isSchema()198 bool SessionAddAction::isSchema() const { return false; }
199 
SetReciproceAction(Session * session,const std::string & joinName,MetaDboBase * value)200 SetReciproceAction::SetReciproceAction(Session *session,
201 				       const std::string& joinName,
202 				       MetaDboBase *value)
203   : session_(session),
204     joinName_(joinName),
205     value_(value)
206 { }
207 
actMapping(Impl::MappingInfo * mapping)208 void SetReciproceAction::actMapping(Impl::MappingInfo *mapping)
209 { }
210 
getsValue()211 bool SetReciproceAction::getsValue() const { return false; }
setsValue()212 bool SetReciproceAction::setsValue() const { return true; }
isSchema()213 bool SetReciproceAction::isSchema() const { return false; }
214 
ToAnysAction(std::vector<cpp17::any> & result)215 ToAnysAction::ToAnysAction(std::vector<cpp17::any>& result)
216   : session_(nullptr),
217     result_(result)
218 { }
219 
actMapping(Impl::MappingInfo * mapping)220 void ToAnysAction::actMapping(Impl::MappingInfo *mapping)
221 { }
222 
getsValue()223 bool ToAnysAction::getsValue() const { return true; }
setsValue()224 bool ToAnysAction::setsValue() const { return false; }
isSchema()225 bool ToAnysAction::isSchema() const { return false; }
226 
FromAnyAction(int & index,const cpp17::any & value)227 FromAnyAction::FromAnyAction(int& index, const cpp17::any& value)
228   : session_(nullptr),
229     index_(index),
230     value_(value)
231 { }
232 
actMapping(Impl::MappingInfo * mapping)233 void FromAnyAction::actMapping(Impl::MappingInfo *mapping)
234 { }
235 
getsValue()236 bool FromAnyAction::getsValue() const { return false; }
setsValue()237 bool FromAnyAction::setsValue() const { return true; }
isSchema()238 bool FromAnyAction::isSchema() const { return false; }
239 
240   }
241 }
242