| 
									
										
										
										
											2018-11-12 01:48:01 +00:00
										 |  |  | #ifndef QT_DB_HELPERS_HPP_
 | 
					
						
							|  |  |  | #define QT_DB_HELPERS_HPP_
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <utility>
 | 
					
						
							|  |  |  | #include <stdexcept>
 | 
					
						
							|  |  |  | #include <QString>
 | 
					
						
							|  |  |  | #include <QSqlError>
 | 
					
						
							|  |  |  | #include <QSqlTableModel>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<typename T, typename Func, typename... Args> | 
					
						
							|  |  |  | void SQL_error_check (T&& object, Func func, Args&&... args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (!(std::forward<T> (object).*func) (std::forward<Args> (args)...)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       auto error = object.lastError (); | 
					
						
							|  |  |  |       if (QSqlError::NoError != error.type ()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           throw std::runtime_error {("Database Error: " + error.text ()).toStdString ()}; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ConditionalTransaction final | 
					
						
							|  |  |  |   : private boost::noncopyable | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |   explicit ConditionalTransaction (QSqlTableModel& model) | 
					
						
							| 
									
										
										
										
											2018-11-15 01:31:21 +00:00
										 |  |  |     : model_ (model) | 
					
						
							| 
									
										
										
										
											2018-11-12 01:48:01 +00:00
										 |  |  |     , submitted_ {false} | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     model_.database ().transaction (); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 01:48:01 +00:00
										 |  |  |   bool submit (bool throw_on_error = true) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     bool ok {true}; | 
					
						
							|  |  |  |     if (throw_on_error) | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  |         SQL_error_check (model_ | 
					
						
							|  |  |  |                          , QSqlTableModel::OnManualSubmit == model_.editStrategy () | 
					
						
							|  |  |  |                          ? &QSqlTableModel::submitAll | 
					
						
							|  |  |  |                          : &QSqlTableModel::submit); | 
					
						
							| 
									
										
										
										
											2018-11-12 01:48:01 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  |         ok = QSqlTableModel::OnManualSubmit == model_.editStrategy () | 
					
						
							|  |  |  |           ? model_.submitAll () : model_.submit (); | 
					
						
							| 
									
										
										
										
											2018-11-12 01:48:01 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     submitted_ = submitted_ || ok; | 
					
						
							|  |  |  |     return ok; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 01:48:01 +00:00
										 |  |  |   void revert () | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  |     if (QSqlTableModel::OnManualSubmit == model_.editStrategy ()) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         model_.revertAll (); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         model_.revert (); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-11-12 01:48:01 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 01:48:01 +00:00
										 |  |  |   ~ConditionalTransaction () | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (model_.isDirty ()) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         // abandon un-submitted changes to the model
 | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  |         if (QSqlTableModel::OnManualSubmit == model_.editStrategy ()) | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             model_.revertAll (); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             model_.revert (); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-11-12 01:48:01 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     auto database = model_.database (); | 
					
						
							|  |  |  |     if (submitted_) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         SQL_error_check (database, &QSqlDatabase::commit); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         database.rollback (); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-11-25 22:19:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 01:48:01 +00:00
										 |  |  | private: | 
					
						
							|  |  |  |   QSqlTableModel& model_; | 
					
						
							|  |  |  |   bool submitted_; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 |