1#ifndef DOXYGEN_SHOULD_SKIP_THIS
29 #define NANODBC_ASSERT(expr) assert(expr)
32#ifdef NANODBC_USE_BOOST_CONVERT
33 #include <boost/locale/encoding_utf.hpp>
38#if defined(_MSC_VER) && _MSC_VER <= 1800
40 #pragma warning(disable:4244)
41 #pragma warning(disable:4312)
42 #pragma warning(disable:4996)
47 #define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_6
60#ifndef NANODBC_ODBC_VERSION
61 #ifdef SQL_OV_ODBC3_80
63 #define NANODBC_ODBC_VERSION SQL_OV_ODBC3_80
66 #define NANODBC_ODBC_VERSION SQL_OV_ODBC3
80#ifdef NANODBC_USE_UNICODE
81 #ifdef NANODBC_USE_IODBC_WIDE_STRINGS
82 #define NANODBC_TEXT(s) U ## s
84 #define NANODBC_TEXT(s) u ## s
86 #define NANODBC_FUNC(f) f ## W
87 #define NANODBC_SQLCHAR SQLWCHAR
89 #define NANODBC_TEXT(s) s
90 #define NANODBC_FUNC(f) f
91 #define NANODBC_SQLCHAR SQLCHAR
94#ifdef NANODBC_USE_IODBC_WIDE_STRINGS
95 typedef std::u32string wide_string_type;
96 #define NANODBC_CODECVT_TYPE std::codecvt_utf8
98 typedef std::u16string wide_string_type;
99 #define NANODBC_CODECVT_TYPE std::codecvt_utf8_utf16
101typedef wide_string_type::value_type wide_char_t;
104 #ifndef NANODBC_USE_UNICODE
108 #define SQL_NOUNICODEMAP
122#define NANODBC_STRINGIZE_I(text) #text
123#define NANODBC_STRINGIZE(text) NANODBC_STRINGIZE_I(text)
128#ifdef NANODBC_ODBC_API_DEBUG
130 #define NANODBC_CALL_RC(FUNC, RC, ...) \
133 std::cerr << __FILE__ ":" NANODBC_STRINGIZE( __LINE__) " " \
134 NANODBC_STRINGIZE(FUNC) "(" # __VA_ARGS__ ")" << std::endl; \
135 RC = FUNC( __VA_ARGS__); \
138 #define NANODBC_CALL(FUNC, ...) \
141 std::cerr << __FILE__ ":" NANODBC_STRINGIZE( __LINE__) " " \
142 NANODBC_STRINGIZE(FUNC) "(" # __VA_ARGS__ ")" << std::endl; \
143 FUNC( __VA_ARGS__); \
147 #define NANODBC_CALL_RC(FUNC, RC, ...) RC = FUNC( __VA_ARGS__)
148 #define NANODBC_CALL(FUNC, ...) FUNC( __VA_ARGS__)
166 #ifdef NANODBC_ODBC_API_DEBUG
167 inline nanodbc::string_type return_code(RETCODE rc)
171 case SQL_SUCCESS:
return NANODBC_TEXT(
"SQL_SUCCESS");
172 case SQL_SUCCESS_WITH_INFO:
return NANODBC_TEXT(
"SQL_SUCCESS_WITH_INFO");
173 case SQL_ERROR:
return NANODBC_TEXT(
"SQL_ERROR");
174 case SQL_INVALID_HANDLE:
return NANODBC_TEXT(
"SQL_INVALID_HANDLE");
175 case SQL_NO_DATA:
return NANODBC_TEXT(
"SQL_NO_DATA");
176 case SQL_NEED_DATA:
return NANODBC_TEXT(
"SQL_NEED_DATA");
177 case SQL_STILL_EXECUTING:
return NANODBC_TEXT(
"SQL_STILL_EXECUTING");
185 inline bool success(RETCODE rc)
187 #ifdef NANODBC_ODBC_API_DEBUG
188 std::cerr <<
"<-- rc: " << return_code(rc) <<
" | ";
190 return rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO;
194 template<
typename T, std::
size_t N>
195 inline std::size_t arrlen(T(&)[N])
201 template<
typename T, std::
size_t N>
202 inline std::size_t strarrlen(T(&a)[N])
206 while(*s++ && i < N) i++;
210 inline void convert(
const wide_string_type& in, std::string& out)
212 #ifdef NANODBC_USE_BOOST_CONVERT
213 using boost::locale::conv::utf_to_utf;
214 out = utf_to_utf<char>(in.c_str(), in.c_str() + in.size());
216 #if defined(_MSC_VER) && (_MSC_VER == 1900)
219 auto p =
reinterpret_cast<wide_char_t const*
>(in.data());
220 out = std::wstring_convert<NANODBC_CODECVT_TYPE<wide_char_t>, wide_char_t>().to_bytes(p, p + in.size());
222 out = std::wstring_convert<NANODBC_CODECVT_TYPE<wide_char_t>, wide_char_t>().to_bytes(in);
227 #ifdef NANODBC_USE_UNICODE
228 inline void convert(
const std::string& in, wide_string_type& out)
230 #ifdef NANODBC_USE_BOOST_CONVERT
231 using boost::locale::conv::utf_to_utf;
232 out = utf_to_utf<wide_char_t>(in.c_str(), in.c_str() + in.size());
233 #elif defined(_MSC_VER) && (_MSC_VER == 1900)
236 auto s = std::wstring_convert<NANODBC_CODECVT_TYPE<wide_char_t>, wide_char_t>().from_bytes(in);
237 auto p =
reinterpret_cast<wide_char_t const*
>(s.data());
238 out.assign(p, p + s.size());
240 out = std::wstring_convert<NANODBC_CODECVT_TYPE<wide_char_t>, wide_char_t>().from_bytes(in);
244 inline void convert(
const wide_string_type& in, wide_string_type& out)
249 inline void convert(
const std::string& in, std::string& out)
257 inline std::string recent_error(
259 , SQLSMALLINT handle_type
261 , std::string &state)
263 nanodbc::string_type result;
265 std::vector<NANODBC_SQLCHAR> sql_message(SQL_MAX_MESSAGE_LENGTH);
266 sql_message[0] =
'\0';
269 SQLINTEGER native_error;
270 SQLSMALLINT total_bytes;
271 NANODBC_SQLCHAR sql_state[6];
277 NANODBC_FUNC(SQLGetDiagRec)
288 if(success(rc) && total_bytes > 0)
289 sql_message.resize(total_bytes + 1);
291 if(rc == SQL_NO_DATA)
295 NANODBC_FUNC(SQLGetDiagRec)
303 , (SQLSMALLINT)sql_message.size()
308 convert(result, rvalue);
315 result += nanodbc::string_type(sql_message.begin(), sql_message.end());
324 }
while(rc != SQL_NO_DATA);
326 convert(result, rvalue);
327 state = std::string(&sql_state[0], &sql_state[arrlen(sql_state) - 1]);
328 native = native_error;
329 std::string status = state;
335 replace(status.begin(), status.end(),
'\0',
' ');
343 type_incompatible_error::type_incompatible_error()
344 : std::runtime_error(
"type incompatible") { }
346 const char* type_incompatible_error::what() const NANODBC_NOEXCEPT
348 return std::runtime_error::what();
351 null_access_error::null_access_error()
352 :
std::runtime_error(
"null access") { }
354 const char* null_access_error::what() const NANODBC_NOEXCEPT
356 return std::runtime_error::what();
359 index_range_error::index_range_error()
360 :
std::runtime_error(
"index out of range") { }
362 const char* index_range_error::what() const NANODBC_NOEXCEPT
364 return std::runtime_error::what();
367 programming_error::programming_error(
const std::string& info)
368 :
std::runtime_error(info.c_str()) { }
370 const char* programming_error::what() const NANODBC_NOEXCEPT
372 return std::runtime_error::what();
375 database_error::database_error(
void* handle,
short handle_type,
const std::string& info)
376 :
std::runtime_error(info), native_error(0), sql_state(
"00000")
378 message = std::string(std::runtime_error::what()) + recent_error(handle, handle_type, native_error, sql_state);
381 const char* database_error::what() const NANODBC_NOEXCEPT
383 return message.c_str();
386 const long database_error::native() const NANODBC_NOEXCEPT
391 const std::string database_error::state() const NANODBC_NOEXCEPT
400#define NANODBC_THROW_DATABASE_ERROR(handle, handle_type) \
401 throw nanodbc::database_error( \
404 , __FILE__ ":" NANODBC_STRINGIZE( __LINE__) ": ") \
425 struct sql_ctype { };
428 struct sql_ctype<nanodbc::string_type::value_type>
430 #ifdef NANODBC_USE_UNICODE
431 static const SQLSMALLINT value = SQL_C_WCHAR;
433 static const SQLSMALLINT value = SQL_C_CHAR;
438 struct sql_ctype<short>
440 static const SQLSMALLINT value = SQL_C_SSHORT;
444 struct sql_ctype<unsigned short>
446 static const SQLSMALLINT value = SQL_C_USHORT;
450 struct sql_ctype<int32_t>
452 static const SQLSMALLINT value = SQL_C_SLONG;
456 struct sql_ctype<uint32_t>
458 static const SQLSMALLINT value = SQL_C_ULONG;
462 struct sql_ctype<int64_t>
464 static const SQLSMALLINT value = SQL_C_SBIGINT;
468 struct sql_ctype<uint64_t>
470 static const SQLSMALLINT value = SQL_C_UBIGINT;
474 struct sql_ctype<float>
476 static const SQLSMALLINT value = SQL_C_FLOAT;
482 static const SQLSMALLINT value = SQL_C_DOUBLE;
486 struct sql_ctype<nanodbc::string_type>
488 #ifdef NANODBC_USE_UNICODE
489 static const SQLSMALLINT value = SQL_C_WCHAR;
491 static const SQLSMALLINT value = SQL_C_CHAR;
496 struct sql_ctype<nanodbc::date>
498 static const SQLSMALLINT value = SQL_C_DATE;
502 struct sql_ctype<nanodbc::timestamp>
504 static const SQLSMALLINT value = SQL_C_TIMESTAMP;
511 bound_column(
const bound_column& rhs) =
delete;
512 bound_column& operator=(bound_column rhs) =
delete;
536 nanodbc::string_type name_;
538 SQLSMALLINT sqltype_;
544 nanodbc::null_type* cbdata_;
549 inline void allocate_handle(SQLHENV& env, SQLHDBC& conn)
559 NANODBC_THROW_DATABASE_ERROR(env, SQL_HANDLE_ENV);
567 , SQL_ATTR_ODBC_VERSION
568 , (SQLPOINTER)NANODBC_ODBC_VERSION
571 NANODBC_THROW_DATABASE_ERROR(env, SQL_HANDLE_ENV);
580 NANODBC_THROW_DATABASE_ERROR(env, SQL_HANDLE_ENV);
609class connection::connection_impl
612 connection_impl(
const connection_impl&) =
delete;
613 connection_impl& operator=(
const connection_impl&) =
delete;
622 allocate_handle(env_, conn_);
626 const string_type& dsn
627 ,
const string_type& user
628 ,
const string_type& pass
636 allocate_handle(env_, conn_);
639 connect(dsn, user, pass, timeout);
655 connection_impl(
const string_type& connection_string,
long timeout)
662 allocate_handle(env_, conn_);
665 connect(connection_string, timeout);
681 ~connection_impl() NANODBC_NOEXCEPT
701#ifdef SQL_ATTR_ASYNC_DBC_EVENT
702 void enable_async(
void* event_handle)
709 , SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE
710 , (SQLPOINTER)SQL_ASYNC_DBC_ENABLE_ON
713 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
719 , SQL_ATTR_ASYNC_DBC_EVENT
723 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
726 void async_complete()
735 if(!success(rc) || !success(arc))
736 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
742 , SQL_ATTR_ASYNC_ENABLE
743 , (SQLPOINTER)SQL_ASYNC_ENABLE_OFF
746 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
748 connected_ = success(rc);
753 const string_type& dsn
754 ,
const string_type& user
755 ,
const string_type& pass
757 ,
void* event_handle = NULL)
768 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
777 NANODBC_THROW_DATABASE_ERROR(env_, SQL_HANDLE_ENV);
784 , (SQLPOINTER)(std::intptr_t)timeout
787 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
789 #ifdef SQL_ATTR_ASYNC_DBC_EVENT
790 if(event_handle != NULL)
791 enable_async(event_handle);
795 NANODBC_FUNC(SQLConnect)
798 , (NANODBC_SQLCHAR*)dsn.c_str(), SQL_NTS
799 , !user.empty() ? (NANODBC_SQLCHAR*)user.c_str() : 0, SQL_NTS
800 , !pass.empty() ? (NANODBC_SQLCHAR*)pass.c_str() : 0, SQL_NTS);
801 if(!success(rc) && (event_handle == NULL || rc != SQL_STILL_EXECUTING))
802 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
804 connected_ = success(rc);
807 void connect(
const string_type& connection_string,
long timeout,
void* event_handle = NULL)
818 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
827 NANODBC_THROW_DATABASE_ERROR(env_, SQL_HANDLE_ENV);
834 , (SQLPOINTER)(std::intptr_t)timeout
837 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
839 #ifdef SQL_ATTR_ASYNC_DBC_EVENT
840 if(event_handle != NULL)
841 enable_async(event_handle);
844 NANODBC_SQLCHAR dsn[1024];
845 SQLSMALLINT dsn_size = 0;
847 NANODBC_FUNC(SQLDriverConnect)
851 , (NANODBC_SQLCHAR*)connection_string.c_str(), SQL_NTS
853 ,
sizeof(dsn) /
sizeof(NANODBC_SQLCHAR)
855 , SQL_DRIVER_NOPROMPT);
856 if(!success(rc) && (event_handle == NULL || rc != SQL_STILL_EXECUTING))
857 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
859 connected_ = success(rc);
862 bool connected()
const
877 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
882 std::size_t transactions()
const
884 return transactions_;
887 void* native_dbc_handle()
const
892 void* native_env_handle()
const
897 string_type dbms_name()
const
899 NANODBC_SQLCHAR name[255] = { 0 };
900 SQLSMALLINT length(0);
903 NANODBC_FUNC(SQLGetInfo)
908 ,
sizeof(name) /
sizeof(NANODBC_SQLCHAR)
911 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
912 return string_type(&name[0], &name[strarrlen(name)]);
915 string_type dbms_version()
const
917 NANODBC_SQLCHAR version[255] = { 0 };
918 SQLSMALLINT length(0);
921 NANODBC_FUNC(SQLGetInfo)
926 ,
sizeof(version) /
sizeof(NANODBC_SQLCHAR)
929 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
930 return string_type(&version[0], &version[strarrlen(version)]);
933 string_type driver_name()
const
935 NANODBC_SQLCHAR name[1024];
939 NANODBC_FUNC(SQLGetInfo)
944 ,
sizeof(name) /
sizeof(NANODBC_SQLCHAR)
947 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
948 return string_type(&name[0], &name[strarrlen(name)]);
951 string_type database_name()
const
957 NANODBC_SQLCHAR name[255] = { 0 };
958 SQLSMALLINT length(0);
961 NANODBC_FUNC(SQLGetInfo)
966 ,
sizeof(name) /
sizeof(NANODBC_SQLCHAR)
969 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
970 return string_type(&name[0], &name[strarrlen(name)]);
973 string_type catalog_name()
const
975 NANODBC_SQLCHAR name[SQL_MAX_OPTION_STRING_LENGTH] = { 0 };
976 SQLINTEGER length(0);
979 NANODBC_FUNC(SQLGetConnectAttr)
982 , SQL_ATTR_CURRENT_CATALOG
984 ,
sizeof(name) /
sizeof(NANODBC_SQLCHAR)
987 NANODBC_THROW_DATABASE_ERROR(conn_, SQL_HANDLE_DBC);
988 return string_type(&name[0], &name[strarrlen(name)]);
992 std::size_t ref_transaction()
994 return --transactions_;
997 std::size_t unref_transaction()
999 return ++transactions_;
1002 bool rollback()
const
1007 void rollback(
bool onoff)
1016 std::size_t transactions_;
1038class transaction::transaction_impl
1041 transaction_impl(
const transaction_impl&) =
delete;
1042 transaction_impl& operator=(
const transaction_impl&) =
delete;
1044 transaction_impl(
const class connection& conn)
1048 if(conn_.transactions() == 0 && conn_.connected())
1054 , conn_.native_dbc_handle()
1055 , SQL_ATTR_AUTOCOMMIT
1056 , (SQLPOINTER)SQL_AUTOCOMMIT_OFF
1059 NANODBC_THROW_DATABASE_ERROR(conn_.native_dbc_handle(), SQL_HANDLE_DBC);
1061 conn_.ref_transaction();
1064 ~transaction_impl() NANODBC_NOEXCEPT
1068 conn_.rollback(
true);
1069 conn_.unref_transaction();
1072 if(conn_.transactions() == 0 && conn_.connected())
1074 if(conn_.rollback())
1079 , conn_.native_dbc_handle()
1081 conn_.rollback(
false);
1086 , conn_.native_dbc_handle()
1087 , SQL_ATTR_AUTOCOMMIT
1088 , (SQLPOINTER)SQL_AUTOCOMMIT_ON
1098 if(conn_.unref_transaction() == 0 && conn_.connected())
1105 , conn_.native_dbc_handle()
1108 NANODBC_THROW_DATABASE_ERROR(conn_.native_dbc_handle(), SQL_HANDLE_DBC);
1112 void rollback() NANODBC_NOEXCEPT
1116 conn_.rollback(
true);
1119 class connection& connection()
1124 const class connection& connection()
const
1130 class connection conn_;
1152class statement::statement_impl
1155 statement_impl(
const statement_impl&) =
delete;
1156 statement_impl& operator=(
const statement_impl&) =
delete;
1162 , bind_len_or_null_()
1167 statement_impl(
class connection& conn)
1171 , bind_len_or_null_()
1176 statement_impl(
class connection& conn,
const string_type& query,
long timeout)
1180 , bind_len_or_null_()
1182 prepare(conn, query, timeout);
1185 ~statement_impl() NANODBC_NOEXCEPT
1187 if(open() && connected())
1200 void open(
class connection& conn)
1208 , conn.native_dbc_handle()
1210 open_ = success(rc);
1212 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1221 bool connected()
const
1223 return conn_.connected();
1226 const class connection& connection()
const
1231 class connection& connection()
1236 void* native_statement_handle()
const
1243 if(open() && connected())
1251 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1261 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1276 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1279 void prepare(
class connection& conn,
const string_type& query,
long timeout)
1282 prepare(query, timeout);
1285 void prepare(
const string_type& query,
long timeout)
1288 throw programming_error(
"statement has no associated open connection");
1292 NANODBC_FUNC(SQLPrepare)
1295 , (NANODBC_SQLCHAR*)query.c_str()
1296 , (SQLINTEGER)query.size());
1298 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1300 this->timeout(timeout);
1303 void timeout(
long timeout)
1310 , SQL_ATTR_QUERY_TIMEOUT
1311 , (SQLPOINTER)(std::intptr_t)timeout,
1316 if(!success(rc) && (timeout != 0))
1317 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1320#if defined(SQL_ATTR_ASYNC_STMT_EVENT) && defined(SQL_API_SQLCOMPLETEASYNC)
1321 void enable_async(
void* event_handle)
1328 , SQL_ATTR_ASYNC_ENABLE
1329 , (SQLPOINTER)SQL_ASYNC_ENABLE_ON
1332 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1338 , SQL_ATTR_ASYNC_STMT_EVENT
1342 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1345 void async_execute_direct(
1346 class connection& conn
1347 ,
void* event_handle
1348 ,
const string_type& query
1349 ,
long batch_operations
1351 , statement& statement)
1353 RETCODE rc = just_execute_direct(
1361 if(rc != SQL_STILL_EXECUTING)
1362 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1365 result async_complete(
long batch_operations, statement& statement)
1374 if(!success(rc) || !success(arc))
1375 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1381 , SQL_ATTR_ASYNC_ENABLE
1382 , (SQLPOINTER)SQL_ASYNC_ENABLE_OFF
1385 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1387 return result(statement, batch_operations);
1391 result execute_direct(
1392 class connection& conn
1393 ,
const string_type& query
1394 ,
long batch_operations
1396 , statement& statement)
1398 #ifdef NANODBC_HANDLE_NODATA_BUG
1399 const RETCODE rc = just_execute_direct(conn, query, batch_operations, timeout, statement);
1400 if(rc == SQL_NO_DATA)
1403 just_execute_direct(conn, query, batch_operations, timeout, statement);
1405 return result(statement, batch_operations);
1408 RETCODE just_execute_direct(
1409 class connection& conn
1410 ,
const string_type& query
1411 ,
long batch_operations
1414 ,
void* event_handle = NULL)
1418 #if defined(SQL_ATTR_ASYNC_STMT_EVENT) && defined(SQL_API_SQLCOMPLETEASYNC)
1419 if(event_handle != NULL)
1420 enable_async(event_handle);
1428 , SQL_ATTR_PARAMSET_SIZE
1429 , (SQLPOINTER)(std::intptr_t)batch_operations
1432 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1434 this->timeout(timeout);
1437 NANODBC_FUNC(SQLExecDirect)
1440 , (NANODBC_SQLCHAR*)query.c_str()
1442 if(!success(rc) && rc != SQL_NO_DATA && rc != SQL_STILL_EXECUTING)
1443 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1448 result execute(
long batch_operations,
long timeout, statement& statement)
1450 #ifdef NANODBC_HANDLE_NODATA_BUG
1451 const RETCODE rc = just_execute(batch_operations, timeout, statement);
1452 if(rc == SQL_NO_DATA)
1455 just_execute(batch_operations, timeout, statement);
1457 return result(statement, batch_operations);
1460 RETCODE just_execute(
long batch_operations,
long timeout, statement& )
1479 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1486 , SQL_ATTR_PARAMSET_SIZE
1487 , (SQLPOINTER)(std::intptr_t)batch_operations
1489 if(!success(rc) && rc != SQL_NO_DATA)
1490 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1492 this->timeout(timeout);
1498 if(!success(rc) && rc != SQL_NO_DATA)
1499 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1504 result procedure_columns(
1505 const string_type& catalog
1506 ,
const string_type& schema
1507 ,
const string_type& procedure
1508 ,
const string_type& column
1509 , statement& statement)
1512 throw programming_error(
"statement has no associated open connection");
1516 NANODBC_FUNC(SQLProcedureColumns)
1519 , (NANODBC_SQLCHAR*)(catalog.empty() ? NULL : catalog.c_str())
1520 , (catalog.empty() ? 0 : SQL_NTS)
1521 , (NANODBC_SQLCHAR*)(schema.empty() ? NULL : schema.c_str())
1522 , (schema.empty() ? 0 : SQL_NTS)
1523 , (NANODBC_SQLCHAR*)procedure.c_str()
1525 , (NANODBC_SQLCHAR*)(column.empty() ? NULL : column.c_str())
1526 , (column.empty() ? 0 : SQL_NTS));
1529 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1531 return result(statement, 1);
1534 long affected_rows()
const
1544 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1545 NANODBC_ASSERT(rows <=
static_cast<SQLLEN
>(std::numeric_limits<long>::max()));
1546 return static_cast<long>(rows);
1549 short columns()
const
1559 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1563 void reset_parameters() NANODBC_NOEXCEPT
1568 , SQL_RESET_PARAMS);
1571 unsigned long parameter_size(
short param)
const
1574 SQLSMALLINT data_type;
1575 SQLSMALLINT nullable;
1576 SQLULEN parameter_size;
1587 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1588 NANODBC_ASSERT(parameter_size <=
static_cast<SQLULEN
>(std::numeric_limits<unsigned long>::max()));
1589 return static_cast<unsigned long>(parameter_size);
1592 static SQLSMALLINT param_type_from_direction(param_direction direction)
1597 return SQL_PARAM_INPUT;
1600 return SQL_PARAM_OUTPUT;
1603 return SQL_PARAM_INPUT_OUTPUT;
1606 return SQL_PARAM_OUTPUT;
1609 NANODBC_ASSERT(
false);
1610 throw programming_error(
"unrecognized param_direction value");
1617 , std::size_t elements
1618 , param_direction direction
1619 , SQLSMALLINT& data_type
1620 , SQLSMALLINT& param_type
1621 , SQLULEN& parameter_size
1622 , SQLSMALLINT& scale)
1625 SQLSMALLINT nullable;
1636 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1638 param_type = param_type_from_direction(direction);
1640 if(!bind_len_or_null_.count(param))
1641 bind_len_or_null_[param] = std::vector<null_type>();
1642 std::vector<null_type>().swap(bind_len_or_null_[param]);
1645 const std::size_t indicator_size = elements > 8 ? elements : 8;
1647 bind_len_or_null_[param].reserve(indicator_size);
1648 bind_len_or_null_[param].assign(indicator_size, SQL_NULL_DATA);
1653 void bind_parameter(
1657 , SQLSMALLINT data_type
1658 , SQLSMALLINT param_type
1659 , SQLULEN parameter_size
1660 , SQLSMALLINT scale)
1669 , sql_ctype<T>::value
1675 , bind_len_or_null_[param].data());
1678 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1683 void bind(
short param,
const T* values, std::size_t elements, param_direction direction);
1688 ,
const string_type::value_type* values
1690 , std::size_t elements
1691 , param_direction direction)
1693 bind(param, values, elements, direction);
1697 void bind_null(
short param, std::size_t elements)
1699 SQLSMALLINT data_type;
1700 SQLSMALLINT param_type;
1701 SQLULEN parameter_size;
1703 prepare_bind(param, elements, PARAM_IN, data_type, param_type, parameter_size, scale);
1718 , bind_len_or_null_[param].data());
1720 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1725 bool equals(
const T& lhs,
const T& rhs)
1735 , std::size_t elements
1737 ,
const T* null_sentry
1738 , param_direction direction);
1743 ,
const string_type::value_type* values
1744 , std::size_t length
1745 , std::size_t elements
1747 ,
const string_type::value_type* null_sentry
1748 , param_direction direction);
1753 class connection conn_;
1754 std::map<short, std::vector<null_type> > bind_len_or_null_;
1760void statement::statement_impl::bind_parameter<string_type::value_type>(
1762 ,
const string_type::value_type* data
1763 , std::size_t elements
1764 , SQLSMALLINT data_type
1765 , SQLSMALLINT param_type
1766 , SQLULEN parameter_size
1767 , SQLSMALLINT scale)
1776 , sql_ctype<string_type::value_type>::value
1782 , (elements <= 1 ? NULL : bind_len_or_null_[param].data()));
1785 NANODBC_THROW_DATABASE_ERROR(stmt_, SQL_HANDLE_STMT);
1789void statement::statement_impl::bind(
1792 , std::size_t elements
1793 , param_direction direction)
1795 SQLSMALLINT data_type;
1796 SQLSMALLINT param_type;
1797 SQLULEN parameter_size;
1799 prepare_bind(param, elements, direction, data_type, param_type, parameter_size, scale);
1801 for(std::size_t i = 0; i < elements; ++i)
1802 bind_len_or_null_[param][i] = parameter_size;
1804 bind_parameter(param, values, elements, data_type, param_type, parameter_size, scale);
1808void statement::statement_impl::bind(
1811 , std::size_t elements
1813 ,
const T* null_sentry
1814 , param_direction direction)
1816 SQLSMALLINT data_type;
1817 SQLSMALLINT param_type;
1818 SQLULEN parameter_size;
1820 prepare_bind(param, elements, direction, data_type, param_type, parameter_size, scale);
1822 for(std::size_t i = 0; i < elements; ++i)
1823 if((null_sentry && !equals(values[i], *null_sentry)) || (nulls && !nulls[i]))
1824 bind_len_or_null_[param][i] = parameter_size;
1826 bind_parameter(param, values, elements, data_type, param_type, parameter_size, scale);
1829void statement::statement_impl::bind_strings(
1831 ,
const string_type::value_type* values
1832 , std::size_t length
1833 , std::size_t elements
1835 ,
const string_type::value_type* null_sentry
1836 , param_direction direction)
1838 SQLSMALLINT data_type;
1839 SQLSMALLINT param_type;
1840 SQLULEN parameter_size;
1842 prepare_bind(param, elements, direction, data_type, param_type, parameter_size, scale);
1846 for(std::size_t i = 0; i < elements; ++i)
1848 const string_type s_lhs(values + i * length, values + (i + 1) * length);
1849 const string_type s_rhs(null_sentry);
1850 #if NANODBC_USE_UNICODE
1851 std::string narrow_lhs;
1852 narrow_lhs.reserve(s_lhs.size());
1853 convert(s_lhs, narrow_lhs);
1854 std::string narrow_rhs;
1855 narrow_rhs.reserve(s_rhs.size());
1856 convert(s_rhs, narrow_lhs);
1857 if(std::strncmp(narrow_lhs.c_str(), narrow_rhs.c_str(), length))
1858 bind_len_or_null_[param][i] = parameter_size;
1860 if(std::strncmp(s_lhs.c_str(), s_rhs.c_str(), length))
1861 bind_len_or_null_[param][i] = parameter_size;
1867 for(std::size_t i = 0; i < elements; ++i)
1870 bind_len_or_null_[param][i] = SQL_NTS;
1874 bind_parameter(param, values, elements, data_type, param_type, parameter_size, scale);
1878bool statement::statement_impl::equals(
const date& lhs,
const date& rhs)
1880 return lhs.year == rhs.year
1881 && lhs.month == rhs.month
1882 && lhs.day == rhs.day;
1886bool statement::statement_impl::equals(
const timestamp& lhs,
const timestamp& rhs)
1888 return lhs.year == rhs.year
1889 && lhs.month == rhs.month
1890 && lhs.day == rhs.day
1891 && lhs.hour == rhs.hour
1892 && lhs.min == rhs.min
1893 && lhs.sec == rhs.sec
1894 && lhs.fract == rhs.fract;
1915class result::result_impl
1918 result_impl(
const result_impl&) =
delete;
1919 result_impl& operator=(
const result_impl&) =
delete;
1921 result_impl(statement stmt,
long rowset_size)
1923 , rowset_size_(rowset_size)
1926 , bound_columns_size_(0)
1927 , rowset_position_(0)
1928 , bound_columns_by_name_()
1935 , stmt_.native_statement_handle()
1936 , SQL_ATTR_ROW_ARRAY_SIZE
1937 , (SQLPOINTER)(std::intptr_t)rowset_size_
1940 NANODBC_THROW_DATABASE_ERROR(stmt_.native_statement_handle(), SQL_HANDLE_STMT);
1945 , stmt_.native_statement_handle()
1946 , SQL_ATTR_ROWS_FETCHED_PTR
1950 NANODBC_THROW_DATABASE_ERROR(stmt_.native_statement_handle(), SQL_HANDLE_STMT);
1955 ~result_impl() NANODBC_NOEXCEPT
1957 cleanup_bound_columns();
1960 void* native_statement_handle()
const
1962 return stmt_.native_statement_handle();
1965 long rowset_size()
const
1967 return rowset_size_;
1970 long affected_rows()
const
1972 return stmt_.affected_rows();
1975 long rows() const NANODBC_NOEXCEPT
1977 NANODBC_ASSERT(row_count_ <=
static_cast<SQLULEN
>(std::numeric_limits<long>::max()));
1978 return static_cast<long>(row_count_);
1981 short columns()
const
1983 return stmt_.columns();
1988 rowset_position_ = 0;
1989 return fetch(0, SQL_FETCH_FIRST);
1994 rowset_position_ = 0;
1995 return fetch(0, SQL_FETCH_LAST);
2000 if(rows() && ++rowset_position_ < rowset_size_)
2001 return rowset_position_ < rows();
2002 rowset_position_ = 0;
2003 return fetch(0, SQL_FETCH_NEXT);
2008 if(rows() && --rowset_position_ >= 0)
2010 rowset_position_ = 0;
2011 return fetch(0, SQL_FETCH_PRIOR);
2016 rowset_position_ = 0;
2017 return fetch(row, SQL_FETCH_ABSOLUTE);
2020 bool skip(
long rows)
2022 rowset_position_ += rows;
2023 if(this->rows() && rowset_position_ < rowset_size_)
2024 return rowset_position_ < this->rows();
2025 rowset_position_ = 0;
2026 return fetch(rows, SQL_FETCH_RELATIVE);
2029 unsigned long position()
const
2036 , stmt_.native_statement_handle()
2037 , SQL_ATTR_ROW_NUMBER
2042 NANODBC_THROW_DATABASE_ERROR(stmt_.native_statement_handle(), SQL_HANDLE_STMT);
2052 if (pos == 0 || pos ==
static_cast<SQLULEN
>(SQL_ROW_NUMBER_UNKNOWN))
2055 NANODBC_ASSERT(pos <=
static_cast<SQLULEN
>(std::numeric_limits<unsigned long>::max()));
2056 return static_cast<unsigned long>(pos) + rowset_position_;
2059 bool end() const NANODBC_NOEXCEPT
2068 , stmt_.native_statement_handle()
2069 , SQL_ATTR_ROW_NUMBER
2073 return (!success(rc) || rows() < 0 || pos - 1 >
static_cast<unsigned long>(rows()));
2076 bool is_null(
short column)
const
2078 if(column >= bound_columns_size_)
2079 throw index_range_error();
2080 bound_column& col = bound_columns_[column];
2081 if(rowset_position_ >= rows())
2082 throw index_range_error();
2083 return col.cbdata_[rowset_position_] == SQL_NULL_DATA;
2086 bool is_null(
const string_type& column_name)
const
2088 const short column = this->column(column_name);
2089 return is_null(column);
2092 string_type column_name(
short column)
const
2094 if(column >= bound_columns_size_)
2095 throw index_range_error();
2096 return bound_columns_[column].name_;
2099 long column_size(
short column)
const
2101 if(column >= bound_columns_size_)
2102 throw index_range_error();
2103 bound_column& col = bound_columns_[column];
2104 NANODBC_ASSERT(col.sqlsize_ <=
static_cast<SQLULEN
>(std::numeric_limits<long>::max()));
2105 return static_cast<long>(col.sqlsize_);
2108 short column(
const string_type& column_name)
const
2110 typedef std::map<string_type, bound_column*>::const_iterator iter;
2111 iter i = bound_columns_by_name_.find(column_name);
2112 if(i == bound_columns_by_name_.end())
2113 throw index_range_error();
2114 return i->second->column_;
2117 int column_datatype(
short column)
const
2119 if(column >= bound_columns_size_)
2120 throw index_range_error();
2121 bound_column& col = bound_columns_[column];
2122 return col.sqltype_;
2125 int column_datatype(
const string_type& column_name)
const
2127 const short column = this->column(column_name);
2128 bound_column& col = bound_columns_[column];
2129 return col.sqltype_;
2132 int column_c_datatype(
short column)
const
2134 if(column >= bound_columns_size_)
2135 throw index_range_error();
2136 bound_column& col = bound_columns_[column];
2140 int column_c_datatype(
const string_type& column_name)
const
2142 const short column = this->column(column_name);
2143 bound_column& col = bound_columns_[column];
2153 , stmt_.native_statement_handle());
2154 if(rc == SQL_NO_DATA)
2157 NANODBC_THROW_DATABASE_ERROR(stmt_.native_statement_handle(), SQL_HANDLE_STMT);
2163 void get_ref(
short column, T& result)
const
2165 if(column >= bound_columns_size_)
2166 throw index_range_error();
2168 throw null_access_error();
2169 get_ref_impl<T>(column, result);
2173 void get_ref(
short column,
const T& fallback, T& result)
const
2175 if(column >= bound_columns_size_)
2176 throw index_range_error();
2182 get_ref_impl<T>(column, result);
2186 void get_ref(
const string_type& column_name, T& result)
const
2188 const short column = this->column(column_name);
2190 throw null_access_error();
2191 get_ref_impl<T>(column, result);
2195 void get_ref(
const string_type& column_name,
const T& fallback, T& result)
const
2197 const short column = this->column(column_name);
2203 get_ref_impl<T>(column, result);
2207 T get(
short column)
const
2210 get_ref(column, result);
2215 T get(
short column,
const T& fallback)
const
2218 get_ref(column, fallback, result);
2223 T get(
const string_type& column_name)
const
2226 get_ref(column_name, result);
2231 T get(
const string_type& column_name,
const T& fallback)
const
2234 get_ref(column_name, fallback, result);
2240 void get_ref_impl(
short column, T& result)
const;
2242 void before_move() NANODBC_NOEXCEPT
2244 for(
short i = 0; i < bound_columns_size_; ++i)
2246 bound_column& col = bound_columns_[i];
2247 for(
long j = 0; j < rowset_size_; ++j)
2249 if(col.blob_ && col.pdata_)
2250 release_bound_resources(i);
2254 void release_bound_resources(
short column) NANODBC_NOEXCEPT
2256 NANODBC_ASSERT(column < bound_columns_size_);
2257 bound_column& col = bound_columns_[column];
2258 delete[] col.pdata_;
2263 void cleanup_bound_columns() NANODBC_NOEXCEPT
2266 delete[] bound_columns_;
2267 bound_columns_ = NULL;
2268 bound_columns_size_ = 0;
2269 bound_columns_by_name_.clear();
2272 bool fetch(
long rows, SQLUSMALLINT orientation)
2279 , stmt_.native_statement_handle()
2282 if(rc == SQL_NO_DATA)
2288 NANODBC_THROW_DATABASE_ERROR(stmt_.native_statement_handle(), SQL_HANDLE_STMT);
2294 cleanup_bound_columns();
2296 const short n_columns = columns();
2300 NANODBC_ASSERT(!bound_columns_);
2301 NANODBC_ASSERT(!bound_columns_size_);
2302 bound_columns_ =
new bound_column[n_columns];
2303 bound_columns_size_ = n_columns;
2306 NANODBC_SQLCHAR column_name[1024];
2307 SQLSMALLINT sqltype, scale, nullable, len;
2310 for(SQLSMALLINT i = 0; i < n_columns; ++i)
2313 NANODBC_FUNC(SQLDescribeCol)
2315 , stmt_.native_statement_handle()
2317 , (NANODBC_SQLCHAR*)column_name
2318 ,
sizeof(column_name)/
sizeof(NANODBC_SQLCHAR)
2325 NANODBC_THROW_DATABASE_ERROR(stmt_.native_statement_handle(), SQL_HANDLE_STMT);
2328 bool is_blob =
false;
2344 bound_column& col = bound_columns_[i];
2345 col.name_ =
reinterpret_cast<string_type::value_type*
>(column_name);
2347 col.sqltype_ = sqltype;
2348 col.sqlsize_ = sqlsize;
2350 bound_columns_by_name_[col.name_] = &col;
2352 using namespace std;
2353 switch(col.sqltype_)
2359 col.ctype_ = SQL_C_LONG;
2360 col.clen_ =
sizeof(int32_t);
2363 col.ctype_ = SQL_C_SBIGINT;
2364 col.clen_ =
sizeof(int64_t);
2371 col.ctype_ = SQL_C_DOUBLE;
2372 col.clen_ =
sizeof(double);
2376 col.ctype_ = SQL_C_DATE;
2377 col.clen_ =
sizeof(date);
2380 case SQL_TYPE_TIMESTAMP:
2381 col.ctype_ = SQL_C_TIMESTAMP;
2382 col.clen_ =
sizeof(timestamp);
2386 col.ctype_ = SQL_C_CHAR;
2387 col.clen_ = (col.sqlsize_ + 1) *
sizeof(SQLCHAR);
2396 col.ctype_ = SQL_C_WCHAR;
2397 col.clen_ = (col.sqlsize_ + 1) *
sizeof(SQLWCHAR);
2404 case SQL_LONGVARCHAR:
2405 col.ctype_ = SQL_C_CHAR;
2411 case SQL_LONGVARBINARY:
2412 col.ctype_ = SQL_C_BINARY;
2417 col.ctype_ = sql_ctype<string_type>::value;
2423 for(SQLSMALLINT i = 0; i < n_columns; ++i)
2425 bound_column& col = bound_columns_[i];
2426 col.cbdata_ =
new null_type[rowset_size_];
2432 , stmt_.native_statement_handle()
2439 NANODBC_THROW_DATABASE_ERROR(stmt_.native_statement_handle(), SQL_HANDLE_STMT);
2443 col.pdata_ =
new char[rowset_size_ * col.clen_];
2447 , stmt_.native_statement_handle()
2454 NANODBC_THROW_DATABASE_ERROR(stmt_.native_statement_handle(), SQL_HANDLE_STMT);
2461 const long rowset_size_;
2463 bound_column* bound_columns_;
2464 short bound_columns_size_;
2465 long rowset_position_;
2466 std::map<string_type, bound_column*> bound_columns_by_name_;
2471inline void result::result_impl::get_ref_impl<date>(
short column, date& result)
const
2473 bound_column& col = bound_columns_[column];
2477 result = *
reinterpret_cast<date*
>(col.pdata_ + rowset_position_ * col.clen_);
2479 case SQL_C_TIMESTAMP:
2481 timestamp stamp = *
reinterpret_cast<timestamp*
>(col.pdata_ + rowset_position_ * col.clen_ );
2482 date d = { stamp.year, stamp.month, stamp.day };
2487 throw type_incompatible_error();
2491inline void result::result_impl::get_ref_impl<timestamp>(
short column, timestamp& result)
const
2493 bound_column& col = bound_columns_[column];
2498 date d = *
reinterpret_cast<date*
>(col.pdata_ + rowset_position_ * col.clen_);
2499 timestamp stamp = { d.year, d.month, d.day, 0, 0, 0, 0 };
2503 case SQL_C_TIMESTAMP:
2504 result = *
reinterpret_cast<timestamp*
>(col.pdata_ + rowset_position_ * col.clen_);
2507 throw type_incompatible_error();
2511inline void result::result_impl::get_ref_impl<string_type>(
short column, string_type& result)
const
2513 bound_column& col = bound_columns_[column];
2514 const SQLULEN column_size = col.sqlsize_;
2525 SQLLEN ValueLenOrInd;
2527 void* handle = native_statement_handle();
2530 char buffer[1024] = {0};
2531 const std::size_t buffer_size =
sizeof(buffer);
2541 if(ValueLenOrInd > 0)
2543 else if(ValueLenOrInd == SQL_NULL_DATA)
2544 *col.cbdata_ = (SQLINTEGER) SQL_NULL_DATA;
2547 }
while(rc == SQL_SUCCESS_WITH_INFO);
2548 if (rc == SQL_SUCCESS || rc == SQL_NO_DATA)
2549 convert(out, result);
2553 const char* s = col.pdata_ + rowset_position_ * col.clen_;
2554 const std::string::size_type str_size = std::strlen(s);
2555 result.assign(s, s + str_size);
2566 wide_string_type out;
2567 SQLLEN ValueLenOrInd;
2569 void* handle = native_statement_handle();
2572 wide_char_t buffer[512] = {0};
2573 const std::size_t buffer_size =
sizeof(buffer);
2583 if(ValueLenOrInd > 0)
2585 else if(ValueLenOrInd == SQL_NULL_DATA)
2586 *col.cbdata_ = (SQLINTEGER) SQL_NULL_DATA;
2589 }
while(rc == SQL_SUCCESS_WITH_INFO);
2590 if (rc == SQL_SUCCESS || rc == SQL_NO_DATA)
2591 convert(out, result);
2596 const SQLWCHAR* s =
reinterpret_cast<SQLWCHAR*
>(col.pdata_ + rowset_position_ * col.clen_);
2597 const string_type::size_type str_size = *col.cbdata_ /
sizeof(SQLWCHAR);
2598 wide_string_type temp(s, s + str_size);
2599 convert(temp, result);
2606 const char* s = col.pdata_ + rowset_position_ * col.clen_;
2607 result.assign(s, s + column_size);
2614 buffer.reserve(column_size + 1);
2615 buffer.resize(buffer.capacity());
2617 fill(buffer.begin(), buffer.end(),
'\0');
2618 const wide_char_t data = *
reinterpret_cast<wide_char_t*
>(col.pdata_ + rowset_position_ * col.clen_);
2619 const int bytes = std::snprintf(
const_cast<char*
>(buffer.data()), column_size,
"%d", data);
2621 throw type_incompatible_error();
2622 else if((SQLULEN)bytes < column_size)
2623 buffer.resize(bytes);
2624 buffer.resize(std::strlen(buffer.data()));
2625 result.reserve(buffer.size() *
sizeof(string_type::value_type));
2626 convert(buffer, result);
2632 using namespace std;
2634 buffer.reserve(column_size + 1);
2635 buffer.resize(buffer.capacity());
2637 fill(buffer.begin(), buffer.end(),
'\0');
2638 const intmax_t data = (intmax_t)*
reinterpret_cast<int64_t*
>(col.pdata_ + rowset_position_ * col.clen_);
2639 const int bytes = std::snprintf(
const_cast<char*
>(buffer.data()), column_size,
"%jd", data);
2641 throw type_incompatible_error();
2642 else if((SQLULEN)bytes < column_size)
2643 buffer.resize(bytes);
2644 buffer.resize(std::strlen(buffer.data()));
2645 result.reserve(buffer.size() *
sizeof(string_type::value_type));
2646 convert(buffer, result);
2653 buffer.reserve(column_size + 1);
2654 buffer.resize(buffer.capacity());
2656 fill(buffer.begin(), buffer.end(),
'\0');
2657 const float data = *
reinterpret_cast<float*
>(col.pdata_ + rowset_position_ * col.clen_);
2658 const int bytes = std::snprintf(
const_cast<char*
>(buffer.data()), column_size,
"%f", data);
2660 throw type_incompatible_error();
2661 else if((SQLULEN)bytes < column_size)
2662 buffer.resize(bytes);
2663 buffer.resize(std::strlen(buffer.data()));
2664 result.reserve(buffer.size() *
sizeof(string_type::value_type));
2665 convert(buffer, result);
2672 const SQLULEN width = column_size + 2;
2673 buffer.reserve(width + 1);
2674 buffer.resize(buffer.capacity());
2676 fill(buffer.begin(), buffer.end(),
'\0');
2677 const double data = *
reinterpret_cast<double*
>(col.pdata_ + rowset_position_ * col.clen_);
2678 const int bytes = std::snprintf(
2679 const_cast<char*
>(buffer.data())
2685 throw type_incompatible_error();
2686 else if((SQLULEN)bytes < column_size)
2687 buffer.resize(bytes);
2688 buffer.resize(std::strlen(buffer.data()));
2689 result.reserve(buffer.size() *
sizeof(string_type::value_type));
2690 convert(buffer, result);
2696 const date d = *
reinterpret_cast<date*
>(col.pdata_ + rowset_position_ * col.clen_);
2698 st.tm_year = d.year - 1900;
2699 st.tm_mon = d.month - 1;
2701 char* old_lc_time = std::setlocale(LC_TIME, NULL);
2702 std::setlocale(LC_TIME,
"");
2704 std::strftime(date_str,
sizeof(date_str),
"%Y-%m-%d", &st);
2705 std::setlocale(LC_TIME, old_lc_time);
2706 convert(date_str, result);
2710 case SQL_C_TIMESTAMP:
2712 const timestamp stamp = *
reinterpret_cast<timestamp*
>(col.pdata_ + rowset_position_ * col.clen_);
2714 st.tm_year = stamp.year - 1900;
2715 st.tm_mon = stamp.month - 1;
2716 st.tm_mday = stamp.day;
2717 st.tm_hour = stamp.hour;
2718 st.tm_min = stamp.min;
2719 st.tm_sec = stamp.sec;
2720 char* old_lc_time = std::setlocale(LC_TIME, NULL);
2721 std::setlocale(LC_TIME,
"");
2723 std::strftime(date_str,
sizeof(date_str),
"%Y-%m-%d %H:%M:%S %z", &st);
2724 std::setlocale(LC_TIME, old_lc_time);
2725 convert(date_str, result);
2729 throw type_incompatible_error();
2733void result::result_impl::get_ref_impl(
short column, T& result)
const
2735 bound_column& col = bound_columns_[column];
2736 using namespace std;
2737 const char* s = col.pdata_ + rowset_position_ * col.clen_;
2740 case SQL_C_CHAR: result = (T)*(
char*)(s);
return;
2741 case SQL_C_SSHORT: result = (T)*(
short*)(s);
return;
2742 case SQL_C_USHORT: result = (T)*(
unsigned short*)(s);
return;
2743 case SQL_C_LONG: result = (T)*(int32_t*)(s);
return;
2744 case SQL_C_SLONG: result = (T)*(int32_t*)(s);
return;
2745 case SQL_C_ULONG: result = (T)*(uint32_t*)(s);
return;
2746 case SQL_C_FLOAT: result = (T)*(
float*)(s);
return;
2747 case SQL_C_DOUBLE: result = (T)*(
double*)(s);
return;
2748 case SQL_C_SBIGINT: result = (T)*(int64_t*)(s);
return;
2749 case SQL_C_UBIGINT: result = (T)*(uint64_t*)(s);
return;
2751 throw type_incompatible_error();
2769result execute(connection& conn,
const string_type& query,
long batch_operations,
long timeout)
2771 class statement statement;
2772 return statement.execute_direct(conn, query, batch_operations, timeout);
2775void just_execute(connection& conn,
const string_type& query,
long batch_operations,
long timeout) {
2776 class statement statement;
2777 statement.just_execute_direct(conn, query, batch_operations, timeout);
2780result execute(statement& stmt,
long batch_operations)
2782 return stmt.execute(batch_operations);
2785void just_execute(statement& stmt,
long batch_operations)
2787 return stmt.just_execute(batch_operations);
2790result transact(statement& stmt,
long batch_operations)
2792 class transaction transaction(stmt.connection());
2793 result rvalue = stmt.execute(batch_operations);
2794 transaction.commit();
2798void just_transact(statement& stmt,
long batch_operations)
2800 class transaction transaction(stmt.connection());
2801 stmt.just_execute(batch_operations);
2802 transaction.commit();
2805void prepare(statement& stmt,
const string_type& query,
long timeout)
2807 stmt.prepare(stmt.connection(), query, timeout);
2825connection::connection()
2826: impl_(new connection_impl())
2831connection::connection(
const connection& rhs)
2837#ifndef NANODBC_NO_MOVE_CTOR
2838 connection::connection(connection&& rhs) NANODBC_NOEXCEPT
2839 : impl_(std::move(rhs.impl_))
2845connection& connection::operator=(connection rhs)
2851void connection::swap(connection& rhs) NANODBC_NOEXCEPT
2854 swap(impl_, rhs.impl_);
2857connection::connection(
2858 const string_type& dsn
2859 ,
const string_type& user
2860 ,
const string_type& pass
2862: impl_(new connection_impl(dsn, user, pass, timeout))
2867connection::connection(
const string_type& connection_string,
long timeout)
2868: impl_(new connection_impl(connection_string, timeout))
2873connection::~connection() NANODBC_NOEXCEPT
2878void connection::connect(
2879 const string_type& dsn
2880 ,
const string_type& user
2881 ,
const string_type& pass
2884 impl_->connect(dsn, user, pass, timeout);
2887void connection::connect(
const string_type& connection_string,
long timeout)
2889 impl_->connect(connection_string, timeout);
2892#ifdef SQL_ATTR_ASYNC_DBC_EVENT
2893void connection::async_connect(
2894 const string_type& dsn
2895 ,
const string_type& user
2896 ,
const string_type& pass
2897 ,
void* event_handle
2900 impl_->connect(dsn, user, pass, timeout, event_handle);
2903void connection::async_connect(
const string_type& connection_string,
void* event_handle,
long timeout)
2905 impl_->connect(connection_string, timeout, event_handle);
2908void connection::async_complete()
2910 impl_->async_complete();
2914bool connection::connected()
const
2916 return impl_->connected();
2919void connection::disconnect()
2921 impl_->disconnect();
2924std::size_t connection::transactions()
const
2926 return impl_->transactions();
2929void* connection::native_dbc_handle()
const
2931 return impl_->native_dbc_handle();
2934void* connection::native_env_handle()
const
2936 return impl_->native_env_handle();
2939string_type connection::dbms_name()
const
2941 return impl_->dbms_name();
2944string_type connection::dbms_version()
const
2946 return impl_->dbms_version();
2949string_type connection::driver_name()
const
2951 return impl_->driver_name();
2954string_type connection::database_name()
const
2956 return impl_->database_name();
2959string_type connection::catalog_name()
const
2961 return impl_->catalog_name();
2964std::size_t connection::ref_transaction()
2966 return impl_->ref_transaction();
2969std::size_t connection::unref_transaction()
2971 return impl_->unref_transaction();
2974bool connection::rollback()
const
2976 return impl_->rollback();
2979void connection::rollback(
bool onoff)
2981 impl_->rollback(onoff);
2999transaction::transaction(
const class connection& conn)
3000: impl_(new transaction_impl(conn))
3005transaction::transaction(
const transaction& rhs)
3011#ifndef NANODBC_NO_MOVE_CTOR
3012 transaction::transaction(transaction&& rhs) NANODBC_NOEXCEPT
3013 : impl_(std::move(rhs.impl_))
3019transaction& transaction::operator=(transaction rhs)
3025void transaction::swap(transaction& rhs) NANODBC_NOEXCEPT
3028 swap(impl_, rhs.impl_);
3031transaction::~transaction() NANODBC_NOEXCEPT
3036void transaction::commit()
3041void transaction::rollback() NANODBC_NOEXCEPT
3046class connection& transaction::connection()
3048 return impl_->connection();
3051const class connection& transaction::connection()
const
3053 return impl_->connection();
3056transaction::operator
class connection&()
3058 return impl_->connection();
3061transaction::operator
const class connection&()
const
3063 return impl_->connection();
3081statement::statement()
3082: impl_(new statement_impl())
3087statement::statement(
class connection& conn)
3088: impl_(new statement_impl(conn))
3093#ifndef NANODBC_NO_MOVE_CTOR
3094 statement::statement(statement&& rhs) NANODBC_NOEXCEPT
3095 : impl_(std::move(rhs.impl_))
3101statement::statement(
class connection& conn,
const string_type& query,
long timeout)
3102: impl_(new statement_impl(conn, query, timeout))
3107statement::statement(
const statement& rhs)
3113statement& statement::operator=(statement rhs)
3119void statement::swap(statement& rhs) NANODBC_NOEXCEPT
3122 swap(impl_, rhs.impl_);
3125statement::~statement() NANODBC_NOEXCEPT
3130void statement::open(
class connection& conn)
3135bool statement::open()
const
3137 return impl_->open();
3140bool statement::connected()
const
3142 return impl_->connected();
3145const class connection& statement::connection()
const
3147 return impl_->connection();
3150class connection& statement::connection()
3152 return impl_->connection();
3155void* statement::native_statement_handle()
const
3157 return impl_->native_statement_handle();
3160void statement::close()
3165void statement::cancel()
3170void statement::prepare(
class connection& conn,
const string_type& query,
long timeout)
3172 impl_->prepare(conn, query, timeout);
3175void statement::prepare(
const string_type& query,
long timeout)
3177 impl_->prepare(query, timeout);
3180void statement::timeout(
long timeout)
3182 impl_->timeout(timeout);
3185result statement::execute_direct(
3186 class connection& conn
3187 ,
const string_type& query
3188 ,
long batch_operations
3191 return impl_->execute_direct(conn, query, batch_operations, timeout, *
this);
3194#if defined(SQL_ATTR_ASYNC_STMT_EVENT) && defined(SQL_API_SQLCOMPLETEASYNC)
3195 void statement::async_execute_direct(
3196 class connection& conn
3197 ,
void* event_handle
3198 ,
const string_type& query
3199 ,
long batch_operations
3202 impl_->async_execute_direct(conn, event_handle, query, batch_operations, timeout, *
this);
3205 result statement::async_complete(
long batch_operations)
3207 return impl_->async_complete(batch_operations, *
this);
3211void statement::just_execute_direct(
3212 class connection& conn
3213 ,
const string_type& query
3214 ,
long batch_operations
3217 impl_->just_execute_direct(conn, query, batch_operations, timeout, *
this);
3220result statement::execute(
long batch_operations,
long timeout)
3222 return impl_->execute(batch_operations, timeout, *
this);
3225void statement::just_execute(
long batch_operations,
long timeout)
3227 impl_->just_execute(batch_operations, timeout, *
this);
3230result statement::procedure_columns(
3231 const string_type& catalog
3232 ,
const string_type& schema
3233 ,
const string_type& procedure
3234 ,
const string_type& column)
3236 return impl_->procedure_columns(catalog, schema, procedure, column, *
this);
3239long statement::affected_rows()
const
3241 return impl_->affected_rows();
3244short statement::columns()
const
3246 return impl_->columns();
3249void statement::reset_parameters() NANODBC_NOEXCEPT
3251 impl_->reset_parameters();
3254unsigned long statement::parameter_size(
short param)
const
3256 return impl_->parameter_size(param);
3260#define NANODBC_INSTANTIATE_BINDS(type) \
3261 template void statement::bind(short, const type*, param_direction); \
3262 template void statement::bind(short, const type*, std::size_t, param_direction); \
3263 template void statement::bind(short, const type*, std::size_t, const type*, param_direction); \
3264 template void statement::bind(short, const type*, std::size_t, const bool*, param_direction) \
3268NANODBC_INSTANTIATE_BINDS(string_type::value_type);
3269NANODBC_INSTANTIATE_BINDS(
short);
3270NANODBC_INSTANTIATE_BINDS(
unsigned short);
3271NANODBC_INSTANTIATE_BINDS(int32_t);
3272NANODBC_INSTANTIATE_BINDS(uint32_t);
3273NANODBC_INSTANTIATE_BINDS(int64_t);
3274NANODBC_INSTANTIATE_BINDS(uint64_t);
3275NANODBC_INSTANTIATE_BINDS(
float);
3276NANODBC_INSTANTIATE_BINDS(
double);
3277NANODBC_INSTANTIATE_BINDS(date);
3278NANODBC_INSTANTIATE_BINDS(timestamp);
3280#undef NANODBC_INSTANTIATE_BINDS
3283void statement::bind(
short param,
const T* value, param_direction direction)
3285 impl_->bind(param, value, 1, direction);
3289void statement::bind(
short param,
const T* values, std::size_t elements, param_direction direction)
3291 impl_->bind(param, values, elements, direction);
3295void statement::bind(
3298 , std::size_t elements
3299 ,
const T* null_sentry
3300 , param_direction direction)
3302 impl_->bind(param, values, elements, 0, null_sentry, direction);
3306void statement::bind(
3309 , std::size_t elements
3311 , param_direction direction)
3313 impl_->bind(param, values, elements, nulls, (T*)0, direction);
3316void statement::bind_strings(
3318 ,
const string_type::value_type* values
3319 , std::size_t length
3320 , std::size_t elements
3321 , param_direction direction)
3323 impl_->bind_strings(param, values, length, elements, direction);
3326void statement::bind_strings(
3328 ,
const string_type::value_type* values
3329 , std::size_t length
3330 , std::size_t elements
3331 ,
const string_type::value_type* null_sentry
3332 , param_direction direction)
3334 impl_->bind_strings(param, values, length, elements, (
bool*)0, null_sentry, direction);
3337void statement::bind_strings(
3339 ,
const string_type::value_type* values
3340 , std::size_t length
3341 , std::size_t elements
3343 , param_direction direction)
3345 impl_->bind_strings(
3351 , (string_type::value_type*)0
3355void statement::bind_null(
short param, std::size_t elements)
3357 impl_->bind_null(param, elements);
3365catalog::tables::tables(result& find_result)
3366: result_(find_result)
3370bool catalog::tables::next()
3372 return result_.next();
3375string_type catalog::tables::table_catalog()
const
3378 return result_.get<string_type>(0, string_type());
3381string_type catalog::tables::table_schema()
const
3384 return result_.get<string_type>(1, string_type());
3387string_type catalog::tables::table_name()
const
3390 return result_.get<string_type>(2);
3393string_type catalog::tables::table_type()
const
3396 return result_.get<string_type>(3);
3399string_type catalog::tables::table_remarks()
const
3402 return result_.get<string_type>(4, string_type());
3405catalog::primary_keys::primary_keys(result& find_result)
3406: result_(find_result)
3410bool catalog::primary_keys::next()
3412 return result_.next();
3415string_type catalog::primary_keys::table_catalog()
const
3418 return result_.get<string_type>(0, string_type());
3421string_type catalog::primary_keys::table_schema()
const
3424 return result_.get<string_type>(1, string_type());
3427string_type catalog::primary_keys::table_name()
const
3430 return result_.get<string_type>(2);
3433string_type catalog::primary_keys::column_name()
const
3436 return result_.get<string_type>(3);
3439short catalog::primary_keys::column_number()
const
3442 return result_.get<
short>(4);
3445string_type catalog::primary_keys::primary_key_name()
const
3448 return result_.get<string_type>(5);
3451catalog::columns::columns(result& find_result)
3452: result_(find_result)
3456bool catalog::columns::next()
3458 return result_.next();
3461string_type catalog::columns::table_catalog()
const
3464 return result_.get<string_type>(0, string_type());
3467string_type catalog::columns::table_schema()
const
3470 return result_.get<string_type>(1, string_type());
3473string_type catalog::columns::table_name()
const
3476 return result_.get<string_type>(2);
3479string_type catalog::columns::column_name()
const
3482 return result_.get<string_type>(3);
3485short catalog::columns::data_type()
const
3488 return result_.get<
short>(4);
3491string_type catalog::columns::type_name()
const
3494 return result_.get<string_type>(5);
3497long catalog::columns::column_size()
const
3500 return result_.get<
long>(6);
3503long catalog::columns::buffer_length()
const
3506 return result_.get<
long>(7);
3509short catalog::columns::decimal_digits()
const
3512 return result_.get<
short>(8, 0);
3515short catalog::columns::numeric_precision_radix()
const
3518 return result_.get<
short>(9, 0);
3521short catalog::columns::nullable()
const
3524 return result_.get<
short>(10);
3527string_type catalog::columns::remarks()
const
3530 return result_.get<string_type>(11, string_type());
3533string_type catalog::columns::column_default()
const
3536 return result_.get<string_type>(12, string_type());
3539short catalog::columns::sql_data_type()
const
3542 return result_.get<
short>(13);
3545short catalog::columns::sql_datetime_subtype()
const
3548 return result_.get<
short>(14, 0);
3551long catalog::columns::char_octed_length()
const
3554 return result_.get<
long>(15, 0);
3557long catalog::columns::ordinal_position()
const
3560 return result_.get<
long>(16);
3563string_type catalog::columns::is_nullable()
const
3570 return result_.get<string_type>(17, string_type());
3573catalog::catalog(connection& conn)
3578catalog::tables catalog::find_tables(
3579 const string_type& table
3580 ,
const string_type& type
3581 ,
const string_type& schema
3582 ,
const string_type& catalog)
3584 statement stmt(conn_);
3587 NANODBC_FUNC(SQLTables)
3589 , stmt.native_statement_handle()
3590 , (NANODBC_SQLCHAR*)(catalog.empty() ? NULL : catalog.c_str())
3591 , (catalog.empty() ? 0 : SQL_NTS)
3592 , (NANODBC_SQLCHAR*)(schema.empty() ? NULL : schema.c_str())
3593 , (schema.empty() ? 0 : SQL_NTS)
3594 , (NANODBC_SQLCHAR*)(table.empty() ? NULL : table.c_str())
3595 , (table.empty() ? 0 : SQL_NTS)
3596 , (NANODBC_SQLCHAR*)(type.empty() ? NULL : type.c_str())
3597 , (type.empty() ? 0 : SQL_NTS));
3599 NANODBC_THROW_DATABASE_ERROR(stmt.native_statement_handle(), SQL_HANDLE_STMT);
3601 result find_result(stmt, 1);
3602 return catalog::tables(find_result);
3605catalog::columns catalog::find_columns(
3606 const string_type& column
3607 ,
const string_type& table
3608 ,
const string_type& schema
3609 ,
const string_type& catalog)
3611 statement stmt(conn_);
3614 NANODBC_FUNC(SQLColumns)
3616 , stmt.native_statement_handle()
3617 , (NANODBC_SQLCHAR*)(catalog.empty() ? NULL : catalog.c_str())
3618 , (catalog.empty() ? 0 : SQL_NTS)
3619 , (NANODBC_SQLCHAR*)(schema.empty() ? NULL : schema.c_str())
3620 , (schema.empty() ? 0 : SQL_NTS)
3621 , (NANODBC_SQLCHAR*)(table.empty() ? NULL : table.c_str())
3622 , (table.empty() ? 0 : SQL_NTS)
3623 , (NANODBC_SQLCHAR*)(column.empty() ? NULL : column.c_str())
3624 , (column.empty() ? 0 : SQL_NTS));
3626 NANODBC_THROW_DATABASE_ERROR(stmt.native_statement_handle(), SQL_HANDLE_STMT);
3628 result find_result(stmt, 1);
3629 return catalog::columns(find_result);
3632catalog::primary_keys catalog::find_primary_keys(
3633 const string_type& table
3634 ,
const string_type& schema
3635 ,
const string_type& catalog)
3637 statement stmt(conn_);
3640 NANODBC_FUNC(SQLPrimaryKeys)
3642 , stmt.native_statement_handle()
3643 , (NANODBC_SQLCHAR*)(catalog.empty() ? NULL : catalog.c_str())
3644 , (catalog.empty() ? 0 : SQL_NTS)
3645 , (NANODBC_SQLCHAR*)(schema.empty() ? NULL : schema.c_str())
3646 , (schema.empty() ? 0 : SQL_NTS)
3647 , (NANODBC_SQLCHAR*)(table.empty() ? NULL : table.c_str())
3648 , (table.empty() ? 0 : SQL_NTS));
3650 NANODBC_THROW_DATABASE_ERROR(stmt.native_statement_handle(), SQL_HANDLE_STMT);
3652 result find_result(stmt, 1);
3653 return catalog::primary_keys(find_result);
3677result::~result() NANODBC_NOEXCEPT
3682result::result(statement stmt,
long rowset_size)
3683: impl_(new result_impl(stmt, rowset_size))
3688#ifndef NANODBC_NO_MOVE_CTOR
3689 result::result(result&& rhs) NANODBC_NOEXCEPT
3690 : impl_(std::move(rhs.impl_))
3696result::result(
const result& rhs)
3702result& result::operator=(result rhs)
3708void result::swap(result& rhs) NANODBC_NOEXCEPT
3711 swap(impl_, rhs.impl_);
3714void* result::native_statement_handle()
const
3716 return impl_->native_statement_handle();
3719long result::rowset_size() const NANODBC_NOEXCEPT
3721 return impl_->rowset_size();
3724long result::affected_rows()
const
3726 return impl_->affected_rows();
3729long result::rows() const NANODBC_NOEXCEPT
3731 return impl_->rows();
3734short result::columns()
const
3736 return impl_->columns();
3741 return impl_->first();
3746 return impl_->last();
3751 return impl_->next();
3756 return impl_->prior();
3759bool result::move(
long row)
3761 return impl_->move(row);
3764bool result::skip(
long rows)
3766 return impl_->skip(rows);
3769unsigned long result::position()
const
3771 return impl_->position();
3774bool result::end() const NANODBC_NOEXCEPT
3776 return impl_->end();
3779bool result::is_null(
short column)
const
3781 return impl_->is_null(column);
3784bool result::is_null(
const string_type& column_name)
const
3786 return impl_->is_null(column_name);
3789string_type result::column_name(
short column)
const
3791 return impl_->column_name(column);
3794long result::column_size(
short column)
const
3796 return impl_->column_size(column);
3799short result::column(
const string_type& column_name)
const
3801 return impl_->column(column_name);
3804int result::column_datatype(
short column)
const
3806 return impl_->column_datatype(column);
3809int result::column_datatype(
const string_type& column_name)
const
3811 return impl_->column_datatype(column_name);
3814int result::column_c_datatype(
short column)
const
3816 return impl_->column_c_datatype(column);
3819int result::column_c_datatype(
const string_type& column_name)
const
3821 return impl_->column_c_datatype(column_name);
3824bool result::next_result()
3826 return impl_->next_result();
3830void result::get_ref(
short column, T& result)
const
3832 return impl_->get_ref<T>(column, result);
3836void result::get_ref(
short column,
const T& fallback, T& result)
const
3838 return impl_->get_ref<T>(column, fallback, result);
3842void result::get_ref(
const string_type& column_name, T& result)
const
3844 return impl_->get_ref<T>(column_name, result);
3848void result::get_ref(
const string_type& column_name,
const T& fallback, T& result)
const
3850 return impl_->get_ref<T>(column_name, fallback, result);
3854T result::get(
short column)
const
3856 return impl_->get<T>(column);
3860T result::get(
short column,
const T& fallback)
const
3862 return impl_->get<T>(column, fallback);
3866T result::get(
const string_type& column_name)
const
3868 return impl_->get<T>(column_name);
3872T result::get(
const string_type& column_name,
const T& fallback)
const
3874 return impl_->get<T>(column_name, fallback);
3877result::operator
bool()
const
3879 return static_cast<bool>(impl_);
3883template void result::get_ref(
short, string_type::value_type&)
const;
3884template void result::get_ref(
short,
short&)
const;
3885template void result::get_ref(
short,
unsigned short&)
const;
3886template void result::get_ref(
short, int32_t&)
const;
3887template void result::get_ref(
short, uint32_t&)
const;
3888template void result::get_ref(
short, int64_t&)
const;
3889template void result::get_ref(
short, uint64_t&)
const;
3890template void result::get_ref(
short,
float&)
const;
3891template void result::get_ref(
short,
double&)
const;
3892template void result::get_ref(
short, string_type&)
const;
3893template void result::get_ref(
short, date&)
const;
3894template void result::get_ref(
short, timestamp&)
const;
3896template void result::get_ref(
const string_type&, string_type::value_type&)
const;
3897template void result::get_ref(
const string_type&,
short&)
const;
3898template void result::get_ref(
const string_type&,
unsigned short&)
const;
3899template void result::get_ref(
const string_type&, int32_t&)
const;
3900template void result::get_ref(
const string_type&, uint32_t&)
const;
3901template void result::get_ref(
const string_type&, int64_t&)
const;
3902template void result::get_ref(
const string_type&, uint64_t&)
const;
3903template void result::get_ref(
const string_type&,
float&)
const;
3904template void result::get_ref(
const string_type&,
double&)
const;
3905template void result::get_ref(
const string_type&, string_type&)
const;
3906template void result::get_ref(
const string_type&, date&)
const;
3907template void result::get_ref(
const string_type&, timestamp&)
const;
3910template void result::get_ref(
short,
const string_type::value_type&, string_type::value_type&)
const;
3911template void result::get_ref(
short,
const short&,
short&)
const;
3912template void result::get_ref(
short,
const unsigned short&,
unsigned short&)
const;
3913template void result::get_ref(
short,
const int32_t&, int32_t&)
const;
3914template void result::get_ref(
short,
const uint32_t&, uint32_t&)
const;
3915template void result::get_ref(
short,
const int64_t&, int64_t&)
const;
3916template void result::get_ref(
short,
const uint64_t&, uint64_t&)
const;
3917template void result::get_ref(
short,
const float&,
float&)
const;
3918template void result::get_ref(
short,
const double&,
double&)
const;
3919template void result::get_ref(
short,
const string_type&, string_type&)
const;
3920template void result::get_ref(
short,
const date&, date&)
const;
3921template void result::get_ref(
short,
const timestamp&, timestamp&)
const;
3923template void result::get_ref(
const string_type&,
const string_type::value_type&, string_type::value_type&)
const;
3924template void result::get_ref(
const string_type&,
const short&,
short&)
const;
3925template void result::get_ref(
const string_type&,
const unsigned short&,
unsigned short&)
const;
3926template void result::get_ref(
const string_type&,
const int32_t&, int32_t&)
const;
3927template void result::get_ref(
const string_type&,
const uint32_t&, uint32_t&)
const;
3928template void result::get_ref(
const string_type&,
const int64_t&, int64_t&)
const;
3929template void result::get_ref(
const string_type&,
const uint64_t&, uint64_t&)
const;
3930template void result::get_ref(
const string_type&,
const float&,
float&)
const;
3931template void result::get_ref(
const string_type&,
const double&,
double&)
const;
3932template void result::get_ref(
const string_type&,
const string_type&, string_type&)
const;
3933template void result::get_ref(
const string_type&,
const date&, date&)
const;
3934template void result::get_ref(
const string_type&,
const timestamp&, timestamp&)
const;
3937template string_type::value_type result::get(
short)
const;
3938template short result::get(
short)
const;
3939template unsigned short result::get(
short)
const;
3940template int32_t result::get(
short)
const;
3941template uint32_t result::get(
short)
const;
3942template int64_t result::get(
short)
const;
3943template uint64_t result::get(
short)
const;
3944template float result::get(
short)
const;
3945template double result::get(
short)
const;
3946template string_type result::get(
short)
const;
3947template date result::get(
short)
const;
3948template timestamp result::get(
short)
const;
3950template string_type::value_type result::get(
const string_type&)
const;
3951template short result::get(
const string_type&)
const;
3952template unsigned short result::get(
const string_type&)
const;
3953template int32_t result::get(
const string_type&)
const;
3954template uint32_t result::get(
const string_type&)
const;
3955template int64_t result::get(
const string_type&)
const;
3956template uint64_t result::get(
const string_type&)
const;
3957template float result::get(
const string_type&)
const;
3958template double result::get(
const string_type&)
const;
3959template string_type result::get(
const string_type&)
const;
3960template date result::get(
const string_type&)
const;
3961template timestamp result::get(
const string_type&)
const;
3964template string_type::value_type result::get(
short,
const string_type::value_type&)
const;
3965template short result::get(
short,
const short&)
const;
3966template unsigned short result::get(
short,
const unsigned short&)
const;
3967template int32_t result::get(
short,
const int32_t&)
const;
3968template uint32_t result::get(
short,
const uint32_t&)
const;
3969template int64_t result::get(
short,
const int64_t&)
const;
3970template uint64_t result::get(
short,
const uint64_t&)
const;
3971template float result::get(
short,
const float&)
const;
3972template double result::get(
short,
const double&)
const;
3973template string_type result::get(
short,
const string_type&)
const;
3974template date result::get(
short,
const date&)
const;
3975template timestamp result::get(
short,
const timestamp&)
const;
3977template string_type::value_type result::get(
const string_type&,
const string_type::value_type&)
const;
3978template short result::get(
const string_type&,
const short&)
const;
3979template unsigned short result::get(
const string_type&,
const unsigned short&)
const;
3980template int32_t result::get(
const string_type&,
const int32_t&)
const;
3981template uint32_t result::get(
const string_type&,
const uint32_t&)
const;
3982template int64_t result::get(
const string_type&,
const int64_t&)
const;
3983template uint64_t result::get(
const string_type&,
const uint64_t&)
const;
3984template float result::get(
const string_type&,
const float&)
const;
3985template double result::get(
const string_type&,
const double&)
const;
3986template string_type result::get(
const string_type&,
const string_type&)
const;
3987template date result::get(
const string_type&,
const date&)
const;
3988template timestamp result::get(
const string_type&,
const timestamp&)
const;
3992#undef NANODBC_THROW_DATABASE_ERROR
3993#undef NANODBC_STRINGIZE
3994#undef NANODBC_STRINGIZE_I
3995#undef NANODBC_CALL_RC
void swap(RefPtr< Val > &ptr1, RefPtr< Val > &ptr2)
Swap the contents of two RefPtr.
std::string replace(const std::string &s, const std::string &val, const std::string &new_val)
not usable for gcc 4.8 std::vector<std::string> split( const std::string& orig, ...