factory.cpp 3.38 KB
Newer Older
1
//
msobczak's avatar
msobczak committed
2
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
3 4 5 6 7
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//

8
#define SOCI_POSTGRESQL_SOURCE
9
#include "soci/postgresql/soci-postgresql.h"
10
#include "soci/connection-parameters.h"
11
#include "soci/backend-loader.h"
12
#include <libpq/libpq-fs.h> // libpq
13 14 15 16 17

#ifdef _MSC_VER
#pragma warning(disable:4355)
#endif

18 19
using namespace soci;
using namespace soci::details;
20

21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
namespace // unnamed
{

// iterates the string pointed by i, searching for pairs of key value.
// it returns the position after the value
std::string::const_iterator get_key_value(std::string::const_iterator & i,
                                          std::string::const_iterator const & end,
                                          std::string & key,
                                          std::string & value)
{
    bool in_value = false;
    bool quoted = false;

    key.clear();
    value.clear();

    while (i != end)
    {
        if (in_value == false)
        {
            if (*i == '=')
            {
                in_value = true;
                if (i != end && *(i + 1) == '"')
                {
                    quoted = true;
                    ++i; // jump over the quote
                }
            }
            else if (!isspace(*i))
            {
                key += *i;
            }
        }
        else
        {
            if ((quoted == true && *i == '"') || (quoted == false && isspace(*i)))
            {
                return ++i;
            }
            else
            {
                value += *i;
            }
        }
        ++i;
    }
    return i;
}

// retrieves specific parameters from the
// uniform connect string
std::string chop_connect_string(std::string const & connectString,
    bool & single_row_mode)
{
    std::string pruned_conn_string;
77

78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
    single_row_mode = false;

    std::string key, value;
    std::string::const_iterator i = connectString.begin();
    while (i != connectString.end())
    {
        i = get_key_value(i, connectString.end(), key, value);
        if (key == "singlerow" || key == "singlerows")
        {
            single_row_mode = (value == "true" || value == "yes");
        }
        else
        {
            if (pruned_conn_string.empty() == false)
            {
                pruned_conn_string += ' ';
            }

            pruned_conn_string += key + '=' + value;
        }
    }

    return pruned_conn_string;
}

} // unnamed namespace

105
// concrete factory for Empty concrete strategies
106
postgresql_session_backend * postgresql_backend_factory::make_session(
107
     connection_parameters const & parameters) const
108
{
109 110 111 112 113 114 115
    bool single_row_mode;

    const std::string pruned_conn_string =
        chop_connect_string(parameters.get_connect_string(), single_row_mode);

    connection_parameters pruned_parameters(parameters);
    pruned_parameters.set_connect_string(pruned_conn_string);
116

117
    return new postgresql_session_backend(pruned_parameters, single_row_mode);
118 119
}

120
postgresql_backend_factory const soci::postgresql;
121 122 123 124 125 126 127 128 129 130

extern "C"
{

// for dynamic backend loading
SOCI_POSTGRESQL_DECL backend_factory const * factory_postgresql()
{
    return &soci::postgresql;
}

131 132 133 134 135
SOCI_POSTGRESQL_DECL void register_factory_postgresql()
{
    soci::dynamic_backends::register_backend("postgresql", soci::postgresql);
}

136
} // extern "C"