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
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.