// ============================================================================ // // = LIBRARY // ULib - c++ library // // = FILENAME // orm.h - Object Relational Mapping // // = AUTHOR // Stefano Casazza // // ============================================================================ #ifndef ULIB_ORM_H #define ULIB_ORM_H 1 #include 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(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 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::bindParam(%p)", stmt) ((T*)pval)->bindParam(stmt); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::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 void use(T1& r1); template void use(T1& r1, T2& r2); template void use(T1& r1, T2& r2, T3& r3); template void use(T1& r1, T2& r2, T3& r3, T4& r4); template void use(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5); template void use(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5, T6& r6); template 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 void bindParam(UOrmTypeHandler t) { U_TRACE(0, "UOrmStatement::bindParam(%p)", &t) t.bindParam(this); } template void bindParam(UOrmTypeHandler& t) { U_TRACE(0, "UOrmStatement::bindParam(%p)", &t) t.bindParam(this); } // Syntactic sugar for bindResult() used with into() binding result registers template void into(T1& r1); template void into(T1& r1, T2& r2); template void into(T1& r1, T2& r2, T3& r3); template void into(T1& r1, T2& r2, T3& r3, T4& r4); template void into(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5); template void into(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5, T6& r6); template 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 void bindResult(UOrmTypeHandler t) { U_TRACE(0, "UOrmStatement::bindResult(%p)", &t) t.bindResult(this); } template void bindResult(UOrmTypeHandler& t) { U_TRACE(0, "UOrmStatement::bindResult(%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 inline void UOrmStatement::use(T1& r1) { U_TRACE(0, "UOrmStatement::use(%p)", &r1) bindParam(UOrmTypeHandler(r1)); } template inline void UOrmStatement::use(T1& r1, T2& r2) { U_TRACE(0, "UOrmStatement::use(%p,%p)", &r1, &r2) bindParam(UOrmTypeHandler(r1)); bindParam(UOrmTypeHandler(r2)); } template inline void UOrmStatement::use(T1& r1, T2& r2, T3& r3) { U_TRACE(0, "UOrmStatement::use(%p,%p,%p)", &r1, &r2, &r3) bindParam(UOrmTypeHandler(r1)); bindParam(UOrmTypeHandler(r2)); bindParam(UOrmTypeHandler(r3)); } template inline void UOrmStatement::use(T1& r1, T2& r2, T3& r3, T4& r4) { U_TRACE(0, "UOrmStatement::use(%p,%p,%p,%p)", &r1, &r2, &r3, &r4) bindParam(UOrmTypeHandler(r1)); bindParam(UOrmTypeHandler(r2)); bindParam(UOrmTypeHandler(r3)); bindParam(UOrmTypeHandler(r4)); } template inline void UOrmStatement::use(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5) { U_TRACE(0, "UOrmStatement::use(%p,%p,%p,%p,%p)", &r1, &r2, &r3, &r4, &r5) bindParam(UOrmTypeHandler(r1)); bindParam(UOrmTypeHandler(r2)); bindParam(UOrmTypeHandler(r3)); bindParam(UOrmTypeHandler(r4)); bindParam(UOrmTypeHandler(r5)); } template inline void UOrmStatement::use(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5, T6& r6) { U_TRACE(0, "UOrmStatement::use(%p,%p,%p,%p,%p,%p)", &r1, &r2, &r3, &r4, &r5, &r6) bindParam(UOrmTypeHandler(r1)); bindParam(UOrmTypeHandler(r2)); bindParam(UOrmTypeHandler(r3)); bindParam(UOrmTypeHandler(r4)); bindParam(UOrmTypeHandler(r5)); bindParam(UOrmTypeHandler(r6)); } template inline void UOrmStatement::use(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5, T6& r6, T7& r7) { U_TRACE(0, "UOrmStatement::use(%p,%p,%p,%p,%p,%p,%p)", &r1, &r2, &r3, &r4, &r5, &r6, &r7) bindParam(UOrmTypeHandler(r1)); bindParam(UOrmTypeHandler(r2)); bindParam(UOrmTypeHandler(r3)); bindParam(UOrmTypeHandler(r4)); bindParam(UOrmTypeHandler(r5)); bindParam(UOrmTypeHandler(r6)); bindParam(UOrmTypeHandler(r7)); } // Syntactic sugar for bindResult() used with into() binding result registers template inline void UOrmStatement::into(T1& r1) { U_TRACE(0, "UOrmStatement::into(%p)", &r1) bindResult(UOrmTypeHandler(r1)); } template inline void UOrmStatement::into(T1& r1, T2& r2) { U_TRACE(0, "UOrmStatement::into(%p,%p)", &r1, &r2) bindResult(UOrmTypeHandler(r1)); bindResult(UOrmTypeHandler(r2)); } template inline void UOrmStatement::into(T1& r1, T2& r2, T3& r3) { U_TRACE(0, "UOrmStatement::into(%p,%p,%p)", &r1, &r2, &r3) bindResult(UOrmTypeHandler(r1)); bindResult(UOrmTypeHandler(r2)); bindResult(UOrmTypeHandler(r3)); } template inline void UOrmStatement::into(T1& r1, T2& r2, T3& r3, T4& r4) { U_TRACE(0, "UOrmStatement::into(%p,%p,%p,%p)", &r1, &r2, &r3, &r4) bindResult(UOrmTypeHandler(r1)); bindResult(UOrmTypeHandler(r2)); bindResult(UOrmTypeHandler(r3)); bindResult(UOrmTypeHandler(r4)); } template inline void UOrmStatement::into(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5) { U_TRACE(0, "UOrmStatement::into(%p,%p,%p,%p,%p)", &r1, &r2, &r3, &r4, &r5) bindResult(UOrmTypeHandler(r1)); bindResult(UOrmTypeHandler(r2)); bindResult(UOrmTypeHandler(r3)); bindResult(UOrmTypeHandler(r4)); bindResult(UOrmTypeHandler(r5)); } template inline void UOrmStatement::into(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5, T6& r6) { U_TRACE(0, "UOrmStatement::into(%p,%p,%p,%p,%p,%p)", &r1, &r2, &r3, &r4, &r5, &r6) bindResult(UOrmTypeHandler(r1)); bindResult(UOrmTypeHandler(r2)); bindResult(UOrmTypeHandler(r3)); bindResult(UOrmTypeHandler(r4)); bindResult(UOrmTypeHandler(r5)); bindResult(UOrmTypeHandler(r6)); } template inline void UOrmStatement::into(T1& r1, T2& r2, T3& r3, T4& r4, T5& r5, T6& r6, T7& r7) { U_TRACE(0, "UOrmStatement::into(%p,%p,%p,%p,%p,%p,%p)", &r1, &r2, &r3, &r4, &r5, &r6, &r7) bindResult(UOrmTypeHandler(r1)); bindResult(UOrmTypeHandler(r2)); bindResult(UOrmTypeHandler(r3)); bindResult(UOrmTypeHandler(r4)); bindResult(UOrmTypeHandler(r5)); bindResult(UOrmTypeHandler(r6)); bindResult(UOrmTypeHandler(r7)); } // TEMPLATE SPECIALIZATIONS template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(null& val) : UOrmTypeHandler_Base(U_NULLPTR) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(bool& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(bool*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) stmt->bindResult(*(bool*)pval); } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(char& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(char*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) stmt->bindResult(*(char*)pval); } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(unsigned char& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(unsigned char*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) stmt->bindResult(*(unsigned char*)pval); } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(short& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(short*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) stmt->bindResult(*(short*)pval); } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(unsigned short& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(unsigned short*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) stmt->bindResult(*(unsigned short*)pval); } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(int& val) : UOrmTypeHandler_Base(&val) { U_TRACE(0, "UOrmTypeHandler::UOrmTypeHandler(%d)", val) U_INTERNAL_DUMP("this = %p", this) } void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) U_INTERNAL_DUMP("pval(%p) = %d", pval, *(int*)pval) stmt->bindParam(*(int*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) U_INTERNAL_DUMP("pval(%p) = %d", pval, *(int*)pval) stmt->bindResult(*(int*)pval); } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(unsigned int& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(unsigned int*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) stmt->bindResult(*(unsigned int*)pval); } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(long& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(long*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) stmt->bindResult(*(long*)pval); } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(unsigned long& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(unsigned long*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) stmt->bindResult(*(unsigned long*)pval); } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(long long& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(long long*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) stmt->bindResult(*(long long*)pval); } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(unsigned long long& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(unsigned long long*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) stmt->bindResult(*(unsigned long long*)pval); } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(float& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(float*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) stmt->bindResult(*(float*)pval); } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(double& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(double*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) stmt->bindResult(*(double*)pval); } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(long double& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(long double*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) stmt->bindResult(*(long double*)pval); } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(const char* val) : UOrmTypeHandler_Base((void*)val) { U_TRACE(0, "UOrmTypeHandler::UOrmTypeHandler(%S)", val) U_INTERNAL_DUMP("this = %p", this) } void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) U_INTERNAL_DUMP("pval(%p) = %S", pval, pval) stmt->bindParam((const char*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(UStringRep& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(UStringRep*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) U_ERROR("UOrmTypeHandler::bindResult(): sorry, we cannot use UStringRep type to bind ORM type handler..."); } }; template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(UString& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(UString*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) stmt->bindResult(*(UString*)pval); } }; #ifdef U_STDCPP_ENABLE template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(istream& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(istream*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) } }; #endif template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base { public: explicit UOrmTypeHandler(struct tm& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt) stmt->bindParam(*(struct tm*)pval); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt) } }; // TEMPLATE SPECIALIZATIONS FOR CONTAINERS template class U_EXPORT UOrmTypeHandler > : public UOrmTypeHandler_Base { public: typedef UVector uvector; explicit UOrmTypeHandler(uvector& val) : UOrmTypeHandler_Base(&val) {} void bindParam(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::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*)(*ptr))); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler::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*)(*ptr))); } }; template <> class U_EXPORT UOrmTypeHandler > : public UOrmTypeHandler > { public: typedef UVector uvectorbase; explicit UOrmTypeHandler(UVector& val) : UOrmTypeHandler(*((uvector*)&val)) {} void bindParam(UOrmStatement* stmt) { ((UOrmTypeHandler*)this)->bindParam( stmt); } void bindResult(UOrmStatement* stmt) { U_TRACE(0, "UOrmTypeHandler>::bindResult(%p)", stmt) U_ERROR("UOrmTypeHandler>::bindResult(): sorry, we cannot use UVector type to bind ORM type handler..."); } }; #endif