1 #ifndef DOXYGEN_SHOULD_SKIP_THIS 26 #ifndef NANODBC_ASSERT 28 #define NANODBC_ASSERT(expr) assert(expr) 31 #ifdef NANODBC_USE_BOOST_CONVERT 32 #include <boost/locale/encoding_utf.hpp> 37 #if defined(_MSC_VER) && _MSC_VER <= 1800
39 #pragma warning(disable:4244
) 40 #pragma warning(disable:4312
) 41 #pragma warning(disable:4996
) 46 #define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_6 59 #ifndef NANODBC_ODBC_VERSION 60 #ifdef SQL_OV_ODBC3_80 62 #define NANODBC_ODBC_VERSION SQL_OV_ODBC3_80 65 #define NANODBC_ODBC_VERSION SQL_OV_ODBC3 79 #ifdef NANODBC_USE_UNICODE 80 #ifdef NANODBC_USE_IODBC_WIDE_STRINGS 81 #define NANODBC_TEXT(s) U ## s 83 #define NANODBC_TEXT(s) u ## s 85 #define NANODBC_FUNC(f) f ## W 86 #define NANODBC_SQLCHAR SQLWCHAR 88 #define NANODBC_TEXT(s) s 89 #define NANODBC_FUNC(f) f 90 #define NANODBC_SQLCHAR SQLCHAR 93 #ifdef NANODBC_USE_IODBC_WIDE_STRINGS 94 typedef std::u32string wide_string_type;
95 #define NANODBC_CODECVT_TYPE std::codecvt_utf8 97 typedef std::u16string wide_string_type;
98 #define NANODBC_CODECVT_TYPE std::codecvt_utf8_utf16 100 typedef wide_string_type::value_type wide_char_t;
102 #if defined(_MSC_VER) 103 #ifndef NANODBC_USE_UNICODE 107 #define SQL_NOUNICODEMAP 121 #define NANODBC_STRINGIZE_I(text) #text 122 #define NANODBC_STRINGIZE(text) NANODBC_STRINGIZE_I(text) 127 #ifdef NANODBC_ODBC_API_DEBUG 129 #define NANODBC_CALL_RC(FUNC, RC, ...) 132 std::cerr << __FILE__ ":" NANODBC_STRINGIZE( __LINE__) " " 133 NANODBC_STRINGIZE(FUNC) "(" # __VA_ARGS__ ")" << std::endl; 134 RC = FUNC( __VA_ARGS__); 137 #define NANODBC_CALL(FUNC, ...) 140 std::cerr << __FILE__ ":" NANODBC_STRINGIZE( __LINE__) " " 141 NANODBC_STRINGIZE(FUNC) "(" # __VA_ARGS__ ")" << std::endl; 146 #define NANODBC_CALL_RC(FUNC, RC, ...) RC = FUNC( __VA_ARGS__) 147 #define NANODBC_CALL(FUNC, ...) FUNC( __VA_ARGS__) 165 #ifdef NANODBC_ODBC_API_DEBUG 166 inline nanodbc::string_type return_code(RETCODE rc)
170 case SQL_SUCCESS:
return NANODBC_TEXT(
"SQL_SUCCESS");
171 case SQL_SUCCESS_WITH_INFO:
return NANODBC_TEXT(
"SQL_SUCCESS_WITH_INFO");
172 case SQL_ERROR:
return NANODBC_TEXT(
"SQL_ERROR");
173 case SQL_INVALID_HANDLE:
return NANODBC_TEXT(
"SQL_INVALID_HANDLE");
174 case SQL_NO_DATA:
return NANODBC_TEXT(
"SQL_NO_DATA");
175 case SQL_NEED_DATA:
return NANODBC_TEXT(
"SQL_NEED_DATA");
176 case SQL_STILL_EXECUTING:
return NANODBC_TEXT(
"SQL_STILL_EXECUTING");
184 inline bool success(RETCODE rc)
186 #ifdef NANODBC_ODBC_API_DEBUG 187 std::cerr <<
"<-- rc: " << return_code(rc) <<
" | ";
189 return rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO;
193 template<
typename T, std::size_t N>
194 inline std::size_t arrlen(T(&)[N])
200 template<
typename T, std::size_t N>
201 inline std::size_t strarrlen(T(&a)[N])
205 while(*s++ && i < N) i++;
209 inline void convert(
const wide_string_type& in, std::string& out)
211 #ifdef NANODBC_USE_BOOST_CONVERT 212 using boost::locale::conv::utf_to_utf;
213 out = utf_to_utf<
char>(in.c_str(), in.c_str() + in.size());
215 #if defined(_MSC_VER) && (_MSC_VER == 1900
) 218 auto p =
reinterpret_cast<wide_char_t
const*>(in.data());
219 out = std::wstring_convert<NANODBC_CODECVT_TYPE<wide_char_t>, wide_char_t>().to_bytes(p, p + in.size());
221 out = std::wstring_convert<NANODBC_CODECVT_TYPE<wide_char_t>, wide_char_t>().to_bytes(in);
226 #ifdef NANODBC_USE_UNICODE 227 inline void convert(
const std::string& in, wide_string_type& out)
229 #ifdef NANODBC_USE_BOOST_CONVERT 230 using boost::locale::conv::utf_to_utf;
231 out = utf_to_utf<wide_char_t>(in.c_str(), in.c_str() + in.size());
232 #elif defined(_MSC_VER) && (_MSC_VER == 1900
) 235 auto s = std::wstring_convert<NANODBC_CODECVT_TYPE<wide_char_t>, wide_char_t>().from_bytes(in);
236 auto p =
reinterpret_cast<wide_char_t
const*>(s.data());
237 out.assign(p, p + s.size());
239 out = std::wstring_convert<NANODBC_CODECVT_TYPE<wide_char_t>, wide_char_t>().from_bytes(in);
243 inline void convert(
const wide_string_type& in, wide_string_type& out)
248 inline void convert(
const std::string& in, std::string& out)
256 inline std::string recent_error(
258 , SQLSMALLINT handle_type
260 , std::string &state)
262 nanodbc::string_type result;
264 std::vector<NANODBC_SQLCHAR> sql_message(SQL_MAX_MESSAGE_LENGTH);
265 sql_message[0] =
'\0';
268 SQLINTEGER native_error;
269 SQLSMALLINT total_bytes;
270 NANODBC_SQLCHAR sql_state[6];
276 NANODBC_FUNC(SQLGetDiagRec)
287 if(success(rc) && total_bytes > 0)
288 sql_message.resize(total_bytes + 1);
290 if(rc == SQL_NO_DATA)
294 NANODBC_FUNC(SQLGetDiagRec)
302 , (SQLSMALLINT)sql_message.size()
307 convert(result, rvalue);
314 result += nanodbc::string_type(sql_message.begin(), sql_message.end());
323 }
while(rc != SQL_NO_DATA);
325 convert(result, rvalue);
326 state = std::string(&sql_state[0], &sql_state[arrlen(sql_state) - 1]);
327 native = native_error;
328 std::string status = state;
334 replace(status.begin(), status.end(),
'\0',
' ');
342 type_incompatible_error::type_incompatible_error()
343 : std::runtime_error(
"type incompatible") { }
345 const char* type_incompatible_error::what()
const NANODBC_NOEXCEPT
347 return std::runtime_error::what();
350 null_access_error::null_access_error()
351 : std::runtime_error(
"null access") { }
353 const char* null_access_error::what()
const NANODBC_NOEXCEPT
355 return std::runtime_error::what();
358 index_range_error::index_range_error()
359 : std::runtime_error(
"index out of range") { }
361 const char* index_range_error::what()
const NANODBC_NOEXCEPT
363 return std::runtime_error::what();
366 programming_error::programming_error(
const std::string& info)
367 : std::runtime_error(info.c_str()) { }
369 const char* programming_error::what()
const NANODBC_NOEXCEPT
371 return std::runtime_error::what();
374 database_error::database_error(
void* handle,
short handle_type,
const std::string& info)
375 : std::runtime_error(info), native_error(0), sql_state(
"00000")
377 message = std::string(std::runtime_error::what()) + recent_error(handle, handle_type, native_error, sql_state);
380 const char* database_error::what()
const NANODBC_NOEXCEPT
382 return message.c_str();
385 const long database_error::native()
const NANODBC_NOEXCEPT
390 const std::string database_error::state()
const NANODBC_NOEXCEPT
399 #define NANODBC_THROW_DATABASE_ERROR(handle, handle_type) 400 throw nanodbc::database_error( 403 , __FILE__ ":" NANODBC_STRINGIZE( __LINE__) ": ") 424 struct sql_ctype { };
427 struct sql_ctype<nanodbc::string_type::value_type>
429 #ifdef NANODBC_USE_UNICODE 430 static const SQLSMALLINT value = SQL_C_WCHAR;
432 static const SQLSMALLINT value = SQL_C_CHAR;
437 struct sql_ctype<
short>
439 static const SQLSMALLINT value = SQL_C_SSHORT;
443 struct sql_ctype<
unsigned short>
445 static const SQLSMALLINT value = SQL_C_USHORT;
449 struct sql_ctype<int32_t>
451 static const SQLSMALLINT value = SQL_C_SLONG;
455 struct sql_ctype<uint32_t>
457 static const SQLSMALLINT value = SQL_C_ULONG;
461 struct sql_ctype<int64_t>
463 static const SQLSMALLINT value = SQL_C_SBIGINT;
467 struct sql_ctype<uint64_t>
469 static const SQLSMALLINT value = SQL_C_UBIGINT;
473 struct sql_ctype<
float>
475 static const SQLSMALLINT value = SQL_C_FLOAT;
479 struct sql_ctype<
double>
481 static const SQLSMALLINT value = SQL_C_DOUBLE;
485 struct sql_ctype<nanodbc::string_type>
487 #ifdef NANODBC_USE_UNICODE 488 static const SQLSMALLINT value = SQL_C_WCHAR;
490 static const SQLSMALLINT value = SQL_C_CHAR;
495 struct sql_ctype<nanodbc::date>
497 static const SQLSMALLINT value = SQL_C_DATE;
501 struct sql_ctype<nanodbc::timestamp>
503 static const SQLSMALLINT value = SQL_C_TIMESTAMP;
510 bound_column(
const bound_column& rhs) =
delete;
511 bound_column& operator=(bound_column rhs) =
delete;
535 nanodbc::string_type name_;
537 SQLSMALLINT sqltype_;
543 nanodbc::null_type* cbdata_;
548 inline void allocate_handle(SQLHENV& env, SQLHDBC& conn)
558 NANODBC_THROW_DATABASE_ERROR(env, SQL_HANDLE_ENV);
566 , SQL_ATTR_ODBC_VERSION
567 , (SQLPOINTER)NANODBC_ODBC_VERSION
570 NANODBC_THROW_DATABASE_ERROR(env, SQL_HANDLE_ENV);
579 NANODBC_THROW_DATABASE_ERROR(env, SQL_HANDLE_ENV);
608 class connection::connection_impl
611 connection_impl(
const connection_impl&) =
delete;
612 connection_impl& operator=(
const connection_impl&) =
delete;
621 allocate_handle(env_, conn_);
625 const string_type& dsn
626 ,
const string_type& user
627 ,
const string_type& pass
635 allocate_handle(env_, conn_);
638 connect(dsn, user, pass, timeout);
654 connection_impl(
const string_type& connection_string,
long timeout)
661 allocate_handle(env_, conn_);
664 connect(connection_string, timeout);
680 ~connection_impl() NANODBC_NOEXCEPT
700 #ifdef SQL_ATTR_ASYNC_DBC_EVENT 701 void enable_async(
void* event_handle)
708 , SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE
709 , (SQLPOINTER)SQL_ASYNC_DBC_ENABLE_ON
712 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
718 , SQL_ATTR_ASYNC_DBC_EVENT
722 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
725 void async_complete()
734 if(!success(rc) || !success(arc))
735 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
741 , SQL_ATTR_ASYNC_ENABLE
742 , (SQLPOINTER)SQL_ASYNC_ENABLE_OFF
745 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
747 connected_ = success(rc);
752 const string_type& dsn
753 ,
const string_type& user
754 ,
const string_type& pass
756 ,
void* event_handle = NULL)
767 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
776 NANODBC_THROW_DATABASE_ERROR(env_, SQL_HANDLE_ENV);
783 , (SQLPOINTER)(std::intptr_t)timeout
786 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
788 #ifdef SQL_ATTR_ASYNC_DBC_EVENT 789 if(event_handle != NULL)
790 enable_async(event_handle);
794 NANODBC_FUNC(SQLConnect)
797 , (NANODBC_SQLCHAR*)dsn.c_str(), SQL_NTS
798 , !user.empty() ? (NANODBC_SQLCHAR*)user.c_str() : 0, SQL_NTS
799 , !pass.empty() ? (NANODBC_SQLCHAR*)pass.c_str() : 0, SQL_NTS);
800 if(!success(rc) && (event_handle == NULL || rc != SQL_STILL_EXECUTING))
801 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
803 connected_ = success(rc);
806 void connect(
const string_type& connection_string,
long timeout,
void* event_handle = NULL)
817 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
826 NANODBC_THROW_DATABASE_ERROR(env_, SQL_HANDLE_ENV);
833 , (SQLPOINTER)(std::intptr_t)timeout
836 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
838 #ifdef SQL_ATTR_ASYNC_DBC_EVENT 839 if(event_handle != NULL)
840 enable_async(event_handle);
843 NANODBC_SQLCHAR dsn[1024];
844 SQLSMALLINT dsn_size = 0;
846 NANODBC_FUNC(SQLDriverConnect)
850 , (NANODBC_SQLCHAR*)connection_string.c_str(), SQL_NTS
852 ,
sizeof(dsn) /
sizeof(NANODBC_SQLCHAR)
854 , SQL_DRIVER_NOPROMPT);
855 if(!success(rc) && (event_handle == NULL || rc != SQL_STILL_EXECUTING))
856 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
858 connected_ = success(rc);
861 bool connected()
const 876 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
881 std::size_t transactions()
const 883 return transactions_;
886 void* native_dbc_handle()
const 891 void* native_env_handle()
const 896 string_type dbms_name()
const 898 NANODBC_SQLCHAR name[255] = { 0 };
899 SQLSMALLINT length(0);
902 NANODBC_FUNC(SQLGetInfo)
907 ,
sizeof(name) /
sizeof(NANODBC_SQLCHAR)
910 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
911 return string_type(&name[0], &name[strarrlen(name)]);
914 string_type dbms_version()
const 916 NANODBC_SQLCHAR version[255] = { 0 };
917 SQLSMALLINT length(0);
920 NANODBC_FUNC(SQLGetInfo)
925 ,
sizeof(version) /
sizeof(NANODBC_SQLCHAR)
928 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
929 return string_type(&version[0], &version[strarrlen(version)]);
932 string_type driver_name()
const 934 NANODBC_SQLCHAR name[1024];
938 NANODBC_FUNC(SQLGetInfo)
943 ,
sizeof(name) /
sizeof(NANODBC_SQLCHAR)
946 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
947 return string_type(&name[0], &name[strarrlen(name)]);
950 string_type database_name()
const 956 NANODBC_SQLCHAR name[255] = { 0 };
957 SQLSMALLINT length(0);
960 NANODBC_FUNC(SQLGetInfo)
965 ,
sizeof(name) /
sizeof(NANODBC_SQLCHAR)
968 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
969 return string_type(&name[0], &name[strarrlen(name)]);
972 string_type catalog_name()
const 974 NANODBC_SQLCHAR name[SQL_MAX_OPTION_STRING_LENGTH] = { 0 };
975 SQLINTEGER length(0);
978 NANODBC_FUNC(SQLGetConnectAttr)
981 , SQL_ATTR_CURRENT_CATALOG
983 ,
sizeof(name) /
sizeof(NANODBC_SQLCHAR)
986 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
987 return string_type(&name[0], &name[strarrlen(name)]);
991 std::size_t ref_transaction()
993 return --transactions_;
996 std::size_t unref_transaction()
998 return ++transactions_;
1001 bool rollback()
const 1006 void rollback(
bool onoff)
1015 std::size_t transactions_;
1037 class transaction::transaction_impl
1040 transaction_impl(
const transaction_impl&) =
delete;
1041 transaction_impl& operator=(
const transaction_impl&) =
delete;
1043 transaction_impl(
const class connection& conn)
1047 if(conn_.transactions() == 0 && conn_.connected())
1053 , conn_.native_dbc_handle()
1054 , SQL_ATTR_AUTOCOMMIT
1055 , (SQLPOINTER)SQL_AUTOCOMMIT_OFF
1058 NANODBC_THROW_DATABASE_ERROR(conn_.native_dbc_handle(), SQL_HANDLE_DBC);
1060 conn_.ref_transaction();
1063 ~transaction_impl() NANODBC_NOEXCEPT
1067 conn_.rollback(
true);
1068 conn_.unref_transaction();
1071 if(conn_.transactions() == 0 && conn_.connected())
1073 if(conn_.rollback())
1078 , conn_.native_dbc_handle()
1080 conn_.rollback(
false);
1085 , conn_.native_dbc_handle()
1086 , SQL_ATTR_AUTOCOMMIT
1087 , (SQLPOINTER)SQL_AUTOCOMMIT_ON
1097 if(conn_.unref_transaction() == 0 && conn_.connected())
1104 , conn_.native_dbc_handle()
1107 NANODBC_THROW_DATABASE_ERROR(conn_.native_dbc_handle(), SQL_HANDLE_DBC);
1111 void rollback() NANODBC_NOEXCEPT
1115 conn_.rollback(
true);
1118 class connection& connection()
1123 const class connection& connection()
const 1129 class connection conn_;
1151 class statement::statement_impl
1154 statement_impl(
const statement_impl&) =
delete;
1155 statement_impl& operator=(
const statement_impl&) =
delete;
1161 , bind_len_or_null_()
1166 statement_impl(
class connection& conn)
1170 , bind_len_or_null_()
1175 statement_impl(
class connection& conn,
const string_type& query,
long timeout)
1179 , bind_len_or_null_()
1181 prepare(conn, query, timeout);
1184 ~statement_impl() NANODBC_NOEXCEPT
1186 if(open() && connected())
1199 void open(
class connection& conn)
1207 , conn.native_dbc_handle()
1209 open_ = success(rc);
1211 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1220 bool connected()
const 1222 return conn_.connected();
1225 const class connection& connection()
const 1230 class connection& connection()
1235 void* native_statement_handle()
const 1242 if(open() && connected())
1250 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1260 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1275 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1278 void prepare(
class connection& conn,
const string_type& query,
long timeout)
1281 prepare(query, timeout);
1284 void prepare(
const string_type& query,
long timeout)
1287 throw programming_error(
"statement has no associated open connection");
1291 NANODBC_FUNC(SQLPrepare)
1294 , (NANODBC_SQLCHAR*)query.c_str()
1295 , (SQLINTEGER)query.size());
1297 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1299 this->timeout(timeout);
1302 void timeout(
long timeout)
1309 , SQL_ATTR_QUERY_TIMEOUT
1310 , (SQLPOINTER)(std::intptr_t)timeout,
1315 if(!success(rc) && (timeout != 0))
1316 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1319 #if defined(SQL_ATTR_ASYNC_STMT_EVENT) && defined(SQL_API_SQLCOMPLETEASYNC) 1320 void enable_async(
void* event_handle)
1327 , SQL_ATTR_ASYNC_ENABLE
1328 , (SQLPOINTER)SQL_ASYNC_ENABLE_ON
1331 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1337 , SQL_ATTR_ASYNC_STMT_EVENT
1341 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1344 void async_execute_direct(
1345 class connection& conn
1346 ,
void* event_handle
1347 ,
const string_type& query
1348 ,
long batch_operations
1350 , statement& statement)
1352 RETCODE rc = just_execute_direct(
1360 if(rc != SQL_STILL_EXECUTING)
1361 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1364 result async_complete(
long batch_operations, statement& statement)
1373 if(!success(rc) || !success(arc))
1374 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1380 , SQL_ATTR_ASYNC_ENABLE
1381 , (SQLPOINTER)SQL_ASYNC_ENABLE_OFF
1384 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1386 return result(statement, batch_operations);
1390 result execute_direct(
1391 class connection& conn
1392 ,
const string_type& query
1393 ,
long batch_operations
1395 , statement& statement)
1397 #ifdef NANODBC_HANDLE_NODATA_BUG 1398 const RETCODE rc = just_execute_direct(conn, query, batch_operations, timeout, statement);
1399 if(rc == SQL_NO_DATA)
1402 just_execute_direct(conn, query, batch_operations, timeout, statement);
1404 return result(statement, batch_operations);
1407 RETCODE just_execute_direct(
1408 class connection& conn
1409 ,
const string_type& query
1410 ,
long batch_operations
1413 ,
void* event_handle = NULL)
1417 #if defined(SQL_ATTR_ASYNC_STMT_EVENT) && defined(SQL_API_SQLCOMPLETEASYNC) 1418 if(event_handle != NULL)
1419 enable_async(event_handle);
1427 , SQL_ATTR_PARAMSET_SIZE
1428 , (SQLPOINTER)(std::intptr_t)batch_operations
1431 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1433 this->timeout(timeout);
1436 NANODBC_FUNC(SQLExecDirect)
1439 , (NANODBC_SQLCHAR*)query.c_str()
1441 if(!success(rc) && rc != SQL_NO_DATA && rc != SQL_STILL_EXECUTING)
1442 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1447 result execute(
long batch_operations,
long timeout, statement& statement)
1449 #ifdef NANODBC_HANDLE_NODATA_BUG 1450 const RETCODE rc = just_execute(batch_operations, timeout, statement);
1451 if(rc == SQL_NO_DATA)
1454 just_execute(batch_operations, timeout, statement);
1456 return result(statement, batch_operations);
1459 RETCODE just_execute(
long batch_operations,
long timeout, statement& )
1478 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1485 , SQL_ATTR_PARAMSET_SIZE
1486 , (SQLPOINTER)(std::intptr_t)batch_operations
1488 if(!success(rc) && rc != SQL_NO_DATA)
1489 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1491 this->timeout(timeout);
1497 if(!success(rc) && rc != SQL_NO_DATA)
1498 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1503 result procedure_columns(
1504 const string_type& catalog
1505 ,
const string_type& schema
1506 ,
const string_type& procedure
1507 ,
const string_type& column
1508 , statement& statement)
1511 throw programming_error(
"statement has no associated open connection");
1515 NANODBC_FUNC(SQLProcedureColumns)
1518 , (NANODBC_SQLCHAR*)(catalog.empty() ? NULL : catalog.c_str())
1519 , (catalog.empty() ? 0 : SQL_NTS)
1520 , (NANODBC_SQLCHAR*)(schema.empty() ? NULL : schema.c_str())
1521 , (schema.empty() ? 0 : SQL_NTS)
1522 , (NANODBC_SQLCHAR*)procedure.c_str()
1524 , (NANODBC_SQLCHAR*)(column.empty() ? NULL : column.c_str())
1525 , (column.empty() ? 0 : SQL_NTS));
1528 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1530 return result(statement, 1);
1533 long affected_rows()
const 1543 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1544 NANODBC_ASSERT(rows <=
static_cast<SQLLEN>(std::numeric_limits<
long>::max()));
1545 return static_cast<
long>(rows);
1548 short columns()
const 1558 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1562 void reset_parameters() NANODBC_NOEXCEPT
1567 , SQL_RESET_PARAMS);
1570 unsigned long parameter_size(
short param)
const 1573 SQLSMALLINT data_type;
1574 SQLSMALLINT nullable;
1575 SQLULEN parameter_size;
1586 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1587 NANODBC_ASSERT(parameter_size <=
static_cast<SQLULEN>(std::numeric_limits<
unsigned long>::max()));
1588 return static_cast<
unsigned long>(parameter_size);
1591 static SQLSMALLINT param_type_from_direction(param_direction direction)
1596 return SQL_PARAM_INPUT;
1599 return SQL_PARAM_OUTPUT;
1602 return SQL_PARAM_INPUT_OUTPUT;
1605 return SQL_PARAM_OUTPUT;
1608 NANODBC_ASSERT(
false);
1609 throw programming_error(
"unrecognized param_direction value");
1616 , std::size_t elements
1617 , param_direction direction
1618 , SQLSMALLINT& data_type
1619 , SQLSMALLINT& param_type
1620 , SQLULEN& parameter_size
1621 , SQLSMALLINT& scale)
1624 SQLSMALLINT nullable;
1635 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1637 param_type = param_type_from_direction(direction);
1639 if(!bind_len_or_null_.count(param))
1640 bind_len_or_null_[param] = std::vector<null_type>();
1641 std::vector<null_type>().swap(bind_len_or_null_[param]);
1644 const std::size_t indicator_size = elements > 8 ? elements : 8;
1646 bind_len_or_null_[param].reserve(indicator_size);
1647 bind_len_or_null_[param].assign(indicator_size, SQL_NULL_DATA);
1652 void bind_parameter(
1656 , SQLSMALLINT data_type
1657 , SQLSMALLINT param_type
1658 , SQLULEN parameter_size
1659 , SQLSMALLINT scale)
1668 , sql_ctype<T>::value
1674 , bind_len_or_null_[param].data());
1677 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1682 void bind(
short param,
const T* values, std::size_t elements, param_direction direction);
1687 ,
const string_type::value_type* values
1689 , std::size_t elements
1690 , param_direction direction)
1692 bind(param, values, elements, direction);
1696 void bind_null(
short param, std::size_t elements)
1698 SQLSMALLINT data_type;
1699 SQLSMALLINT param_type;
1700 SQLULEN parameter_size;
1702 prepare_bind(param, elements, PARAM_IN, data_type, param_type, parameter_size, scale);
1717 , bind_len_or_null_[param].data());
1719 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1724 bool equals(
const T& lhs,
const T& rhs)
1734 , std::size_t elements
1736 ,
const T* null_sentry
1737 , param_direction direction);
1742 ,
const string_type::value_type* values
1743 , std::size_t length
1744 , std::size_t elements
1746 ,
const string_type::value_type* null_sentry
1747 , param_direction direction);
1752 class connection conn_;
1753 std::map<
short, std::vector<null_type> > bind_len_or_null_;
1759 void statement::statement_impl::bind_parameter<string_type::value_type>(
1761 ,
const string_type::value_type* data
1762 , std::size_t elements
1763 , SQLSMALLINT data_type
1764 , SQLSMALLINT param_type
1765 , SQLULEN parameter_size
1766 , SQLSMALLINT scale)
1775 , sql_ctype<string_type::value_type>::value
1781 , (elements <= 1 ? NULL : bind_len_or_null_[param].data()));
1784 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1788 void statement::statement_impl::bind(
1791 , std::size_t elements
1792 , param_direction direction)
1794 SQLSMALLINT data_type;
1795 SQLSMALLINT param_type;
1796 SQLULEN parameter_size;
1798 prepare_bind(param, elements, direction, data_type, param_type, parameter_size, scale);
1800 for(std::size_t i = 0; i < elements; ++i)
1801 bind_len_or_null_[param][i] = parameter_size;
1803 bind_parameter(param, values, elements, data_type, param_type, parameter_size, scale);
1807 void statement::statement_impl::bind(
1810 , std::size_t elements
1812 ,
const T* null_sentry
1813 , param_direction direction)
1815 SQLSMALLINT data_type;
1816 SQLSMALLINT param_type;
1817 SQLULEN parameter_size;
1819 prepare_bind(param, elements, direction, data_type, param_type, parameter_size, scale);
1821 for(std::size_t i = 0; i < elements; ++i)
1822 if((null_sentry && !equals(values[i], *null_sentry)) || (nulls && !nulls[i]))
1823 bind_len_or_null_[param][i] = parameter_size;
1825 bind_parameter(param, values, elements, data_type, param_type, parameter_size, scale);
1828 void statement::statement_impl::bind_strings(
1830 ,
const string_type::value_type* values
1831 , std::size_t length
1832 , std::size_t elements
1834 ,
const string_type::value_type* null_sentry
1835 , param_direction direction)
1837 SQLSMALLINT data_type;
1838 SQLSMALLINT param_type;
1839 SQLULEN parameter_size;
1841 prepare_bind(param, elements, direction, data_type, param_type, parameter_size, scale);
1845 for(std::size_t i = 0; i < elements; ++i)
1847 const string_type s_lhs(values + i * length, values + (i + 1) * length);
1848 const string_type s_rhs(null_sentry);
1849 #if NANODBC_USE_UNICODE 1850 std::string narrow_lhs;
1851 narrow_lhs.reserve(s_lhs.size());
1852 convert(s_lhs, narrow_lhs);
1853 std::string narrow_rhs;
1854 narrow_rhs.reserve(s_rhs.size());
1855 convert(s_rhs, narrow_lhs);
1856 if(std::strncmp(narrow_lhs.c_str(), narrow_rhs.c_str(), length))
1857 bind_len_or_null_[param][i] = parameter_size;
1859 if(std::strncmp(s_lhs.c_str(), s_rhs.c_str(), length))
1860 bind_len_or_null_[param][i] = parameter_size;
1866 for(std::size_t i = 0; i < elements; ++i)
1869 bind_len_or_null_[param][i] = SQL_NTS;
1873 bind_parameter(param, values, elements, data_type, param_type, parameter_size, scale);
1877 bool statement::statement_impl::equals(
const date& lhs,
const date& rhs)
1879 return lhs.year == rhs.year
1880 && lhs.month == rhs.month
1881 && lhs.day == rhs.day;
1885 bool statement::statement_impl::equals(
const timestamp& lhs,
const timestamp& rhs)
1887 return lhs.year == rhs.year
1888 && lhs.month == rhs.month
1889 && lhs.day == rhs.day
1890 && lhs.hour == rhs.hour
1891 && lhs.min == rhs.min
1892 && lhs.sec == rhs.sec
1893 && lhs.fract == rhs.fract;
1914 class result::result_impl
1917 result_impl(
const result_impl&) =
delete;
1918 result_impl& operator=(
const result_impl&) =
delete;
1920 result_impl(statement stmt,
long rowset_size)
1922 , rowset_size_(rowset_size)
1925 , bound_columns_size_(0)
1926 , rowset_position_(0)
1927 , bound_columns_by_name_()
1934 , stmt_.native_statement_handle()
1935 , SQL_ATTR_ROW_ARRAY_SIZE
1936 , (SQLPOINTER)(std::intptr_t)rowset_size_
1939 NANODBC_THROW_DATABASE_ERROR(stmt_.native_statement_handle(), SQL_HANDLE_STMT);
1944 , stmt_.native_statement_handle()
1945 , SQL_ATTR_ROWS_FETCHED_PTR
1949 NANODBC_THROW_DATABASE_ERROR(stmt_.native_statement_handle(), SQL_HANDLE_STMT);
1954 ~result_impl() NANODBC_NOEXCEPT
1956 cleanup_bound_columns();
1959 void* native_statement_handle()
const 1961 return stmt_.native_statement_handle();
1964 long rowset_size()
const 1966 return rowset_size_;
1969 long affected_rows()
const 1971 return stmt_.affected_rows();
1974 long rows()
const NANODBC_NOEXCEPT
1976 NANODBC_ASSERT(row_count_ <=
static_cast<SQLULEN>(std::numeric_limits<
long>::max()));
1977 return static_cast<
long>(row_count_);
1980 short columns()
const 1982 return stmt_.columns();
1987 rowset_position_ = 0;
1988 return fetch(0, SQL_FETCH_FIRST);
1993 rowset_position_ = 0;
1994 return fetch(0, SQL_FETCH_LAST);
1999 if(rows() && ++rowset_position_ < rowset_size_)
2000 return rowset_position_ < rows();
2001 rowset_position_ = 0;
2002 return fetch(0, SQL_FETCH_NEXT);
2007 if(rows() && --rowset_position_ >= 0)
2009 rowset_position_ = 0;
2010 return fetch(0, SQL_FETCH_PRIOR);
2015 rowset_position_ = 0;
2016 return fetch(row, SQL_FETCH_ABSOLUTE);
2019 bool skip(
long rows)
2021 rowset_position_ += rows;
2022 if(
this->rows() && rowset_position_ < rowset_size_)
2023 return rowset_position_ <
this->rows();
2024 rowset_position_ = 0;
2025 return fetch(rows, SQL_FETCH_RELATIVE);
2028 unsigned long position()
const 2035 , stmt_.native_statement_handle()
2036 , SQL_ATTR_ROW_NUMBER
2041 NANODBC_THROW_DATABASE_ERROR(stmt_.native_statement_handle(), SQL_HANDLE_STMT);
2051 if (pos == 0 || pos ==
static_cast<SQLULEN>(SQL_ROW_NUMBER_UNKNOWN))
2054 NANODBC_ASSERT(pos <=
static_cast<SQLULEN>(std::numeric_limits<
unsigned long>::max()));
2055 return static_cast<
unsigned long>(pos) + rowset_position_;
2058 bool end()
const NANODBC_NOEXCEPT
2067 , stmt_.native_statement_handle()
2068 , SQL_ATTR_ROW_NUMBER
2072 return (!success(rc) || rows() < 0 || pos - 1 >
static_cast<
unsigned long>(rows()));
2075 bool is_null(
short column)
const 2077 if(column >= bound_columns_size_)
2078 throw index_range_error();
2079 bound_column& col = bound_columns_[column];
2080 if(rowset_position_ >= rows())
2081 throw index_range_error();
2082 return col.cbdata_[rowset_position_] == SQL_NULL_DATA;
2085 bool is_null(
const string_type& column_name)
const 2087 const short column =
this->column(column_name);
2088 return is_null(column);
2091 string_type column_name(
short column)
const 2093 if(column >= bound_columns_size_)
2094 throw index_range_error();
2095 return bound_columns_[column].name_;
2098 long column_size(
short column)
const 2100 if(column >= bound_columns_size_)
2101 throw index_range_error();
2102 bound_column& col = bound_columns_[column];
2103 NANODBC_ASSERT(col.sqlsize_ <=
static_cast<SQLULEN>(std::numeric_limits<
long>::max()));
2104 return static_cast<
long>(col.sqlsize_);
2107 short column(
const string_type& column_name)
const 2109 typedef std::map<string_type, bound_column*>::const_iterator iter;
2110 iter i = bound_columns_by_name_.find(column_name);
2111 if(i == bound_columns_by_name_.end())
2112 throw index_range_error();
2113 return i->second->column_;
2116 int column_datatype(
short column)
const 2118 if(column >= bound_columns_size_)
2119 throw index_range_error();
2120 bound_column& col = bound_columns_[column];
2121 return col.sqltype_;
2124 int column_datatype(
const string_type& column_name)
const 2126 const short column =
this->column(column_name);
2127 bound_column& col = bound_columns_[column];
2128 return col.sqltype_;
2131 int column_c_datatype(
short column)
const 2133 if(column >= bound_columns_size_)
2134 throw index_range_error();
2135 bound_column& col = bound_columns_[column];
2139 int column_c_datatype(
const string_type& column_name)
const 2141 const short column =
this->column(column_name);
2142 bound_column& col = bound_columns_[column];
2152 , stmt_.native_statement_handle());
2153 if(rc == SQL_NO_DATA)
2156 NANODBC_THROW_DATABASE_ERROR(stmt_.native_statement_handle(), SQL_HANDLE_STMT);
2162 void get_ref(
short column, T& result)
const 2164 if(column >= bound_columns_size_)
2165 throw index_range_error();
2167 throw null_access_error();
2168 get_ref_impl<T>(column, result);
2172 void get_ref(
short column,
const T& fallback, T& result)
const 2174 if(column >= bound_columns_size_)
2175 throw index_range_error();
2181 get_ref_impl<T>(column, result);
2185 void get_ref(
const string_type& column_name, T& result)
const 2187 const short column =
this->column(column_name);
2189 throw null_access_error();
2190 get_ref_impl<T>(column, result);
2194 void get_ref(
const string_type& column_name,
const T& fallback, T& result)
const 2196 const short column =
this->column(column_name);
2202 get_ref_impl<T>(column, result);
2206 T get(
short column)
const 2209 get_ref(column, result);
2214 T get(
short column,
const T& fallback)
const 2217 get_ref(column, fallback, result);
2222 T get(
const string_type& column_name)
const 2225 get_ref(column_name, result);
2230 T get(
const string_type& column_name,
const T& fallback)
const 2233 get_ref(column_name, fallback, result);
2239 void get_ref_impl(
short column, T& result)
const;
2241 void before_move() NANODBC_NOEXCEPT
2243 for(
short i = 0; i < bound_columns_size_; ++i)
2245 bound_column& col = bound_columns_[i];
2246 for(
long j = 0; j < rowset_size_; ++j)
2248 if(col.blob_ && col.pdata_)
2249 release_bound_resources(i);
2253 void release_bound_resources(
short column) NANODBC_NOEXCEPT
2255 NANODBC_ASSERT(column < bound_columns_size_);
2256 bound_column& col = bound_columns_[column];
2257 delete[] col.pdata_;
2262 void cleanup_bound_columns() NANODBC_NOEXCEPT
2265 delete[] bound_columns_;
2266 bound_columns_ = NULL;
2267 bound_columns_size_ = 0;
2268 bound_columns_by_name_.clear();
2271 bool fetch(
long rows, SQLUSMALLINT orientation)
2278 , stmt_.native_statement_handle()
2281 if(rc == SQL_NO_DATA)
2287 NANODBC_THROW_DATABASE_ERROR(stmt_.native_statement_handle(), SQL_HANDLE_STMT);
2293 cleanup_bound_columns();
2295 const short n_columns = columns();
2299 NANODBC_ASSERT(!bound_columns_);
2300 NANODBC_ASSERT(!bound_columns_size_);
2301 bound_columns_ =
new bound_column[n_columns];
2302 bound_columns_size_ = n_columns;
2305 NANODBC_SQLCHAR column_name[1024];
2306 SQLSMALLINT sqltype, scale, nullable, len;
2309 for(SQLSMALLINT i = 0; i < n_columns; ++i)
2312 NANODBC_FUNC(SQLDescribeCol)
2314 , stmt_.native_statement_handle()
2316 , (NANODBC_SQLCHAR*)column_name
2317 ,
sizeof(column_name)/
sizeof(NANODBC_SQLCHAR)
2324 NANODBC_THROW_DATABASE_ERROR(stmt_.native_statement_handle(), SQL_HANDLE_STMT);
2327 bool is_blob =
false;
2343 bound_column& col = bound_columns_[i];
2344 col.name_ =
reinterpret_cast<string_type::value_type*>(column_name);
2346 col.sqltype_ = sqltype;
2347 col.sqlsize_ = sqlsize;
2349 bound_columns_by_name_[col.name_] = &col;
2351 using namespace std;
2352 switch(col.sqltype_)
2358 col.ctype_ = SQL_C_LONG;
2359 col.clen_ =
sizeof(int32_t);
2362 col.ctype_ = SQL_C_SBIGINT;
2363 col.clen_ =
sizeof(int64_t);
2370 col.ctype_ = SQL_C_DOUBLE;
2371 col.clen_ =
sizeof(
double);
2375 col.ctype_ = SQL_C_DATE;
2376 col.clen_ =
sizeof(date);
2379 case SQL_TYPE_TIMESTAMP:
2380 col.ctype_ = SQL_C_TIMESTAMP;
2381 col.clen_ =
sizeof(timestamp);
2385 col.ctype_ = SQL_C_CHAR;
2386 col.clen_ = (col.sqlsize_ + 1) *
sizeof(SQLCHAR);
2395 col.ctype_ = SQL_C_WCHAR;
2396 col.clen_ = (col.sqlsize_ + 1) *
sizeof(SQLWCHAR);
2403 case SQL_LONGVARCHAR:
2404 col.ctype_ = SQL_C_CHAR;
2410 case SQL_LONGVARBINARY:
2411 col.ctype_ = SQL_C_BINARY;
2416 col.ctype_ = sql_ctype<string_type>::value;
2422 for(SQLSMALLINT i = 0; i < n_columns; ++i)
2424 bound_column& col = bound_columns_[i];
2425 col.cbdata_ =
new null_type[rowset_size_];
2431 , stmt_.native_statement_handle()
2438 NANODBC_THROW_DATABASE_ERROR(stmt_.native_statement_handle(), SQL_HANDLE_STMT);
2442 col.pdata_ =
new char[rowset_size_ * col.clen_];
2446 , stmt_.native_statement_handle()
2453 NANODBC_THROW_DATABASE_ERROR(stmt_.native_statement_handle(), SQL_HANDLE_STMT);
2460 const long rowset_size_;
2462 bound_column* bound_columns_;
2463 short bound_columns_size_;
2464 long rowset_position_;
2465 std::map<string_type, bound_column*> bound_columns_by_name_;
2470 inline void result::result_impl::get_ref_impl<date>(
short column, date& result)
const 2472 bound_column& col = bound_columns_[column];
2476 result = *
reinterpret_cast<date*>(col.pdata_ + rowset_position_ * col.clen_);
2478 case SQL_C_TIMESTAMP:
2480 timestamp stamp = *
reinterpret_cast<timestamp*>(col.pdata_ + rowset_position_ * col.clen_ );
2481 date d = { stamp.year, stamp.month, stamp.day };
2486 throw type_incompatible_error();
2490 inline void result::result_impl::get_ref_impl<timestamp>(
short column, timestamp& result)
const 2492 bound_column& col = bound_columns_[column];
2497 date d = *
reinterpret_cast<date*>(col.pdata_ + rowset_position_ * col.clen_);
2498 timestamp stamp = { d.year, d.month, d.day, 0, 0, 0, 0 };
2502 case SQL_C_TIMESTAMP:
2503 result = *
reinterpret_cast<timestamp*>(col.pdata_ + rowset_position_ * col.clen_);
2506 throw type_incompatible_error();
2510 inline void result::result_impl::get_ref_impl<string_type>(
short column, string_type& result)
const 2512 bound_column& col = bound_columns_[column];
2513 const SQLULEN column_size = col.sqlsize_;
2524 SQLLEN ValueLenOrInd;
2526 void* handle = native_statement_handle();
2529 char buffer[1024] = {0};
2530 const std::size_t buffer_size =
sizeof(buffer);
2540 if(ValueLenOrInd > 0)
2542 else if(ValueLenOrInd == SQL_NULL_DATA)
2543 *col.cbdata_ = (SQLINTEGER) SQL_NULL_DATA;
2546 }
while(rc == SQL_SUCCESS_WITH_INFO);
2547 if (rc == SQL_SUCCESS || rc == SQL_NO_DATA)
2548 convert(out, result);
2552 const char* s = col.pdata_ + rowset_position_ * col.clen_;
2553 const std::string::size_type str_size = std::strlen(s);
2554 result.assign(s, s + str_size);
2565 wide_string_type out;
2566 SQLLEN ValueLenOrInd;
2568 void* handle = native_statement_handle();
2571 wide_char_t buffer[512] = {0};
2572 const std::size_t buffer_size =
sizeof(buffer);
2582 if(ValueLenOrInd > 0)
2584 else if(ValueLenOrInd == SQL_NULL_DATA)
2585 *col.cbdata_ = (SQLINTEGER) SQL_NULL_DATA;
2588 }
while(rc == SQL_SUCCESS_WITH_INFO);
2589 if (rc == SQL_SUCCESS || rc == SQL_NO_DATA)
2590 convert(out, result);
2595 const SQLWCHAR* s =
reinterpret_cast<SQLWCHAR*>(col.pdata_ + rowset_position_ * col.clen_);
2596 const string_type::size_type str_size = *col.cbdata_ /
sizeof(SQLWCHAR);
2597 wide_string_type temp(s, s + str_size);
2598 convert(temp, result);
2605 const char* s = col.pdata_ + rowset_position_ * col.clen_;
2606 result.assign(s, s + column_size);
2613 buffer.reserve(column_size + 1);
2614 buffer.resize(buffer.capacity());
2616 fill(buffer.begin(), buffer.end(),
'\0');
2617 const wide_char_t data = *
reinterpret_cast<wide_char_t*>(col.pdata_ + rowset_position_ * col.clen_);
2618 const int bytes = std::snprintf(
const_cast<
char*>(buffer.data()), column_size,
"%d", data);
2620 throw type_incompatible_error();
2621 else if((SQLULEN)bytes < column_size)
2622 buffer.resize(bytes);
2623 buffer.resize(std::strlen(buffer.data()));
2624 result.reserve(buffer.size() *
sizeof(string_type::value_type));
2625 convert(buffer, result);
2631 using namespace std;
2633 buffer.reserve(column_size + 1);
2634 buffer.resize(buffer.capacity());
2636 fill(buffer.begin(), buffer.end(),
'\0');
2637 const intmax_t data = (intmax_t)*
reinterpret_cast<int64_t*>(col.pdata_ + rowset_position_ * col.clen_);
2638 const int bytes = std::snprintf(
const_cast<
char*>(buffer.data()), column_size,
"%jd", data);
2640 throw type_incompatible_error();
2641 else if((SQLULEN)bytes < column_size)
2642 buffer.resize(bytes);
2643 buffer.resize(std::strlen(buffer.data()));
2644 result.reserve(buffer.size() *
sizeof(string_type::value_type));
2645 convert(buffer, result);
2652 buffer.reserve(column_size + 1);
2653 buffer.resize(buffer.capacity());
2655 fill(buffer.begin(), buffer.end(),
'\0');
2656 const float data = *
reinterpret_cast<
float*>(col.pdata_ + rowset_position_ * col.clen_);
2657 const int bytes = std::snprintf(
const_cast<
char*>(buffer.data()), column_size,
"%f", data);
2659 throw type_incompatible_error();
2660 else if((SQLULEN)bytes < column_size)
2661 buffer.resize(bytes);
2662 buffer.resize(std::strlen(buffer.data()));
2663 result.reserve(buffer.size() *
sizeof(string_type::value_type));
2664 convert(buffer, result);
2671 const SQLULEN width = column_size + 2;
2672 buffer.reserve(width + 1);
2673 buffer.resize(buffer.capacity());
2675 fill(buffer.begin(), buffer.end(),
'\0');
2676 const double data = *
reinterpret_cast<
double*>(col.pdata_ + rowset_position_ * col.clen_);
2677 const int bytes = std::snprintf(
2678 const_cast<
char*>(buffer.data())
2684 throw type_incompatible_error();
2685 else if((SQLULEN)bytes < column_size)
2686 buffer.resize(bytes);
2687 buffer.resize(std::strlen(buffer.data()));
2688 result.reserve(buffer.size() *
sizeof(string_type::value_type));
2689 convert(buffer, result);
2695 const date d = *
reinterpret_cast<date*>(col.pdata_ + rowset_position_ * col.clen_);
2697 st.tm_year = d.year - 1900;
2698 st.tm_mon = d.month - 1;
2700 char* old_lc_time = std::setlocale(LC_TIME, NULL);
2701 std::setlocale(LC_TIME,
"");
2703 std::strftime(date_str,
sizeof(date_str),
"%Y-%m-%d", &st);
2704 std::setlocale(LC_TIME, old_lc_time);
2705 convert(date_str, result);
2709 case SQL_C_TIMESTAMP:
2711 const timestamp stamp = *
reinterpret_cast<timestamp*>(col.pdata_ + rowset_position_ * col.clen_);
2713 st.tm_year = stamp.year - 1900;
2714 st.tm_mon = stamp.month - 1;
2715 st.tm_mday = stamp.day;
2716 st.tm_hour = stamp.hour;
2717 st.tm_min = stamp.min;
2718 st.tm_sec = stamp.sec;
2719 char* old_lc_time = std::setlocale(LC_TIME, NULL);
2720 std::setlocale(LC_TIME,
"");
2722 std::strftime(date_str,
sizeof(date_str),
"%Y-%m-%d %H:%M:%S %z", &st);
2723 std::setlocale(LC_TIME, old_lc_time);
2724 convert(date_str, result);
2728 throw type_incompatible_error();
2732 void result::result_impl::get_ref_impl(
short column, T& result)
const 2734 bound_column& col = bound_columns_[column];
2735 using namespace std;
2736 const char* s = col.pdata_ + rowset_position_ * col.clen_;
2739 case SQL_C_CHAR: result = (T)*(
char*)(s);
return;
2740 case SQL_C_SSHORT: result = (T)*(
short*)(s);
return;
2741 case SQL_C_USHORT: result = (T)*(
unsigned short*)(s);
return;
2742 case SQL_C_LONG: result = (T)*(int32_t*)(s);
return;
2743 case SQL_C_SLONG: result = (T)*(int32_t*)(s);
return;
2744 case SQL_C_ULONG: result = (T)*(uint32_t*)(s);
return;
2745 case SQL_C_FLOAT: result = (T)*(
float*)(s);
return;
2746 case SQL_C_DOUBLE: result = (T)*(
double*)(s);
return;
2747 case SQL_C_SBIGINT: result = (T)*(int64_t*)(s);
return;
2748 case SQL_C_UBIGINT: result = (T)*(uint64_t*)(s);
return;
2750 throw type_incompatible_error();
2768 result execute(connection& conn,
const string_type& query,
long batch_operations,
long timeout)
2770 class statement statement;
2771 return statement.execute_direct(conn, query, batch_operations, timeout);
2774 void just_execute(connection& conn,
const string_type& query,
long batch_operations,
long timeout) {
2775 class statement statement;
2776 statement.just_execute_direct(conn, query, batch_operations, timeout);
2779 result execute(statement& stmt,
long batch_operations)
2781 return stmt.execute(batch_operations);
2784 void just_execute(statement& stmt,
long batch_operations)
2786 return stmt.just_execute(batch_operations);
2789 result transact(statement& stmt,
long batch_operations)
2791 class transaction transaction(stmt.connection());
2792 result rvalue = stmt.execute(batch_operations);
2793 transaction.commit();
2797 void just_transact(statement& stmt,
long batch_operations)
2799 class transaction transaction(stmt.connection());
2800 stmt.just_execute(batch_operations);
2801 transaction.commit();
2804 void prepare(statement& stmt,
const string_type& query,
long timeout)
2806 stmt.prepare(stmt.connection(), query, timeout);
2824 connection::connection()
2825 : impl_(
new connection_impl())
2830 connection::connection(
const connection& rhs)
2836 #ifndef NANODBC_NO_MOVE_CTOR 2837 connection::connection(connection&& rhs) NANODBC_NOEXCEPT
2838 : impl_(std::move(rhs.impl_))
2844 connection& connection::operator=(connection rhs)
2850 void connection::swap(connection& rhs) NANODBC_NOEXCEPT
2853 swap(impl_, rhs.impl_);
2856 connection::connection(
2857 const string_type& dsn
2858 ,
const string_type& user
2859 ,
const string_type& pass
2861 : impl_(
new connection_impl(dsn, user, pass, timeout))
2866 connection::connection(
const string_type& connection_string,
long timeout)
2867 : impl_(
new connection_impl(connection_string, timeout))
2872 connection::~connection() NANODBC_NOEXCEPT
2877 void connection::connect(
2878 const string_type& dsn
2879 ,
const string_type& user
2880 ,
const string_type& pass
2883 impl_->connect(dsn, user, pass, timeout);
2886 void connection::connect(
const string_type& connection_string,
long timeout)
2888 impl_->connect(connection_string, timeout);
2891 #ifdef SQL_ATTR_ASYNC_DBC_EVENT 2892 void connection::async_connect(
2893 const string_type& dsn
2894 ,
const string_type& user
2895 ,
const string_type& pass
2896 ,
void* event_handle
2899 impl_->connect(dsn, user, pass, timeout, event_handle);
2902 void connection::async_connect(
const string_type& connection_string,
void* event_handle,
long timeout)
2904 impl_->connect(connection_string, timeout, event_handle);
2907 void connection::async_complete()
2909 impl_->async_complete();
2913 bool connection::connected()
const 2915 return impl_->connected();
2918 void connection::disconnect()
2920 impl_->disconnect();
2923 std::size_t connection::transactions()
const 2925 return impl_->transactions();
2928 void* connection::native_dbc_handle()
const 2930 return impl_->native_dbc_handle();
2933 void* connection::native_env_handle()
const 2935 return impl_->native_env_handle();
2938 string_type connection::dbms_name()
const 2940 return impl_->dbms_name();
2943 string_type connection::dbms_version()
const 2945 return impl_->dbms_version();
2948 string_type connection::driver_name()
const 2950 return impl_->driver_name();
2953 string_type connection::database_name()
const 2955 return impl_->database_name();
2958 string_type connection::catalog_name()
const 2960 return impl_->catalog_name();
2963 std::size_t connection::ref_transaction()
2965 return impl_->ref_transaction();
2968 std::size_t connection::unref_transaction()
2970 return impl_->unref_transaction();
2973 bool connection::rollback()
const 2975 return impl_->rollback();
2978 void connection::rollback(
bool onoff)
2980 impl_->rollback(onoff);
2998 transaction::transaction(
const class connection& conn)
2999 : impl_(
new transaction_impl(conn))
3004 transaction::transaction(
const transaction& rhs)
3010 #ifndef NANODBC_NO_MOVE_CTOR 3011 transaction::transaction(transaction&& rhs) NANODBC_NOEXCEPT
3012 : impl_(std::move(rhs.impl_))
3018 transaction& transaction::operator=(transaction rhs)
3024 void transaction::swap(transaction& rhs) NANODBC_NOEXCEPT
3027 swap(impl_, rhs.impl_);
3030 transaction::~transaction() NANODBC_NOEXCEPT
3035 void transaction::commit()
3040 void transaction::rollback() NANODBC_NOEXCEPT
3045 class connection& transaction::connection()
3047 return impl_->connection();
3050 const class connection& transaction::connection()
const 3052 return impl_->connection();
3055 transaction::operator
class connection&()
3057 return impl_->connection();
3060 transaction::operator
const class connection&()
const 3062 return impl_->connection();
3080 statement::statement()
3081 : impl_(
new statement_impl())
3086 statement::statement(
class connection& conn)
3087 : impl_(
new statement_impl(conn))
3092 #ifndef NANODBC_NO_MOVE_CTOR 3093 statement::statement(statement&& rhs) NANODBC_NOEXCEPT
3094 : impl_(std::move(rhs.impl_))
3100 statement::statement(
class connection& conn,
const string_type& query,
long timeout)
3101 : impl_(
new statement_impl(conn, query, timeout))
3106 statement::statement(
const statement& rhs)
3112 statement& statement::operator=(statement rhs)
3118 void statement::swap(statement& rhs) NANODBC_NOEXCEPT
3121 swap(impl_, rhs.impl_);
3124 statement::~statement() NANODBC_NOEXCEPT
3129 void statement::open(
class connection& conn)
3134 bool statement::open()
const 3136 return impl_->open();
3139 bool statement::connected()
const 3141 return impl_->connected();
3144 const class connection& statement::connection()
const 3146 return impl_->connection();
3149 class connection& statement::connection()
3151 return impl_->connection();
3154 void* statement::native_statement_handle()
const 3156 return impl_->native_statement_handle();
3159 void statement::close()
3164 void statement::cancel()
3169 void statement::prepare(
class connection& conn,
const string_type& query,
long timeout)
3171 impl_->prepare(conn, query, timeout);
3174 void statement::prepare(
const string_type& query,
long timeout)
3176 impl_->prepare(query, timeout);
3179 void statement::timeout(
long timeout)
3181 impl_->timeout(timeout);
3184 result statement::execute_direct(
3185 class connection& conn
3186 ,
const string_type& query
3187 ,
long batch_operations
3190 return impl_->execute_direct(conn, query, batch_operations, timeout, *
this);
3193 #if defined(SQL_ATTR_ASYNC_STMT_EVENT) && defined(SQL_API_SQLCOMPLETEASYNC) 3194 void statement::async_execute_direct(
3195 class connection& conn
3196 ,
void* event_handle
3197 ,
const string_type& query
3198 ,
long batch_operations
3201 impl_->async_execute_direct(conn, event_handle, query, batch_operations, timeout, *
this);
3204 result statement::async_complete(
long batch_operations)
3206 return impl_->async_complete(batch_operations, *
this);
3210 void statement::just_execute_direct(
3211 class connection& conn
3212 ,
const string_type& query
3213 ,
long batch_operations
3216 impl_->just_execute_direct(conn, query, batch_operations, timeout, *
this);
3219 result statement::execute(
long batch_operations,
long timeout)
3221 return impl_->execute(batch_operations, timeout, *
this);
3224 void statement::just_execute(
long batch_operations,
long timeout)
3226 impl_->just_execute(batch_operations, timeout, *
this);
3229 result statement::procedure_columns(
3230 const string_type& catalog
3231 ,
const string_type& schema
3232 ,
const string_type& procedure
3233 ,
const string_type& column)
3235 return impl_->procedure_columns(catalog, schema, procedure, column, *
this);
3238 long statement::affected_rows()
const 3240 return impl_->affected_rows();
3243 short statement::columns()
const 3245 return impl_->columns();
3248 void statement::reset_parameters() NANODBC_NOEXCEPT
3250 impl_->reset_parameters();
3253 unsigned long statement::parameter_size(
short param)
const 3255 return impl_->parameter_size(param);
3259 #define NANODBC_INSTANTIATE_BINDS(type) 3260 template void statement::bind(short, const type*, param_direction); 3261 template void statement::bind(short, const type*, std::size_t, param_direction); 3262 template void statement::bind(short, const type*, std::size_t, const type*, param_direction); 3263 template void statement::bind(short, const type*, std::size_t, const bool*, param_direction) 3267 NANODBC_INSTANTIATE_BINDS(string_type::value_type);
3268 NANODBC_INSTANTIATE_BINDS(
short);
3269 NANODBC_INSTANTIATE_BINDS(
unsigned short);
3270 NANODBC_INSTANTIATE_BINDS(int32_t);
3271 NANODBC_INSTANTIATE_BINDS(uint32_t);
3272 NANODBC_INSTANTIATE_BINDS(int64_t);
3273 NANODBC_INSTANTIATE_BINDS(uint64_t);
3274 NANODBC_INSTANTIATE_BINDS(
float);
3275 NANODBC_INSTANTIATE_BINDS(
double);
3276 NANODBC_INSTANTIATE_BINDS(date);
3277 NANODBC_INSTANTIATE_BINDS(timestamp);
3279 #undef NANODBC_INSTANTIATE_BINDS 3282 void statement::bind(
short param,
const T* value, param_direction direction)
3284 impl_->bind(param, value, 1, direction);
3288 void statement::bind(
short param,
const T* values, std::size_t elements, param_direction direction)
3290 impl_->bind(param, values, elements, direction);
3294 void statement::bind(
3297 , std::size_t elements
3298 ,
const T* null_sentry
3299 , param_direction direction)
3301 impl_->bind(param, values, elements, 0, null_sentry, direction);
3305 void statement::bind(
3308 , std::size_t elements
3310 , param_direction direction)
3312 impl_->bind(param, values, elements, nulls, (T*)0, direction);
3315 void statement::bind_strings(
3317 ,
const string_type::value_type* values
3318 , std::size_t length
3319 , std::size_t elements
3320 , param_direction direction)
3322 impl_->bind_strings(param, values, length, elements, direction);
3325 void statement::bind_strings(
3327 ,
const string_type::value_type* values
3328 , std::size_t length
3329 , std::size_t elements
3330 ,
const string_type::value_type* null_sentry
3331 , param_direction direction)
3333 impl_->bind_strings(param, values, length, elements, (
bool*)0, null_sentry, direction);
3336 void statement::bind_strings(
3338 ,
const string_type::value_type* values
3339 , std::size_t length
3340 , std::size_t elements
3342 , param_direction direction)
3344 impl_->bind_strings(
3350 , (string_type::value_type*)0
3354 void statement::bind_null(
short param, std::size_t elements)
3356 impl_->bind_null(param, elements);
3364 catalog::tables::tables(result& find_result)
3365 : result_(find_result)
3369 bool catalog::tables::next()
3371 return result_.next();
3374 string_type catalog::tables::table_catalog()
const 3377 return result_.get<string_type>(0, string_type());
3380 string_type catalog::tables::table_schema()
const 3383 return result_.get<string_type>(1, string_type());
3386 string_type catalog::tables::table_name()
const 3389 return result_.get<string_type>(2);
3392 string_type catalog::tables::table_type()
const 3395 return result_.get<string_type>(3);
3398 string_type catalog::tables::table_remarks()
const 3401 return result_.get<string_type>(4, string_type());
3404 catalog::primary_keys::primary_keys(result& find_result)
3405 : result_(find_result)
3409 bool catalog::primary_keys::next()
3411 return result_.next();
3414 string_type catalog::primary_keys::table_catalog()
const 3417 return result_.get<string_type>(0, string_type());
3420 string_type catalog::primary_keys::table_schema()
const 3423 return result_.get<string_type>(1, string_type());
3426 string_type catalog::primary_keys::table_name()
const 3429 return result_.get<string_type>(2);
3432 string_type catalog::primary_keys::column_name()
const 3435 return result_.get<string_type>(3);
3438 short catalog::primary_keys::column_number()
const 3441 return result_.get<
short>(4);
3444 string_type catalog::primary_keys::primary_key_name()
const 3447 return result_.get<string_type>(5);
3450 catalog::columns::columns(result& find_result)
3451 : result_(find_result)
3455 bool catalog::columns::next()
3457 return result_.next();
3460 string_type catalog::columns::table_catalog()
const 3463 return result_.get<string_type>(0, string_type());
3466 string_type catalog::columns::table_schema()
const 3469 return result_.get<string_type>(1, string_type());
3472 string_type catalog::columns::table_name()
const 3475 return result_.get<string_type>(2);
3478 string_type catalog::columns::column_name()
const 3481 return result_.get<string_type>(3);
3484 short catalog::columns::data_type()
const 3487 return result_.get<
short>(4);
3490 string_type catalog::columns::type_name()
const 3493 return result_.get<string_type>(5);
3496 long catalog::columns::column_size()
const 3499 return result_.get<
long>(6);
3502 long catalog::columns::buffer_length()
const 3505 return result_.get<
long>(7);
3508 short catalog::columns::decimal_digits()
const 3511 return result_.get<
short>(8, 0);
3514 short catalog::columns::numeric_precision_radix()
const 3517 return result_.get<
short>(9, 0);
3520 short catalog::columns::nullable()
const 3523 return result_.get<
short>(10);
3526 string_type catalog::columns::remarks()
const 3529 return result_.get<string_type>(11, string_type());
3532 string_type catalog::columns::column_default()
const 3535 return result_.get<string_type>(12, string_type());
3538 short catalog::columns::sql_data_type()
const 3541 return result_.get<
short>(13);
3544 short catalog::columns::sql_datetime_subtype()
const 3547 return result_.get<
short>(14, 0);
3550 long catalog::columns::char_octed_length()
const 3553 return result_.get<
long>(15, 0);
3556 long catalog::columns::ordinal_position()
const 3559 return result_.get<
long>(16);
3562 string_type catalog::columns::is_nullable()
const 3569 return result_.get<string_type>(17, string_type());
3572 catalog::catalog(connection& conn)
3577 catalog::tables catalog::find_tables(
3578 const string_type& table
3579 ,
const string_type& type
3580 ,
const string_type& schema
3581 ,
const string_type& catalog)
3583 statement stmt(conn_);
3586 NANODBC_FUNC(SQLTables)
3588 , stmt.native_statement_handle()
3589 , (NANODBC_SQLCHAR*)(catalog.empty() ? NULL : catalog.c_str())
3590 , (catalog.empty() ? 0 : SQL_NTS)
3591 , (NANODBC_SQLCHAR*)(schema.empty() ? NULL : schema.c_str())
3592 , (schema.empty() ? 0 : SQL_NTS)
3593 , (NANODBC_SQLCHAR*)(table.empty() ? NULL : table.c_str())
3594 , (table.empty() ? 0 : SQL_NTS)
3595 , (NANODBC_SQLCHAR*)(type.empty() ? NULL : type.c_str())
3596 , (type.empty() ? 0 : SQL_NTS));
3598 NANODBC_THROW_DATABASE_ERROR(stmt.native_statement_handle(), SQL_HANDLE_STMT);
3600 result find_result(stmt, 1);
3601 return catalog::tables(find_result);
3604 catalog::columns catalog::find_columns(
3605 const string_type& column
3606 ,
const string_type& table
3607 ,
const string_type& schema
3608 ,
const string_type& catalog)
3610 statement stmt(conn_);
3613 NANODBC_FUNC(SQLColumns)
3615 , stmt.native_statement_handle()
3616 , (NANODBC_SQLCHAR*)(catalog.empty() ? NULL : catalog.c_str())
3617 , (catalog.empty() ? 0 : SQL_NTS)
3618 , (NANODBC_SQLCHAR*)(schema.empty() ? NULL : schema.c_str())
3619 , (schema.empty() ? 0 : SQL_NTS)
3620 , (NANODBC_SQLCHAR*)(table.empty() ? NULL : table.c_str())
3621 , (table.empty() ? 0 : SQL_NTS)
3622 , (NANODBC_SQLCHAR*)(column.empty() ? NULL : column.c_str())
3623 , (column.empty() ? 0 : SQL_NTS));
3625 NANODBC_THROW_DATABASE_ERROR(stmt.native_statement_handle(), SQL_HANDLE_STMT);
3627 result find_result(stmt, 1);
3628 return catalog::columns(find_result);
3631 catalog::primary_keys catalog::find_primary_keys(
3632 const string_type& table
3633 ,
const string_type& schema
3634 ,
const string_type& catalog)
3636 statement stmt(conn_);
3639 NANODBC_FUNC(SQLPrimaryKeys)
3641 , stmt.native_statement_handle()
3642 , (NANODBC_SQLCHAR*)(catalog.empty() ? NULL : catalog.c_str())
3643 , (catalog.empty() ? 0 : SQL_NTS)
3644 , (NANODBC_SQLCHAR*)(schema.empty() ? NULL : schema.c_str())
3645 , (schema.empty() ? 0 : SQL_NTS)
3646 , (NANODBC_SQLCHAR*)(table.empty() ? NULL : table.c_str())
3647 , (table.empty() ? 0 : SQL_NTS));
3649 NANODBC_THROW_DATABASE_ERROR(stmt.native_statement_handle(), SQL_HANDLE_STMT);
3651 result find_result(stmt, 1);
3652 return catalog::primary_keys(find_result);
3676 result::~result() NANODBC_NOEXCEPT
3681 result::result(statement stmt,
long rowset_size)
3682 : impl_(
new result_impl(stmt, rowset_size))
3687 #ifndef NANODBC_NO_MOVE_CTOR 3688 result::result(result&& rhs) NANODBC_NOEXCEPT
3689 : impl_(std::move(rhs.impl_))
3695 result::result(
const result& rhs)
3701 result& result::operator=(result rhs)
3707 void result::swap(result& rhs) NANODBC_NOEXCEPT
3710 swap(impl_, rhs.impl_);
3713 void* result::native_statement_handle()
const 3715 return impl_->native_statement_handle();
3718 long result::rowset_size()
const NANODBC_NOEXCEPT
3720 return impl_->rowset_size();
3723 long result::affected_rows()
const 3725 return impl_->affected_rows();
3728 long result::rows()
const NANODBC_NOEXCEPT
3730 return impl_->rows();
3733 short result::columns()
const 3735 return impl_->columns();
3738 bool result::first()
3740 return impl_->first();
3745 return impl_->last();
3750 return impl_->next();
3753 bool result::prior()
3755 return impl_->prior();
3758 bool result::move(
long row)
3760 return impl_->move(row);
3763 bool result::skip(
long rows)
3765 return impl_->skip(rows);
3768 unsigned long result::position()
const 3770 return impl_->position();
3773 bool result::end()
const NANODBC_NOEXCEPT
3775 return impl_->end();
3778 bool result::is_null(
short column)
const 3780 return impl_->is_null(column);
3783 bool result::is_null(
const string_type& column_name)
const 3785 return impl_->is_null(column_name);
3788 string_type result::column_name(
short column)
const 3790 return impl_->column_name(column);
3793 long result::column_size(
short column)
const 3795 return impl_->column_size(column);
3798 short result::column(
const string_type& column_name)
const 3800 return impl_->column(column_name);
3803 int result::column_datatype(
short column)
const 3805 return impl_->column_datatype(column);
3808 int result::column_datatype(
const string_type& column_name)
const 3810 return impl_->column_datatype(column_name);
3813 int result::column_c_datatype(
short column)
const 3815 return impl_->column_c_datatype(column);
3818 int result::column_c_datatype(
const string_type& column_name)
const 3820 return impl_->column_c_datatype(column_name);
3823 bool result::next_result()
3825 return impl_->next_result();
3829 void result::get_ref(
short column, T& result)
const 3831 return impl_->get_ref<T>(column, result);
3835 void result::get_ref(
short column,
const T& fallback, T& result)
const 3837 return impl_->get_ref<T>(column, fallback, result);
3841 void result::get_ref(
const string_type& column_name, T& result)
const 3843 return impl_->get_ref<T>(column_name, result);
3847 void result::get_ref(
const string_type& column_name,
const T& fallback, T& result)
const 3849 return impl_->get_ref<T>(column_name, fallback, result);
3853 T result::get(
short column)
const 3855 return impl_->get<T>(column);
3859 T result::get(
short column,
const T& fallback)
const 3861 return impl_->get<T>(column, fallback);
3865 T result::get(
const string_type& column_name)
const 3867 return impl_->get<T>(column_name);
3871 T result::get(
const string_type& column_name,
const T& fallback)
const 3873 return impl_->get<T>(column_name, fallback);
3876 result::operator
bool()
const 3878 return static_cast<
bool>(impl_);
3882 template void result::get_ref(
short, string_type::value_type&)
const;
3883 template void result::get_ref(
short,
short&)
const;
3884 template void result::get_ref(
short,
unsigned short&)
const;
3885 template void result::get_ref(
short, int32_t&)
const;
3886 template void result::get_ref(
short, uint32_t&)
const;
3887 template void result::get_ref(
short, int64_t&)
const;
3888 template void result::get_ref(
short, uint64_t&)
const;
3889 template void result::get_ref(
short,
float&)
const;
3890 template void result::get_ref(
short,
double&)
const;
3891 template void result::get_ref(
short, string_type&)
const;
3892 template void result::get_ref(
short, date&)
const;
3893 template void result::get_ref(
short, timestamp&)
const;
3895 template void result::get_ref(
const string_type&, string_type::value_type&)
const;
3896 template void result::get_ref(
const string_type&,
short&)
const;
3897 template void result::get_ref(
const string_type&,
unsigned short&)
const;
3898 template void result::get_ref(
const string_type&, int32_t&)
const;
3899 template void result::get_ref(
const string_type&, uint32_t&)
const;
3900 template void result::get_ref(
const string_type&, int64_t&)
const;
3901 template void result::get_ref(
const string_type&, uint64_t&)
const;
3902 template void result::get_ref(
const string_type&,
float&)
const;
3903 template void result::get_ref(
const string_type&,
double&)
const;
3904 template void result::get_ref(
const string_type&, string_type&)
const;
3905 template void result::get_ref(
const string_type&, date&)
const;
3906 template void result::get_ref(
const string_type&, timestamp&)
const;
3909 template void result::get_ref(
short,
const string_type::value_type&, string_type::value_type&)
const;
3910 template void result::get_ref(
short,
const short&,
short&)
const;
3911 template void result::get_ref(
short,
const unsigned short&,
unsigned short&)
const;
3912 template void result::get_ref(
short,
const int32_t&, int32_t&)
const;
3913 template void result::get_ref(
short,
const uint32_t&, uint32_t&)
const;
3914 template void result::get_ref(
short,
const int64_t&, int64_t&)
const;
3915 template void result::get_ref(
short,
const uint64_t&, uint64_t&)
const;
3916 template void result::get_ref(
short,
const float&,
float&)
const;
3917 template void result::get_ref(
short,
const double&,
double&)
const;
3918 template void result::get_ref(
short,
const string_type&, string_type&)
const;
3919 template void result::get_ref(
short,
const date&, date&)
const;
3920 template void result::get_ref(
short,
const timestamp&, timestamp&)
const;
3922 template void result::get_ref(
const string_type&,
const string_type::value_type&, string_type::value_type&)
const;
3923 template void result::get_ref(
const string_type&,
const short&,
short&)
const;
3924 template void result::get_ref(
const string_type&,
const unsigned short&,
unsigned short&)
const;
3925 template void result::get_ref(
const string_type&,
const int32_t&, int32_t&)
const;
3926 template void result::get_ref(
const string_type&,
const uint32_t&, uint32_t&)
const;
3927 template void result::get_ref(
const string_type&,
const int64_t&, int64_t&)
const;
3928 template void result::get_ref(
const string_type&,
const uint64_t&, uint64_t&)
const;
3929 template void result::get_ref(
const string_type&,
const float&,
float&)
const;
3930 template void result::get_ref(
const string_type&,
const double&,
double&)
const;
3931 template void result::get_ref(
const string_type&,
const string_type&, string_type&)
const;
3932 template void result::get_ref(
const string_type&,
const date&, date&)
const;
3933 template void result::get_ref(
const string_type&,
const timestamp&, timestamp&)
const;
3936 template string_type::value_type result::get(
short)
const;
3937 template short result::get(
short)
const;
3938 template unsigned short result::get(
short)
const;
3939 template int32_t result::get(
short)
const;
3940 template uint32_t result::get(
short)
const;
3941 template int64_t result::get(
short)
const;
3942 template uint64_t result::get(
short)
const;
3943 template float result::get(
short)
const;
3944 template double result::get(
short)
const;
3945 template string_type result::get(
short)
const;
3946 template date result::get(
short)
const;
3947 template timestamp result::get(
short)
const;
3949 template string_type::value_type result::get(
const string_type&)
const;
3950 template short result::get(
const string_type&)
const;
3951 template unsigned short result::get(
const string_type&)
const;
3952 template int32_t result::get(
const string_type&)
const;
3953 template uint32_t result::get(
const string_type&)
const;
3954 template int64_t result::get(
const string_type&)
const;
3955 template uint64_t result::get(
const string_type&)
const;
3956 template float result::get(
const string_type&)
const;
3957 template double result::get(
const string_type&)
const;
3958 template string_type result::get(
const string_type&)
const;
3959 template date result::get(
const string_type&)
const;
3960 template timestamp result::get(
const string_type&)
const;
3963 template string_type::value_type result::get(
short,
const string_type::value_type&)
const;
3964 template short result::get(
short,
const short&)
const;
3965 template unsigned short result::get(
short,
const unsigned short&)
const;
3966 template int32_t result::get(
short,
const int32_t&)
const;
3967 template uint32_t result::get(
short,
const uint32_t&)
const;
3968 template int64_t result::get(
short,
const int64_t&)
const;
3969 template uint64_t result::get(
short,
const uint64_t&)
const;
3970 template float result::get(
short,
const float&)
const;
3971 template double result::get(
short,
const double&)
const;
3972 template string_type result::get(
short,
const string_type&)
const;
3973 template date result::get(
short,
const date&)
const;
3974 template timestamp result::get(
short,
const timestamp&)
const;
3976 template string_type::value_type result::get(
const string_type&,
const string_type::value_type&)
const;
3977 template short result::get(
const string_type&,
const short&)
const;
3978 template unsigned short result::get(
const string_type&,
const unsigned short&)
const;
3979 template int32_t result::get(
const string_type&,
const int32_t&)
const;
3980 template uint32_t result::get(
const string_type&,
const uint32_t&)
const;
3981 template int64_t result::get(
const string_type&,
const int64_t&)
const;
3982 template uint64_t result::get(
const string_type&,
const uint64_t&)
const;
3983 template float result::get(
const string_type&,
const float&)
const;
3984 template double result::get(
const string_type&,
const double&)
const;
3985 template string_type result::get(
const string_type&,
const string_type&)
const;
3986 template date result::get(
const string_type&,
const date&)
const;
3987 template timestamp result::get(
const string_type&,
const timestamp&)
const;
3991 #undef NANODBC_THROW_DATABASE_ERROR 3992 #undef NANODBC_STRINGIZE 3993 #undef NANODBC_STRINGIZE_I 3994 #undef NANODBC_CALL_RC