1 // Copyright 2011 The Kyua Authors. 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/exceptions.hpp" 30 31 extern "C" { 32 #include <sqlite3.h> 33 } 34 35 #include <string> 36 37 #include "utils/format/macros.hpp" 38 #include "utils/fs/path.hpp" 39 #include "utils/optional.ipp" 40 #include "utils/sqlite/c_gate.hpp" 41 #include "utils/sqlite/database.hpp" 42 43 namespace fs = utils::fs; 44 namespace sqlite = utils::sqlite; 45 46 using utils::optional; 47 48 49 namespace { 50 51 52 /// Formats the database filename returned by sqlite for user consumption. 53 /// 54 /// \param db_filename An optional database filename. 55 /// 56 /// \return A string describing the filename. 57 static std::string 58 format_db_filename(const optional< fs::path >& db_filename) 59 { 60 if (db_filename) 61 return db_filename.get().str(); 62 else 63 return "in-memory or temporary"; 64 } 65 66 67 } // anonymous namespace 68 69 70 /// Constructs a new error with a plain-text message. 71 /// 72 /// \param db_filename_ Database filename as returned by database::db_filename() 73 /// for error reporting purposes. 74 /// \param message The plain-text error message. 75 sqlite::error::error(const optional< fs::path >& db_filename_, 76 const std::string& message) : 77 std::runtime_error(F("%s (sqlite db: %s)") % message % 78 format_db_filename(db_filename_)), 79 _db_filename(db_filename_) 80 { 81 } 82 83 84 /// Destructor for the error. 85 sqlite::error::~error(void) throw() 86 { 87 } 88 89 90 /// Returns the path to the database that raised this error. 91 /// 92 /// \return A database filename as returned by database::db_filename(). 93 const optional< fs::path >& 94 sqlite::error::db_filename(void) const 95 { 96 return _db_filename; 97 } 98 99 100 /// Constructs a new error. 101 /// 102 /// \param db_filename_ Database filename as returned by database::db_filename() 103 /// for error reporting purposes. 104 /// \param api_function_ The name of the API function that caused the error. 105 /// \param message_ The plain-text error message provided by SQLite. 106 sqlite::api_error::api_error(const optional< fs::path >& db_filename_, 107 const std::string& api_function_, 108 const std::string& message_) : 109 error(db_filename_, F("%s (sqlite op: %s)") % message_ % api_function_), 110 _api_function(api_function_) 111 { 112 } 113 114 115 /// Destructor for the error. 116 sqlite::api_error::~api_error(void) throw() 117 { 118 } 119 120 121 /// Constructs a new api_error with the message in the SQLite database. 122 /// 123 /// \param database_ The SQLite database. 124 /// \param api_function_ The name of the SQLite C API function that caused the 125 /// error. 126 /// 127 /// \return A new api_error with the retrieved message. 128 sqlite::api_error 129 sqlite::api_error::from_database(database& database_, 130 const std::string& api_function_) 131 { 132 ::sqlite3* c_db = database_c_gate(database_).c_database(); 133 return api_error(database_.db_filename(), api_function_, 134 ::sqlite3_errmsg(c_db)); 135 } 136 137 138 /// Gets the name of the SQlite C API function that caused this error. 139 /// 140 /// \return The name of the function. 141 const std::string& 142 sqlite::api_error::api_function(void) const 143 { 144 return _api_function; 145 } 146 147 148 /// Constructs a new error. 149 /// 150 /// \param db_filename_ Database filename as returned by database::db_filename() 151 /// for error reporting purposes. 152 /// \param name_ The name of the unknown column. 153 sqlite::invalid_column_error::invalid_column_error( 154 const optional< fs::path >& db_filename_, 155 const std::string& name_) : 156 error(db_filename_, F("Unknown column '%s'") % name_), 157 _column_name(name_) 158 { 159 } 160 161 162 /// Destructor for the error. 163 sqlite::invalid_column_error::~invalid_column_error(void) throw() 164 { 165 } 166 167 168 /// Gets the name of the column that could not be found. 169 /// 170 /// \return The name of the column requested by the user. 171 const std::string& 172 sqlite::invalid_column_error::column_name(void) const 173 { 174 return _column_name; 175 } 176