libdballe  7.7
odbc/internals.h
Go to the documentation of this file.
1 /*
2  * db/odbc/internals - Implementation infrastructure for the ODBC DB connection
3  *
4  * Copyright (C) 2005--2014 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_ODBC_INTERNALS_H
23 #define DBALLE_DB_ODBC_INTERNALS_H
24 
32 #include <dballe/db/db.h>
33 #include <dballe/db/sql.h>
34 #include <dballe/db/querybuf.h>
35 #include <sqltypes.h>
36 #include <list>
37 
38 // Bit values for server/driver quirks
39 #define DBA_DB_QUIRK_NO_ROWCOUNT_IN_DIAG (1 << 0)
40 
41 namespace dballe {
42 namespace db {
43 struct ODBCStatement;
44 
45 // Define this to get warnings when a Statement is closed but its data have not
46 // all been read yet
47 // #define DEBUG_WARN_OPEN_TRANSACTIONS
48 
52 struct error_odbc : public db::error
53 {
54  std::string msg;
55 
60  error_odbc(SQLSMALLINT handleType, SQLHANDLE handle, const std::string& msg);
61  ~error_odbc() throw () {}
62 
63  wreport::ErrorCode code() const throw () { return wreport::WR_ERR_ODBC; }
64 
65  virtual const char* what() const throw () { return msg.c_str(); }
66 
67  static void throwf(SQLSMALLINT handleType, SQLHANDLE handle, const char* fmt, ...) WREPORT_THROWF_ATTRS(3, 4);
68 };
69 
72 {
73  SQLHENV od_env;
74 
75  Environment();
76  ~Environment();
77 
78  static Environment& get();
79 
80 private:
81  // disallow copy
82  Environment(const Environment&);
83  Environment& operator=(const Environment&);
84 };
85 
87 struct ODBCConnection : public Connection
88 {
90  SQLHDBC od_conn;
92  bool connected;
94  unsigned server_quirks;
95 
96 protected:
101 
102 public:
103  ODBCConnection();
104  ODBCConnection(const ODBCConnection&) = delete;
105  ODBCConnection(const ODBCConnection&&) = delete;
106  ~ODBCConnection();
107 
108  ODBCConnection& operator=(const ODBCConnection&) = delete;
109 
110  void connect(const char* dsn, const char* user, const char* password);
111  void connect_url(const char* url);
112  // void connect_file(const std::string& fname);
113  void connect_test();
114  void driver_connect(const char* config);
115  std::string driver_name();
116  std::string driver_version();
117  void get_info(SQLUSMALLINT info_type, SQLINTEGER& res);
118  void set_autocommit(bool val);
119 
120  void exec(const std::string& query);
121 
122  std::unique_ptr<Transaction> transaction() override;
123  std::unique_ptr<ODBCStatement> odbcstatement(const std::string& query);
124 
126  bool has_table(const std::string& name) override;
127 
133  std::string get_setting(const std::string& key) override;
134 
140  void set_setting(const std::string& key, const std::string& value) override;
141 
143  void drop_settings() override;
144 
148  void drop_table_if_exists(const char* name);
149 
153  void drop_sequence_if_exists(const char* name);
154 
161  int get_last_insert_id();
162 
163  void add_datetime(Querybuf& qb, const Datetime& dt) const override;
164 
165 protected:
166  void init_after_connect();
167 };
168 
171 {
172  const ODBCConnection& conn;
173  SQLHSTMT stm = nullptr;
175  const char* ignore_error = nullptr;
176 #ifdef DEBUG_WARN_OPEN_TRANSACTIONS
177  std::string debug_query;
179  bool debug_reached_completion = false;
180 #endif
181 
183  ODBCStatement(const ODBCStatement&) = delete;
184  ODBCStatement(const ODBCStatement&&) = delete;
185  ~ODBCStatement();
186  ODBCStatement& operator=(const ODBCStatement&) = delete;
187 
188  void bind_in(int idx, const int& val);
189  void bind_in(int idx, const int& val, const SQLLEN& ind);
190  void bind_in(int idx, const unsigned& val);
191  void bind_in(int idx, const unsigned& val, const SQLLEN& ind);
192  void bind_in(int idx, const unsigned short& val);
193  void bind_in(int idx, const unsigned short& val, const SQLLEN& ind);
194  void bind_in(int idx, const char* val);
195  void bind_in(int idx, const char* val, const SQLLEN& ind);
196  void bind_in(int idx, const std::string& val);
197  void bind_in(int idx, const SQL_TIMESTAMP_STRUCT& val);
198 
199  void bind_out(int idx, int& val);
200  void bind_out(int idx, int& val, SQLLEN& ind);
201  void bind_out(int idx, unsigned& val);
202  void bind_out(int idx, unsigned& val, SQLLEN& ind);
203  void bind_out(int idx, unsigned short& val);
204  void bind_out(int idx, unsigned short& val, SQLLEN& ind);
205  void bind_out(int idx, char* val, SQLLEN buflen);
206  void bind_out(int idx, char* val, SQLLEN buflen, SQLLEN& ind);
207  void bind_out(int idx, SQL_TIMESTAMP_STRUCT& val);
208  void bind_out(int idx, SQL_TIMESTAMP_STRUCT& val, SQLLEN& ind);
209 
210  void prepare(const char* query);
211  void prepare(const char* query, int qlen);
212  void prepare(const std::string& query);
213 
215  int execute();
216 
218  int execute_and_close();
220  int exec_direct_and_close(const char* query, int qlen);
221 
222  void execute_ignoring_results();
223 
228  int columns_count();
229  bool fetch();
230  bool fetch_expecting_one();
231  void close_cursor();
232  void close_cursor_if_needed();
234  size_t select_rowcount();
236  size_t rowcount();
237 
238  void set_cursor_forward_only();
239  void set_cursor_static();
240 
241 protected:
242  bool error_is_ignored();
243  bool is_error(int sqlres);
244 };
245 
247 struct Sequence : public ODBCStatement
248 {
249  int out;
250 
251  Sequence(ODBCConnection& conn, const char* name);
252  ~Sequence();
253 
255  const int& read();
256 
257 private:
258  // disallow copy
259  Sequence(const Sequence&);
260  Sequence& operator=(const Sequence&);
261 };
262 
263 static inline bool operator!=(const SQL_TIMESTAMP_STRUCT& a, const SQL_TIMESTAMP_STRUCT& b)
264 {
265  return a.year != b.year || a.month != b.month || a.day != b.day || a.hour != b.hour || a.minute != b.minute || a.second != b.second || a.fraction != b.fraction;
266 }
267 
268 std::ostream& operator<<(std::ostream& o, const SQL_TIMESTAMP_STRUCT& t);
269 
270 static inline SQL_TIMESTAMP_STRUCT make_sql_timestamp(int year, int month, int day, int hour, int minute, int second)
271 {
272  SQL_TIMESTAMP_STRUCT res;
273  res.year = year;
274  res.month = month;
275  res.day = day;
276  res.hour = hour;
277  res.minute = minute;
278  res.second = second;
279  res.fraction = 0;
280  return res;
281 }
282 
283 
284 } // namespace db
285 } // namespace dballe
286 
287 /* vim:set ts=4 sw=4: */
288 #endif
Report an ODBC error, using informations from the ODBC diagnostic record.
Definition: odbc/internals.h:52
error_odbc(SQLSMALLINT handleType, SQLHANDLE handle, const std::string &msg)
Copy informations from the ODBC diagnostic record to the dba error report.
ODBC statement.
Definition: odbc/internals.h:170
Base exception for database errors.
Definition: db/defs.h:54
Copyright (C) 2008–2010 ARPA-SIM urpsim@smr.arpa.emr.it
Definition: cmdline.h:17
unsigned server_quirks
Bitfield of quirks we should be aware of when using ODBC.
Definition: odbc/internals.h:94
SQLHDBC od_conn
ODBC database connection.
Definition: odbc/internals.h:90
String buffer for composing database queries.
Definition: querybuf.h:37
bool connected
True if the connection is open.
Definition: odbc/internals.h:92
Functions used to connect to DB-All.e and insert, query and delete data.
Implementation of an efficient string buffer for composing database queries.
ODBC environment.
Definition: odbc/internals.h:71
int m_last_insert_id
ID of the last autogenerated primary key.
Definition: odbc/internals.h:100
Date and time.
Definition: types.h:147
ODBC statement to read a sequence.
Definition: odbc/internals.h:247
ODBCStatement * stm_last_insert_id
Precompiled LAST_INSERT_ID (or equivalent) SQL statement.
Definition: odbc/internals.h:98
Definition: sql.h:69
Database connection.
Definition: odbc/internals.h:87