Mercurial > malikania
diff database/postgresql/src/driver.cpp @ 29:99792c6c8b06
Server: add initial postgresql account management, #475
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 26 May 2016 07:32:05 +0200 |
parents | |
children | a1e80d991968 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/database/postgresql/src/driver.cpp Thu May 26 07:32:05 2016 +0200 @@ -0,0 +1,113 @@ +/* + * driver.cpp -- PostgreSQL database driver + * + * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sstream> +#include <string> +#include <unordered_map> + +#include <malikania/dynlib.h> + +#include "driver.h" + +namespace pgsql { + +PGconn *connection{nullptr}; + +std::shared_ptr<PGresult> exec(const std::string &sql) +{ + std::shared_ptr<PGresult> ptr(PQexec(connection, sql.c_str()), PQclear); + + if (PQresultStatus(ptr.get()) != PGRES_TUPLES_OK && PQresultStatus(ptr.get()) != PGRES_COMMAND_OK) + throw std::runtime_error(PQresultErrorMessage(ptr.get())); + + return ptr; +} + +std::string escape(const std::string &input) +{ + auto text = PQescapeLiteral(connection, input.c_str(), input.length()); + + if (!text) + throw std::runtime_error(PQerrorMessage(connection)); + + std::string result(text); + + PQfreemem(text); + + return result; +} + +} // !pgsql + +namespace { + +std::string parameters(const std::unordered_map<std::string, std::string> ¶ms) +{ + std::ostringstream oss; + std::unordered_map<std::string, std::string>::const_iterator it; + + // Host. + if ((it = params.find("host")) == params.end()) + throw std::runtime_error("missing 'host' parameter"); + + oss << "host = " << it->second << " "; + + // Database. + if ((it = params.find("database")) == params.end()) + throw std::runtime_error("missing 'database' parameter"); + + oss << "dbname = " << it->second << " "; + + // User. + if ((it = params.find("user")) == params.end()) + throw std::runtime_error("missing 'user' parameter"); + + oss << "user = " << it->second << " "; + + // Port (optional). + if ((it = params.find("port")) != params.end()) + oss << "port = " << it->second << " "; + + // Password (optional). + if ((it = params.find("password")) != params.end()) + oss << "password = " << it->second << " "; + + return oss.str(); +} + +} // !namespace + +extern "C" { + +DYNLIB_EXPORT void malikania_driver_load(const std::unordered_map<std::string, std::string> ¶ms) +{ + pgsql::connection = PQconnectdb(parameters(params).c_str()); + + if (!pgsql::connection) + throw std::runtime_error(PQerrorMessage(pgsql::connection)); +} + +DYNLIB_EXPORT void malikania_driver_unload() +{ + if (pgsql::connection) { + PQfinish(pgsql::connection); + pgsql::connection = nullptr; + } +} + +} // !C