Home Libraries Author Links

dbmaptest.cpp

This example is a CLI based console C++ program demonstrating the usage and testing the implementation of the SysToMath DbMap C++ Library stmdbmap.

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the SysToMath DB C++ Libraries package (LibStmDb).
 *
 * The Initial Developer of the Original Code is
 * Tom Michaelis, SysToMath.
 * Portions created by the Initial Developer are Copyright (C) 2003-2008
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

/******************************************************************************
 *                       First Release 2003-03-15
 ******************************************************************************/


const char *Copyright = "(C) 2003-2008 Tom Michaelis, SysToMath";
const char *Version   = "1.04-r364";


#ifdef _WIN32
#include <direct.h>
#else
#define _MAX_PATH 1024
#include <unistd.h>
#endif
#include <stdlib.h>
#include <time.h>
#include <exception>
#include <string>
#include <iostream>


// Test of stm::db::map interface.

#include <stm/dbmap.hpp>

static void test ();

struct Data
{
    Data (const std::string &c = std::string (), unsigned int s = 0) :
        company (c),
        salary (s)
    {}

    std::string company;
    unsigned int salary;
};


namespace stm {
namespace db {
template <>
struct stream<Data>
{
    static void get (buffer &buf, const Data &value)
    {
        buf << value.company << value.salary;
        return;
    }

    static void put (buffer &buf, Data &value)
    {
        buf >> value.company >> value.salary;
        return;
    }
};
}}  // namespace stm::db


typedef stm::db::map<unsigned int, Data> DataMap;
typedef DataMap::index<std::string> CompIndex;
typedef DataMap::index<unsigned int> SalIndex;


static bool getCompany (const DataMap::value_type &value, CompIndex::skey_type &skey)
{
    skey = value.second.company;
    return true;
}


static bool getSalary (const DataMap::value_type &value, SalIndex::skey_type &skey)
{
    skey = value.second.salary;
    return true;
}


int main (int argc, char *argv [])
{
    static std::string prog = argv [0];
    prog = prog.substr (prog.find_last_of ("/\\") + 1);
    srand ((unsigned int) time (NULL));
    if (argc > 1 && !strcmp (argv [1], "-t"))
    {
        test ();
    }
    try
    {
        char buffer [_MAX_PATH];
        std::string dbPath = getcwd (buffer, _MAX_PATH);
        DataMap dataMap (dbPath + "/../../../test/Data");
        CompIndex compIndex (dataMap, getCompany, "Company");
        SalIndex salIndex (dataMap, getSalary, "Salary");
        for (int i = 0; i < 200; ++ i)
        {
            std::string company;
            size_t len = 4 + rand () % 7;
            for (size_t l = 0; l < len; ++ l)
            {
                company += char ('a' + rand () % 26);
            }
            dataMap [rand () % 5000] = Data (company, (rand () * 100) % 4711);
        }
        for (int i = 0; i < 500; ++ i)
        {
            dataMap.erase (rand () % 5000);
        }
        for (DataMap::const_iterator i = dataMap.begin (); i != dataMap.end (); ++ i)
        {
            std::cout << "Primary key: " << i -> first << ", "
                      << "Company: " << i -> second.company << ", "
                      << "Salary: " << i -> second.salary << std::endl;
        }
        std::cout << std::endl;
        for (SalIndex::const_iterator i = salIndex.begin (); i != salIndex.end (); ++ i)
        {
            std::cout << "Secondary key: " << i () << ", "
                      << "Primary key: " << i -> first << ", "
                      << "Company: " << i -> second.company << ", "
                      << "Salary: " << i -> second.salary << std::endl;
        }
        std::cout << std::endl;

        // Test of const non-const handling
        DataMap::iterator nci = dataMap.begin ();
        DataMap::const_iterator ci;
        ci = nci;
        ++ ci;
        SalIndex::iterator ncx = salIndex.begin ();
        SalIndex::const_iterator cx;
        cx = ncx;
        ++ cx;
        ci = cx;
        ++ ci;
        ci = ncx;
        ++ ci;

        CompIndex::iterator lb = compIndex.lower_bound ("y");
        CompIndex::iterator ub = compIndex.lower_bound ("z");
        for (CompIndex::iterator i = lb; i != ub; ++ i)
        {
            std::cout << "Secondary key: " << i () << ", "
                      << "Primary key: " << i -> first << ", "
                      << "Company: " << i -> second.company << ", "
                      << "Salary: " << i -> second.salary << std::endl;
        }
        std::cout << int (std::distance (lb, ub)) << " records begin with 'y'." << std::endl;
        std::cout << "The database contains " << dataMap.size ()
                  << " (" << compIndex.size () << ") records before erasure." << std::endl;
        CompIndex::iterator d = compIndex.lower_bound ("z");
        std::cout << int (std::distance (d, compIndex.end ())) << " records begin with 'z'." << std::endl;
        compIndex.erase (d, compIndex.end ());
        std::cout << "The database contains " << dataMap.size ()
                  << " (" << compIndex.size () << ") records after erasure." << std::endl;
    }
    catch (std::exception &exc)
    {
        std::cerr << prog << ": " << exc.what () << std::endl;
    }
    return 0;
}


#include <boost/mpl/transform.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/static_assert.hpp>
#include <boost/lambda/lambda.hpp>
static void test ()
{
    typedef boost::mpl::list<char, short, int, long, float, double> types;
    typedef boost::mpl::list<char *, short *, int *, long *, float *, double *> pointers;
    typedef boost::mpl::transform <types, boost::add_pointer<boost::mpl::_1> >::type result;
    BOOST_STATIC_ASSERT ((boost::mpl::equal<result, pointers>::type::value));

    typedef stm::db::conslist
    <
        boost::mpl::list
        <
            int,
            double,
            int,
            int,
            int,
            int,
            int,
            int,
            int,
            int
        >
    > ConsList;
    ConsList aconslist;
    aconslist.get<0> () = 1;
    aconslist.get<1> () = 3.14;
    aconslist.get<9> () = 13;
    std::cout << aconslist.get<0> () << ", "
              << aconslist.get<1> () << ", "
              << aconslist.get<9> () << std::endl;
    typedef stm::db::optional<int> OptInt;
    typedef boost::variant<int, std::string, float> Var1;
    Var1 var1 = "hello!";
    typedef boost::make_variant_over
    <
        boost::mpl::pop_front<Var1::types>::type
    >::type Var2;
    Var2 var2 = boost::get<std::string> (var1);
    std::cout << "is_variant<Var1>: " << stm::db::is_variant<Var1>::value << std::endl;
    std::cout << "is_variant<Var2>: " << stm::db::is_variant<Var2>::value << std::endl;
    std::cout << "is_variant<int>: " << stm::db::is_variant<int>::value << std::endl;
    typedef boost::tuple<int, std::string, float> Tuple;
    std::cout << "is_conslist<Tuple>: " << stm::db::is_conslist<Tuple>::value << std::endl;
    std::cout << "length<Tuple>: " << boost::tuples::length<Tuple>::value << std::endl;
    std::cout << "is_conslist<ConsList>: " << stm::db::is_conslist<ConsList>::value << std::endl;
    std::cout << "length<ConsList>: " << boost::tuples::length<ConsList>::value << std::endl;
    std::cout << "is_conslist<int>: " << stm::db::is_conslist<int>::value << std::endl;
    std::cout << "is_optional<OptInt>: " << stm::db::is_optional<OptInt>::value << std::endl;
    std::cout << "is_variant<OptInt>: " << stm::db::is_variant<OptInt>::value << std::endl;
    std::cout << "is_optional<int>: " << stm::db::is_optional<int>::value << std::endl;
    std::cout << "sizeof (bool): " << sizeof (bool) << std::endl;
    std::cout << "sizeof (boost::tuples::null_type): " << sizeof (boost::tuples::null_type) << std::endl;
    std::cout << "boost::is_empty<boost::tuples::null_type>::value: " << boost::is_empty<boost::tuples::null_type>::value << std::endl;
    std::cout << "boost::is_empty<boost::mpl::false_>::value: " << boost::is_empty<boost::mpl::false_>::value << std::endl;
    std::cout << "boost::is_empty<boost::tuple<> >::value: " << boost::is_empty<boost::tuple<> >::value << std::endl;
    std::cout << "boost::is_empty<stm::db::conslist<boost::mpl::list<> > >::value: " << boost::is_empty<stm::db::conslist<boost::mpl::list<> > >::value << std::endl;
    std::cout << "boost::is_same<boost::tuple<>, stm::db::conslist<boost::mpl::list<> > >::value: "
              << boost::is_same<boost::tuple<>, stm::db::conslist<boost::mpl::list<> > >::value << std::endl;

    exit (0);
}



© Copyright Tom Michaelis 2002-2007

Distributed under the SysToMath Software License (See the accompanying file license.txt or a copy at www.SysToMath.com).