standard-into-type.cpp 3.7 KB
Newer Older
1 2 3 4 5 6 7
//
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, David Courtney
// 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_ODBC_SOURCE
9
#include "soci-odbc.h"
10
#include <ctime>
11

12 13
using namespace soci;
using namespace soci::details;
14 15


16
void odbc_standard_into_type_backend::define_by_pos(
17
    int & position, void * data, exchange_type type)
18 19 20 21 22 23
{
    data_ = data;
    type_ = type;
    position_ = position++;

    SQLINTEGER size = 0;
24

25 26
    switch (type_)
    {
27
    case x_char:
28 29 30 31 32
        odbcType_ = SQL_C_CHAR;
        size = sizeof(char) + 1;
        buf_ = new char[size];
        data = buf_;
        break;
33
    case x_stdstring:
34
        odbcType_ = SQL_C_CHAR;
dacourtney's avatar
dacourtney committed
35 36
        size = 32769;
        buf_ = new char[size];
37 38
        data = buf_;
        break;
39
    case x_short:
40 41 42
        odbcType_ = SQL_C_SSHORT;
        size = sizeof(short);
        break;
43
    case x_integer:
44 45 46
        odbcType_ = SQL_C_SLONG;
        size = sizeof(long);
        break;
47
    case x_unsigned_long:
48 49 50
        odbcType_ = SQL_C_ULONG;
        size = sizeof(unsigned long);
        break;
51
    case x_double:
52 53 54
        odbcType_ = SQL_C_DOUBLE;
        size = sizeof(double);
        break;
55
    case x_stdtm:
56 57 58 59 60
        odbcType_ = SQL_C_TYPE_TIMESTAMP;
        size = sizeof(TIMESTAMP_STRUCT);
        buf_ = new char[size];
        data = buf_;
        break;
61
    case x_rowid:
62 63 64 65
        odbcType_ = SQL_C_ULONG;
        size = sizeof(unsigned long);
        break;
    default:
66
        throw soci_error("Into element used with non-supported type.");
67 68 69
    }

    valueLen_ = 0;
70

mloskot's avatar
mloskot committed
71 72
    SQLRETURN rc = SQLBindCol(statement_.hstmt_, static_cast<SQLUSMALLINT>(position_),
        static_cast<SQLUSMALLINT>(odbcType_), data, size, &valueLen_);
73 74
    if (is_odbc_error(rc))
    {
75
        throw odbc_soci_error(SQL_HANDLE_STMT, statement_.hstmt_,
76
                            "into type pre_fetch");
77
    }
78 79
}

80
void odbc_standard_into_type_backend::pre_fetch()
81 82 83 84
{
    //...
}

85
void odbc_standard_into_type_backend::post_fetch(
86
    bool gotData, bool calledFromFetch, indicator * ind)
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
{
    if (calledFromFetch == true && gotData == false)
    {
        // this is a normal end-of-rowset condition,
        // no need to do anything (fetch() will return false)
        return;
    }

    if (gotData)
    {
        // first, deal with indicators
        if (SQL_NULL_DATA == valueLen_)
        {
            if (ind == NULL)
            {
102
                throw soci_error(
103 104 105
                    "Null value fetched and no indicator defined.");
            }

106
            *ind = i_null;
107 108 109 110 111 112
            return;
        }
        else
        {
            if (ind != NULL)
            {
113
                *ind = i_ok;
114 115 116 117
            }
        }

        // only std::string and std::tm need special handling
118
        if (type_ == x_char)
119 120 121 122
        {
            char *c = static_cast<char*>(data_);
            *c = buf_[0];
        }
123
        if (type_ == x_stdstring)
124 125 126 127
        {
            std::string *s = static_cast<std::string *>(data_);
            *s = buf_;
        }
128
        else if (type_ == x_stdtm)
129 130 131 132 133
        {
            std::tm *t = static_cast<std::tm *>(data_);

            TIMESTAMP_STRUCT * ts = reinterpret_cast<TIMESTAMP_STRUCT*>(buf_);
            t->tm_isdst = -1;
134 135
            t->tm_year = ts->year - 1900;
            t->tm_mon = ts->month - 1;
136 137 138 139 140 141 142 143 144 145 146
            t->tm_mday = ts->day;
            t->tm_hour = ts->hour;
            t->tm_min = ts->minute;
            t->tm_sec = ts->second;

            // normalize and compute the remaining fields
            std::mktime(t);
        }
    }
}

147
void odbc_standard_into_type_backend::clean_up()
148
{
dacourtney's avatar
dacourtney committed
149
    if (buf_)
150
    {
151
        delete [] buf_;
152 153 154
        buf_ = 0;
    }
}