File indexing completed on 2025-02-23 05:15:20
0001 // 0002 // Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton 0003 // Distributed under the Boost Software License, Version 1.0. 0004 // (See accompanying file LICENSE_1_0.txt or copy at 0005 // http://www.boost.org/LICENSE_1_0.txt) 0006 // 0007 0008 #define SOCI_POSTGRESQL_SOURCE 0009 #include "soci/postgresql/soci-postgresql.h" 0010 #include "soci/connection-parameters.h" 0011 #include "soci/backend-loader.h" 0012 #include <libpq/libpq-fs.h> // libpq 0013 0014 #ifdef _MSC_VER 0015 #pragma warning(disable:4355) 0016 #endif 0017 0018 using namespace soci; 0019 using namespace soci::details; 0020 0021 namespace // unnamed 0022 { 0023 0024 // iterates the string pointed by i, searching for pairs of key value. 0025 // it returns the position after the value 0026 std::string::const_iterator get_key_value(std::string::const_iterator & i, 0027 std::string::const_iterator const & end, 0028 std::string & key, 0029 std::string & value) 0030 { 0031 bool in_value = false; 0032 bool quoted = false; 0033 0034 key.clear(); 0035 value.clear(); 0036 0037 while (i != end) 0038 { 0039 if (in_value == false) 0040 { 0041 if (*i == '=') 0042 { 0043 in_value = true; 0044 if (i != end && *(i + 1) == '"') 0045 { 0046 quoted = true; 0047 ++i; // jump over the quote 0048 } 0049 } 0050 else if (!isspace(*i)) 0051 { 0052 key += *i; 0053 } 0054 } 0055 else 0056 { 0057 if ((quoted == true && *i == '"') || (quoted == false && isspace(*i))) 0058 { 0059 return ++i; 0060 } 0061 else 0062 { 0063 value += *i; 0064 } 0065 } 0066 ++i; 0067 } 0068 return i; 0069 } 0070 0071 // retrieves specific parameters from the 0072 // uniform connect string 0073 std::string chop_connect_string(std::string const & connectString, 0074 bool & single_row_mode) 0075 { 0076 std::string pruned_conn_string; 0077 0078 single_row_mode = false; 0079 0080 std::string key, value; 0081 std::string::const_iterator i = connectString.begin(); 0082 while (i != connectString.end()) 0083 { 0084 i = get_key_value(i, connectString.end(), key, value); 0085 if (key == "singlerow" || key == "singlerows") 0086 { 0087 single_row_mode = (value == "true" || value == "yes"); 0088 } 0089 else 0090 { 0091 if (pruned_conn_string.empty() == false) 0092 { 0093 pruned_conn_string += ' '; 0094 } 0095 0096 pruned_conn_string += key + '=' + value; 0097 } 0098 } 0099 0100 return pruned_conn_string; 0101 } 0102 0103 } // unnamed namespace 0104 0105 // concrete factory for Empty concrete strategies 0106 postgresql_session_backend * postgresql_backend_factory::make_session( 0107 connection_parameters const & parameters) const 0108 { 0109 bool single_row_mode; 0110 0111 const std::string pruned_conn_string = 0112 chop_connect_string(parameters.get_connect_string(), single_row_mode); 0113 0114 connection_parameters pruned_parameters(parameters); 0115 pruned_parameters.set_connect_string(pruned_conn_string); 0116 0117 return new postgresql_session_backend(pruned_parameters, single_row_mode); 0118 } 0119 0120 postgresql_backend_factory const soci::postgresql; 0121 0122 extern "C" 0123 { 0124 0125 // for dynamic backend loading 0126 SOCI_POSTGRESQL_DECL backend_factory const * factory_postgresql() 0127 { 0128 return &soci::postgresql; 0129 } 0130 0131 SOCI_POSTGRESQL_DECL void register_factory_postgresql() 0132 { 0133 soci::dynamic_backends::register_backend("postgresql", soci::postgresql); 0134 } 0135 0136 } // extern "C"