libdballe  5.18
internals.h
Go to the documentation of this file.
1 /*
2  * db/internals - Internal support infrastructure for the DB
3  *
4  * Copyright (C) 2005--2010 ARPA-SIM <urpsim@smr.arpa.emr.it>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  * Author: Enrico Zini <enrico@enricozini.com>
20  */
21 
22 #ifndef DBALLE_DB_INTERNALS_H
23 #define DBALLE_DB_INTERNALS_H
24 
32 #include <dballe/db/querybuf.h>
34 #include <wreport/error.h>
35 
36 #include <sqltypes.h>
37 
38 /*
39  * Define to true to enable the use of transactions during writes
40  */
41 #define DBA_USE_TRANSACTIONS
42 
43 /* Define this to enable referential integrity */
44 #undef USE_REF_INT
45 
46 namespace dballe {
47 namespace db {
48 
53 // #define TRACE_DB
54 
55 #ifdef TRACE_DB
56 #define TRACE(...) fprintf(stderr, __VA_ARGS__)
57 #define IFTRACE if (1)
58 #else
59 
60 #define TRACE(...) do { } while (0)
61 
62 #define IFTRACE if (0)
63 #endif
64 
67 // Define this to get warnings when a Statement is closed but its data have not
68 // all been read yet
69 // #define DEBUG_WARN_OPEN_TRANSACTIONS
70 
74 struct error_odbc : public wreport::error
75 {
76  std::string msg;
77 
82  error_odbc(SQLSMALLINT handleType, SQLHANDLE handle, const std::string& msg);
83  ~error_odbc() throw () {}
84 
85  wreport::ErrorCode code() const throw () { return wreport::WR_ERR_ODBC; }
86 
87  virtual const char* what() const throw () { return msg.c_str(); }
88 
89  static void throwf(SQLSMALLINT handleType, SQLHANDLE handle, const char* fmt, ...) WREPORT_THROWF_ATTRS(3, 4);
90 };
91 
95 enum ServerType
96 {
97  MYSQL,
98  SQLITE,
99  ORACLE,
100  POSTGRES,
101 };
102 
105 {
106  SQLHENV od_env;
107 
108  Environment();
109  ~Environment();
110 
111  static Environment& get();
112 
113 private:
114  // disallow copy
115  Environment(const Environment&);
116  Environment& operator=(const Environment&);
117 };
118 
121 {
123  SQLHDBC od_conn;
125  bool connected;
127  enum ServerType server_type;
128 
129  Connection();
130  ~Connection();
131 
132  void connect(const char* dsn, const char* user, const char* password);
133  void driver_connect(const char* config);
134  std::string driver_name();
135  void set_autocommit(bool val);
136 
138  void commit();
139 
141  void rollback();
142 
143 protected:
144  void init_after_connect();
145 
146 private:
147  // disallow copy
148  Connection(const Connection&);
149  Connection& operator=(const Connection&);
150 };
151 
154 {
155  Connection& conn;
156  bool fired;
157 
158  Transaction(Connection& conn) : conn(conn), fired(false) {}
159  ~Transaction() { if (!fired) rollback(); }
160 
161  void commit() { conn.commit(); fired = true; }
162  void rollback() { conn.rollback(); fired = true; }
163 };
164 
166 struct Statement
167 {
168  //Connection& conn;
169  SQLHSTMT stm;
171  const char* ignore_error;
172 #ifdef DEBUG_WARN_OPEN_TRANSACTIONS
173 
174  std::string debug_query;
175  bool debug_reached_completion;
176 #endif
177 
178  Statement(Connection& conn);
179  ~Statement();
180 
181  void bind_in(int idx, const DBALLE_SQL_C_SINT_TYPE& val);
182  void bind_in(int idx, const DBALLE_SQL_C_SINT_TYPE& val, const SQLLEN& ind);
183  void bind_in(int idx, const DBALLE_SQL_C_UINT_TYPE& val);
184  void bind_in(int idx, const DBALLE_SQL_C_UINT_TYPE& val, const SQLLEN& ind);
185  void bind_in(int idx, const unsigned short& val);
186  void bind_in(int idx, const char* val);
187  void bind_in(int idx, const char* val, const SQLLEN& ind);
188  void bind_in(int idx, const SQL_TIMESTAMP_STRUCT& val);
189 
190  void bind_out(int idx, DBALLE_SQL_C_SINT_TYPE& val);
191  void bind_out(int idx, DBALLE_SQL_C_SINT_TYPE& val, SQLLEN& ind);
192  void bind_out(int idx, DBALLE_SQL_C_UINT_TYPE& val);
193  void bind_out(int idx, DBALLE_SQL_C_UINT_TYPE& val, SQLLEN& ind);
194  void bind_out(int idx, unsigned short& val);
195  void bind_out(int idx, char* val, SQLLEN buflen);
196  void bind_out(int idx, char* val, SQLLEN buflen, SQLLEN& ind);
197  void bind_out(int idx, SQL_TIMESTAMP_STRUCT& val);
198 
199  void prepare(const char* query);
200  void prepare(const char* query, int qlen);
201 
203  int execute();
205  int exec_direct(const char* query);
207  int exec_direct(const char* query, int qlen);
208 
210  int execute_and_close();
212  int exec_direct_and_close(const char* query);
214  int exec_direct_and_close(const char* query, int qlen);
215 
220  int columns_count();
221  bool fetch();
222  bool fetch_expecting_one();
223  void close_cursor();
224  size_t rowcount();
225 
226  void set_cursor_forward_only();
227 
228 protected:
229  bool error_is_ignored();
230  bool is_error(int sqlres);
231 
232 private:
233  // disallow copy
234  Statement(const Statement&);
235  Statement& operator=(const Statement&);
236 };
237 
239 struct Sequence : public Statement
240 {
241  DBALLE_SQL_C_SINT_TYPE out;
242 
243  Sequence(Connection& conn, const char* name);
244  ~Sequence();
245 
247  const DBALLE_SQL_C_SINT_TYPE& read();
248 
249 private:
250  // disallow copy
251  Sequence(const Sequence&);
252  Sequence& operator=(const Sequence&);
253 };
254 
256 const char* default_repinfo_file();
257 
258 } // namespace db
259 } // namespace dballe
260 
261 /* vim:set ts=4 sw=4: */
262 #endif