[SF 2807750] Support additional SQL types in SQLite

This commit is contained in:
Aleksandar Fabijanic 2009-06-17 19:00:49 +00:00
parent 5b64140891
commit 8123e9e2f4
3 changed files with 89 additions and 24 deletions

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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");