1 // Copyright 2011 Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // * Neither the name of Google Inc. nor the names of its contributors 14 // may be used to endorse or promote products derived from this software 15 // without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 #include "utils/sqlite/transaction.hpp" 30 31 #include "utils/format/macros.hpp" 32 #include "utils/logging/macros.hpp" 33 #include "utils/sanity.hpp" 34 #include "utils/sqlite/database.hpp" 35 #include "utils/sqlite/exceptions.hpp" 36 #include "utils/sqlite/statement.ipp" 37 38 namespace sqlite = utils::sqlite; 39 40 41 /// Internal implementation for the transaction. 42 struct utils::sqlite::transaction::impl { 43 /// The database this transaction belongs to. 44 database& db; 45 46 /// Possible statuses of a transaction. 47 enum statuses { 48 open_status, 49 committed_status, 50 rolled_back_status, 51 }; 52 53 /// The current status of the transaction. 54 statuses status; 55 56 /// Constructs a new transaction. 57 /// 58 /// \param db_ The database this transaction belongs to. 59 /// \param status_ The status of the new transaction. 60 impl(database& db_, const statuses status_) : 61 db(db_), 62 status(status_) 63 { 64 } 65 66 /// Destroys the transaction. 67 /// 68 /// This rolls back the transaction if it is open. 69 ~impl(void) 70 { 71 if (status == impl::open_status) { 72 try { 73 rollback(); 74 } catch (const sqlite::error& e) { 75 LW(F("Error while rolling back a transaction: %s") % e.what()); 76 } 77 } 78 } 79 80 /// Commits the transaction. 81 /// 82 /// \throw api_error If there is any problem while committing the 83 /// transaction. 84 void 85 commit(void) 86 { 87 PRE(status == impl::open_status); 88 db.exec("COMMIT"); 89 status = impl::committed_status; 90 } 91 92 /// Rolls the transaction back. 93 /// 94 /// \throw api_error If there is any problem while rolling the 95 /// transaction back. 96 void 97 rollback(void) 98 { 99 PRE(status == impl::open_status); 100 db.exec("ROLLBACK"); 101 status = impl::rolled_back_status; 102 } 103 }; 104 105 106 /// Initializes a transaction object. 107 /// 108 /// This is an internal function. Use database::begin_transaction() to 109 /// instantiate one of these objects. 110 /// 111 /// \param db The database this transaction belongs to. 112 sqlite::transaction::transaction(database& db) : 113 _pimpl(new impl(db, impl::open_status)) 114 { 115 } 116 117 118 /// Destructor for the transaction. 119 sqlite::transaction::~transaction(void) 120 { 121 } 122 123 124 /// Commits the transaction. 125 /// 126 /// \throw api_error If there is any problem while committing the transaction. 127 void 128 sqlite::transaction::commit(void) 129 { 130 _pimpl->commit(); 131 } 132 133 134 /// Rolls the transaction back. 135 /// 136 /// \throw api_error If there is any problem while rolling the transaction back. 137 void 138 sqlite::transaction::rollback(void) 139 { 140 _pimpl->rollback(); 141 } 142