nanodbc
A small C++ wrapper for the native C ODBC API
Loading...
Searching...
No Matches
nanodbc.h
Go to the documentation of this file.
1
2
76
77#ifndef NANODBC_NANODBC_H
78#define NANODBC_NANODBC_H
79
80#include <cstddef>
81#include <cstdint>
82#include <exception>
83#include <functional>
84#include <iterator>
85#include <list>
86#include <memory>
87#include <stdexcept>
88#include <string>
89#include <type_traits>
90#include <utility>
91#include <vector>
92
93#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
94#define NANODBC_HAS_STD_STRING_VIEW
95#include <optional>
96#define NANODBC_HAS_STD_OPTIONAL
97#include <variant>
98#define NANODBC_HAS_STD_VARIANT
99#endif
100
107namespace nanodbc
108{
109
110// clang-format off
111// .d8888b. .d888 d8b 888 d8b
112// d88P Y88b d88P" Y8P 888 Y8P
113// 888 888 888 888
114// 888 .d88b. 88888b. 888888 888 .d88b. 888 888 888d888 8888b. 888888 888 .d88b. 88888b.
115// 888 d88""88b 888 "88b 888 888 d88P"88b 888 888 888P" "88b 888 888 d88""88b 888 "88b
116// 888 888 888 888 888 888 888 888 888 888 888 888 888 .d888888 888 888 888 888 888 888
117// Y88b d88P Y88..88P 888 888 888 888 Y88b 888 Y88b 888 888 888 888 Y88b. 888 Y88..88P 888 888
118// "Y8888P" "Y88P" 888 888 888 888 "Y88888 "Y88888 888 "Y888888 "Y888 888 "Y88P" 888 888
119// 888
120// Y8b d88P
121// "Y88P"
122// MARK: Configuration -
123// clang-format on
124
129#ifdef DOXYGEN
130
136#define NANODBC_THROW_NO_SOURCE_LOCATION 1
137
152#define NANODBC_ASSERT(expression) assert(expression)
153
154#endif
156
157// You must explicitly request Unicode support by defining NANODBC_ENABLE_UNICODE at compile time.
158#ifndef DOXYGEN
159#ifdef NANODBC_ENABLE_UNICODE
160#ifdef NANODBC_USE_IODBC_WIDE_STRINGS
161#define NANODBC_TEXT(s) U##s
162typedef std::u32string string;
163#ifdef NANODBC_HAS_STD_STRING_VIEW
164typedef std::u32string_view string_view;
165#endif
166#else
167#ifdef _MSC_VER
168typedef std::wstring string;
169#ifdef NANODBC_HAS_STD_STRING_VIEW
170typedef std::wstring_view string_view;
171#endif
172#define NANODBC_TEXT(s) L##s
173#else
174typedef std::u16string string;
175#ifdef NANODBC_HAS_STD_STRING_VIEW
176typedef std::u16string_view string_view;
177#endif
178#define NANODBC_TEXT(s) u##s
179#endif
180#endif
181#else
182typedef std::string string;
183#ifdef NANODBC_HAS_STD_STRING_VIEW
184typedef std::string_view string_view;
185#endif
186#define NANODBC_TEXT(s) s
187#endif
188
189#ifdef NANODBC_USE_IODBC_WIDE_STRINGS
190typedef std::u32string wide_string;
191#ifdef NANODBC_HAS_STD_STRING_VIEW
192typedef std::u32string_view wide_string_view;
193#endif
194#else
195#ifdef _MSC_VER
196typedef std::wstring wide_string;
197#ifdef NANODBC_HAS_STD_STRING_VIEW
198typedef std::wstring_view wide_string_view;
199#endif
200#else
201typedef std::u16string wide_string;
202#ifdef NANODBC_HAS_STD_STRING_VIEW
203typedef std::u16string_view wide_string_view;
204#endif
205#endif
206#endif
207
208typedef wide_string::value_type wide_char_t;
209
210#if defined(_WIN64)
211// LLP64 machine: Windows
212typedef std::int64_t null_type;
213#elif !defined(_WIN64) && defined(__LP64__)
214// LP64 machine: OS X or Linux
215typedef long null_type;
216#else
217// 32-bit machine
218typedef long null_type;
219#endif
220#else
230#define NANODBC_TEXT(s) s
231
236typedef unspecified - type string;
238typedef unspecified - type null_type;
239#endif
240
243#define NANODBC_DEPRECATED [[deprecated]]
244
245// forward declare
246#ifndef NANODBC_DISABLE_MSSQL_TVP
247class table_valued_parameter;
248#endif
249class statement;
250class connection;
251class transaction;
252class catalog;
253class result;
254
255// clang-format off
256// 8888888888 888 888 888 888 d8b
257// 888 888 888 888 888 Y8P
258// 888 888 888 888 888
259// 8888888 888d888 888d888 .d88b. 888d888 8888888888 8888b. 88888b. .d88888 888 888 88888b. .d88b.
260// 888 888P" 888P" d88""88b 888P" 888 888 "88b 888 "88b d88" 888 888 888 888 "88b d88P"88b
261// 888 888 888 888 888 888 888 888 .d888888 888 888 888 888 888 888 888 888 888 888
262// 888 888 888 Y88..88P 888 888 888 888 888 888 888 Y88b 888 888 888 888 888 Y88b 888
263// 8888888888 888 888 "Y88P" 888 888 888 "Y888888 888 888 "Y88888 888 888 888 888 "Y88888
264// 888
265// Y8b d88P
266// "Y88P"
267// MARK: Error Handling -
268// clang-format on
269
279
282class type_incompatible_error : public std::runtime_error
283{
284public:
286
288 char const* what() const noexcept override;
289};
290
293class null_access_error : public std::runtime_error
294{
295public:
297
299 char const* what() const noexcept override;
300};
301
304class index_range_error : public std::runtime_error
305{
306public:
308
310 char const* what() const noexcept override;
311};
312
315class programming_error : public std::runtime_error
316{
317public:
320 explicit programming_error(std::string const& info);
321
323 char const* what() const noexcept override;
324};
325
328class database_error : public std::runtime_error
329{
330public:
335 database_error(void* handle, short handle_type, std::string const& info = "");
336
338 char const* what() const noexcept override;
339
341 long native() const noexcept;
342
344 std::string const& state() const noexcept;
345
346private:
347 long native_error;
348 std::string sql_state;
349 std::string message;
350};
351
353
354// clang-format off
355// 888 888 888 d8b 888 d8b 888 d8b
356// 888 888 888 Y8P 888 Y8P 888 Y8P
357// 888 888 888 888 888
358// 888 888 888888 888 888 888 888888 888 .d88b. .d8888b
359// 888 888 888 888 888 888 888 888 d8P Y8b 88K
360// 888 888 888 888 888 888 888 888 88888888 "Y8888b.
361// Y88b. .d88P Y88b. 888 888 888 Y88b. 888 Y8b. X88
362// "Y88888P" "Y888 888 888 888 "Y888 888 "Y8888 88888P'
363// MARK: Utilities -
364// clang-format on
365
370
374{
377
379 batch_ops() noexcept
380 : parameter_array_length(-1L)
381 , rowset_size(-1L) {};
382
385 batch_ops(const long all_length) noexcept
386 : parameter_array_length(all_length)
387 , rowset_size(all_length) {};
388};
389
391struct date
392{
393 std::int16_t year;
394 std::int16_t month;
395 std::int16_t day;
396};
397
399struct time
400{
401 std::int16_t hour;
402 std::int16_t min;
403 std::int16_t sec;
404};
405
408{
409 std::int16_t year;
410 std::int16_t month;
411 std::int16_t day;
412 std::int16_t hour;
413 std::int16_t min;
414 std::int16_t sec;
415 std::int32_t fract;
416};
417
420{
422 std::int16_t offset_hour;
423 std::int16_t offset_minute;
424};
425
426#ifdef NANODBC_HAS_STD_VARIANT
431// `SQLSetConnectAttr`, or `SQLSetStmtAttr`. The second is the StringLength,
432// and the third is used to inform the ValuePtr argument. This argument,
438class attribute
439{
440public:
441#ifdef NANODBC_ENABLE_UNICODE
442 typedef std::variant<std::vector<uint8_t>, string, std::string, std::intptr_t, std::uintptr_t>
443 variant;
444#else
445 typedef std::variant<std::vector<uint8_t>, string, std::intptr_t, std::uintptr_t> variant;
446#endif
447 attribute() = delete;
448 attribute& operator=(attribute const&) = delete;
449
451 attribute(attribute const& other) noexcept;
452
457 attribute(long const& attribute, long const& string_length, variant const& resource) noexcept;
458
459protected:
461 void extractValuePtr();
462
463 long attribute_;
464 long string_length_;
465 variant resource_;
466 void* value_ptr_;
467};
468#else
476{
477public:
482 attribute(long const& attribute, long const& string_length, std::uintptr_t value_ptr) noexcept
483 : attribute_(attribute)
484 , string_length_(string_length)
485 , value_ptr_((void*)value_ptr) {};
486
487protected:
491};
492#endif
493
496template <typename T>
497using is_string = std::integral_constant<
498 bool,
499 std::is_same<typename std::decay<T>::type, std::string>::value ||
500 std::is_same<typename std::decay<T>::type, wide_string>::value
501#ifdef NANODBC_HAS_STD_STRING_VIEW
502 || std::is_same<typename std::decay<T>::type, std::string_view>::value ||
503 std::is_same<typename std::decay<T>::type, wide_string_view>::value
504#endif
505 >;
506
509template <typename T>
510using is_character = std::integral_constant<
511 bool,
512 std::is_same<typename std::decay<T>::type, std::string::value_type>::value ||
513 std::is_same<typename std::decay<T>::type, wide_char_t>::value>;
514
516template <typename T>
517using enable_if_string = typename std::enable_if<is_string<T>::value>::type;
518
520template <typename T>
521using enable_if_character = typename std::enable_if<is_character<T>::value>::type;
522
524
529
530// clang-format off
531// 88888888888 888 d8b
532// 888 888 Y8P
533// 888 888
534// 888 888d888 8888b. 88888b. .d8888b 8888b. .d8888b 888888 888 .d88b. 88888b.
535// 888 888P" "88b 888 "88b 88K "88b d88P" 888 888 d88""88b 888 "88b
536// 888 888 .d888888 888 888 "Y8888b. .d888888 888 888 888 888 888 888 888
537// 888 888 888 888 888 888 X88 888 888 Y88b. Y88b. 888 Y88..88P 888 888
538// 888 888 "Y888888 888 888 88888P' "Y888888 "Y8888P "Y888 888 "Y88P" 888 888
539// MARK: Transaction -
540// clang-format on
541
546{
547public:
551 explicit transaction(const class connection& conn);
552
554 transaction(const transaction& rhs) noexcept;
555
557 transaction(transaction&& rhs) noexcept;
558
561
563 void swap(transaction& rhs) noexcept;
564
566 ~transaction() noexcept;
567
570 void commit();
571
573 void rollback() noexcept;
574
576 class connection& connection() noexcept;
577
579 const class connection& connection() const noexcept;
580
582 operator class connection &() noexcept;
583
585 operator const class connection &() const noexcept;
586
587private:
588 class transaction_impl;
589 friend class nanodbc::connection;
590
591private:
592 std::shared_ptr<transaction_impl> impl_;
593};
594
595// clang-format off
596// 888b d888 .d8888b. .d8888b. .d88888b. 888 88888888888 888 888 8888888b.
597// 8888b d8888 d88P Y88b d88P Y88b d88P" "Y88b 888 888 888 888 888 Y88b
598// 88888b.d88888 Y88b. Y88b. 888 888 888 888 888 888 888 888
599// 888Y88888P888 "Y888b. "Y888b. 888 888 888 888 Y88b d88P 888 d88P
600// 888 Y888P 888 "Y88b. "Y88b. 888 888 888 888 Y88b d88P 8888888P"
601// 888 Y8P 888 "888 "888 888 Y8b 888 888 888888 888 Y88o88P 888
602// 888 " 888 Y88b d88P Y88b d88P Y88b.Y8b88P 888 888 Y888P 888
603// 888 888 "Y8888P" "Y8888P" "Y888888" 88888888 888 Y8P 888
604// Y8b
605// MARK: MSSQL - TVP (Table Valued Parameters) -
606// clang-format on
607#ifndef NANODBC_DISABLE_MSSQL_TVP
610{
611public:
614
617
620
623 table_valued_parameter(statement& stmt, short param_index, size_t row_count);
624
627
637 void open(statement& stmt, short param_index, std::size_t row_count);
638
641 void close();
642
662
665 template <class T>
666 void bind(short param_index, T const* values, std::size_t batch_size);
667
670 template <class T>
671 void bind(short param_index, T const* values, std::size_t batch_size, T const* null_sentry);
672
675 template <class T>
676 void bind(short param_index, T const* values, std::size_t batch_size, bool const* nulls);
677
680 void bind(short param_index, std::vector<std::vector<uint8_t>> const& values);
681
684 void
685 bind(short param_index, std::vector<std::vector<uint8_t>> const& values, bool const* nulls);
686
689 void bind(
690 short param_index,
691 std::vector<std::vector<uint8_t>> const& values,
692 uint8_t const* null_sentry);
693
695
715
718 template <class T, typename = enable_if_character<T>>
719 void bind_strings(
720 short param_index,
721 T const* values,
722 std::size_t value_size,
723 std::size_t batch_size);
724
731 template <class T, typename = enable_if_string<T>>
732 void bind_strings(short param_index, std::vector<T> const& values);
733
736 template <
737 std::size_t BatchSize,
738 std::size_t ValueSize,
739 class T,
740 typename = enable_if_character<T>>
741 void bind_strings(short param_index, T const (&values)[BatchSize][ValueSize])
742 {
743 auto param_values = reinterpret_cast<T const*>(values);
744 bind_strings(param_index, param_values, ValueSize, BatchSize);
745 }
746
749 template <class T, typename = enable_if_character<T>>
751 short param_index,
752 T const* values,
753 std::size_t value_size,
754 std::size_t batch_size,
755 T const* null_sentry);
756
759 template <class T, typename = enable_if_string<T>>
761 short param_index,
762 std::vector<T> const& values,
763 typename T::value_type const* null_sentry);
764
767 template <
768 std::size_t BatchSize,
769 std::size_t ValueSize,
770 class T,
771 typename = enable_if_character<T>>
772 void
773 bind_strings(short param_index, T const (&values)[BatchSize][ValueSize], T const* null_sentry)
774 {
775 auto param_values = reinterpret_cast<T const*>(values);
776 bind_strings(param_index, param_values, ValueSize, BatchSize, nullptr, null_sentry);
777 }
778
781 template <class T, typename = enable_if_character<T>>
783 short param_index,
784 T const* values,
785 std::size_t value_size,
786 std::size_t batch_size,
787 bool const* nulls);
788
791 template <class T, typename = enable_if_string<T>>
792 void bind_strings(short param_index, std::vector<T> const& values, bool const* nulls);
793
796 template <
797 std::size_t BatchSize,
798 std::size_t ValueSize,
799 class T,
800 typename = enable_if_character<T>>
801 void bind_strings(short param_index, T const (&values)[BatchSize][ValueSize], bool const* nulls)
802 {
803 auto param_values = reinterpret_cast<T const*>(values);
804 bind_strings(param_index, param_values, ValueSize, BatchSize, nulls);
805 }
806
808
812 void bind_null(short param_index);
813
825 const std::vector<short>& idx,
826 const std::vector<short>& type,
827 const std::vector<unsigned long>& size,
828 const std::vector<short>& scale);
829
831 short parameters() const noexcept;
832
834 unsigned long parameter_size(short param_index) const;
835
837 short parameter_scale(short param_index) const;
838
840 short parameter_type(short param_index) const;
841
842private:
843 class table_valued_parameter_impl;
844 friend class statement;
845
846private:
847 std::shared_ptr<table_valued_parameter_impl> impl_;
848};
849#endif // NANODBC_DISABLE_MSSQL_TVP
850
851// clang-format off
852// .d8888b. 888 888 888
853// d88P Y88b 888 888 888
854// Y88b. 888 888 888
855// "Y888b. 888888 8888b. 888888 .d88b. 88888b.d88b. .d88b. 88888b. 888888
856// "Y88b. 888 "88b 888 d8P Y8b 888 "888 "88b d8P Y8b 888 "88b 888
857// "888 888 .d888888 888 88888888 888 888 888 88888888 888 888 888
858// Y88b d88P Y88b. 888 888 Y88b. Y8b. 888 888 888 Y8b. 888 888 Y88b.
859// "Y8888P" "Y888 "Y888888 "Y888 "Y8888 888 888 888 "Y8888 888 888 "Y888
860// MARK: Statement -
861// clang-format on
862
865{
866
867private:
868 class statement_impl;
869
870#ifdef NANODBC_HAS_STD_VARIANT
871public:
872 class attribute : public nanodbc::attribute
873 {
874 public:
875 attribute(attribute const& other) noexcept
876 : nanodbc::attribute(other) {};
877 attribute(
878 long const& attribute,
879 long const& string_length,
880 variant const& resource) noexcept
881 : nanodbc::attribute(attribute, string_length, resource) {};
882
883 private:
884 friend class nanodbc::statement::statement_impl;
885 };
886#else
887public:
889 {
890 public:
891 attribute(
892 long const& attribute,
893 long const& string_length,
894 std::uintptr_t value_ptr) noexcept
895 : nanodbc::attribute(attribute, string_length, value_ptr) {};
896
897 private:
898 friend class nanodbc::statement::statement_impl;
899 };
900#endif
901
902public:
913
914public:
918
922 explicit statement(class connection& conn);
923
929 explicit statement(class connection& conn, std::list<attribute> const& attributes);
930
936 statement(class connection& conn, string const& query, long timeout = 0);
937
939 statement(const statement& rhs) noexcept;
940
942 statement(statement&& rhs) noexcept;
943
946
948 void swap(statement& rhs) noexcept;
949
952 ~statement() noexcept;
953
957 void open(class connection& conn);
958
960 bool open() const noexcept;
961
963 bool connected() const noexcept;
964
966 class connection& connection() noexcept;
967
969 const class connection& connection() const noexcept;
970
972 void* native_statement_handle() const noexcept;
973
975 void close();
976
979 void cancel();
980
987 void prepare(class connection& conn, string const& query, long timeout = 0);
988
996 void prepare(string const& query, long timeout = 0);
997
1000 void timeout(long timeout = 0);
1001
1012 class result execute_direct(
1013 class connection& conn,
1014 string const& query,
1015 long batch_operations = 1,
1016 long timeout = 0);
1017
1028 class result execute_direct(
1029 class connection& conn,
1030 string const& query,
1031 batch_ops const& array_sizes,
1032 long timeout = 0);
1033
1034#if !defined(NANODBC_DISABLE_ASYNC)
1051 bool async_prepare(string const& query, void* event_handle, long timeout = 0);
1052
1065
1086 class connection& conn,
1087 void* event_handle,
1088 string const& query,
1089 long batch_operations = 1,
1090 long timeout = 0);
1091
1109 bool async_execute(void* event_handle, long batch_operations = 1, long timeout = 0);
1110
1124 class result complete_execute(long batch_operations = 1);
1125
1127 void enable_async(void* event_handle);
1128
1130 void disable_async() const;
1131#endif
1132
1143 class connection& conn,
1144 string const& query,
1145 long batch_operations = 1,
1146 long timeout = 0);
1147
1156 class result execute(long batch_operations = 1, long timeout = 0);
1157
1172 class result execute(batch_ops const& array_sizes, long timeout = 0);
1173
1181 void just_execute(long batch_operations = 1, long timeout = 0);
1182
1190 class result procedure_columns(
1191 string const& catalog,
1192 string const& schema,
1193 string const& procedure,
1194 string const& column);
1195
1198 long affected_rows() const;
1199
1202 short columns() const;
1203
1205 void reset_parameters() noexcept;
1206
1209 short parameters() const;
1210
1212 unsigned long parameter_size(short param_index) const;
1213
1215 short parameter_scale(short param_index) const;
1216
1218 short parameter_type(short param_index) const;
1219
1242
1255 template <class T>
1256 void bind(short param_index, T const* value, param_direction direction = PARAM_IN);
1257
1276
1279 template <class T>
1280 void bind(
1281 short param_index,
1282 T const* values,
1283 std::size_t batch_size,
1284 param_direction direction = PARAM_IN);
1285
1288 template <class T>
1289 void bind(
1290 short param_index,
1291 T const* values,
1292 std::size_t batch_size,
1293 T const* null_sentry,
1294 param_direction direction = PARAM_IN);
1295
1298 template <class T>
1299 void bind(
1300 short param_index,
1301 T const* values,
1302 std::size_t batch_size,
1303 bool const* nulls,
1304 param_direction direction = PARAM_IN);
1305
1308 void bind(
1309 short param_index,
1310 std::vector<std::vector<uint8_t>> const& values,
1311 param_direction direction = PARAM_IN);
1312
1315 void bind(
1316 short param_index,
1317 std::vector<std::vector<uint8_t>> const& values,
1318 bool const* nulls,
1319 param_direction direction = PARAM_IN);
1320
1323 void bind(
1324 short param_index,
1325 std::vector<std::vector<uint8_t>> const& values,
1326 uint8_t const* null_sentry,
1327 param_direction direction = PARAM_IN);
1328
1335 template <class T>
1336 void
1337 bind(short param_index, std::vector<T> const& values, param_direction direction = PARAM_IN);
1338
1341 template <class T>
1342 void bind(
1343 short param_index,
1344 std::vector<T> const& values,
1345 bool const* nulls,
1346 param_direction direction = PARAM_IN);
1347
1349
1370
1373 template <class T, typename = enable_if_character<T>>
1374 void bind_strings(
1375 short param_index,
1376 T const* values,
1377 std::size_t value_size,
1378 std::size_t batch_size,
1379 param_direction direction = PARAM_IN);
1380
1387 template <class T, typename = enable_if_string<T>>
1388 void bind_strings(
1389 short param_index,
1390 std::vector<T> const& values,
1391 param_direction direction = PARAM_IN);
1392
1395 template <
1396 std::size_t BatchSize,
1397 std::size_t ValueSize,
1398 class T,
1399 typename = enable_if_character<T>>
1400 void bind_strings(
1401 short param_index,
1402 T const (&values)[BatchSize][ValueSize],
1403 param_direction direction = PARAM_IN)
1404 {
1405 auto param_values = reinterpret_cast<T const*>(values);
1406 bind_strings(param_index, param_values, ValueSize, BatchSize, direction);
1407 }
1408
1411 template <class T, typename = enable_if_character<T>>
1413 short param_index,
1414 T const* values,
1415 std::size_t value_size,
1416 std::size_t batch_size,
1417 T const* null_sentry,
1418 param_direction direction = PARAM_IN);
1419
1422 template <class T, typename = enable_if_string<T>>
1424 short param_index,
1425 std::vector<T> const& values,
1426 typename T::value_type const* null_sentry,
1427 param_direction direction = PARAM_IN);
1428
1431 template <
1432 std::size_t BatchSize,
1433 std::size_t ValueSize,
1434 class T,
1435 typename = enable_if_character<T>>
1437 short param_index,
1438 T const (&values)[BatchSize][ValueSize],
1439 T const* null_sentry,
1440 param_direction direction = PARAM_IN)
1441 {
1442 auto param_values = reinterpret_cast<T const*>(values);
1443 bind_strings(param_index, param_values, ValueSize, BatchSize, null_sentry, direction);
1444 }
1445
1448 template <class T, typename = enable_if_character<T>>
1450 short param_index,
1451 T const* values,
1452 std::size_t value_size,
1453 std::size_t batch_size,
1454 bool const* nulls,
1455 param_direction direction = PARAM_IN);
1456
1459 template <class T, typename = enable_if_string<T>>
1461 short param_index,
1462 std::vector<T> const& values,
1463 bool const* nulls,
1464 param_direction direction = PARAM_IN);
1465
1468 template <
1469 std::size_t BatchSize,
1470 std::size_t ValueSize,
1471 class T,
1472 typename = enable_if_character<T>>
1474 short param_index,
1475 T const (&values)[BatchSize][ValueSize],
1476 bool const* nulls,
1477 param_direction direction = PARAM_IN)
1478 {
1479 auto param_values = reinterpret_cast<T const*>(values);
1480 bind_strings(param_index, param_values, ValueSize, BatchSize, nulls, direction);
1481 }
1482
1484
1496 void bind_null(short param_index, std::size_t batch_size = 1);
1497
1499
1518 const std::vector<short>& idx,
1519 const std::vector<short>& type,
1520 const std::vector<unsigned long>& size,
1521 const std::vector<short>& scale);
1522
1523private:
1524 typedef std::function<bool(std::size_t)> null_predicate_type;
1525 friend class nanodbc::result;
1526#ifndef NANODBC_DISABLE_MSSQL_TVP
1527 friend class nanodbc::table_valued_parameter::table_valued_parameter_impl;
1528#endif
1529
1530private:
1531 std::shared_ptr<statement_impl> impl_;
1532};
1533
1534// clang-format off
1535// .d8888b. 888 d8b
1536// d88P Y88b 888 Y8P
1537// 888 888 888
1538// 888 .d88b. 88888b. 88888b. .d88b. .d8888b 888888 888 .d88b. 88888b.
1539// 888 d88""88b 888 "88b 888 "88b d8P Y8b d88P" 888 888 d88""88b 888 "88b
1540// 888 888 888 888 888 888 888 888 88888888 888 888 888 888 888 888 888
1541// Y88b d88P Y88..88P 888 888 888 888 Y8b. Y88b. Y88b. 888 Y88..88P 888 888
1542// "Y8888P" "Y88P" 888 888 888 888 "Y8888 "Y8888P "Y888 888 "Y88P" 888 888
1543// MARK: Connection -
1544// clang-format on
1545
1548{
1549
1550private:
1551 class connection_impl;
1552 friend class nanodbc::transaction::transaction_impl;
1553
1554#ifdef NANODBC_HAS_STD_VARIANT
1555public:
1556 class attribute : public nanodbc::attribute
1557 {
1558 public:
1559 attribute(attribute const& other) noexcept
1560 : nanodbc::attribute(other) {};
1561 attribute(
1562 long const& attribute,
1563 long const& string_length,
1564 variant const& resource) noexcept
1565 : nanodbc::attribute(attribute, string_length, resource) {};
1566
1567 private:
1568 friend class nanodbc::connection::connection_impl;
1569 };
1570#else
1571public:
1573 {
1574 public:
1575 attribute(
1576 long const& attribute,
1577 long const& string_length,
1578 std::uintptr_t value_ptr) noexcept
1579 : nanodbc::attribute(attribute, string_length, value_ptr) {};
1580
1581 private:
1582 friend class nanodbc::connection::connection_impl;
1583 };
1584#endif
1585public:
1588
1590 connection(const connection& rhs) noexcept;
1591
1593 connection(connection&& rhs) noexcept;
1594
1597
1599 void swap(connection&) noexcept;
1600
1611 connection(string const& dsn, string const& user, string const& pass, long timeout = 0);
1612
1622 explicit connection(string const& connection_string, long timeout = 0);
1623
1636
1638 string const& dsn,
1639 string const& user,
1640 string const& pass,
1641 std::list<attribute> const& attributes);
1652 connection(string const& connection_string, std::list<attribute> const& attributes);
1657 ~connection() noexcept;
1658
1667 void allocate();
1668
1671 void deallocate();
1672
1680 void connect(string const& dsn, string const& user, string const& pass, long timeout = 0);
1681
1687 void connect(string const& connection_string, long timeout = 0);
1688
1697 void connect(
1698 string const& dsn,
1699 string const& user,
1700 string const& pass,
1701 std::list<attribute> const& attributes);
1702
1709 void connect(string const& connection_string, std::list<attribute> const& attributes);
1710#if !defined(NANODBC_DISABLE_ASYNC)
1729 string const& dsn,
1730 string const& user,
1731 string const& pass,
1732 void* event_handle,
1733 long timeout = 0);
1734
1750 bool async_connect(string const& connection_string, void* event_handle, long timeout = 0);
1751
1757#endif
1758
1760 bool connected() const noexcept;
1761
1763 void disconnect();
1764
1766 std::size_t transactions() const noexcept;
1767
1769 void* native_dbc_handle() const noexcept;
1770
1772 void* native_env_handle() const noexcept;
1773
1777 template <class T>
1778 T get_info(short info_type) const;
1779
1783 string dbms_name() const;
1784
1788 string dbms_version() const;
1789
1792 string driver_name() const;
1793
1796 string driver_version() const;
1797
1800 string database_name() const;
1801
1804 string catalog_name() const;
1805
1806private:
1807 std::size_t ref_transaction() noexcept;
1808 std::size_t unref_transaction() noexcept;
1809 bool rollback() const noexcept;
1810 void rollback(bool onoff) noexcept;
1811
1812private:
1813 std::shared_ptr<connection_impl> impl_;
1814};
1815
1816// clang-format off
1817// 8888888b. 888 888
1818// 888 Y88b 888 888
1819// 888 888 888 888
1820// 888 d88P .d88b. .d8888b 888 888 888 888888
1821// 8888888P" d8P Y8b 88K 888 888 888 888
1822// 888 T88b 88888888 "Y8888b. 888 888 888 888
1823// 888 T88b Y8b. X88 Y88b 888 888 Y88b.
1824// 888 T88b "Y8888 88888P' "Y88888 888 "Y888
1825// MARK: Result -
1826// clang-format on
1827
1828class catalog;
1829class variant_row_cached_result;
1830
1836{
1837public:
1839 result() noexcept;
1840
1842 ~result() noexcept;
1843
1845 result(const result& rhs) noexcept;
1846
1848 result(result&& rhs) noexcept;
1849
1851 result& operator=(result rhs) noexcept;
1852
1854 void swap(result& rhs) noexcept;
1855
1857 void* native_statement_handle() const noexcept;
1858
1860 long rowset_size() const noexcept;
1861
1864 long affected_rows() const;
1865
1874 bool has_affected_rows() const;
1875
1877 long rows() const noexcept;
1878
1881 short columns() const;
1882
1886 bool first();
1887
1891 bool last();
1892
1896 bool next();
1897
1898#if !defined(NANODBC_DISABLE_ASYNC)
1903 bool async_next(void* event_handle);
1904
1909#endif
1910
1914 bool prior();
1915
1923 bool move(long row);
1924
1928 bool skip(long rows);
1929
1931 unsigned long position() const;
1932
1934 bool at_end() const noexcept;
1935
1941 void unbind();
1942
1950 void unbind(string const& column_name);
1951
1967 void unbind(short column);
1968
1985
1995 template <class T>
1996 void get_ref(short column, T& result) const;
1997
2009 template <class T>
2010 void get_ref(short column, T const& fallback, T& result) const;
2011
2020 template <class T>
2021 void get_ref(string const& column_name, T& result) const;
2022
2033 template <class T>
2034 void get_ref(string const& column_name, T const& fallback, T& result) const;
2035
2044 template <class T>
2045 T get(short column) const;
2046
2057 template <class T>
2058 T get(short column, T const& fallback) const;
2059
2067 template <class T>
2068 T get(string const& column_name) const;
2069
2079 template <class T>
2080 T get(string const& column_name, T const& fallback) const;
2081
2083
2105 bool is_null(short column) const;
2106
2114 bool is_null(string const& column_name) const;
2115
2126 bool is_bound(short column) const;
2127
2134 bool is_bound(string const& column_name) const;
2135
2141 short column(string const& column_name) const;
2142
2148 string column_name(short column) const;
2149
2155 long column_size(short column) const;
2156
2158 long column_size(string const& column_name) const;
2159
2168 int column_decimal_digits(short column) const;
2169
2171 int column_decimal_digits(string const& column_name) const;
2172
2174 int column_datatype(short column) const;
2175
2177 int column_datatype(string const& column_name) const;
2178
2186 string column_datatype_name(short column) const;
2187
2195 string column_datatype_name(string const& column_name) const;
2196
2198 int column_c_datatype(short column) const;
2199
2201 int column_c_datatype(string const& column_name) const;
2202
2210 bool column_unsigned(short column) const;
2211
2214 bool column_unsigned(string const& column_name) const;
2215
2217 bool next_result();
2218
2220 explicit operator bool() const noexcept;
2221
2222private:
2223 result(statement statement, long rowset_size);
2224
2225private:
2226 class result_impl;
2227 friend class nanodbc::statement::statement_impl;
2228 friend class nanodbc::catalog;
2229#ifdef _MSC_VER
2230 friend class nanodbc::variant_row_cached_result;
2231#endif
2232
2233private:
2234 std::shared_ptr<result_impl> impl_;
2235};
2236
2239{
2240public:
2241 typedef std::input_iterator_tag iterator_category;
2243 typedef result* pointer;
2245 typedef std::ptrdiff_t difference_type;
2246
2248 result_iterator() = default;
2249
2252 : result_(r)
2253 {
2254 ++(*this);
2255 }
2256
2258 reference operator*() noexcept { return result_; }
2259
2262 {
2263 if (!result_)
2264 throw std::runtime_error("result is empty");
2265 return &(operator*());
2266 }
2267
2270 {
2271 try
2272 {
2273 if (!result_.next())
2274 result_ = result();
2275 }
2276 catch (...)
2277 {
2278 result_ = result();
2279 }
2280 return *this;
2281 }
2282
2288 void operator++(int) { ++(*this); }
2289
2291 bool operator==(result_iterator const& rhs) const noexcept
2292 {
2293 if (result_ && rhs.result_)
2294 return result_.native_statement_handle() == rhs.result_.native_statement_handle();
2295 else
2296 return !result_ && !rhs.result_;
2297 }
2298
2300 bool operator!=(result_iterator const& rhs) const noexcept { return !(*this == rhs); }
2301
2302private:
2303 result result_;
2304};
2305
2308{
2309 return result_iterator(r);
2310}
2311
2318inline result_iterator end(result& /*r*/) noexcept
2319{
2320 return {};
2321}
2322
2323// clang-format off
2324// 8888888b. d8b 888
2325// 888 "Y88b Y8P 888
2326// 888 888 888
2327// 888 888 .d88b. .d8888b .d8888b 888d888 888 88888b. 888888 .d88b. 888d888 .d8888b
2328// 888 888 d8P Y8b 88K d88P" 888P" 888 888 "88b 888 d88""88b 888P" 88K
2329// 888 888 88888888 "Y8888b. 888 888 888 888 888 888 888 888 888 "Y8888b.
2330// 888 .d88P Y8b. X88 Y88b. 888 888 888 d88P Y88b. Y88..88P 888 X88
2331// 8888888P" "Y8888 88888P' "Y8888P 888 888 88888P" "Y888 "Y88P" 888 88888P'
2332// 888
2333// 888
2334// 888
2335// MARK: Descriptors -
2336// clang-format on
2337
2344{
2345public:
2348
2361
2363 auto alloc_type() const -> short;
2364
2366 auto count() const noexcept -> short;
2367
2368 // Descriptor record fields (records) accessors
2369
2371 auto auto_unique_value(short record) const -> bool;
2372
2374 auto base_column_name(short record) const -> string;
2375
2377 auto base_table_name(short record) const -> string;
2378
2380 auto case_sensitive(short record) const -> bool;
2381
2383 auto catalog_name(short record) const -> string;
2384
2386 auto concise_type(short record) const -> short;
2387
2389 auto display_size(short record) const -> std::int64_t;
2390
2392 auto fixed_prec_scale(short record) const -> short;
2393
2395 auto label(short record) const -> string;
2396
2398 auto length(short record) const -> std::uint64_t;
2399
2401 auto local_type_name(short record) const -> string;
2402
2404 auto name(short record) const -> string;
2405
2409 auto nullable(short record) const -> short;
2410
2412 auto num_prec_radix(short record) const -> short;
2413
2415 auto octet_length(short record) const -> std::int64_t;
2416
2418 auto precision(short record) const -> short;
2419
2421 auto rowver(short record) const -> short;
2422
2424 auto scale(short record) const -> short;
2425
2427 auto schema_name(short record) const -> string;
2428
2433 auto searchable(short record) const -> short;
2434
2436 auto table_name(short record) const -> string;
2437
2439 auto type(short record) const -> short;
2440
2442 auto type_name(short record) const -> string;
2443
2445 auto unnamed(short record) const -> bool;
2446
2448 auto unsigned_(short record) const -> bool;
2449
2454 auto updatable(short record) const -> short;
2455
2456private:
2457 // Convenience wrapper for SQLGetDescrField accesor.
2458 struct sql_get_descr_field
2459 {
2460 sql_get_descr_field(
2462 short record,
2463 std::uint16_t field_identifier) noexcept;
2464 operator std::int64_t() const;
2465 operator std::uint64_t() const;
2466 operator string() const;
2467
2469 short record_;
2470 std::uint16_t field_identifier_;
2471 };
2472 friend sql_get_descr_field;
2473
2474 void initialize_descriptor();
2475 void throw_if_record_is_out_of_range(short record) const;
2476
2477 void* statement_handle_{nullptr};
2478 short statement_columns_count_{0};
2479 void* descriptor_handle_{nullptr};
2480 short descriptor_records_count_{0};
2481};
2482
2483// clang-format off
2484//
2485// .d8888b. 888 888
2486// d88P Y88b 888 888
2487// 888 888 888 888
2488// 888 8888b. 888888 8888b. 888 .d88b. .d88b.
2489// 888 "88b 888 "88b 888 d88""88b d88P"88b
2490// 888 888 .d888888 888 .d888888 888 888 888 888 888
2491// Y88b d88P 888 888 Y88b. 888 888 888 Y88..88P Y88b 888
2492// "Y8888P" "Y888888 "Y888 "Y888888 888 "Y88P" "Y88888
2493// 888
2494// Y8b d88P
2495// "Y88P"
2496// MARK: Catalog -
2497// clang-format on
2498
2505{
2506public:
2509 {
2510 public:
2511 bool next();
2512 string table_catalog() const;
2513 string table_schema() const;
2514 string table_name() const;
2515 string table_type() const;
2516 string table_remarks() const;
2517
2518 private:
2519 friend class nanodbc::catalog;
2520 explicit tables(result& find_result) noexcept;
2521 result result_;
2522 };
2523
2526 {
2527 public:
2528 bool next();
2529 string table_catalog() const;
2530 string table_schema() const;
2531 string table_name() const;
2532 string column_name() const;
2533 short data_type() const;
2534 string type_name() const;
2535 long column_size() const;
2536 long buffer_length() const;
2537 short decimal_digits() const;
2539 short nullable() const;
2540 string remarks() const;
2541 string column_default() const;
2542 short sql_data_type() const;
2543 short sql_datetime_subtype() const;
2544 long char_octet_length() const;
2545
2549 long ordinal_position() const;
2550
2556 string is_nullable() const;
2557
2558 private:
2559 friend class nanodbc::catalog;
2560 explicit columns(result& find_result) noexcept;
2561 result result_;
2562 };
2563
2566 {
2567 public:
2568 bool next();
2569 string table_catalog() const;
2570 string table_schema() const;
2571 string table_name() const;
2572 string column_name() const;
2573
2576 short column_number() const;
2577
2581 string primary_key_name() const;
2582
2583 private:
2584 friend class nanodbc::catalog;
2585 explicit primary_keys(result& find_result) noexcept;
2586 result result_;
2587 };
2588
2591 {
2592 public:
2593 bool next();
2594 string table_catalog() const;
2595 string table_schema() const;
2596 string table_name() const;
2597 string grantor() const;
2598 string grantee() const;
2599 string privilege() const;
2601 string is_grantable() const;
2602
2603 private:
2604 friend class nanodbc::catalog;
2605 explicit table_privileges(result& find_result) noexcept;
2606 result result_;
2607 };
2608
2611 {
2612 public:
2613 bool next();
2614 string procedure_catalog() const;
2615 string procedure_schema() const;
2616 string procedure_name() const;
2617 string procedure_remarks() const;
2618 short procedure_type() const;
2619
2620 private:
2621 friend class nanodbc::catalog;
2622 explicit procedures(result& find_result) noexcept;
2623 result result_;
2624 };
2625
2628 {
2629 public:
2630 bool next();
2631 string procedure_catalog() const;
2632 string procedure_schema() const;
2633 string procedure_name() const;
2634 string column_name() const;
2635 short column_type() const;
2636 short data_type() const;
2637 string type_name() const;
2638 long column_size() const;
2639 long buffer_length() const;
2640 short decimal_digits() const;
2642 short nullable() const;
2643 string remarks() const;
2644 string column_default() const;
2645 short sql_data_type() const;
2646 short sql_datetime_subtype() const;
2647 long char_octet_length() const;
2648
2652 long ordinal_position() const;
2653
2659 string is_nullable() const;
2660
2661 private:
2662 friend class nanodbc::catalog;
2663 explicit procedure_columns(result& find_result) noexcept;
2664 result result_;
2665 };
2666
2668 explicit catalog(connection& conn) noexcept;
2669
2680 string const& table = string(),
2681 string const& type = string(),
2682 string const& schema = string(),
2683 string const& catalog = string());
2684
2699 string const& catalog,
2700 string const& table = string(),
2701 string const& schema = string());
2702
2713 string const& column = string(),
2714 string const& table = string(),
2715 string const& schema = string(),
2716 string const& catalog = string());
2717
2727 string const& table,
2728 string const& schema = string(),
2729 string const& catalog = string());
2730
2740
2742 string const& procedure = string(),
2743 string const& schema = string(),
2744 string const& catalog = string());
2745
2757 string const& column = string(),
2758 string const& procedure = string(),
2759 string const& schema = string(),
2760 string const& catalog = string());
2761
2765 std::list<string> list_catalogs();
2766
2770 std::list<string> list_schemas();
2771
2776 std::list<string> list_table_types();
2777
2778private:
2779 connection conn_;
2780};
2781
2783
2784// clang-format off
2785// 8888888888 8888888888 888 d8b
2786// 888 888 888 Y8P
2787// 888 888 888
2788// 8888888 888d888 .d88b. .d88b. 8888888 888 888 88888b. .d8888b 888888 888 .d88b. 88888b. .d8888b
2789// 888 888P" d8P Y8b d8P Y8b 888 888 888 888 "88b d88P" 888 888 d88""88b 888 "88b 88K
2790// 888 888 88888888 88888888 888 888 888 888 888 888 888 888 888 888 888 888 "Y8888b.
2791// 888 888 Y8b. Y8b. 888 Y88b 888 888 888 Y88b. Y88b. 888 Y88..88P 888 888 X88
2792// 888 888 "Y8888 "Y8888 888 "Y88888 888 888 "Y8888P "Y888 888 "Y88P" 888 888 88888P'
2793// MARK: Free Functions -
2794// clang-format on
2795
2800
2803{
2810
2812 std::list<attribute> attributes;
2813};
2814
2821
2823std::list<driver> list_drivers();
2824
2826std::list<datasource> list_datasources();
2827
2838result execute(connection& conn, string const& query, long batch_operations = 1, long timeout = 0);
2839
2849 connection& conn,
2850 string const& query,
2851 long batch_operations = 1,
2852 long timeout = 0);
2853
2855namespace detail
2856{
2857
2859template <class Row, class Member, class Class>
2860Member const& read_field(Row const& row, Member Class::* field)
2861{
2862 return row.*field;
2863}
2864
2866template <class Row, class Accessor>
2867auto read_field(Row const& row, Accessor const& accessor) -> decltype(accessor(row))
2868{
2869 return accessor(row);
2870}
2871
2873template <class Row, class Accessor>
2875{
2876 using type = typename std::decay<
2877 decltype(read_field(std::declval<Row const&>(), std::declval<Accessor const&>()))>::type;
2878};
2879
2880template <class T>
2881struct is_optional : std::false_type
2882{
2883};
2884
2885#ifdef NANODBC_HAS_STD_OPTIONAL
2886template <class T>
2887struct is_optional<std::optional<T>> : std::true_type
2888{
2889};
2890#endif
2891
2892template <class T>
2893struct is_bindable_string : std::false_type
2894{
2895};
2896
2897template <>
2898struct is_bindable_string<std::string> : std::true_type
2899{
2900};
2901
2902template <>
2903struct is_bindable_string<wide_string> : std::true_type
2904{
2905};
2906
2907// Four ways to bind a column, told apart by what the accessor yields.
2909{
2910};
2912{
2913};
2915{
2916};
2918{
2919};
2920
2921template <class T, bool IsOptional = is_optional<T>::value>
2923{
2924 using type = typename std::
2925 conditional<is_bindable_string<T>::value, bind_as_string, bind_as_value>::type;
2926};
2927
2928#ifdef NANODBC_HAS_STD_OPTIONAL
2929template <class T>
2930struct bind_kind<T, true>
2931{
2932 using type = typename std::conditional<
2936};
2937#endif
2938
2939template <class Rows, class Accessor>
2940void bind_column(
2941 statement& stmt,
2942 short param_index,
2943 Rows const& rows,
2944 Accessor const& accessor,
2945 bind_as_value)
2946{
2947 using value_type = typename field_type<typename Rows::value_type, Accessor>::type;
2948 std::vector<value_type> column;
2949 column.reserve(rows.size());
2950 for (auto const& row : rows)
2951 column.push_back(read_field(row, accessor));
2952 stmt.bind(param_index, column);
2953}
2954
2955template <class Rows, class Accessor>
2956void bind_column(
2957 statement& stmt,
2958 short param_index,
2959 Rows const& rows,
2960 Accessor const& accessor,
2961 bind_as_string)
2962{
2963 using value_type = typename field_type<typename Rows::value_type, Accessor>::type;
2964 std::vector<value_type> column;
2965 column.reserve(rows.size());
2966 for (auto const& row : rows)
2967 column.push_back(read_field(row, accessor));
2968 stmt.bind_strings(param_index, column);
2969}
2970
2971#ifdef NANODBC_HAS_STD_OPTIONAL
2972// An absent value still occupies its place in the column, so that the values line up with
2973// the flags marking which of them are null.
2974template <class Rows, class Accessor, class Column>
2975std::unique_ptr<bool[]> gather_optional(Rows const& rows, Accessor const& accessor, Column& column)
2976{
2977 std::unique_ptr<bool[]> nulls(new bool[rows.size()]);
2978 std::size_t i = 0;
2979 for (auto const& row : rows)
2980 {
2981 auto const& value = read_field(row, accessor);
2982 nulls[i++] = !value.has_value();
2983 column.push_back(value ? *value : typename Column::value_type());
2984 }
2985 return nulls;
2986}
2987
2988template <class Rows, class Accessor>
2989void bind_column(
2990 statement& stmt,
2991 short param_index,
2992 Rows const& rows,
2993 Accessor const& accessor,
2994 bind_as_optional_value)
2995{
2996 using optional_type = typename field_type<typename Rows::value_type, Accessor>::type;
2997 std::vector<typename optional_type::value_type> column;
2998 column.reserve(rows.size());
2999 auto const nulls = gather_optional(rows, accessor, column);
3000 stmt.bind(param_index, column, nulls.get());
3001}
3002
3003template <class Rows, class Accessor>
3004void bind_column(
3005 statement& stmt,
3006 short param_index,
3007 Rows const& rows,
3008 Accessor const& accessor,
3009 bind_as_optional_string)
3010{
3011 using optional_type = typename field_type<typename Rows::value_type, Accessor>::type;
3012 std::vector<typename optional_type::value_type> column;
3013 column.reserve(rows.size());
3014 auto const nulls = gather_optional(rows, accessor, column);
3015 stmt.bind_strings(param_index, column, nulls.get());
3016}
3017#endif
3018
3019template <class Rows, class Accessor>
3020void bind_one(statement& stmt, short param_index, Rows const& rows, Accessor const& accessor)
3021{
3022 using value_type = typename field_type<typename Rows::value_type, Accessor>::type;
3023 bind_column(stmt, param_index, rows, accessor, typename bind_kind<value_type>::type());
3024}
3025
3026} // namespace detail
3027
3059template <class Rows, class... Accessors>
3060void bind_rows(statement& stmt, Rows const& rows, Accessors const&... accessors)
3061{
3062 short param_index = 0;
3063 // Expanded through a braced list, which C++14 orders left to right where a fold
3064 // expression is not yet available.
3065 int const sequence[] = {0, (detail::bind_one(stmt, param_index++, rows, accessors), 0)...};
3066 (void)sequence;
3067}
3068
3077result execute(statement& stmt, long batch_operations = 1);
3078
3086void just_execute(statement& stmt, long batch_operations = 1);
3087
3096result transact(statement& stmt, long batch_operations);
3097
3105void just_transact(statement& stmt, long batch_operations);
3106
3116void prepare(statement& stmt, string const& query, long timeout = 0);
3117
3119
3120} // namespace nanodbc
3121
3122#endif
A class representing a connection or a statement attribute.
Definition nanodbc.h:476
long string_length_
The StringLength argument of the ODBC call.
Definition nanodbc.h:489
void * value_ptr_
The ValuePtr argument of the ODBC call.
Definition nanodbc.h:490
long attribute_
The Attribute argument of the ODBC call.
Definition nanodbc.h:488
attribute(long const &attribute, long const &string_length, std::uintptr_t value_ptr) noexcept
Creates an attribute from the three arguments the ODBC call takes.
Definition nanodbc.h:482
Result set for a list of columns in one or more tables.
Definition nanodbc.h:2526
string remarks() const
Fetch column remarks.
short sql_data_type() const
Fetch column's SQL data type.
string table_catalog() const
Fetch table catalog.
short numeric_precision_radix() const
Fetch numeric precission.
string column_default() const
Fetch column's default.
string table_schema() const
Fetch table schema.
string type_name() const
Fetch column type name.
short sql_datetime_subtype() const
Fetch datetime subtype of column.
bool next()
Move to the next result in the result set.
short nullable() const
True iff column is nullable.
string column_name() const
Fetch column name.
string table_name() const
Fetch table name.
long column_size() const
Fetch column size.
short decimal_digits() const
Fetch decimal digits.
long char_octet_length() const
Fetch char octet length.
long ordinal_position() const
Ordinal position of the column in the table.
string is_nullable() const
Fetch column is-nullable information.
long buffer_length() const
Fetch buffer length.
short data_type() const
Fetch column data type.
Result set for a list of columns that compose the primary key of a single table.
Definition nanodbc.h:2566
bool next()
Move to the next result in the result set.
string column_name() const
Fetch column name.
short column_number() const
Column sequence number in the key (starting with 1).
string table_name() const
Fetch table name.
string primary_key_name() const
Primary key name.
string table_schema() const
Fetch table schema.
string table_catalog() const
Fetch table catalog.
Result set for a list of procedures in the data source.
Definition nanodbc.h:2628
string column_default() const
Fetch column's default.
string type_name() const
Fetch column type name.
long ordinal_position() const
Ordinal position of the column in the table.
bool next()
Move to the next result in the result set.
short decimal_digits() const
Fetch decimal digits.
long column_size() const
Fetch column size.
short sql_datetime_subtype() const
Fetch datetime subtype of column.
string remarks() const
Fetch column remarks.
long char_octet_length() const
Fetch char octet length.
string procedure_schema() const
Fetch procedure schema.
string procedure_catalog() const
Fetch procedure catalog.
short sql_data_type() const
Fetch column's SQL data type.
short column_type() const
Fetch column type.
short numeric_precision_radix() const
Fetch numeric precission.
string is_nullable() const
Fetch column is-nullable information.
long buffer_length() const
Fetch buffer length.
short nullable() const
True iff column is nullable.
string column_name() const
Fetch column name.
string procedure_name() const
Fetch procedure name.
short data_type() const
Fetch column data type.
Result set for a list of procedures in the data source.
Definition nanodbc.h:2611
string procedure_name() const
Fetch procedure name.
short procedure_type() const
Fetch procedure type.
string procedure_schema() const
Fetch procedure schema.
string procedure_catalog() const
Fetch procedure catalog.
string procedure_remarks() const
Fetch procedure remarks.
bool next()
Move to the next result in the result set.
Result set for a list of tables and the privileges associated with each table.
Definition nanodbc.h:2591
string privilege() const
Fetch the table privilege.
string grantor() const
Fetch name of user who granted the privilege.
bool next()
Move to the next result in the result set.
string table_schema() const
Fetch table schema.
string table_catalog() const
Fetch table catalog.
string table_name() const
Fetch table name.
string grantee() const
Fetch name of user whom the privilege was granted.
string is_grantable() const
Fetch indicator whether the grantee is permitted to grant the privilege to other users.
Result set for a list of tables in the data source.
Definition nanodbc.h:2509
string table_name() const
Fetch table name.
string table_catalog() const
Fetch table catalog.
bool next()
Move to the next result in the result set.
string table_remarks() const
Fetch table remarks.
string table_type() const
Fetch table type.
string table_schema() const
Fetch table schema.
A resource for get catalog information from connected data source.
Definition nanodbc.h:2505
std::list< string > list_schemas()
Returns names of all schemas available in connected data source.
std::list< string > list_catalogs()
Returns names of all catalogs (or databases) available in connected data source.
catalog(connection &conn) noexcept
Creates catalog operating on database accessible through the specified connection.
catalog::procedures find_procedures(string const &procedure=string(), string const &schema=string(), string const &catalog=string())
Creates result set with catalog, schema, procedure, and procedure types.
std::list< string > list_table_types()
Returns all available table types in the connected data source.
catalog::table_privileges find_table_privileges(string const &catalog, string const &table=string(), string const &schema=string())
Creates result set with tables and the privileges associated with each table.
catalog::tables find_tables(string const &table=string(), string const &type=string(), string const &schema=string(), string const &catalog=string())
Creates result set with catalogs, schemas, tables, or table types.
catalog::columns find_columns(string const &column=string(), string const &table=string(), string const &schema=string(), string const &catalog=string())
Creates result set with columns in one or more tables.
catalog::primary_keys find_primary_keys(string const &table, string const &schema=string(), string const &catalog=string())
Creates result set with columns that compose the primary key of a single table.
catalog::procedure_columns find_procedure_columns(string const &column=string(), string const &procedure=string(), string const &schema=string(), string const &catalog=string())
Creates result set with columns in one or more procedures.
Definition nanodbc.h:1573
Manages and encapsulates ODBC resources such as the connection and environment handles.
Definition nanodbc.h:1548
~connection() noexcept
Automatically disconnects from the database and frees all associated resources.
connection(string const &dsn, string const &user, string const &pass, std::list< attribute > const &attributes)
Create new connection object, set the connection attributes passed as arguments and connect to the gi...
bool async_connect(string const &connection_string, void *event_handle, long timeout=0)
Initiate an asynchronous connection operation using the given connection string.
connection(const connection &rhs) noexcept
Copy constructor.
bool connected() const noexcept
Returns true if connected to the database.
void async_complete()
Completes a previously initiated asynchronous connection operation.
connection(connection &&rhs) noexcept
Move constructor.
connection(string const &connection_string, std::list< attribute > const &attributes)
Create new connection object, set the connection attributes passed as arguments and connect to the gi...
connection(string const &dsn, string const &user, string const &pass, long timeout=0)
Create new connection object and immediately connect to the given data source.
connection & operator=(connection rhs) noexcept
Assignment.
connection()
Create new connection object, initially not connected.
bool async_connect(string const &dsn, string const &user, string const &pass, void *event_handle, long timeout=0)
Initiate an asynchronous connection operation to the given data source.
void swap(connection &) noexcept
Member swap.
connection(string const &connection_string, long timeout=0)
Create new connection object and immediately connect using the given connection string.
General database error.
Definition nanodbc.h:329
char const * what() const noexcept override
Returns the full message, including the driver's own text.
database_error(void *handle, short handle_type, std::string const &info="")
Creates runtime_error with message about last ODBC error.
Provides access to metadata in the Implementation Row Descriptor (IRD) implicitly allocated for a pre...
Definition nanodbc.h:2344
implementation_row_descriptor(statement const &statement)
Initializes IRD access from prepared or executed statement.
implementation_row_descriptor(result const &result)
Initializes IRD access from statement of executed result set.
auto alloc_type() const -> short
Value of the header field SQL_DESC_ALLOC_AUTO.
Index out of range.
Definition nanodbc.h:305
char const * what() const noexcept override
Returns the message describing the out of range index.
Accessed null data.
Definition nanodbc.h:294
char const * what() const noexcept override
Returns the message describing the null access.
Programming logic error.
Definition nanodbc.h:316
programming_error(std::string const &info)
Creates a programming error with the given message.
char const * what() const noexcept override
Returns the message describing the error.
Single pass input iterator that accesses successive rows in the attached result set.
Definition nanodbc.h:2239
result_iterator()=default
Default iterator; an empty result set.
bool operator!=(result_iterator const &rhs) const noexcept
Iterators are not equal if they have different native statemnt handles.
Definition nanodbc.h:2300
result * pointer
Pointer to iteration values.
Definition nanodbc.h:2243
pointer operator->()
Access through dereference.
Definition nanodbc.h:2261
result value_type
Values returned by iterator access.
Definition nanodbc.h:2242
void operator++(int)
Iteration.
Definition nanodbc.h:2288
bool operator==(result_iterator const &rhs) const noexcept
Iterators are equal if they a tied to the same native statemnt handle, or both empty.
Definition nanodbc.h:2291
result_iterator & operator++()
Iteration.
Definition nanodbc.h:2269
reference operator*() noexcept
Dereference.
Definition nanodbc.h:2258
result & reference
Reference to iteration values.
Definition nanodbc.h:2244
result_iterator(result &r)
Create result iterator for a given result set.
Definition nanodbc.h:2251
std::ptrdiff_t difference_type
Iterator difference.
Definition nanodbc.h:2245
std::input_iterator_tag iterator_category
Category of iterator.
Definition nanodbc.h:2241
A resource for managing result sets from statement execution.
Definition nanodbc.h:1836
bool complete_next()
Completes a previously-initiated async fetch for next row in the current result set.
unsigned long position() const
Returns the row position in the current result set.
bool move(long row)
Moves to and fetches the specified row in the current result set.
bool async_next(void *event_handle)
Initiates an asynchronous fetch of the next row in the current result set.
bool at_end() const noexcept
Returns true if there are no more results in the current result set.
bool skip(long rows)
Skips a number of rows and then fetches the resulting row in the current result set.
result() noexcept
Empty result set.
bool prior()
Fetches the prior row in the current result set.
Definition nanodbc.h:889
Represents a statement on the database.
Definition nanodbc.h:865
statement(class connection &conn, std::list< attribute > const &attributes)
Constructs a statement object and associates it to the given connection, applying the given ODBC stat...
statement & operator=(statement rhs) noexcept
Assignment.
void just_execute_direct(class connection &conn, string const &query, long batch_operations=1, long timeout=0)
Execute the previously prepared query now without constructing result object.
void complete_prepare()
Completes a previously initiated asynchronous query preparation.
param_direction
Provides support for retrieving output/return parameters.
Definition nanodbc.h:906
@ PARAM_OUT
Binding an output parameter.
Definition nanodbc.h:908
@ PARAM_INOUT
Binding an input/output parameter.
Definition nanodbc.h:909
@ PARAM_IN
Binding an input parameter.
Definition nanodbc.h:907
bool async_prepare(string const &query, void *event_handle, long timeout=0)
Prepare the given statement, in asynchronous mode.
short columns() const
Returns the number of columns in a result set.
void disable_async() const
undocumented - for internal use only (used from result_impl)
bool async_execute_direct(class connection &conn, void *event_handle, string const &query, long batch_operations=1, long timeout=0)
Opens, prepares, and executes query directly on the given connection, in async mode.
void describe_parameters(const std::vector< short > &idx, const std::vector< short > &type, const std::vector< unsigned long > &size, const std::vector< short > &scale)
Sets descriptions for parameters in the prepared statement.
statement(statement &&rhs) noexcept
Move constructor.
~statement() noexcept
Closes the statement.
statement(class connection &conn)
Constructs a statement object and associates it to the given connection.
void swap(statement &rhs) noexcept
Member swap.
bool async_execute(void *event_handle, long batch_operations=1, long timeout=0)
Execute the previously prepared query now, in asynchronous mode.
statement()
Creates a new un-prepared statement.
statement(const statement &rhs) noexcept
Copy constructor.
void enable_async(void *event_handle)
undocumented - for internal use only (used from result_impl)
statement(class connection &conn, string const &query, long timeout=0)
Constructs and prepares a statement using the given connection and query.
void reset_parameters() noexcept
Resets all currently bound parameters.
void just_execute(long batch_operations=1, long timeout=0)
Execute the previously prepared query now without constructing result object.
long affected_rows() const
Returns rows affected by the request or -1 if affected rows is not available.
Support for table-valued parameter.
Definition nanodbc.h:610
table_valued_parameter(statement &stmt, short param_index, size_t row_count)
Creates a table-valued parameter and opens it on the given statement.
~table_valued_parameter() noexcept
Closes the parameter, if it is still open.
void bind_null(short param_index)
Binds a null value to the given column of every row.
table_valued_parameter(const table_valued_parameter &rhs) noexcept
Copy constructor.
short parameters() const noexcept
Returns the number of columns in the table valued parameter.
table_valued_parameter(table_valued_parameter &&rhs) noexcept
Move constructor.
table_valued_parameter()
Creates a table-valued parameter that is not yet open.
void describe_parameters(const std::vector< short > &idx, const std::vector< short > &type, const std::vector< unsigned long > &size, const std::vector< short > &scale)
Sets descriptions for columns of the table-valued parameter.
A resource for managing transaction commits and rollbacks.
Definition nanodbc.h:546
~transaction() noexcept
If this transaction has not been committed, it will rollback any modifying ops.
transaction(const class connection &conn)
Begin a transaction on the given connection object.
transaction(transaction &&rhs) noexcept
Move constructor.
transaction(const transaction &rhs) noexcept
Copy constructor.
transaction & operator=(transaction rhs) noexcept
Assignment.
void swap(transaction &rhs) noexcept
Member swap.
Type incompatible.
Definition nanodbc.h:283
char const * what() const noexcept override
Returns the message describing the incompatibility.
void bind_strings(short param_index, T const (&values)[BatchSize][ValueSize], bool const *nulls, param_direction direction=PARAM_IN)
Binds multiple string values.
Definition nanodbc.h:1473
void bind_strings(short param_index, T const (&values)[BatchSize][ValueSize], bool const *nulls)
Binds multiple string values.
Definition nanodbc.h:801
void bind_strings(short param_index, T const *values, std::size_t value_size, std::size_t batch_size, T const *null_sentry)
Binds multiple string values.
void bind_strings(short param_index, std::vector< T > const &values, bool const *nulls)
Binds multiple string values.
void bind_strings(short param_index, std::vector< T > const &values, typename T::value_type const *null_sentry)
Binds multiple string values.
void bind_strings(short param_index, std::vector< T > const &values, bool const *nulls, param_direction direction=PARAM_IN)
Binds multiple string values.
void bind_strings(short param_index, T const (&values)[BatchSize][ValueSize], T const *null_sentry)
Binds multiple string values.
Definition nanodbc.h:773
void bind_strings(short param_index, T const *values, std::size_t value_size, std::size_t batch_size, T const *null_sentry, param_direction direction=PARAM_IN)
Binds multiple string values.
void bind_strings(short param_index, T const *values, std::size_t value_size, std::size_t batch_size, bool const *nulls)
Binds multiple string values.
void bind_strings(short param_index, std::vector< T > const &values, typename T::value_type const *null_sentry, param_direction direction=PARAM_IN)
Binds multiple string values.
void bind_strings(short param_index, T const *values, std::size_t value_size, std::size_t batch_size, bool const *nulls, param_direction direction=PARAM_IN)
Binds multiple string values.
void bind_strings(short param_index, T const (&values)[BatchSize][ValueSize], T const *null_sentry, param_direction direction=PARAM_IN)
Binds multiple string values.
Definition nanodbc.h:1436
void bind_null(short param_index, std::size_t batch_size=1)
Binds null values to the parameter placeholder number in the prepared statement.
void bind(short param_index, T const *value, param_direction direction=PARAM_IN)
Binds given value to given parameter placeholder number in the prepared statement.
result_iterator end(result &) noexcept
Returns an iterator to the end of a result set.
Definition nanodbc.h:2318
result_iterator begin(result &r)
Returns an iterator to the beginning of the given result set.
Definition nanodbc.h:2307
void prepare(statement &stmt, string const &query, long timeout=0)
Prepares the given statement to execute on it associated connection.
void bind_rows(statement &stmt, Rows const &rows, Accessors const &... accessors)
Binds a range of rows, a parameter at a time.
Definition nanodbc.h:3060
result execute(connection &conn, string const &query, long batch_operations=1, long timeout=0)
Immediately opens, prepares, and executes the given query directly on the given connection.
void just_transact(statement &stmt, long batch_operations)
Execute the previously prepared query now and without creating result object.
result transact(statement &stmt, long batch_operations)
Execute the previously prepared query now.
std::list< driver > list_drivers()
Returns a list of ODBC drivers on your system.
std::list< datasource > list_datasources()
Returns a list of ODBC data sources on your system.
void just_execute(connection &conn, string const &query, long batch_operations=1, long timeout=0)
Opens, prepares, and executes query directly without creating result object.
typename std::enable_if< is_string< T >::value >::type enable_if_string
Enables an overload only for the string types nanodbc binds as strings.
Definition nanodbc.h:517
typename std::enable_if< is_character< T >::value >::type enable_if_character
Enables an overload only for the character types nanodbc binds as strings.
Definition nanodbc.h:521
std::integral_constant< bool, std::is_same< typename std::decay< T >::type, std::string >::value||std::is_same< typename std::decay< T >::type, wide_string >::value > is_string
A type trait for testing if a type is a std::basic_string compatible with the current nanodbc configu...
Definition nanodbc.h:505
std::integral_constant< bool, std::is_same< typename std::decay< T >::type, std::string::value_type >::value||std::is_same< typename std::decay< T >::type, wide_char_t >::value > is_character
A type trait for testing if a type is a character compatible with the current nanodbc configuration.
Definition nanodbc.h:513
Member const & read_field(Row const &row, Member Class::*field)
Reads a member through a pointer to it.
Definition nanodbc.h:2860
The entirety of nanodbc can be found within this one namespace.
Definition nanodbc.h:108
unspecified type string
string will be std::u16string or std::32string if NANODBC_ENABLE_UNICODE defined.
Definition nanodbc.h:236
unspecified type null_type
null_type will be int64_t for 64-bit compilations, otherwise long.
Definition nanodbc.h:238
A type capturing parameter array length as well as number of rows in a rowset of a result.
Definition nanodbc.h:374
batch_ops() noexcept
Creates lengths of -1, meaning neither has been chosen.
Definition nanodbc.h:379
batch_ops(const long all_length) noexcept
Creates both lengths with the same value.
Definition nanodbc.h:385
long rowset_size
Number of rows fetched into a rowset at a time.
Definition nanodbc.h:376
long parameter_array_length
Number of parameter values bound per execution.
Definition nanodbc.h:375
A data source name registered with the driver manager.
Definition nanodbc.h:2817
nanodbc::string driver
Driver description.
Definition nanodbc.h:2819
nanodbc::string name
DSN name.
Definition nanodbc.h:2818
A type for representing date data.
Definition nanodbc.h:392
std::int16_t month
Month of the year [1-12].
Definition nanodbc.h:394
std::int16_t day
Day of the month [1-31].
Definition nanodbc.h:395
std::int16_t year
Year [0-inf).
Definition nanodbc.h:393
Definition nanodbc.h:2912
Definition nanodbc.h:2909
Definition nanodbc.h:2923
The type an accessor yields for a row, stripped of reference and const.
Definition nanodbc.h:2875
Definition nanodbc.h:2894
Definition nanodbc.h:2882
Driver attributes.
Definition nanodbc.h:2806
nanodbc::string keyword
Driver keyword attribute.
Definition nanodbc.h:2807
nanodbc::string value
Driver attribute value.
Definition nanodbc.h:2808
Information on a configured ODBC driver.
Definition nanodbc.h:2803
nanodbc::string name
Driver name.
Definition nanodbc.h:2811
std::list< attribute > attributes
List of driver attributes.
Definition nanodbc.h:2812
A type for representing time data.
Definition nanodbc.h:400
std::int16_t hour
Hours since midnight [0-23].
Definition nanodbc.h:401
std::int16_t min
Minutes after the hour [0-59].
Definition nanodbc.h:402
std::int16_t sec
Seconds after the minute.
Definition nanodbc.h:403
A type for representing timestamp data.
Definition nanodbc.h:408
std::int16_t hour
Hours since midnight [0-23].
Definition nanodbc.h:412
std::int16_t sec
Seconds after the minute.
Definition nanodbc.h:414
std::int16_t day
Day of the month [1-31].
Definition nanodbc.h:411
std::int16_t year
Year [0-inf).
Definition nanodbc.h:409
std::int16_t min
Minutes after the hour [0-59].
Definition nanodbc.h:413
std::int32_t fract
Fractional seconds.
Definition nanodbc.h:415
std::int16_t month
Month of the year [1-12].
Definition nanodbc.h:410
A type for representing timestamp+offset data.
Definition nanodbc.h:420
std::int16_t offset_minute
Minutes part of time zome offset.
Definition nanodbc.h:423
timestamp stamp
Date and time, in the offset's local terms.
Definition nanodbc.h:421
std::int16_t offset_hour
Whole hour part of time zone offset.
Definition nanodbc.h:422