aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
nanodbc.h
Go to the documentation of this file.
1#ifndef DOXYGEN_SHOULD_SKIP_THIS
2
3#ifdef _ODBC // Enable Nanodbc only if an odbc driver was found
4
6
77
78#ifndef NANODBC_H
79#define NANODBC_H
80
81#include <functional>
82#include <memory>
83#include <stdexcept>
84#include <string>
85#include <vector>
86
87#ifndef __clang__
88 #include <cstdint>
89#endif
90
93namespace nanodbc
94{
95
96// .d8888b. .d888 d8b 888 d8b
97// d88P Y88b d88P" Y8P 888 Y8P
98// 888 888 888 888
99// 888 .d88b. 88888b. 888888 888 .d88b. 888 888 888d888 8888b. 888888 888 .d88b. 88888b.
100// 888 d88""88b 888 "88b 888 888 d88P"88b 888 888 888P" "88b 888 888 d88""88b 888 "88b
101// 888 888 888 888 888 888 888 888 888 888 888 888 888 .d888888 888 888 888 888 888 888
102// Y88b d88P Y88..88P 888 888 888 888 Y88b 888 Y88b 888 888 888 888 Y88b. 888 Y88..88P 888 888
103// "Y8888P" "Y88P" 888 888 888 888 "Y88888 "Y88888 888 "Y888888 "Y888 888 "Y88P" 888 888
104// 888
105// Y8b d88P
106// "Y88P"
107// MARK: Configuration -
108
113
114#ifdef DOXYGEN
129 #define NANODBC_ASSERT(expression) assert(expression)
130#endif
131
133
134// You must explicitly request Unicode support by defining NANODBC_USE_UNICODE at compile time.
135#ifndef DOXYGEN
136 #ifdef NANODBC_USE_UNICODE
137 #ifdef NANODBC_USE_IODBC_WIDE_STRINGS
138 typedef std::u32string string_type;
139 #else
140 typedef std::u16string string_type;
141 #endif
142 #else
143 typedef std::string string_type;
144 #endif // NANODBC_USE_UNICODE
145
146 #if defined(_WIN64)
147 // LLP64 machine: Windows
148 typedef std::int64_t null_type;
149 #elif !defined(_WIN64) && defined( __LP64__)
150 // LP64 machine: OS X or Linux
151 typedef long null_type;
152 #else
153 // 32-bit machine
154 typedef long null_type;
155 #endif
156#else
158 typedef unspecified-type string_type;
160 typedef unspecified-type null_type;
161#endif // DOXYGEN
162
163#if defined(_MSC_VER) && _MSC_VER <= 1800
164 // These versions of Visual C++ do not yet support \c noexcept or \c std::move.
165 #define NANODBC_NOEXCEPT
166 #define NANODBC_NO_MOVE_CTOR
167#else
168 #define NANODBC_NOEXCEPT noexcept
169#endif
170
171// 8888888888 888 888 888 888 d8b
172// 888 888 888 888 888 Y8P
173// 888 888 888 888 888
174// 8888888 888d888 888d888 .d88b. 888d888 8888888888 8888b. 88888b. .d88888 888 888 88888b. .d88b.
175// 888 888P" 888P" d88""88b 888P" 888 888 "88b 888 "88b d88" 888 888 888 888 "88b d88P"88b
176// 888 888 888 888 888 888 888 888 .d888888 888 888 888 888 888 888 888 888 888 888
177// 888 888 888 Y88..88P 888 888 888 888 888 888 888 Y88b 888 888 888 888 888 Y88b 888
178// 8888888888 888 888 "Y88P" 888 888 888 "Y888888 888 888 "Y88888 888 888 888 888 "Y88888
179// 888
180// Y8b d88P
181// "Y88P"
182// MARK: Error Handling -
183
192
195class type_incompatible_error : public std::runtime_error
196{
197public:
198 type_incompatible_error();
199 const char* what() const NANODBC_NOEXCEPT;
200};
201
204class null_access_error : public std::runtime_error
205{
206public:
207 null_access_error();
208 const char* what() const NANODBC_NOEXCEPT;
209};
210
213class index_range_error : public std::runtime_error
214{
215public:
216 index_range_error();
217 const char* what() const NANODBC_NOEXCEPT;
218};
219
222class programming_error : public std::runtime_error
223{
224public:
225 explicit programming_error(const std::string& info);
226 const char* what() const NANODBC_NOEXCEPT;
227};
228
231class database_error : public std::runtime_error
232{
233public:
238 database_error(void* handle, short handle_type, const std::string& info = "");
239 const char* what() const NANODBC_NOEXCEPT;
240 const long native() const NANODBC_NOEXCEPT;
241 const std::string state() const NANODBC_NOEXCEPT;
242private:
243 long native_error;
244 std::string sql_state;
245 std::string message;
246};
247
249
250// 888 888 888 d8b 888 d8b 888 d8b
251// 888 888 888 Y8P 888 Y8P 888 Y8P
252// 888 888 888 888 888
253// 888 888 888888 888 888 888 888888 888 .d88b. .d8888b
254// 888 888 888 888 888 888 888 888 d8P Y8b 88K
255// 888 888 888 888 888 888 888 888 88888888 "Y8888b.
256// Y88b. .d88P Y88b. 888 888 888 Y88b. 888 Y8b. X88
257// "Y88888P" "Y888 888 888 888 "Y888 888 "Y8888 88888P'
258// MARK: Utilities -
259
264
266struct date
267{
268 std::int16_t year;
269 std::int16_t month;
270 std::int16_t day;
271};
272
274struct timestamp
275{
276 std::int16_t year;
277 std::int16_t month;
278 std::int16_t day;
279 std::int16_t hour;
280 std::int16_t min;
281 std::int16_t sec;
282 std::int32_t fract;
283};
284
286
291
292// 88888888888 888 d8b
293// 888 888 Y8P
294// 888 888
295// 888 888d888 8888b. 88888b. .d8888b 8888b. .d8888b 888888 888 .d88b. 88888b.
296// 888 888P" "88b 888 "88b 88K "88b d88P" 888 888 d88""88b 888 "88b
297// 888 888 .d888888 888 888 "Y8888b. .d888888 888 888 888 888 888 888 888
298// 888 888 888 888 888 888 X88 888 888 Y88b. Y88b. 888 Y88..88P 888 888
299// 888 888 "Y888888 888 888 88888P' "Y888888 "Y8888P "Y888 888 "Y88P" 888 888
300// MARK: Transaction -
301
305class transaction
306{
307public:
311 explicit transaction(const class connection& conn);
312
314 transaction(const transaction& rhs);
315
316 #ifndef NANODBC_NO_MOVE_CTOR
318 transaction(transaction&& rhs) NANODBC_NOEXCEPT;
319 #endif
320
322 transaction& operator=(transaction rhs);
323
325 void swap(transaction& rhs) NANODBC_NOEXCEPT;
326
328 ~transaction() NANODBC_NOEXCEPT;
329
332 void commit();
333
335 void rollback() NANODBC_NOEXCEPT;
336
338 class connection& connection();
339
341 const class connection& connection() const;
342
344 operator class connection&();
345
347 operator const class connection&() const;
348
349private:
350 class transaction_impl;
351 friend class nanodbc::connection;
352
353private:
354 std::shared_ptr<transaction_impl> impl_;
355};
356
357// .d8888b. 888 888 888
358// d88P Y88b 888 888 888
359// Y88b. 888 888 888
360// "Y888b. 888888 8888b. 888888 .d88b. 88888b.d88b. .d88b. 88888b. 888888
361// "Y88b. 888 "88b 888 d8P Y8b 888 "888 "88b d8P Y8b 888 "88b 888
362// "888 888 .d888888 888 88888888 888 888 888 88888888 888 888 888
363// Y88b d88P Y88b. 888 888 Y88b. Y8b. 888 888 888 Y8b. 888 888 Y88b.
364// "Y8888P" "Y888 "Y888888 "Y888 "Y8888 888 888 888 "Y8888 888 888 "Y888
365// MARK: Statement -
366
368class statement
369{
370public:
373 enum param_direction
374 {
375 PARAM_IN
376 , PARAM_OUT
377 , PARAM_INOUT
378 , PARAM_RETURN
379 };
380
381public:
384 statement();
385
389 explicit statement(class connection& conn);
390
396 statement(class connection& conn, const string_type& query, long timeout = 0);
397
399 statement(const statement& rhs);
400
401 #ifndef NANODBC_NO_MOVE_CTOR
403 statement(statement&& rhs) NANODBC_NOEXCEPT;
404 #endif
405
407 statement& operator=(statement rhs);
408
410 void swap(statement& rhs) NANODBC_NOEXCEPT;
411
414 ~statement() NANODBC_NOEXCEPT;
415
419 void open(class connection& conn);
420
422 bool open() const;
423
425 bool connected() const;
426
428 class connection& connection();
429
431 const class connection& connection() const;
432
434 void* native_statement_handle() const;
435
437 void close();
438
441 void cancel();
442
449 void prepare(class connection& conn, const string_type& query, long timeout = 0);
450
457 void prepare(const string_type& query, long timeout = 0);
458
461 void timeout(long timeout = 0);
462
471 class result execute_direct(class connection& conn, const string_type& query, long batch_operations = 1, long timeout = 0);
472
486 void async_execute_direct(class connection& conn, void* event_handle, const string_type& query, long batch_operations = 1, long timeout = 0);
487
495 class result async_complete(long batch_operations = 1);
496
506 void just_execute_direct(class connection& conn, const string_type& query, long batch_operations = 1, long timeout = 0);
507
515 class result execute(long batch_operations = 1, long timeout = 0);
516
524 void just_execute(long batch_operations = 1, long timeout = 0);
525
533 class result procedure_columns(const string_type& catalog, const string_type& schema, const string_type& procedure, const string_type& column);
534
537 long affected_rows() const;
538
541 short columns() const;
542
544 void reset_parameters() NANODBC_NOEXCEPT;
545
547 unsigned long parameter_size(short param) const;
548
553
565 template<class T>
566 void bind(short param, const T* value, param_direction direction = PARAM_IN);
567
585
588 template<class T>
589 void bind(short param, const T* values, std::size_t elements, param_direction direction = PARAM_IN);
590
593 template<class T>
594 void bind(short param, const T* values, std::size_t elements, const T* null_sentry, param_direction direction = PARAM_IN);
595
598 template<class T>
599 void bind(short param, const T* values, std::size_t elements, const bool* nulls, param_direction direction = PARAM_IN);
600
602
621
624 void bind_strings(
625 short param
626 , const string_type::value_type* values
627 , std::size_t length
628 , std::size_t elements
629 , param_direction direction = PARAM_IN);
630
633 template<std::size_t N, std::size_t M>
634 void bind_strings(
635 short param
636 , const string_type::value_type(&values)[N][M]
637 , param_direction direction = PARAM_IN)
638 {
639 bind_strings(
640 param
641 , reinterpret_cast<const string_type::value_type*>(values)
642 , M
643 , N
644 , direction);
645 }
646
649 void bind_strings(
650 short param
651 , const string_type::value_type* values
652 , std::size_t length
653 , std::size_t elements
654 , const string_type::value_type* null_sentry
655 , param_direction direction = PARAM_IN);
656
659 template<std::size_t N, std::size_t M>
660 void bind_strings(
661 short param
662 , const string_type::value_type(&values)[N][M]
663 , const string_type::value_type* null_sentry
664 , param_direction direction = PARAM_IN)
665 {
666 bind_strings(
667 param
668 , reinterpret_cast<const string_type::value_type*>(values)
669 , M
670 , N
671 , null_sentry
672 , direction);
673 }
674
677 void bind_strings(
678 short param
679 , const string_type::value_type* values
680 , std::size_t length
681 , std::size_t elements
682 , const bool* nulls
683 , param_direction direction = PARAM_IN);
684
687 template<std::size_t N, std::size_t M>
688 void bind_strings(
689 short param
690 , const string_type::value_type(&values)[N][M]
691 , const bool* nulls
692 , param_direction direction = PARAM_IN)
693 {
694 bind_strings(
695 param
696 , reinterpret_cast<const string_type::value_type*>(values)
697 , M
698 , N
699 , nulls
700 , direction);
701 }
702
704
715 void bind_null(short param, std::size_t elements = 1);
716
718
719private:
720 typedef std::function<bool (std::size_t)> null_predicate_type;
721
722private:
723 class statement_impl;
724 friend class nanodbc::result;
725
726private:
727 std::shared_ptr<statement_impl> impl_;
728};
729
730// .d8888b. 888 d8b
731// d88P Y88b 888 Y8P
732// 888 888 888
733// 888 .d88b. 88888b. 88888b. .d88b. .d8888b 888888 888 .d88b. 88888b.
734// 888 d88""88b 888 "88b 888 "88b d8P Y8b d88P" 888 888 d88""88b 888 "88b
735// 888 888 888 888 888 888 888 888 88888888 888 888 888 888 888 888 888
736// Y88b d88P Y88..88P 888 888 888 888 Y8b. Y88b. Y88b. 888 Y88..88P 888 888
737// "Y8888P" "Y88P" 888 888 888 888 "Y8888 "Y8888P "Y888 888 "Y88P" 888 888
738// MARK: Connection -
739
741class connection
742{
743public:
745 connection();
746
748 connection(const connection& rhs);
749
750 #ifndef NANODBC_NO_MOVE_CTOR
752 connection(connection&& rhs) NANODBC_NOEXCEPT;
753 #endif
754
756 connection& operator=(connection rhs);
757
759 void swap(connection&) NANODBC_NOEXCEPT;
760
768 connection(
769 const string_type& dsn
770 , const string_type& user
771 , const string_type& pass
772 , long timeout = 0);
773
779 connection(const string_type& connection_string, long timeout = 0);
780
785 ~connection() NANODBC_NOEXCEPT;
786
794 void connect(
795 const string_type& dsn
796 , const string_type& user
797 , const string_type& pass
798 , long timeout = 0);
799
805 void connect(const string_type& connection_string, long timeout = 0);
806
820 void async_connect(
821 const string_type& dsn
822 , const string_type& user
823 , const string_type& pass
824 , void* event_handle
825 , long timeout = 0);
826
838 void async_connect(const string_type& connection_string, void* event_handle, long timeout = 0);
839
841 void async_complete();
842
844 bool connected() const;
845
847 void disconnect();
848
850 std::size_t transactions() const;
851
853 void* native_dbc_handle() const;
854
856 void* native_env_handle() const;
857
861 string_type dbms_name() const;
862
866 string_type dbms_version() const;
867
870 string_type driver_name() const;
871
874 string_type database_name() const;
875
878 string_type catalog_name() const;
879
880private:
881 std::size_t ref_transaction();
882 std::size_t unref_transaction();
883 bool rollback() const;
884 void rollback(bool onoff);
885
886private:
887 class connection_impl;
888 friend class nanodbc::transaction::transaction_impl;
889
890private:
891 std::shared_ptr<connection_impl> impl_;
892};
893
894// 8888888b. 888 888
895// 888 Y88b 888 888
896// 888 888 888 888
897// 888 d88P .d88b. .d8888b 888 888 888 888888
898// 8888888P" d8P Y8b 88K 888 888 888 888
899// 888 T88b 88888888 "Y8888b. 888 888 888 888
900// 888 T88b Y8b. X88 Y88b 888 888 Y88b.
901// 888 T88b "Y8888 88888P' "Y88888 888 "Y888
902// MARK: Result -
903
904class catalog;
905
910class result
911{
912public:
914 result();
915
917 ~result() NANODBC_NOEXCEPT;
918
920 result(const result& rhs);
921
922 #ifndef NANODBC_NO_MOVE_CTOR
924 result(result&& rhs) NANODBC_NOEXCEPT;
925 #endif
926
928 result& operator=(result rhs);
929
931 void swap(result& rhs) NANODBC_NOEXCEPT;
932
934 void* native_statement_handle() const;
935
937 long rowset_size() const NANODBC_NOEXCEPT;
938
941 long affected_rows() const;
942
944 long rows() const NANODBC_NOEXCEPT;
945
948 short columns() const;
949
953 bool first();
954
958 bool last();
959
963 bool next();
964
968 bool prior();
969
973 bool move(long row);
974
978 bool skip(long rows);
979
981 unsigned long position() const;
982
984 bool end() const NANODBC_NOEXCEPT;
985
992 template<class T>
993 void get_ref(short column, T& result) const;
994
1003 template<class T>
1004 void get_ref(short column, const T& fallback, T& result) const;
1005
1011 template<class T>
1012 void get_ref(const string_type& column_name, T& result) const;
1013
1021 template<class T>
1022 void get_ref(const string_type& column_name, const T& fallback, T& result) const;
1023
1029 template<class T>
1030 T get(short column) const;
1031
1039 template<class T>
1040 T get(short column, const T& fallback) const;
1041
1046 template<class T>
1047 T get(const string_type& column_name) const;
1048
1055 template<class T>
1056 T get(const string_type& column_name, const T& fallback) const;
1057
1070 bool is_null(short column) const;
1071
1078 bool is_null(const string_type& column_name) const;
1079
1085 string_type column_name(short column) const;
1086
1092 long column_size(short column) const;
1093
1099 short column(const string_type& column_name) const;
1100
1102 int column_datatype(short column) const;
1103
1105 int column_datatype(const string_type& column_name) const;
1106
1108 int column_c_datatype(short column) const;
1109
1111 int column_c_datatype(const string_type& column_name) const;
1112
1114 bool next_result();
1115
1117 explicit operator bool() const;
1118
1119private:
1120 result(statement statement, long rowset_size);
1121
1122private:
1123 class result_impl;
1124 friend class nanodbc::statement::statement_impl;
1125 friend class nanodbc::catalog;
1126
1127private:
1128 std::shared_ptr<result_impl> impl_;
1129};
1130
1131
1132//
1133// .d8888b. 888 888
1134// d88P Y88b 888 888
1135// 888 888 888 888
1136// 888 8888b. 888888 8888b. 888 .d88b. .d88b.
1137// 888 "88b 888 "88b 888 d88""88b d88P"88b
1138// 888 888 .d888888 888 .d888888 888 888 888 888 888
1139// Y88b d88P 888 888 Y88b. 888 888 888 Y88..88P Y88b 888
1140// "Y8888P" "Y888888 "Y888 "Y888888 888 "Y88P" "Y88888
1141// 888
1142// Y8b d88P
1143// "Y88P"
1144// MARK: Catalog -
1145
1146class catalog
1147{
1148public:
1149
1150 class tables
1151 {
1152 public:
1153 bool next();
1154 string_type table_catalog() const;
1155 string_type table_schema() const;
1156 string_type table_name() const;
1157 string_type table_type() const;
1158 string_type table_remarks() const;
1159
1160 private:
1161 friend class nanodbc::catalog;
1162 tables(result& find_result);
1163 result result_;
1164 };
1165
1166 class columns
1167 {
1168 public:
1169
1171 bool next();
1172
1174 string_type table_catalog() const;
1175
1177 string_type table_schema() const;
1178
1180 string_type table_name() const;
1181
1183 string_type column_name() const;
1184
1186 short data_type() const;
1187
1189 string_type type_name() const;
1190
1192 long column_size() const;
1193
1195 long buffer_length() const;
1196
1198 short decimal_digits() const;
1199
1201 short numeric_precision_radix() const;
1202
1204 short nullable() const;
1205
1207 string_type remarks() const;
1208
1210 string_type column_default() const;
1211
1213 short sql_data_type() const;
1214
1216 short sql_datetime_subtype() const;
1217
1219 long char_octed_length() const;
1220
1224 long ordinal_position() const;
1225
1226 string_type is_nullable() const;
1227
1228 private:
1229 friend class nanodbc::catalog;
1230 columns(result& find_result);
1231 result result_;
1232 };
1233
1234 class primary_keys
1235 {
1236 public:
1237 bool next();
1238 string_type table_catalog() const;
1239 string_type table_schema() const;
1240 string_type table_name() const;
1241 string_type column_name() const;
1242
1245 short column_number() const;
1246
1250 string_type primary_key_name() const;
1251
1252 private:
1253 friend class nanodbc::catalog;
1254 primary_keys(result& find_result);
1255 result result_;
1256 };
1257
1259 catalog(connection& conn);
1260
1267 catalog::tables find_tables(
1268 const string_type& table = string_type()
1269 , const string_type& type = string_type()
1270 , const string_type& schema = string_type()
1271 , const string_type& catalog = string_type());
1272
1279 catalog::columns find_columns(
1280 const string_type& column = string_type()
1281 , const string_type& table = string_type()
1282 , const string_type& schema = string_type()
1283 , const string_type& catalog = string_type());
1284
1290 catalog::primary_keys find_primary_keys(
1291 const string_type& table
1292 , const string_type& schema = string_type()
1293 , const string_type& catalog = string_type());
1294
1295private:
1296 connection conn_;
1297};
1298
1300
1301// 8888888888 8888888888 888 d8b
1302// 888 888 888 Y8P
1303// 888 888 888
1304// 8888888 888d888 .d88b. .d88b. 8888888 888 888 88888b. .d8888b 888888 888 .d88b. 88888b. .d8888b
1305// 888 888P" d8P Y8b d8P Y8b 888 888 888 888 "88b d88P" 888 888 d88""88b 888 "88b 88K
1306// 888 888 88888888 88888888 888 888 888 888 888 888 888 888 888 888 888 888 "Y8888b.
1307// 888 888 Y8b. Y8b. 888 Y88b 888 888 888 Y88b. Y88b. 888 Y88..88P 888 888 X88
1308// 888 888 "Y8888 "Y8888 888 "Y88888 888 888 "Y8888P "Y888 888 "Y88P" 888 888 88888P'
1309// MARK: Free Functions -
1310
1315
1324result execute(
1325 connection& conn
1326 , const string_type& query
1327 , long batch_operations = 1
1328 , long timeout = 0);
1329
1338void just_execute(
1339 connection& conn
1340 , const string_type& query
1341 , long batch_operations = 1
1342 , long timeout = 0);
1343
1351result execute(statement& stmt, long batch_operations = 1);
1352
1360void just_execute(statement& stmt, long batch_operations = 1);
1361
1369result transact(statement& stmt, long batch_operations);
1370
1378void just_transact(statement& stmt, long batch_operations);
1379
1387void prepare(statement& stmt, const string_type& query, long timeout = 0);
1388
1390
1391} // namespace nanodbc
1392
1393#endif // NANODBC_H
1394
1395#endif // _ODBC
1396
1397#endif // DOXYGEN_SHOULD_SKIP_THIS
void swap(RefPtr< Val > &ptr1, RefPtr< Val > &ptr2)
Swap the contents of two RefPtr.
Definition refPtr_tpl.h:269