libdballe 5.10
|
00001 /* 00002 * db/internals - Internal support infrastructure for the DB 00003 * 00004 * Copyright (C) 2005--2010 ARPA-SIM <urpsim@smr.arpa.emr.it> 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 * 00019 * Author: Enrico Zini <enrico@enricozini.com> 00020 */ 00021 00022 #ifndef DBALLE_DB_INTERNALS_H 00023 #define DBALLE_DB_INTERNALS_H 00024 00032 #include <dballe/db/querybuf.h> 00033 #include <dballe/db/odbcworkarounds.h> 00034 #include <wreport/error.h> 00035 00036 #include <sqltypes.h> 00037 00038 /* 00039 * Define to true to enable the use of transactions during writes 00040 */ 00041 #define DBA_USE_TRANSACTIONS 00042 00043 /* Define this to enable referential integrity */ 00044 #undef USE_REF_INT 00045 00046 namespace dballe { 00047 namespace db { 00048 00053 // #define TRACE_DB 00054 00055 #ifdef TRACE_DB 00056 #define TRACE(...) fprintf(stderr, __VA_ARGS__) 00057 #define IFTRACE if (1) 00058 #else 00059 00060 #define TRACE(...) do { } while (0) 00061 00062 #define IFTRACE if (0) 00063 #endif 00064 00067 // Define this to get warnings when a Statement is closed but its data have not 00068 // all been read yet 00069 // #define DEBUG_WARN_OPEN_TRANSACTIONS 00070 00074 struct error_odbc : public wreport::error 00075 { 00076 std::string msg; 00077 00082 error_odbc(SQLSMALLINT handleType, SQLHANDLE handle, const std::string& msg); 00083 ~error_odbc() throw () {} 00084 00085 wreport::ErrorCode code() const throw () { return wreport::WR_ERR_ODBC; } 00086 00087 virtual const char* what() const throw () { return msg.c_str(); } 00088 00089 static void throwf(SQLSMALLINT handleType, SQLHANDLE handle, const char* fmt, ...) WREPORT_THROWF_ATTRS(3, 4); 00090 }; 00091 00095 enum ServerType 00096 { 00097 MYSQL, 00098 SQLITE, 00099 ORACLE, 00100 POSTGRES, 00101 }; 00102 00104 struct Environment 00105 { 00106 SQLHENV od_env; 00107 00108 Environment(); 00109 ~Environment(); 00110 00111 static Environment& get(); 00112 00113 private: 00114 // disallow copy 00115 Environment(const Environment&); 00116 Environment& operator=(const Environment&); 00117 }; 00118 00120 struct Connection 00121 { 00123 SQLHDBC od_conn; 00125 bool connected; 00127 enum ServerType server_type; 00128 00129 Connection(); 00130 ~Connection(); 00131 00132 void connect(const char* dsn, const char* user, const char* password); 00133 void driver_connect(const char* config); 00134 std::string driver_name(); 00135 void set_autocommit(bool val); 00136 00138 void commit(); 00139 00141 void rollback(); 00142 00143 protected: 00144 void init_after_connect(); 00145 00146 private: 00147 // disallow copy 00148 Connection(const Connection&); 00149 Connection& operator=(const Connection&); 00150 }; 00151 00153 struct Transaction 00154 { 00155 Connection& conn; 00156 bool fired; 00157 00158 Transaction(Connection& conn) : conn(conn), fired(false) {} 00159 ~Transaction() { if (!fired) rollback(); } 00160 00161 void commit() { conn.commit(); fired = true; } 00162 void rollback() { conn.rollback(); fired = true; } 00163 }; 00164 00166 struct Statement 00167 { 00168 //Connection& conn; 00169 SQLHSTMT stm; 00171 const char* ignore_error; 00172 #ifdef DEBUG_WARN_OPEN_TRANSACTIONS 00173 00174 std::string debug_query; 00175 bool debug_reached_completion; 00176 #endif 00177 00178 Statement(Connection& conn); 00179 ~Statement(); 00180 00181 void bind_in(int idx, const DBALLE_SQL_C_SINT_TYPE& val); 00182 void bind_in(int idx, const DBALLE_SQL_C_SINT_TYPE& val, const SQLLEN& ind); 00183 void bind_in(int idx, const DBALLE_SQL_C_UINT_TYPE& val); 00184 void bind_in(int idx, const DBALLE_SQL_C_UINT_TYPE& val, const SQLLEN& ind); 00185 void bind_in(int idx, const unsigned short& val); 00186 void bind_in(int idx, const char* val); 00187 void bind_in(int idx, const char* val, const SQLLEN& ind); 00188 void bind_in(int idx, const SQL_TIMESTAMP_STRUCT& val); 00189 00190 void bind_out(int idx, DBALLE_SQL_C_SINT_TYPE& val); 00191 void bind_out(int idx, DBALLE_SQL_C_SINT_TYPE& val, SQLLEN& ind); 00192 void bind_out(int idx, DBALLE_SQL_C_UINT_TYPE& val); 00193 void bind_out(int idx, DBALLE_SQL_C_UINT_TYPE& val, SQLLEN& ind); 00194 void bind_out(int idx, unsigned short& val); 00195 void bind_out(int idx, char* val, SQLLEN buflen); 00196 void bind_out(int idx, char* val, SQLLEN buflen, SQLLEN& ind); 00197 void bind_out(int idx, SQL_TIMESTAMP_STRUCT& val); 00198 00199 void prepare(const char* query); 00200 void prepare(const char* query, int qlen); 00201 00203 int execute(); 00205 int exec_direct(const char* query); 00207 int exec_direct(const char* query, int qlen); 00208 00210 int execute_and_close(); 00212 int exec_direct_and_close(const char* query); 00214 int exec_direct_and_close(const char* query, int qlen); 00215 00220 int columns_count(); 00221 bool fetch(); 00222 bool fetch_expecting_one(); 00223 void close_cursor(); 00224 size_t rowcount(); 00225 00226 void set_cursor_forward_only(); 00227 00228 protected: 00229 bool error_is_ignored(); 00230 bool is_error(int sqlres); 00231 00232 private: 00233 // disallow copy 00234 Statement(const Statement&); 00235 Statement& operator=(const Statement&); 00236 }; 00237 00239 struct Sequence : public Statement 00240 { 00241 DBALLE_SQL_C_SINT_TYPE out; 00242 00243 Sequence(Connection& conn, const char* name); 00244 ~Sequence(); 00245 00247 const DBALLE_SQL_C_SINT_TYPE& read(); 00248 00249 private: 00250 // disallow copy 00251 Sequence(const Sequence&); 00252 Sequence& operator=(const Sequence&); 00253 }; 00254 00256 const char* default_repinfo_file(); 00257 00258 } // namespace db 00259 } // namespace dballe 00260 00261 /* vim:set ts=4 sw=4: */ 00262 #endif