Home | History | Annotate | Line # | Download | only in sqlite
      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