/////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2010-2011 Artyom Beilis (Tonkikh) // // Distributed under: // // the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // or (at your opinion) under: // // The MIT License // (See accompanying file MIT.txt or a copy at // http://www.opensource.org/licenses/mit-license.php) // /////////////////////////////////////////////////////////////////////////////// #define CPPDB_SOURCE #include #include #include #include #include #include #include namespace cppdb { std::string format_time(std::tm const &v) { char buf[64]= {0}; strftime(buf,sizeof(buf),"%Y-%m-%d %H:%M:%S",&v); return std::string(buf); } std::tm parse_time(std::string const &v) { if(strlen(v.c_str())!=v.size()) throw bad_value_cast(); return parse_time(v.c_str()); } std::tm parse_time(char const *v) { std::tm t=std::tm(); int n; double sec = 0; n = sscanf(v,"%d-%d-%d %d:%d:%lf", &t.tm_year,&t.tm_mon,&t.tm_mday, &t.tm_hour,&t.tm_min,&sec); if(n!=3 && n!=6) { throw bad_value_cast(); } t.tm_year-=1900; t.tm_mon-=1; t.tm_isdst = -1; t.tm_sec=static_cast(sec); if(mktime(&t)==-1) throw bad_value_cast(); return t; } namespace { bool is_blank_char(char c) { return c==' ' || c=='\t' || c=='\r' || c=='\n' || c=='\f'; } std::string trim(std::string const &s) { if(s.empty()) return s; size_t start=0,end=s.size()-1; while(start < s.size() && is_blank_char(s[start])) { start++; } while(end > start && is_blank_char(s[end])) { end--; } return s.substr(start,end-start+1); } } void parse_connection_string( std::string const &connection_string, std::string &driver, std::map ¶ms) { params.clear(); size_t p = connection_string.find(':'); if( p == std::string::npos ) throw cppdb_error("cppdb::Invalid connection string - no driver given"); driver = connection_string.substr(0,p); p++; while(p=connection_string.size()) { /// Nothing - empty property } else if(connection_string[p]=='\'') { p++; while(true) { if(p>=connection_string.size()) { throw cppdb_error("Invalid connection string unterminated string"); } if(connection_string[p]=='\'') { if(p+1 < connection_string.size() && connection_string[p+1]=='\'') { value+='\''; p+=2; } else { p++; break; } } else { value+=connection_string[p]; p++; } } } else { size_t n=connection_string.find(';',p); if(n==std::string::npos) { value=trim(connection_string.substr(p)); p=connection_string.size(); } else { value=trim(connection_string.substr(p,n-p)); p=n; } } if(params.find(key)!=params.end()) { throw cppdb_error("cppdb::invalid connection string duplicate key"); } params[key]=value; while(psecond; } bool connection_info::has(std::string const &prop) const { return properties.find(prop) != properties.end(); } int connection_info::get(std::string const &prop,int default_value) const { properties_type::const_iterator p=properties.find(prop); if(p==properties.end()) return default_value; std::istringstream ss; ss.imbue(std::locale::classic()); ss.str(p->second); int val; ss >> val; if(!ss || !ss.eof()) { throw cppdb_error("cppdb::connection_info property " + prop + " expected to be integer value"); } return val; } }