mirror of
https://github.com/pocoproject/poco.git
synced 2025-03-21 21:18:35 +01:00
[SF 2807750] Support additional SQL types in SQLite
This commit is contained in:
parent
5b64140891
commit
8123e9e2f4
@ -42,6 +42,8 @@
|
||||
|
||||
#include "Poco/Data/SQLite/SQLite.h"
|
||||
#include "Poco/Data/MetaColumn.h"
|
||||
#include "Poco/Mutex.h"
|
||||
#include <map>
|
||||
|
||||
|
||||
struct sqlite3;
|
||||
@ -59,6 +61,15 @@ class SQLite_API Utility
|
||||
public:
|
||||
static const std::string SQLITE_DATE_FORMAT;
|
||||
static const std::string SQLITE_TIME_FORMAT;
|
||||
typedef std::map<std::string, MetaColumn::ColumnDataType> TypeMap;
|
||||
|
||||
Utility();
|
||||
/// Maps SQLite column declared types to Poco::Data types through
|
||||
/// static TypeMap member.
|
||||
/// Note: SQLite is type-agnostic and it is the end-user responsibility
|
||||
/// to ensure that column declared data type corresponds to the type of
|
||||
/// data actually held in the database.
|
||||
/// Column types are case-insensitive.
|
||||
|
||||
static std::string lastError(sqlite3* pDb);
|
||||
/// Retreives the last error code from sqlite and converts it to a string
|
||||
@ -68,6 +79,10 @@ public:
|
||||
|
||||
static MetaColumn::ColumnDataType getColumnType(sqlite3_stmt* pStmt, std::size_t pos);
|
||||
/// Returns column data type.
|
||||
|
||||
private:
|
||||
static TypeMap _types;
|
||||
Poco::FastMutex _mutex;
|
||||
};
|
||||
|
||||
|
||||
|
@ -51,6 +51,66 @@ namespace SQLite {
|
||||
|
||||
const std::string Utility::SQLITE_DATE_FORMAT = "%Y-%m-%d";
|
||||
const std::string Utility::SQLITE_TIME_FORMAT = "%H:%M:%S";
|
||||
Utility::TypeMap Utility::_types;
|
||||
|
||||
|
||||
Utility::Utility()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock l(_mutex);
|
||||
|
||||
if (_types.empty())
|
||||
{
|
||||
_types.insert(TypeMap::value_type("", MetaColumn::FDT_STRING));
|
||||
_types.insert(TypeMap::value_type("BOOL", MetaColumn::FDT_BOOL));
|
||||
_types.insert(TypeMap::value_type("BOOLEAN", MetaColumn::FDT_BOOL));
|
||||
_types.insert(TypeMap::value_type("BIT", MetaColumn::FDT_BOOL));
|
||||
_types.insert(TypeMap::value_type("UINT8", MetaColumn::FDT_UINT8));
|
||||
_types.insert(TypeMap::value_type("UTINY", MetaColumn::FDT_UINT8));
|
||||
_types.insert(TypeMap::value_type("UINTEGER8", MetaColumn::FDT_UINT8));
|
||||
_types.insert(TypeMap::value_type("INT8", MetaColumn::FDT_INT8));
|
||||
_types.insert(TypeMap::value_type("TINY", MetaColumn::FDT_INT8));
|
||||
_types.insert(TypeMap::value_type("INTEGER8", MetaColumn::FDT_INT8));
|
||||
_types.insert(TypeMap::value_type("UINT16", MetaColumn::FDT_UINT16));
|
||||
_types.insert(TypeMap::value_type("USHORT", MetaColumn::FDT_UINT16));
|
||||
_types.insert(TypeMap::value_type("UINTEGER16", MetaColumn::FDT_UINT16));
|
||||
_types.insert(TypeMap::value_type("INT16", MetaColumn::FDT_INT16));
|
||||
_types.insert(TypeMap::value_type("SHORT", MetaColumn::FDT_INT16));
|
||||
_types.insert(TypeMap::value_type("INTEGER16", MetaColumn::FDT_INT16));
|
||||
_types.insert(TypeMap::value_type("UINT", MetaColumn::FDT_UINT32));
|
||||
_types.insert(TypeMap::value_type("UINT32", MetaColumn::FDT_UINT32));
|
||||
_types.insert(TypeMap::value_type("UINTEGER32", MetaColumn::FDT_UINT32));
|
||||
_types.insert(TypeMap::value_type("INT", MetaColumn::FDT_INT32));
|
||||
_types.insert(TypeMap::value_type("INT32", MetaColumn::FDT_INT32));
|
||||
_types.insert(TypeMap::value_type("INTEGER", MetaColumn::FDT_INT32));
|
||||
_types.insert(TypeMap::value_type("INTEGER32", MetaColumn::FDT_INT32));
|
||||
_types.insert(TypeMap::value_type("UINT64", MetaColumn::FDT_UINT64));
|
||||
_types.insert(TypeMap::value_type("ULONG", MetaColumn::FDT_INT64));
|
||||
_types.insert(TypeMap::value_type("UINTEGER64", MetaColumn::FDT_UINT64));
|
||||
_types.insert(TypeMap::value_type("INT64", MetaColumn::FDT_INT64));
|
||||
_types.insert(TypeMap::value_type("LONG", MetaColumn::FDT_INT64));
|
||||
_types.insert(TypeMap::value_type("INTEGER64", MetaColumn::FDT_INT64));
|
||||
_types.insert(TypeMap::value_type("COUNTER", MetaColumn::FDT_UINT64));
|
||||
_types.insert(TypeMap::value_type("AUTOINCREMENT", MetaColumn::FDT_UINT64));
|
||||
_types.insert(TypeMap::value_type("REAL", MetaColumn::FDT_DOUBLE));
|
||||
_types.insert(TypeMap::value_type("FLOA", MetaColumn::FDT_DOUBLE));
|
||||
_types.insert(TypeMap::value_type("FLOAT", MetaColumn::FDT_DOUBLE));
|
||||
_types.insert(TypeMap::value_type("DOUB", MetaColumn::FDT_DOUBLE));
|
||||
_types.insert(TypeMap::value_type("DOUBLE", MetaColumn::FDT_DOUBLE));
|
||||
_types.insert(TypeMap::value_type("CHAR", MetaColumn::FDT_STRING));
|
||||
_types.insert(TypeMap::value_type("CLOB", MetaColumn::FDT_STRING));
|
||||
_types.insert(TypeMap::value_type("TEXT", MetaColumn::FDT_STRING));
|
||||
_types.insert(TypeMap::value_type("VARCHAR", MetaColumn::FDT_STRING));
|
||||
_types.insert(TypeMap::value_type("NCHAR", MetaColumn::FDT_STRING));
|
||||
_types.insert(TypeMap::value_type("NCLOB", MetaColumn::FDT_STRING));
|
||||
_types.insert(TypeMap::value_type("NTEXT", MetaColumn::FDT_STRING));
|
||||
_types.insert(TypeMap::value_type("NVARCHAR", MetaColumn::FDT_STRING));
|
||||
_types.insert(TypeMap::value_type("BLOB", MetaColumn::FDT_BLOB));
|
||||
_types.insert(TypeMap::value_type("DATE", MetaColumn::FDT_DATE));
|
||||
_types.insert(TypeMap::value_type("TIME", MetaColumn::FDT_TIME));
|
||||
_types.insert(TypeMap::value_type("DATETIME", MetaColumn::FDT_TIMESTAMP));
|
||||
_types.insert(TypeMap::value_type("TIMESTAMP", MetaColumn::FDT_TIMESTAMP));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string Utility::lastError(sqlite3 *pDB)
|
||||
@ -63,27 +123,17 @@ MetaColumn::ColumnDataType Utility::getColumnType(sqlite3_stmt* pStmt, std::size
|
||||
{
|
||||
poco_assert_dbg (pStmt);
|
||||
|
||||
static Utility u;
|
||||
|
||||
const char* pc = sqlite3_column_decltype(pStmt, (int) pos);
|
||||
std::string sqliteType = pc ? pc : "";
|
||||
Poco::toUpperInPlace(sqliteType);
|
||||
|
||||
if (sqliteType.npos != sqliteType.find("INT"))
|
||||
return MetaColumn::FDT_INT64;
|
||||
else if (sqliteType.empty() ||
|
||||
sqliteType.npos != sqliteType.find("CHAR") ||
|
||||
sqliteType.npos != sqliteType.find("CLOB") ||
|
||||
sqliteType.npos != sqliteType.find("TEXT"))
|
||||
return MetaColumn::FDT_STRING;
|
||||
else if (sqliteType.npos != sqliteType.find("REAL") ||
|
||||
sqliteType.npos != sqliteType.find("FLOA") ||
|
||||
sqliteType.npos != sqliteType.find("DOUB"))
|
||||
return MetaColumn::FDT_DOUBLE;
|
||||
else if (sqliteType.npos != sqliteType.find("BLOB"))
|
||||
return MetaColumn::FDT_BLOB;
|
||||
else if (sqliteType.npos != sqliteType.find("DATE"))
|
||||
return MetaColumn::FDT_TIMESTAMP;
|
||||
sqliteType = sqliteType.substr(0, sqliteType.find_first_of(" ("));
|
||||
|
||||
throw Poco::NotFoundException();
|
||||
TypeMap::const_iterator it = _types.find(Poco::trimInPlace(sqliteType));
|
||||
if (_types.end() == it) throw Poco::NotFoundException();
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
||||
|
@ -89,7 +89,7 @@ using Poco::NotFoundException;
|
||||
using Poco::NullPointerException;
|
||||
using Poco::Data::SQLite::ConstraintViolationException;
|
||||
using Poco::Data::SQLite::ParameterCountMismatchException;
|
||||
using Poco::Int64;
|
||||
using Poco::Int32;
|
||||
|
||||
|
||||
struct Person
|
||||
@ -1759,13 +1759,13 @@ void SQLiteTest::testInternalExtraction()
|
||||
assert (3 == rset2.columnCount());
|
||||
assert (4 == rset2.rowCount());
|
||||
|
||||
Int64 a = rset.value<Int64>(0,2);
|
||||
Int32 a = rset.value<Int32>(0,2);
|
||||
assert (3 == a);
|
||||
|
||||
int c = rset2.value(0);
|
||||
assert (1 == c);
|
||||
|
||||
Int64 b = rset2.value<Int64>("InT0",2);
|
||||
Int32 b = rset2.value<Int32>("InT0",2);
|
||||
assert (3 == b);
|
||||
|
||||
double d = rset.value<double>(1,0);
|
||||
@ -1774,7 +1774,7 @@ void SQLiteTest::testInternalExtraction()
|
||||
std::string s = rset.value<std::string>(2,1);
|
||||
assert ("4" == s);
|
||||
|
||||
typedef std::deque<Int64> IntDeq;
|
||||
typedef std::deque<Int32> IntDeq;
|
||||
|
||||
const Column<IntDeq>& col = rset.column<IntDeq>(0);
|
||||
assert (col[0] == 1);
|
||||
@ -2024,7 +2024,7 @@ void SQLiteTest::testAny()
|
||||
tmp << "DROP TABLE IF EXISTS Anys", now;
|
||||
tmp << "CREATE TABLE Anys (int0 INTEGER, flt0 REAL, str0 VARCHAR)", now;
|
||||
|
||||
Any i = Int64(42);
|
||||
Any i = Int32(42);
|
||||
Any f = double(42.5);
|
||||
Any s = std::string("42");
|
||||
|
||||
@ -2038,7 +2038,7 @@ void SQLiteTest::testAny()
|
||||
f = 0.0;
|
||||
s = std::string("");
|
||||
tmp << "SELECT * FROM Anys", into(i), into(f), into(s), now;
|
||||
assert (AnyCast<Int64>(i) == 42);
|
||||
assert (AnyCast<Int32>(i) == 42);
|
||||
assert (AnyCast<double>(f) == 42.5);
|
||||
assert (AnyCast<std::string>(s) == "42");
|
||||
}
|
||||
@ -2050,7 +2050,7 @@ void SQLiteTest::testDynamicAny()
|
||||
tmp << "DROP TABLE IF EXISTS Anys", now;
|
||||
tmp << "CREATE TABLE Anys (int0 INTEGER, flt0 REAL, str0 VARCHAR)", now;
|
||||
|
||||
DynamicAny i = Int64(42);
|
||||
DynamicAny i = Int32(42);
|
||||
DynamicAny f = double(42.5);
|
||||
DynamicAny s = std::string("42");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user