1
0
mirror of https://github.com/stefanocasazza/ULib.git synced 2025-09-28 19:05:55 +08:00
ULib/include/ulib/orm/orm.h
stefanocasazza d32d21a917 sync
2018-08-21 15:58:45 +02:00

964 lines
28 KiB
C++

// ============================================================================
//
// = LIBRARY
// ULib - c++ library
//
// = FILENAME
// orm.h - Object Relational Mapping
//
// = AUTHOR
// Stefano Casazza
//
// ============================================================================
#ifndef ULIB_ORM_H
#define ULIB_ORM_H 1
#include <ulib/string.h>
class UOrmDriver;
class UOrmStatement;
class USqlStatement;
/**
* \brief SQL session object that represents a single connection and is the gateway to SQL database
*
* It is the main class that is used for access to the DB
*/
class U_EXPORT UOrmSession {
public:
// Check for memory error
U_MEMORY_TEST
// Allocator e Deallocator
U_MEMORY_ALLOCATOR
U_MEMORY_DEALLOCATOR
UOrmSession(const char* dbname, uint32_t len);
UOrmSession(const char* backend, uint32_t len, const UString& option)
{
U_TRACE_CTOR(0, UOrmSession, "%.*S,%u,%V", len, backend, len, option.rep)
loadDriver(backend, len, option);
}
~UOrmSession();
// will be typecast into conn-specific type
bool isReady() const __pure;
void* getConnection() __pure;
bool connect(const UString& option);
UOrmDriver* getDriver() const { return pdrv; }
// statement that should only be executed once and immediately
bool query(const char* query, uint32_t query_len);
// This function returns the number of database rows that were changed
// or inserted or deleted by the most recently completed SQL statement
unsigned long long affected();
// This routine returns the rowid of the most recent successful INSERT into the database
unsigned long long last_insert_rowid(const char* sequence = U_NULLPTR);
// STREAM
#ifdef U_STDCPP_ENABLE
friend U_EXPORT bool operator<<(UOrmSession& session, const char* query) { return session.query(query, u__strlen(query, __PRETTY_FUNCTION__)); }
friend U_EXPORT bool operator<<(UOrmSession& session, const UString& query) { return session.query(U_STRING_TO_PARAM(query)); }
// DEBUG
# ifdef DEBUG
const char* dump(bool reset) const;
# endif
#endif
protected:
UOrmDriver* pdrv;
void loadDriver(const char* backend, uint32_t len, const UString& option);
private:
static void loadDriverFail(const char* ptr, uint32_t len) __noreturn U_NO_EXPORT;
U_DISALLOW_COPY_AND_ASSIGN(UOrmSession)
friend class UOrmStatement;
};
class U_EXPORT UOrmTypeHandler_Base {
public:
// Check for memory error
U_MEMORY_TEST
// Allocator e Deallocator
U_MEMORY_ALLOCATOR
U_MEMORY_DEALLOCATOR
UOrmTypeHandler_Base(const void* ptr) : pval((void*)ptr)
{
U_TRACE_CTOR(0, UOrmTypeHandler_Base, "%p", ptr)
U_INTERNAL_ASSERT_POINTER(pval)
}
~UOrmTypeHandler_Base()
{
U_TRACE_DTOR(0, UOrmTypeHandler_Base)
U_INTERNAL_ASSERT_POINTER(pval)
}
#if defined(U_STDCPP_ENABLE) && defined(DEBUG)
const char* dump(bool reset) const;
#endif
protected:
void* pval;
private:
U_DISALLOW_ASSIGN(UOrmTypeHandler_Base)
};
#define U_ORM_TYPE_HANDLER(name_object_member, type_object_member) UOrmTypeHandler<type_object_member>(name_object_member)
/**
* Converts Rows to a Type and the other way around.
* Provide template specializations to support your own complex types.
*
* Take as example the following (simplified) class:
*
* class Person {
* public:
* int age;
* UString lastName;
* UString firstName;
* };
*
* add this methods to the (simplified) class:
*
* void bindParam(UOrmStatement* stmt)
* {
* // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3))
*
* stmt->bindParam(U_ORM_TYPE_HANDLER(age, int));
* stmt->bindParam(U_ORM_TYPE_HANDLER( lastName, UString));
* stmt->bindParam(U_ORM_TYPE_HANDLER(firstName, UString));
* }
*
* void bindResult(UOrmStatement* stmt)
* {
* // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3))
*
* stmt->bindResult(U_ORM_TYPE_HANDLER(age, int));
* stmt->bindResult(U_ORM_TYPE_HANDLER( lastName, UString));
* stmt->bindResult(U_ORM_TYPE_HANDLER(firstName, UString));
* }
*/
template <class T> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(T* val) : UOrmTypeHandler_Base( val) {}
explicit UOrmTypeHandler(T& val) : UOrmTypeHandler_Base(&val) {}
// SERVICES
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<T>::bindParam(%p)", stmt)
((T*)pval)->bindParam(stmt);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<T>::bindResult(%p)", stmt)
((T*)pval)->bindResult(stmt);
}
private:
U_DISALLOW_ASSIGN(UOrmTypeHandler)
};
/**
* \brief This class represents a prepared (not ordinary) statement that can be executed
*
* Placeholders will escape "special" characters for you automatically, protect you from
* SQL injection vulnerabilities, and potentially make your code faster and cleaner to read.
* The character '?' is used as placeholders in prepared statements
*/
class U_EXPORT UOrmStatement {
public:
// Check for memory error
U_MEMORY_TEST
// Allocator e Deallocator
U_MEMORY_ALLOCATOR
U_MEMORY_DEALLOCATOR
// The string must include one or more parameter markers in the SQL statement by embedding question mark (?) characters into
// the SQL string at the appropriate positions. The markers are legal only in certain places in SQL statements. For example,
// they are permitted in the VALUES() list of an INSERT statement (to specify column values for a row), or in a comparison with
// a column in a WHERE clause to specify a comparison value.
UOrmStatement(UOrmSession& session, const char* query, uint32_t query_len);
~UOrmStatement();
// will be typecast into conn-specific type
UOrmDriver* getDriver() const { return pdrv; }
USqlStatement* getStatement() const { return pstmt; }
// Execute the statement
void execute();
// ASYNC with PIPELINE
bool asyncPipelineProcessQueue(uint32_t n);
bool asyncPipelineSendQueryPrepared(uint32_t i);
bool asyncPipelineMode(vPFu function = U_NULLPTR);
void setAsyncPipelineHandlerResult(vPFu function);
bool asyncPipelineSendQuery(const char* query, uint32_t query_len, uint32_t n);
// This function returns the number of database rows that were changed
// or inserted or deleted by the most recently completed SQL statement
unsigned long long affected();
// This routine returns the rowid of the most recent successful INSERT into the database
unsigned long long last_insert_rowid(const char* sequence = U_NULLPTR);
// Get number of columns in the row
unsigned int cols();
// Move forward to next row, returns false if no more rows available
bool nextRow();
// Resets a prepared statement on client and server to state after creation
void reset();
// Syntactic sugar for bindParam() used with use() binding param registers
template <class T1> void use(T1& r1);
template <class T1, class T2> void use(T1& r1, T2& r2);
template <class T1, class T2, class T3> void use(T1& r1, T2& r2, T3& r3);
template <class T1, class T2, class T3, class T4> void use(T1& r1, T2& r2, T3& r3, T4& r4);
template <class T1, class T2, class T3, class T4, class T5> void use(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5);
template <class T1, class T2, class T3, class T4, class T5, class T6> void use(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5, T6& r6);
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7> void use(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5, T6& r6, T7& r7);
// BIND PARAM
void bindParam();
void bindParam(int& v);
void bindParam(bool& v);
void bindParam(char& v);
void bindParam(long& v);
void bindParam(short& v);
void bindParam(float& v);
void bindParam(double& v);
#ifdef U_STDCPP_ENABLE
void bindParam(istream& v);
#endif
void bindParam(long long& v);
void bindParam(struct tm& v);
void bindParam(const char* s);
void bindParam(long double& v);
void bindParam(unsigned int& v);
void bindParam(unsigned char& v);
void bindParam(unsigned long& v);
void bindParam(unsigned short& v);
void bindParam(unsigned long long& v);
void bindParam(const char* b, const char* e);
void bindParam(const char* s, uint32_t n, bool bstatic, int rebind = -1);
void bindParam(UString& v);
void bindParam(UStringRep& v);
template <typename T> void bindParam(UOrmTypeHandler<T> t)
{
U_TRACE(0, "UOrmStatement::bindParam<T>(%p)", &t)
t.bindParam(this);
}
template <typename T> void bindParam(UOrmTypeHandler<T>& t)
{
U_TRACE(0, "UOrmStatement::bindParam<T>(%p)", &t)
t.bindParam(this);
}
// Syntactic sugar for bindResult() used with into() binding result registers
template <class T1> void into(T1& r1);
template <class T1, class T2> void into(T1& r1, T2& r2);
template <class T1, class T2, class T3> void into(T1& r1, T2& r2, T3& r3);
template <class T1, class T2, class T3, class T4> void into(T1& r1, T2& r2, T3& r3, T4& r4);
template <class T1, class T2, class T3, class T4, class T5> void into(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5);
template <class T1, class T2, class T3, class T4, class T5, class T6> void into(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5, T6& r6);
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7> void into(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5, T6& r6, T7& r7);
// BIND RESULT
void bindResult(int& v);
void bindResult(bool& v);
void bindResult(char& v);
void bindResult(long& v);
void bindResult(short& v);
void bindResult(float& v);
void bindResult(double& v);
void bindResult(long long& v);
void bindResult(long double& v);
void bindResult(unsigned int& v);
void bindResult(unsigned long& v);
void bindResult(unsigned char& v);
void bindResult(unsigned short& v);
void bindResult(unsigned long long& v);
void bindResult(UString& v);
template <typename T> void bindResult(UOrmTypeHandler<T> t)
{
U_TRACE(0, "UOrmStatement::bindResult<T>(%p)", &t)
t.bindResult(this);
}
template <typename T> void bindResult(UOrmTypeHandler<T>& t)
{
U_TRACE(0, "UOrmStatement::bindResult<T>(%p)", &t)
t.bindResult(this);
}
// DEBUG
#if defined(U_STDCPP_ENABLE) && defined(DEBUG)
const char* dump(bool reset) const;
#endif
protected:
UOrmDriver* pdrv;
USqlStatement* pstmt;
UOrmSession* psession;
private:
U_DISALLOW_COPY_AND_ASSIGN(UOrmStatement)
};
// Syntactic sugar for bindParam() used with use() binding registers
template <class T1>
inline void UOrmStatement::use(T1& r1)
{
U_TRACE(0, "UOrmStatement::use<T1>(%p)", &r1)
bindParam(UOrmTypeHandler<T1>(r1));
}
template <class T1, class T2>
inline void UOrmStatement::use(T1& r1, T2& r2)
{
U_TRACE(0, "UOrmStatement::use<T1,T2>(%p,%p)", &r1, &r2)
bindParam(UOrmTypeHandler<T1>(r1));
bindParam(UOrmTypeHandler<T2>(r2));
}
template <class T1, class T2, class T3>
inline void UOrmStatement::use(T1& r1, T2& r2, T3& r3)
{
U_TRACE(0, "UOrmStatement::use<T1,T2,T3>(%p,%p,%p)", &r1, &r2, &r3)
bindParam(UOrmTypeHandler<T1>(r1));
bindParam(UOrmTypeHandler<T2>(r2));
bindParam(UOrmTypeHandler<T3>(r3));
}
template <class T1, class T2, class T3, class T4>
inline void UOrmStatement::use(T1& r1, T2& r2, T3& r3, T4& r4)
{
U_TRACE(0, "UOrmStatement::use<T1,T2,T3,T4>(%p,%p,%p,%p)", &r1, &r2, &r3, &r4)
bindParam(UOrmTypeHandler<T1>(r1));
bindParam(UOrmTypeHandler<T2>(r2));
bindParam(UOrmTypeHandler<T3>(r3));
bindParam(UOrmTypeHandler<T4>(r4));
}
template <class T1, class T2, class T3, class T4, class T5>
inline void UOrmStatement::use(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5)
{
U_TRACE(0, "UOrmStatement::use<T1,T2,T3,T4,T5>(%p,%p,%p,%p,%p)", &r1, &r2, &r3, &r4, &r5)
bindParam(UOrmTypeHandler<T1>(r1));
bindParam(UOrmTypeHandler<T2>(r2));
bindParam(UOrmTypeHandler<T3>(r3));
bindParam(UOrmTypeHandler<T4>(r4));
bindParam(UOrmTypeHandler<T5>(r5));
}
template <class T1, class T2, class T3, class T4, class T5, class T6>
inline void UOrmStatement::use(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5, T6& r6)
{
U_TRACE(0, "UOrmStatement::use<T1,T2,T3,T4,T5,T6>(%p,%p,%p,%p,%p,%p)", &r1, &r2, &r3, &r4, &r5, &r6)
bindParam(UOrmTypeHandler<T1>(r1));
bindParam(UOrmTypeHandler<T2>(r2));
bindParam(UOrmTypeHandler<T3>(r3));
bindParam(UOrmTypeHandler<T4>(r4));
bindParam(UOrmTypeHandler<T5>(r5));
bindParam(UOrmTypeHandler<T6>(r6));
}
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
inline void UOrmStatement::use(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5, T6& r6, T7& r7)
{
U_TRACE(0, "UOrmStatement::use<T1,T2,T3,T4,T5,T6,T7>(%p,%p,%p,%p,%p,%p,%p)", &r1, &r2, &r3, &r4, &r5, &r6, &r7)
bindParam(UOrmTypeHandler<T1>(r1));
bindParam(UOrmTypeHandler<T2>(r2));
bindParam(UOrmTypeHandler<T3>(r3));
bindParam(UOrmTypeHandler<T4>(r4));
bindParam(UOrmTypeHandler<T5>(r5));
bindParam(UOrmTypeHandler<T6>(r6));
bindParam(UOrmTypeHandler<T7>(r7));
}
// Syntactic sugar for bindResult() used with into() binding result registers
template <class T1>
inline void UOrmStatement::into(T1& r1)
{
U_TRACE(0, "UOrmStatement::into<T1>(%p)", &r1)
bindResult(UOrmTypeHandler<T1>(r1));
}
template <class T1, class T2>
inline void UOrmStatement::into(T1& r1, T2& r2)
{
U_TRACE(0, "UOrmStatement::into<T1,T2>(%p,%p)", &r1, &r2)
bindResult(UOrmTypeHandler<T1>(r1));
bindResult(UOrmTypeHandler<T2>(r2));
}
template <class T1, class T2, class T3>
inline void UOrmStatement::into(T1& r1, T2& r2, T3& r3)
{
U_TRACE(0, "UOrmStatement::into<T1,T2,T3>(%p,%p,%p)", &r1, &r2, &r3)
bindResult(UOrmTypeHandler<T1>(r1));
bindResult(UOrmTypeHandler<T2>(r2));
bindResult(UOrmTypeHandler<T3>(r3));
}
template <class T1, class T2, class T3, class T4>
inline void UOrmStatement::into(T1& r1, T2& r2, T3& r3, T4& r4)
{
U_TRACE(0, "UOrmStatement::into<T1,T2,T3,T4>(%p,%p,%p,%p)", &r1, &r2, &r3, &r4)
bindResult(UOrmTypeHandler<T1>(r1));
bindResult(UOrmTypeHandler<T2>(r2));
bindResult(UOrmTypeHandler<T3>(r3));
bindResult(UOrmTypeHandler<T4>(r4));
}
template <class T1, class T2, class T3, class T4, class T5>
inline void UOrmStatement::into(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5)
{
U_TRACE(0, "UOrmStatement::into<T1,T2,T3,T4,T5>(%p,%p,%p,%p,%p)", &r1, &r2, &r3, &r4, &r5)
bindResult(UOrmTypeHandler<T1>(r1));
bindResult(UOrmTypeHandler<T2>(r2));
bindResult(UOrmTypeHandler<T3>(r3));
bindResult(UOrmTypeHandler<T4>(r4));
bindResult(UOrmTypeHandler<T5>(r5));
}
template <class T1, class T2, class T3, class T4, class T5, class T6>
inline void UOrmStatement::into(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5, T6& r6)
{
U_TRACE(0, "UOrmStatement::into<T1,T2,T3,T4,T5,T6>(%p,%p,%p,%p,%p,%p)", &r1, &r2, &r3, &r4, &r5, &r6)
bindResult(UOrmTypeHandler<T1>(r1));
bindResult(UOrmTypeHandler<T2>(r2));
bindResult(UOrmTypeHandler<T3>(r3));
bindResult(UOrmTypeHandler<T4>(r4));
bindResult(UOrmTypeHandler<T5>(r5));
bindResult(UOrmTypeHandler<T6>(r6));
}
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
inline void UOrmStatement::into(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5, T6& r6, T7& r7)
{
U_TRACE(0, "UOrmStatement::into<T1,T2,T3,T4,T5,T6,T7>(%p,%p,%p,%p,%p,%p,%p)", &r1, &r2, &r3, &r4, &r5, &r6, &r7)
bindResult(UOrmTypeHandler<T1>(r1));
bindResult(UOrmTypeHandler<T2>(r2));
bindResult(UOrmTypeHandler<T3>(r3));
bindResult(UOrmTypeHandler<T4>(r4));
bindResult(UOrmTypeHandler<T5>(r5));
bindResult(UOrmTypeHandler<T6>(r6));
bindResult(UOrmTypeHandler<T7>(r7));
}
// TEMPLATE SPECIALIZATIONS
template <> class U_EXPORT UOrmTypeHandler<null> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(null& val) : UOrmTypeHandler_Base(U_NULLPTR) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<null>::bindParam(%p)", stmt)
stmt->bindParam();
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<null>::bindResult(%p)", stmt)
}
};
template <> class U_EXPORT UOrmTypeHandler<bool> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(bool& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<bool>::bindParam(%p)", stmt)
stmt->bindParam(*(bool*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<bool>::bindResult(%p)", stmt)
stmt->bindResult(*(bool*)pval);
}
};
template <> class U_EXPORT UOrmTypeHandler<char> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(char& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<char>::bindParam(%p)", stmt)
stmt->bindParam(*(char*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<char>::bindResult(%p)", stmt)
stmt->bindResult(*(char*)pval);
}
};
template <> class U_EXPORT UOrmTypeHandler<unsigned char> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(unsigned char& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<unsigned char>::bindParam(%p)", stmt)
stmt->bindParam(*(unsigned char*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<unsigned char>::bindResult(%p)", stmt)
stmt->bindResult(*(unsigned char*)pval);
}
};
template <> class U_EXPORT UOrmTypeHandler<short> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(short& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<short>::bindParam(%p)", stmt)
stmt->bindParam(*(short*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<short>::bindResult(%p)", stmt)
stmt->bindResult(*(short*)pval);
}
};
template <> class U_EXPORT UOrmTypeHandler<unsigned short> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(unsigned short& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<unsigned short>::bindParam(%p)", stmt)
stmt->bindParam(*(unsigned short*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<unsigned short>::bindResult(%p)", stmt)
stmt->bindResult(*(unsigned short*)pval);
}
};
template <> class U_EXPORT UOrmTypeHandler<int> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(int& val) : UOrmTypeHandler_Base(&val)
{
U_TRACE(0, "UOrmTypeHandler::UOrmTypeHandler<int>(%d)", val)
U_INTERNAL_DUMP("this = %p", this)
}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<int>::bindParam(%p)", stmt)
U_INTERNAL_DUMP("pval(%p) = %d", pval, *(int*)pval)
stmt->bindParam(*(int*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<int>::bindResult(%p)", stmt)
U_INTERNAL_DUMP("pval(%p) = %d", pval, *(int*)pval)
stmt->bindResult(*(int*)pval);
}
};
template <> class U_EXPORT UOrmTypeHandler<unsigned int> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(unsigned int& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<unsigned int>::bindParam(%p)", stmt)
stmt->bindParam(*(unsigned int*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<unsigned int>::bindResult(%p)", stmt)
stmt->bindResult(*(unsigned int*)pval);
}
};
template <> class U_EXPORT UOrmTypeHandler<long> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(long& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<long>::bindParam(%p)", stmt)
stmt->bindParam(*(long*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<long>::bindResult(%p)", stmt)
stmt->bindResult(*(long*)pval);
}
};
template <> class U_EXPORT UOrmTypeHandler<unsigned long> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(unsigned long& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<unsigned long>::bindParam(%p)", stmt)
stmt->bindParam(*(unsigned long*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<unsigned long>::bindResult(%p)", stmt)
stmt->bindResult(*(unsigned long*)pval);
}
};
template <> class U_EXPORT UOrmTypeHandler<long long> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(long long& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<long long>::bindParam(%p)", stmt)
stmt->bindParam(*(long long*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<long long>::bindResult(%p)", stmt)
stmt->bindResult(*(long long*)pval);
}
};
template <> class U_EXPORT UOrmTypeHandler<unsigned long long> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(unsigned long long& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<unsigned long long>::bindParam(%p)", stmt)
stmt->bindParam(*(unsigned long long*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<unsigned long long>::bindResult(%p)", stmt)
stmt->bindResult(*(unsigned long long*)pval);
}
};
template <> class U_EXPORT UOrmTypeHandler<float> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(float& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<float>::bindParam(%p)", stmt)
stmt->bindParam(*(float*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<float>::bindResult(%p)", stmt)
stmt->bindResult(*(float*)pval);
}
};
template <> class U_EXPORT UOrmTypeHandler<double> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(double& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<double>::bindParam(%p)", stmt)
stmt->bindParam(*(double*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<double>::bindResult(%p)", stmt)
stmt->bindResult(*(double*)pval);
}
};
template <> class U_EXPORT UOrmTypeHandler<long double> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(long double& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<long double>::bindParam(%p)", stmt)
stmt->bindParam(*(long double*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<long double>::bindResult(%p)", stmt)
stmt->bindResult(*(long double*)pval);
}
};
template <> class U_EXPORT UOrmTypeHandler<const char*> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(const char* val) : UOrmTypeHandler_Base((void*)val)
{
U_TRACE(0, "UOrmTypeHandler::UOrmTypeHandler<const char*>(%S)", val)
U_INTERNAL_DUMP("this = %p", this)
}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<const char*>::bindParam(%p)", stmt)
U_INTERNAL_DUMP("pval(%p) = %S", pval, pval)
stmt->bindParam((const char*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<const char*>::bindResult(%p)", stmt)
}
};
template <> class U_EXPORT UOrmTypeHandler<UStringRep> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(UStringRep& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<UStringRep>::bindParam(%p)", stmt)
stmt->bindParam(*(UStringRep*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<UStringRep>::bindResult(%p)", stmt)
U_ERROR("UOrmTypeHandler<UStringRep>::bindResult(): sorry, we cannot use UStringRep type to bind ORM type handler...");
}
};
template <> class U_EXPORT UOrmTypeHandler<UString> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(UString& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<UString>::bindParam(%p)", stmt)
stmt->bindParam(*(UString*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<UString>::bindResult(%p)", stmt)
stmt->bindResult(*(UString*)pval);
}
};
#ifdef U_STDCPP_ENABLE
template <> class U_EXPORT UOrmTypeHandler<istream> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(istream& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<istream>::bindParam(%p)", stmt)
stmt->bindParam(*(istream*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<istream>::bindResult(%p)", stmt)
}
};
#endif
template <> class U_EXPORT UOrmTypeHandler<struct tm> : public UOrmTypeHandler_Base {
public:
explicit UOrmTypeHandler(struct tm& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<struct tm>::bindParam(%p)", stmt)
stmt->bindParam(*(struct tm*)pval);
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<struct tm>::bindResult(%p)", stmt)
}
};
// TEMPLATE SPECIALIZATIONS FOR CONTAINERS
template <class T> class U_EXPORT UOrmTypeHandler<UVector<T*> > : public UOrmTypeHandler_Base {
public:
typedef UVector<T*> uvector;
explicit UOrmTypeHandler(uvector& val) : UOrmTypeHandler_Base(&val) {}
void bindParam(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<uvector>::bindParam(%p)", stmt)
uvector* pvec = (uvector*)pval;
const void** ptr = pvec->vec;
const void** end = pvec->vec + pvec->_length;
for (; ptr < end; ++ptr) stmt->bindParam(UOrmTypeHandler<T>(*(T*)(*ptr)));
}
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<uvector>::bindResult(%p)", stmt)
uvector* pvec = (uvector*)pval;
const void** ptr = pvec->vec;
const void** end = pvec->vec + pvec->_length;
for (; ptr < end; ++ptr) stmt->bindResult(UOrmTypeHandler<T>(*(T*)(*ptr)));
}
};
template <> class U_EXPORT UOrmTypeHandler<UVector<UString> > : public UOrmTypeHandler<UVector<UStringRep*> > {
public:
typedef UVector<UStringRep*> uvectorbase;
explicit UOrmTypeHandler(UVector<UString>& val) : UOrmTypeHandler<uvectorbase>(*((uvector*)&val)) {}
void bindParam(UOrmStatement* stmt) { ((UOrmTypeHandler<uvectorbase>*)this)->bindParam( stmt); }
void bindResult(UOrmStatement* stmt)
{
U_TRACE(0, "UOrmTypeHandler<UVector<UString>>::bindResult(%p)", stmt)
U_ERROR("UOrmTypeHandler<UVector<UString>>::bindResult(): sorry, we cannot use UVector<UString> type to bind ORM type handler...");
}
};
#endif