Savarese Software Research Corporation
serialization.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2009 Savarese Software Research Corporation
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     https://www.savarese.com/software/ApacheLicense-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00023 #ifndef __SSRC_WSPR_DATABASE_SERIALIZATION
00024 #define __SSRC_WSPR_DATABASE_SERIALIZATION
00025 
00026 #include <ssrc/wispers/database/Database.h>
00027 #include <ssrc/wisp/serialization.h>
00028 
00029 __BEGIN_NS_SSRC_WSPR_DATABASE
00030 
00031 using NS_SSRC_SPREAD::detail::ByteBuffer;
00032 
00033 template<typename SerializableType, typename PackerType>
00034 inline NS_SSRC_WSPR_DATABASE::blob_type to_blob(const SerializableType & obj,
00035                                                PackerType & packer,
00036                                                ByteBuffer & buffer)
00037   SSRC_DECL_THROW(boost::archive::archive_exception, std::ios_base::failure)
00038 {
00039   buffer.clear();
00040   return NS_SSRC_WSPR_DATABASE::blob_type(static_cast<const void *>(&buffer[0]),
00041                                          packer.pack(obj, buffer));
00042 }
00043 
00044 namespace detail {
00045   template<typename Packer, typename T, bool is_basic_type> struct SVBinder;
00046 
00047   template<typename Packer, typename T> struct SVBinder<Packer, T, true> {
00048     static void bind(PreparedStatement & statement,
00049                      const unsigned int index, const T & value,
00050                      Packer &, ByteBuffer &)
00051     {
00052       statement.bind(index, value);
00053     }
00054   };
00055 
00056   template<typename Packer, typename T> struct SVBinder<Packer, T, false> {
00057     static void bind(PreparedStatement & statement,
00058                      const unsigned int index, const T & value,
00059                      Packer & packer, ByteBuffer & buffer)
00060     {
00061       buffer.clear();
00062       statement.bind(index,
00063                      static_cast<const void *>(&buffer[0]),
00064                      packer.pack(value, buffer));
00065     }
00066   };
00067 }
00068 
00069 template<typename PackerType>
00070 class SerializableValueBinder {
00071   typedef PackerType packer_type;
00072 
00073   packer_type & _packer;
00074   ByteBuffer & _buffer;
00075   PreparedStatement *_statement;
00076 
00077 public:
00078   typedef SerializableValueBinder binder_type;
00079 
00080   SerializableValueBinder(packer_type & packer, ByteBuffer & buffer) :
00081     _packer(packer), _buffer(buffer), _statement(0)
00082   { }
00083 
00084   binder_type & binder(PreparedStatement & statement) {
00085     _statement = &statement;
00086     return *this;
00087   }
00088 
00089   template<typename T>
00090   binder_type & bind(const unsigned int index, const T & value)
00091     SSRC_DECL_THROW(DatabaseException)
00092   {
00093     detail::SVBinder<packer_type, T, detail::is_basic_type<T>::value>::bind(*_statement, index, value, _packer, _buffer);
00094     return *this;
00095   }
00096 
00097 private:
00098 
00099   template<const unsigned int index, typename T>
00100   binder_type & _bindp(const T & t)
00101     SSRC_DECL_THROW(DatabaseException)
00102   {
00103     return bind(index, t);
00104   }
00105 
00106   template<const unsigned int index, typename T, typename... P>
00107   binder_type &  _bindp(const T & t, const P & ...p)
00108     SSRC_DECL_THROW(DatabaseException)
00109   {
00110     return bind(index, t)._bindp<index + 1>(p...);
00111   }
00112 
00113 public:
00114 
00115   template<typename... P>
00116   binder_type & bindp(const P & ...p)
00117     SSRC_DECL_THROW(DatabaseException)
00118   {
00119     return _bindp<1>(p...);
00120   }
00121 
00122 };
00123 
00124 namespace detail {
00125   template<typename Unpacker, typename T, bool is_basic_type> struct SVLoader;
00126 
00127   template<typename Unpacker, typename T> struct SVLoader<Unpacker, T, true> {
00128     static void load(const ResultSet & result, const unsigned int index,
00129                      T & value, Unpacker &)
00130     {
00131       value = std::move(result.value<typename detail::ResultSetValueTraits<T, detail::is_basic_type<T>::value>::db_value_type>(index));
00132     }
00133   };
00134 
00135   template<typename Unpacker, typename T> struct SVLoader<Unpacker, T, false> {
00136     static void load(const ResultSet & result, const unsigned int index,
00137                      T & value, Unpacker & unpacker)
00138     {
00139       blob_type && blob = result.value<blob_type>(index);
00140       unpacker.unpack(value, blob.first, blob.second);
00141     }
00142   };
00143 }
00144 
00145 template<typename UnpackerType>
00146 class SerializableValueLoader {
00147   typedef UnpackerType unpacker_type;
00148 
00149   unpacker_type & _unpacker;
00150 
00151 public:
00152 
00153   SerializableValueLoader(unpacker_type & unpacker) :
00154     _unpacker(unpacker)
00155   { }
00156 
00157   template<typename T>
00158   SerializableValueLoader &
00159   load(const ResultSet & result, const unsigned int index, T & value) {
00160     detail::SVLoader<unpacker_type, T, detail::is_basic_type<T>::value >::load(result, index, value, _unpacker);
00161     return *this;
00162   }
00163 
00164 private:
00165   template<const unsigned int index, typename T, typename... P>
00166   SerializableValueLoader & _loadp(const ResultSet & result,  T & value)
00167     SSRC_DECL_THROW(DatabaseException)
00168   {
00169     return load(result, index, value);
00170   }
00171 
00172   template<const unsigned int index, typename T, typename... P>
00173   SerializableValueLoader & _loadp(const ResultSet & result,  T & value, P & ...p)
00174     SSRC_DECL_THROW(DatabaseException)
00175   {
00176     return load(result, index, value)._loadp<index + 1>(result, p...);
00177   }
00178 
00179 public:
00180   template<typename... P>
00181   SerializableValueLoader & loadp(const ResultSet & result,  P & ...p)
00182     SSRC_DECL_THROW(DatabaseException)
00183   {
00184     return _loadp<0>(result, p...);
00185   }
00186 
00187   template<const unsigned int index, typename... P>
00188   SerializableValueLoader & loadp(const ResultSet & result,  P & ...p)
00189     SSRC_DECL_THROW(DatabaseException)
00190   {
00191     return _loadp<index>(result, p...);
00192   }
00193 };
00194 
00195 template<typename T>
00196 inline T value(const ResultSet & result_set, const unsigned int index) {
00197 #ifdef WSPR_DEBUG
00198   std::cerr << "WARNING!  POTENTIALLY INEFFICIENT BLOB DESERIALIZATION CODE PATH from ssrc/wispers/database/serialization.h.\n";
00199 #endif
00200   ssrc::wisp::BinaryUnpacker unpacker;
00201   blob_type && blob = result_set.value<blob_type>(index);
00202   T value;
00203   unpacker.unpack(value, blob.first, blob.second);
00204   return value;
00205 }
00206 
00207 __END_NS_SSRC_WSPR_DATABASE
00208 
00209 #endif

Savarese Software Research Corporation
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.