The DAME Primer: DAME - Database Access Made Easy | ||
---|---|---|
Prev | Chapter 3. Selecting Information From Databases | Next |
DAME uses the Iterator object whether the select statement being processed returns single or multiple records. The basic mechanism by which DAME passes the rows selected is through the Iterator object. DAME generates code that uses the Iterator object as follows:
template<Iterator> GetByEmpno (int _p_Empno, Iterator it) { ... GetByEmpno_next (it) ; } template<Iterator> GetByEmpno_next (Iterator it) { ... do { Dame::Example::emp* _l_forClass = new Dame::Example::emp () ; _l_for_Class->SetEmpno (...) ... More set methods to fill the local variable int retval = it (_l_for_Class) ; if ((retval & keepPtr) == 0) delete _l_for_Class ; if (retval & abortRetrieval) return ; } while (there are more records) ; } |
The point to be noted above is that DAME calls the Iterator object's operator() with a pointer to an object. The called function can return DatabaseIf::keepPtr if it wants to have the ownership of the object created within the GetByEmpno_next. If more records are not expected, the called function can return DatabaseIf::abortRetrieval, in which case the loop is terminated. The application can also call directly the GetByEmpno_next for retrieving more records, once the GetByEmpno is called.
This mechanism offers the greatest flexibility. The DAME standard adapter is an example where the flexibility is used.
dame/utility.hpp
template<typename T> class single_value_t : public std::unary_function<T, int> { T* ptr ; bool* isInvoked ; public: single_value_t (T* _ptr, bool* _isInvoked) : ptr(_ptr), isInvoked(_isInvoked) { *ptr = (T) 0 ; if (isInvoked) *isInvoked = false ; } int operator() (T val) { if (isInvoked) *isInvoked = true ; *ptr = val ; return DatabaseIf::keepPtr | DatabaseIf::abortRetrieval ; } }; template<typename T> single_value_t<T> make_single (T* ptr, bool* isInvoked = NULL) { return single_value_t<T>(ptr, isInvoked) ; } |
In case of single value returns, the operator() is returning the value DatabaseIf::keepPtr | DatabaseIf::abortRetrieval, because the application would like to use the pointer later. Since we need only a single record (make_single right?), we are passing the DatabaseIf::abortRetrieval.