|
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Copyright (C) 2010-2011 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
- //
- // 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 <cppdb/utils.h>
- #include <cppdb/errors.h>
- #include <time.h>
- #include <stdio.h>
- #include <string.h>
- #include <sstream>
- #include <locale>
-
- 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<int>(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<std::string,std::string> ¶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()) {
- size_t n=connection_string.find('=',p);
- if(n==std::string::npos)
- throw cppdb_error("Invalid connection string - invalid property");
- std::string key = trim(connection_string.substr(p,n-p));
- p=n+1;
- std::string value;
- while(p<connection_string.size() && is_blank_char(connection_string[p]))
- {
- ++p;
- }
- if(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(p<connection_string.size()) {
- char c=connection_string[p];
- if(is_blank_char(c))
- ++p;
- else if(c==';') {
- ++p;
- break;
- }
- }
- }
- } //
- std::string connection_info::get(std::string const &prop,std::string const &default_value) const
- {
- properties_type::const_iterator p=properties.find(prop);
- if(p==properties.end())
- return default_value;
- else
- return p->second;
- }
-
- 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;
- }
-
- }
|