SOCI Logo Get SOCI at SourceForge.net. Fast, secure and Free Open Source software downloads

standard-into-type.cpp

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
00003 // Distributed under the Boost Software License, Version 1.0.
00004 // (See accompanying file LICENSE_1_0.txt or copy at
00005 // http://www.boost.org/LICENSE_1_0.txt)
00006 //
00007 
00008 #define SOCI_POSTGRESQL_SOURCE
00009 #include "soci-postgresql.h"
00010 #include "common.h"
00011 //
00012 #if defined(SOCI_HEADERS_BURIED)
00013 #       include <soci/core/blob.h>
00014 #       include <soci/core/rowid.h>
00015 #else
00016 #       include <blob.h>
00017 #       include <rowid.h>
00018 #endif
00019 //
00020 #include <libpq/libpq-fs.h> // libpq (PostGreSQL client)
00021 #include <cctype>
00022 #include <cstdio>
00023 #include <cstring>
00024 #include <cstdlib>
00025 #include <ctime>
00026 #include <sstream>
00027 
00028 #ifdef SOCI_PGSQL_NOPARAMS
00029 #define SOCI_PGSQL_NOBINDBYNAME
00030 #endif // SOCI_PGSQL_NOPARAMS
00031 
00032 using namespace soci;
00033 using namespace soci::details;
00034 using namespace soci::details::postgresql;
00035 
00036 
00037 void postgresql_standard_into_type_backend::define_by_pos(
00038     int & position, void * data, exchange_type type)
00039 {
00040     data_ = data;
00041     type_ = type;
00042     position_ = position++;
00043 }
00044 
00045 void postgresql_standard_into_type_backend::pre_fetch()
00046 {
00047     // nothing to do here
00048 }
00049 
00050 void postgresql_standard_into_type_backend::post_fetch(
00051     bool gotData, bool calledFromFetch, indicator * ind)
00052 {
00053     if (calledFromFetch == true && gotData == false)
00054     {
00055         // this is a normal end-of-rowset condition,
00056         // no need to do anything (fetch() will return false)
00057         return;
00058     }
00059 
00060     if (gotData)
00061     {
00062         // postgresql_ positions start at 0
00063         int const pos = position_ - 1;
00064 
00065         // first, deal with indicators
00066         if (PQgetisnull(statement_.result_, statement_.currentRow_, pos) != 0)
00067         {
00068             if (ind == NULL)
00069             {
00070                 throw soci_error(
00071                     "Null value fetched and no indicator defined.");
00072             }
00073 
00074             *ind = i_null;
00075 
00076             // no need to convert data if it is null
00077             return;
00078         }
00079         else
00080         {
00081             if (ind != NULL)
00082             {
00083                 *ind = i_ok;
00084             }
00085         }
00086 
00087         // raw data, in text format
00088         char const * buf = PQgetvalue(statement_.result_,
00089             statement_.currentRow_, pos);
00090 
00091         switch (type_)
00092         {
00093         case x_char:
00094             {
00095                 char * dest = static_cast<char *>(data_);
00096                 *dest = *buf;
00097             }
00098             break;
00099         case x_stdstring:
00100             {
00101                 std::string * dest = static_cast<std::string *>(data_);
00102                 dest->assign(buf);
00103             }
00104             break;
00105         case x_short:
00106             {
00107                 short * dest = static_cast<short *>(data_);
00108                 *dest = string_to_integer<short>(buf);
00109             }
00110             break;
00111         case x_integer:
00112             {
00113                 int * dest = static_cast<int *>(data_);
00114                 *dest = string_to_integer<int>(buf);
00115             }
00116             break;
00117         case x_unsigned_long:
00118             {
00119                 unsigned long * dest = static_cast<unsigned long *>(data_);
00120                 *dest = string_to_unsigned_integer<unsigned long>(buf);
00121             }
00122             break;
00123         case x_long_long:
00124             {
00125                 long long * dest = static_cast<long long *>(data_);
00126                 *dest = string_to_integer<long long>(buf);
00127             }
00128             break;
00129         case x_double:
00130             {
00131                 double * dest = static_cast<double *>(data_);
00132                 *dest = string_to_double(buf);
00133             }
00134             break;
00135         case x_stdtm:
00136             {
00137                 // attempt to parse the string and convert to std::tm
00138                 std::tm * dest = static_cast<std::tm *>(data_);
00139                 parse_std_tm(buf, *dest);
00140             }
00141             break;
00142         case x_rowid:
00143             {
00144                 // RowID is internally identical to unsigned long
00145 
00146                 rowid * rid = static_cast<rowid *>(data_);
00147                 postgresql_rowid_backend * rbe
00148                     = static_cast<postgresql_rowid_backend *>(
00149                         rid->get_backend());
00150 
00151                 rbe->value_ = string_to_unsigned_integer<unsigned long>(buf);
00152             }
00153             break;
00154         case x_blob:
00155             {
00156                 unsigned long oid =
00157                     string_to_unsigned_integer<unsigned long>(buf);
00158 
00159                 int fd = lo_open(statement_.session_.conn_, oid,
00160                     INV_READ | INV_WRITE);
00161                 if (fd == -1)
00162                 {
00163                     throw soci_error("Cannot open the blob object.");
00164                 }
00165 
00166                 blob * b = static_cast<blob *>(data_);
00167                 postgresql_blob_backend * bbe
00168                      = static_cast<postgresql_blob_backend *>(b->get_backend());
00169 
00170                 if (bbe->fd_ != -1)
00171                 {
00172                     lo_close(statement_.session_.conn_, bbe->fd_);
00173                 }
00174 
00175                 bbe->fd_ = fd;
00176                 bbe->oid_ = oid;
00177             }
00178             break;
00179 
00180         default:
00181             throw soci_error("Into element used with non-supported type.");
00182         }
00183     }
00184 }
00185 
00186 void postgresql_standard_into_type_backend::clean_up()
00187 {
00188     // nothing to do here
00189 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
SourceForge Logo

Generated on Sun Oct 3 2010 17:42:16 for EXTRAS-SOCI by Doxygen 1.7.1