Instructions for using the Database Template Library 
  - Contents 
    
      - When you unpack dtl.zip it should create the following 
        directories:
 
      - \docs: Documentation and examples on how to use the Database 
        Template Library. To read, open the main file called index.htm.
 
      - \lib: This is the main code for the DTL. 
 
      - \example_db: Table definitions and sample data for the 
        code in the "example" and "tests" directories.
 
      - \example: Example code for using the DTL.
 
      - \example_unicode: Similar to example, but in unicode.
 
      - \tests: Regression tests for the DTL / further examples.
         
    
   
  
  - Getting Started: 
    
      - Take a look at the docs files starting at index.htm. Be sure to read "Introduction 
        to the DTL" as this gives a good overview of the capabilities of 
        the library.
 
      - Go into the lib directory. Build the library file (DTL.lib 
        in Windows, dtl.a in UNIX). To compile from Visual Studio 6.0 open DTL.dsw. 
        To compile from LINUX type "make" which will run the "Makefile" 
        in this directory. (To compile under LINUX you will need to have unixODBC 2.0.8 or higher and  
        gcc 3.0 or better installed.  See ReadMeLinux.htm for details.)
 
      - Create the sample database from the example_db directory. 
        
          - If you have a copy of Access97 there is nothing to 
            do here. We have a sample Access database in the example_db directory.
 
          - If you are using Oracle perform the following steps 
            from SQL*PLUS: 
            
              - >create user example identified by example;
 
              - >grant dba to example; -- actually we need 
                less than this, but it's easier to grant dba
 
              - >connect example/example;
 
              - >@e:\dtl\example_db\tables.sql -- run the 
                tables script to create the example tables
 
              - >@e:\dtl\example_db\data.sql -- insert sample 
                data into the example tables
 
            
           
          - If you are using MySQL perform the following steps: 
            
              - create a user called "example" with 
                password "example".
 
              - >mysql <database_name> -u example < 
                tables.sql -- run the tables script to create the example tables
 
              - >mysql <database_name> -u example < 
                data_mysql.sql -- insert sample data into the example tables
 
            
           
          - If you are using Microsoft SQL Server: 
            
              - create a user called "example" with 
                password "example".
 
              - Use the data import tool to import the table 
                definitions and data from the Access97 file example.mdb
 
            
           
        
       
      - Create an ODBC data source called "example" 
        from the ODBC Data Source Administrator tool in the control panel: 
        
          - The example code uses the following ODBC connect 
            string: "UID=example;PWD=example;DSN=example;"; Therefore 
            it connects as user "example", password "example" 
            to the ODBC data source named "example". We assume that 
            the user and password are already set up as explained above & 
            show how to set up the data source name.
 
          - Choose the tab labeled "System DSN". Choose 
            "Add --> Microsoft Access Driver (*.mdb)". For the data 
            source name enter "example" and choose the file called example.mdb 
            in the example_db directory. (If you prefer to use Oracle choose the 
            Oracle ODBC driver and enter your SQL*NET connect string etc.)
 
        
       
      - Build and run the example code. 
        
          - Go to the directory called \example. Open the file 
            example.dsw and build from VC++ 6.0 to create the example executable. 
            (Or run "make" from the example directory if you are working 
            under UNIX).
             
        
       
    
   
  
  - Using the library in your own code: 
    
      - To use the library in your own code you will need to 
        do two things: 
        
          - Include the \lib directory in the include (\I) path 
            for your compiler.
 
          - Include the library file (DTL.lib or dtl.a) in the 
            set of files that you link to in producing your executable.
             
        
       
    
   
  
Release Notes 
 
  - Version 3.2.3; Released February 24, 2002.
    ***Bugfixes***  
    
      - Fixed DBStmt::GetData() 
        and DBStmt::PutData() problems 
        for long strings (strings greater than 255 in length). Most of the changes 
        occurred with BoundIO::MoveRead(), BoundIO::MoveWrite(), and BoundIO::MoveWriteAfterExec().
 
      - Fixed typedefs in vec_multiset::iterator 
        and vec_multiset::const_iterator 
        to get rid of GCC compiler warnings.
 
      - SelValidate() calls 
        moved from operator*() to operator++() for select_iterator and sql_iterator 
        to get proper for-loop behavior. 
 
      -  Changed default 
        key mode for DynamicDBView and DynamicIndexedDBView to USE_ALL_FIELDS. 
      
 
      - Fixed case sensitivity 
        bugs dealing with column names in DBIndex and BoundIO/BoundIOs structures.
 
      - Fixed bug to where 
        parameters were getting bound to nonexistent parameter numbers in the 
        case of insert_iterators. 
        In the fix, we don't bind the extra parameters anymore. 
 
    
    
    ***New Features/Improvements/Removed features ***  
    
      - Changed default 
        key mode for DynamicDBView 
        and DynamicIndexedDBView 
        to USE_ALL_FIELDS.
 
      - Limited OpenAccess 
        support now provided: DBView 
        and IndexedDBView support all 
        data types in OpenAccess except for string, 
         wstring, and blob.
 
    
  
   - Version 3.2.2; Released January 31, 2002.
    ***Bugfixes***  
    
      - SQL_C_BIT 
        is now the mapping for the bool 
        type ... SQL_C_USHORT was 
        buggy.
 
      - Fix for single char 
        binding.
 
      - Fixed bug in 
        BuildDefaultQry().
 
      - Fixed iterator/const_iterator 
        typedefs in IndexedDBView.
 
      - Added missing constructor 
        initializers.
 
      - Fixed bug in storing of IndexName 
        for key into indexes map. Also more 
        IndexNamesAndFields parsing fun.
 
      - Fixed support for char[] 
        binding yet again.
 
      - Fixed const 
        problems in comparison operators for 
        select_iterator and sql_iterator 
        and added commutative form of these operators.
 
      - Glitches in the docs.
 
      - Fixed yet some more missing STD_:: 
        qualifcations.
 
      - Moved header guards for 
        IndexedDBView.h and DBIndex.h 
        to proper places.
 
      - Bug identified for SQLServer: execution of a bad statement 
        may result in a rollback, regardless of the IOHandler semantics.
 
      - Note that unicode is not supported by Oracle 8.x or 
        lower. Oracle only support unicode for version 9.01 and higher, but we 
        haven't tested this yet. We've only tested unicode for SQLServer and MS 
        Access.
 
      - Fixed bug in assignment operator for variant_field 
        that caused problem when copying from one  
        DynamicDBView iterator to another.
 
      - Changed default SQL binding for float data parameters 
        from SQL_FLOAT to SQL_REAL.
 
      - Removed bug that caused wide strings over 255 bytes in 
        length to not be written to the database correctly.
 
    
    
    ***New Features/Improvements/Removed features ***  
    
      - GetData() 
        and PutData() used to handle 
        "binding" of all basic_string<> 
        types. Now by default binding a string or blob has the capability to fetch 
        a field of an arbitrarily large size.
 
      - Added DBView::select_update_iterator.
 
      - Changed DEFAULT_IDXCONTAINER 
        to be std::hash_multiset 
        for STLPort. Other configurations default to dtl::vec_multiset. 
        This makes IndexDBView containers run *much* faster. This included downgrading 
        IndexedDBView::iterator from 
        bidirectional iterator to forward iterator if std::hash_multiset 
        is the default index container as it only supports forward iterators.
 
      - TCHAR/tstring 
        concept made universal: TCHAR[] 
        and TCHAR bindings used 
        instead of char and char[] 
        being allowed regardless of the 
        UNICODE setting.
 
      - star_bidirectional_iterator 
        conversion constructors and comparison operators. 
        Also added star_forward_iterator.
 
      - Added DTL_LC 
        and DTL_UC macros 
        to lower-caseify and upper-caseify (respectively) the SQL passed to ODBC.
 
      - Added autokey support. Forced some changes in DynamicBCA, 
        DBView, IndexedDBView, 
        DynamicIndexedDBView to 
        properly support this.
 
      - Changed MAX_J_DATE. 
        Old max date was incorrect & too small.
 
      - Vec_multiset 
        cleanup.
 
      - Removed BoundIO::BoundColMode.
 
      - Added BoundIO::SetSQLType() 
        so that user may specify a different SQL type to bind to other 
        than the one specified in the ETI Map in bind_basics.cpp. 
        
 
      - Added index of code examples.
 
      - Added SetParamsFromClass 
        template to make it easier to set parameters when creating IndexedDBViews.
 
      - General performance tuning. Replace internal wrappers 
        for BCA, BPA, InsVal and SelVal plus did general performance tuning to 
        improve overall speed of execution.
 
    
   - Version 3.1; Released August 13, 2001.
    ***Bugfixes***  
    
      - Fixed bug with IndexedDBView 
        so that any changes made by InsVal 
        to the  DataObj  will be 
        recognized by insert() 
        and replace().
 
      - BoundIO::CopyMember() 
        performed only a shallow copy for char[] 
        members. 
        This has now been fixed with the 
        MakeActualCopyOfMember() template.
 
      - GenericCmp() 
        incorrectly handled doubles 
        by making epsilon equal 
        to 1 >> 20, yielding 
        an actual value of 0.0000000 
        due to the fact that this old value operates on integers and thus the 
        fractional part was dropped. The change to make epsilon 
        equal to pow(2, -20) fixed 
        the problem.
 
      - Fixed DBException::what() 
        error messages so that multiple database messages can be returned.
 
      - Binding for char arrays now uses the size of the array 
        to set the maximum buffer size, this prevents a potential buffer overflow 
        bug.
 
      - BYTE 
        typedef now at global scope to avoid potential clash with the typedef 
        from Windows header files.
 
    
    
    ***New Features/Improvements***  
    
      - Added support for binary data / blob data types.
 
      - Variable size buffer for binding basic_string. 
        This allows us to control buffer sizes to bind larger 
        strings and blobs in the BCA without adding unnecessary overhead.
 
      - In IndexedDBView, 
        addition of begin_AK(), 
        end_AK() and friends to 
        return iterators to beginning and end of 
        DataObj lists for a given key.
 
      - Cleaned up several semantic nits with destructors and 
        also STD_::.
 
      - Variant_row::operator[](const 
        string &fieldName) now case insensitive for 
        fieldName.
 
      - Return type of DBView::select_iterator::operator++(int) 
        changed to void to improve efficiency and C++ standard compliance. It 
        is now equivalent to its preincrement cousin.
 
      - Reimplemented internal comparison function for DBIndex 
        to be more efficient by using raw function objects instead of callbacks 
        in the default implementation. This improves the speed of IndexedDBView 
        containers.
 
      - Upgraded to run against gcc 3.0.
 
      - Exposed DBConnection::GetDefaultEnvironment() 
        and DBEnvironment::Release() 
        to support manual release of HENV.
 
    
    
   - Version 3.0; Released July 19, 2001.
    ***Bugfixes***  
    
      - Fixed IndexedDBView::replace() 
        bug where it threw a DBException 
        when *it == dataObj (replacing 
        object with itself).
 
      - Fixed parsing of 
        IndexNamesAndFields string in IndexedDBView 
        constructor. It crapped out on obstacles such as extra whitespace.
 
      - Typedef for IndexedDBView::reverse_iterator 
        and its const cousin properly fixed to be std::reverse_bidirectional_iterator.
 
      - Fixed bug with DB_iterator 
        copy involving incorrect management of internal buffers for parameter 
        and row data. This bug resulted 
        in incorrect behavior when iterators were copied, most noticeably in standard 
        functions such as std::copy(), 
        which accept their arguments by value.
 
    
    
    ***New Features/Improvements***  
    
      - Full unicode support. (Not avalable for gcc 2.96 due 
        to lack of wide stream support; still a bit flaky for the Oracle ODBC 
        due to driver bugs from Oracle). Also, we have added a pure unicode example 
        project and converted the tests project converted to a pure unicode format.
 
      - "Header Hell" - broke out the implementation 
        of non-template classes into .cpp files to make for faster compile times 
        and give fewer header dependencies.
 
      - Changed code to use stringstream instead of deprecated 
        C++ strstream. NOTE FOR LINUX USERS, this new version requires at least 
        gcc 2.96-85 as older versions of libstdc++ that come with gcc do not support 
        stringstream.
 
      - DBConnections 
        now may reference already existing connections using the Share() 
        method.
 
      - More efficient 
        IndexedDBView::local_insert() implementation. 
        Redundant searches were eliminated by making use of the form of 
        multiset::insert() that takes an iterator hint for where the element 
        should be put into the container.
 
      - Facility for passing 
        named arguments to the constructors for 
        DBView, IndexedDBView, DynamicDBView, and 
        DynamicIndexedDBView objects. 
 
      - DBView 
        and DynamicDBView constructors 
        now accept an initial IOHandler 
        as an argument.
 
      - BuildSpecialQry functors 
        now allow the user to customize the SQL query generated for DBView 
        iterators through the use of template specialization. This is primarily 
        useful for custom queries such as "select distinct" etc.
 
    
    
   - Version 2.5 
    
      -  NOTE: If you are upgrading from a previous version of DTL then the 
        major changes that will affect your old code are: 1. The new signature 
        for InsValidate, which now requires BoundIOs as a parameter. 2. The default 
        error handler for DBView and IndexDBView now throws rather than logging 
        and suppressing errors. This default is user definable -- see DEFAULT_IO_HANDLER 
        below for details. 
 
      -  Added DBView<DataObj, 
        ParamObj>::sql_iterator class (support for general queries). 
        This enables DTL to work with all kinds of SQL queries, including stored 
        procedures.
 
      - Changed syntax of binding operator for BCA's and BPA's to indicate directional 
        flow of information while keeping the old syntax around for backwards 
        compatibility.
 
      - DBStmt::Execute() 
        now allows SQL_NO_DATA 
        to be returned.
 
      - Proper error checking of RETCODE's 
        in DBConnection() 
        and DBEnvironment().
 
      - Enhanced facilities for handling null fields in the following classes: 
        BoundIO, BoundIOs, variant_row, 
        variant_field.
 
      - Modified implementation of IndexedDBView 
        routines mostly in relation to when validation functions are invoked.
 
      - Fixed some bugs with dynamic views.
 
      - Moved DataObj() methods 
        from dynamic views and dynamic indexed views to DBView 
         and 
        IndexedDBView under 
        the method name GetDataObj().
 
      - Now can create variant_field's 
        on the fly, especially for use in BCA's and BPA's using the variant_row::_typename() 
        syntax.
 
      - Support for variant_row's 
        as ParamObj's. 
        
 
      - Reentrancy of BCA's and BPA's.
 
      - Fixed bugs in parsing of IndexNamesAndFields 
        string passed into constructor for IndexedDBView.
 
      - Rationale of example and test projects changed. The examples now also 
        will serve as a preliminary battery of test code for DTL as well as being 
        code meant to clearly show the new user how various things work in the 
        library. Tests contains further code to exercise DTL.
 
      - Removed all using-clauses from DTL and explicitly qualified all code 
        which uses the C++ standard namespace. This involved some tricky preprocessor 
        macros to get the right behavior.
 
      - Generalized the underlying associative container that DBIndex's 
        use to store DataObj 
        *'s. The underlying associative container now is passed in as a 
        template parameter at the IndexedDBView 
        level and whether it's hashable or not as another template parameter. 
        Added GenericHash() 
        as well as a ContainerFactory 
         function object to help accomplish this purpose.
 
      - Added support for null fields in BoundIO, 
        variant_field, GenericCmp() and GenericHash().
 
      - Added MoreResults() 
        support to grab more record sets if a statement contains multiple ones.
 
      - cb_ptr_fun() 
        and cb_ptr_fun_w_ret() 
        now also accept pointer-to-member methods.
 
      - Added DEFAULT_IO_HANDLER 
        macro by which the 
        user can specify the default 
        IOHandler to use. If the user doesn't define this macro, DTL defines 
        AlwaysThrowsHandler to 
        be the default. Previously, the default handler was hardwired to be LoggingHandler.
 
      - Added a dtl_config.h 
        file for user-defined macros and other settings into the lib directory.
 
      - Added full set of comparison operators to variant_row's 
         so objects 
        of that type can be used in STL constructs that require these operators.
 
      - Fixed more typename 
        bugs internally.
 
      - Fixed bug in  
        DBIndex::lt() to compare based on the order 
        of fields that the user passed in. The code now properly uses the first 
        field listed as the most significant field to search on and it compares 
        fields in the order specified in that list, through the last field in 
        the list (the least significant), if necessary. In previous versions, 
        this comparison function mistakenly considered the first field name in 
        alphabetical order as the most signficant and proceeded in pure alphabetical 
        order to make necessary comparisons.
 
      - Fixed global initialization bug with the SQL_types_to_C 
        ETI_Map. Problem was found when certain global IndexedDBView's 
        were not having the map already built so they could construct themselves 
        as initialization order of globals/class statics is undefined. Fixed by 
        replacing with a global function GetSQL_types_to_C() 
        that returns a reference to a local static ETI_Map 
        that is built properly on the first call to the function, which ensures 
        the proper order of initialization.
 
    
   
  
  - Version 
    2.01 
    
      - Added support for bool 
        data type.
 
      - Successfully ported code to Microsoft SQL Server.
 
      - Fixed minor bug with aliased views that did not allow 
        table names to be aliased in queries.
 
      - Renamed std_inc.h  
        to std_dtl_inc.h  and iterator.h 
        to DB_iterator.h to avoid filename 
        clashes.
 
      - Added DBException::GetAllODBCErrors() 
        method.
 
    
    
   - Version 2.0 
    
      - Added support for Boris Fomitchev's STLPort implementation 
        of the SGI Standard Template Library.
 
      - Successfully ported code to Red Hat Linux 7 under gcc 
        2.95 running unixODBC and a MySQL 3.23.33 database.
 
      - Corrected constness throughout DTL. This fixed some issues 
        that we had in 1.1 which prevented us from running correctly versus some 
        of the standard STL algorithms.
 
      - Rewrote the code to make it exception safe.
 
      - Added error handling support for all DTL iterator classes, 
        DBView, and IndexedDBView in the form of IOHandler.
 
      - Iterator refinements:  
        
          - DB_select_iterator::operator*() 
            now returns a const DataObj & to 
            make that operation truly read-only. 
 
          - All output iterators now use proxies to emulate *it = value to enforce 
            their write-only quality. 
 
          - Also fixed prefix/postix implementation for operator++() on 
            all iterators. 
 
        
       
      - Enhanced DBConnection class to use ODBC connection pooling. 
 
      - Added Julian date support through the jtime_c class. 
         
      - Simplified the structure for DBView  to need fewer template parameters. In version 
        1.1 the structure was DBView<DataObj, ParamObj, BCA, BPA> 
         in version 2.0 the structure is simplified to 
        DBView<DataObj, ParamObj> .