Example #1
0
std::string getTextParam(XSQLVAR const *var)
{
    //std::cerr << "getTextParam: var->sqltype=" << var->sqltype << std::endl;
    short size;
    std::size_t offset = 0;

    if ((var->sqltype & ~1) == SQL_VARYING)
    {
        size = *reinterpret_cast<short*>(var->sqldata);
        offset = sizeof(short);
    }
    else if ((var->sqltype & ~1) == SQL_TEXT)
    {
        size = var->sqllen;
    }
    else if ((var->sqltype & ~1) == SQL_SHORT)
    {
        return format_decimal<short>(var->sqldata, var->sqlscale);
    }
    else if ((var->sqltype & ~1) == SQL_LONG)
    {
        return format_decimal<int>(var->sqldata, var->sqlscale);
    }
    else if ((var->sqltype & ~1) == SQL_INT64)
    {
        return format_decimal<long long>(var->sqldata, var->sqlscale);
    }
    else
        throw soci_error("Unexpected string type");

    return std::string(var->sqldata + offset, size);
}
Example #2
0
void statement_impl::describe()
{
    row_->clean_up();

    int numcols = backEnd_->prepare_for_describe();

    for (int i = 1; i <= numcols; ++i)
    {
        data_type dtype;
        std::string columnName;

        backEnd_->describe_column(i, dtype, columnName);

        column_properties props;
        props.set_name(columnName);

        props.set_data_type(dtype);
        switch (dtype)
        {
        case dt_string:
            bind_into<dt_string>();
            break;
        case dt_double:
            bind_into<dt_double>();
            break;
        case dt_integer:
            bind_into<dt_integer>();
            break;
        case dt_unsigned_long:
            bind_into<dt_unsigned_long>();
            break;
        case dt_long_long:
            bind_into<dt_long_long>();
            break;
        case dt_date:
            bind_into<dt_date>();
            break;
        default:
            std::ostringstream msg;
            msg << "db column type " << dtype
                <<" not supported for dynamic selects"<<std::endl;
            throw soci_error(msg.str());
        }
        row_->add_properties(props);
    }

    alreadyDescribed_ = true;
}
Example #3
0
double soci::details::postgresql::string_to_double(char const * buf)
{
    double t;
    int n;
    int const converted = sscanf(buf, "%lf%n", &t, &n);
    if (converted == 1 && static_cast<std::size_t>(n) == strlen(buf))
    {
        // successfully converted to double
        // and no other characters were found in the buffer

        return t;
    }
    else
    {
        throw soci_error("Cannot convert data.");
    }
}
Example #4
0
void tmDecode(short type, void * src, std::tm * dst)
{
    switch (type & ~1)
    {
    case SQL_TIMESTAMP:
        isc_decode_timestamp(static_cast<ISC_TIMESTAMP*>(src), dst);
        break;
    case SQL_TYPE_TIME:
        isc_decode_sql_time(static_cast<ISC_TIME*>(src), dst);
        break;
    case SQL_TYPE_DATE:
        isc_decode_sql_date(static_cast<ISC_DATE*>(src), dst);
        break;
    default:
        std::ostringstream msg;
        msg << "Unexpected type of date/time field (" << type << ")";
        throw soci_error(msg.str());
    }
}
Example #5
0
void tmEncode(short type, std::tm * src, void * dst)
{
    switch (type & ~1)
    {
        // In Interbase v6 DATE represents a date-only data type,
        // in InterBase v5 DATE represents a date+time data type.
    case SQL_TIMESTAMP:
        isc_encode_timestamp(src, static_cast<ISC_TIMESTAMP*>(dst));
        break;
    case SQL_TYPE_TIME:
        isc_encode_sql_time(src, static_cast<ISC_TIME*>(dst));
        break;
    case SQL_TYPE_DATE:
        isc_encode_sql_date(src, static_cast<ISC_DATE*>(dst));
        break;
    default:
        std::ostringstream msg;
        msg << "Unexpected type of date/time field (" << type << ")";
        throw soci_error(msg.str());
    }
}
Example #6
0
void setTextParam(char const * s, std::size_t size, char * buf_,
    XSQLVAR * var)
{
    //std::cerr << "setTextParam: var->sqltype=" << var->sqltype << std::endl;
    short sz = 0;
    if (size < static_cast<std::size_t>(var->sqllen))
    {
        sz = static_cast<short>(size);
    }
    else
    {
        sz = var->sqllen;
    }

    if ((var->sqltype & ~1) == SQL_VARYING)
    {
        std::memcpy(buf_, &sz, sizeof(short));
        std::memcpy(buf_ + sizeof(short), s, sz);
    }
    else if ((var->sqltype & ~1) == SQL_TEXT)
    {
        std::memcpy(buf_, s, sz);
        if (sz < var->sqllen)
        {
            std::memset(buf_+sz, ' ', var->sqllen - sz);
        }
    }
    else if ((var->sqltype & ~1) == SQL_SHORT)
    {
        parse_decimal<short, unsigned short>(buf_, var, s);
    }
    else if ((var->sqltype & ~1) == SQL_LONG)
    {
        parse_decimal<int, unsigned int>(buf_, var, s);
    }
    else if ((var->sqltype & ~1) == SQL_INT64)
    {
        parse_decimal<long long, unsigned long long>(buf_, var, s);
    }
    else if ((var->sqltype & ~1) == SQL_TIMESTAMP
            || (var->sqltype & ~1) == SQL_TYPE_DATE)
    {
        unsigned short year, month, day, hour, min, sec;
        if (std::sscanf(s, "%hu-%hu-%hu %hu:%hu:%hu",
                    &year, &month, &day, &hour, &min, &sec) != 6)
        {
            if (std::sscanf(s, "%hu-%hu-%huT%hu:%hu:%hu",
                        &year, &month, &day, &hour, &min, &sec) != 6)
            {
                hour = min = sec = 0;
                if (std::sscanf(s, "%hu-%hu-%hu", &year, &month, &day) != 3)
                {
                    throw soci_error("Could not parse timestamp value.");
                }
            }
        }
        std::tm t;
        std::memset(&t, 0, sizeof(t));
        t.tm_year = year - 1900;
        t.tm_mon = month - 1;
        t.tm_mday = day;
        t.tm_hour = hour;
        t.tm_min = min;
        t.tm_sec = sec;
        std::memcpy(buf_, &t, sizeof(t));
        tmEncode(var->sqltype, &t, buf_);
    }
    else if ((var->sqltype & ~1) == SQL_TYPE_TIME)
    {
        unsigned short hour, min, sec;
        if (std::sscanf(s, "%hu:%hu:%hu", &hour, &min, &sec) != 3)
        {
            throw soci_error("Could not parse timestamp value.");
        }
        std::tm t;
        std::memset(&t, 0, sizeof(t));
        t.tm_hour = hour;
        t.tm_min = min;
        t.tm_sec = sec;
        std::memcpy(buf_, &t, sizeof(t));
        tmEncode(var->sqltype, &t, buf_);
    }
    else
    {
        throw soci_error("Unexpected string type.");
    }
}
Example #7
0
void setTextParam(char const * s, std::size_t size, char * buf_,
                  XSQLVAR * var)
{
    int const sqltype = var->sqltype & ~1;

    if (sqltype == SQL_VARYING || sqltype == SQL_TEXT)
    {
        if (size > static_cast<std::size_t>(var->sqllen))
        {
            std::ostringstream msg;
            msg << "Value \"" << s << "\" is too long ("
                << size << " bytes) to be stored in column of size "
                << var->sqllen << " bytes";
            throw soci_error(msg.str());
        }

        short const sz = static_cast<short>(size);

        if (sqltype == SQL_VARYING)
        {
            std::memcpy(buf_, &sz, sizeof(short));
            std::memcpy(buf_ + sizeof(short), s, sz);
        }
        else // sqltype == SQL_TEXT
        {
            std::memcpy(buf_, s, sz);
            if (sz < var->sqllen)
            {
                std::memset(buf_+sz, ' ', var->sqllen - sz);
            }
        }
    }
    else if (sqltype == SQL_SHORT)
    {
        parse_decimal<short, unsigned short>(buf_, var, s);
    }
    else if (sqltype == SQL_LONG)
    {
        parse_decimal<int, unsigned int>(buf_, var, s);
    }
    else if (sqltype == SQL_INT64)
    {
        parse_decimal<long long, unsigned long long>(buf_, var, s);
    }
    else if (sqltype == SQL_TIMESTAMP
             || sqltype == SQL_TYPE_DATE)
    {
        unsigned short year, month, day, hour, min, sec;
        if (std::sscanf(s, "%hu-%hu-%hu %hu:%hu:%hu",
                        &year, &month, &day, &hour, &min, &sec) != 6)
        {
            if (std::sscanf(s, "%hu-%hu-%huT%hu:%hu:%hu",
                            &year, &month, &day, &hour, &min, &sec) != 6)
            {
                hour = min = sec = 0;
                if (std::sscanf(s, "%hu-%hu-%hu", &year, &month, &day) != 3)
                {
                    throw soci_error("Could not parse timestamp value.");
                }
            }
        }
        std::tm t;
        std::memset(&t, 0, sizeof(t));
        t.tm_year = year - 1900;
        t.tm_mon = month - 1;
        t.tm_mday = day;
        t.tm_hour = hour;
        t.tm_min = min;
        t.tm_sec = sec;
        std::memcpy(buf_, &t, sizeof(t));
        tmEncode(var->sqltype, &t, buf_);
    }
    else if (sqltype == SQL_TYPE_TIME)
    {
        unsigned short hour, min, sec;
        if (std::sscanf(s, "%hu:%hu:%hu", &hour, &min, &sec) != 3)
        {
            throw soci_error("Could not parse timestamp value.");
        }
        std::tm t;
        std::memset(&t, 0, sizeof(t));
        t.tm_hour = hour;
        t.tm_min = min;
        t.tm_sec = sec;
        std::memcpy(buf_, &t, sizeof(t));
        tmEncode(var->sqltype, &t, buf_);
    }
    else
    {
        throw soci_error("Unexpected string type.");
    }
}