annotate database/postgresql/src/driver.cpp @ 116:d7025649d85c

Server: add database account Implement accounts using a abstract factory mechanism, the database object creates abstract account which are implemented differently depending on the backend. See: - test_database, - test_account - broken_account Refs #687, #682
author David Demelier <markand@malikania.fr>
date Mon, 11 Sep 2017 13:18:43 +0200
parents d4f5f7231b84
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * driver.cpp -- PostgreSQL database driver
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 #include <sstream>
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
20 #include <string>
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 #include <unordered_map>
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
22
33
d4f5f7231b84 Misc: switch to .hpp, dos2unix everything while here, #478
David Demelier <markand@malikania.fr>
parents: 30
diff changeset
23 #include <malikania/dynlib.hpp>
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
24
33
d4f5f7231b84 Misc: switch to .hpp, dos2unix everything while here, #478
David Demelier <markand@malikania.fr>
parents: 30
diff changeset
25 #include "driver.hpp"
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
26
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 namespace pgsql {
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
28
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 PGconn *connection{nullptr};
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
30
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 std::shared_ptr<PGresult> exec(const std::string &sql)
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
32 {
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
33 std::shared_ptr<PGresult> ptr(PQexec(connection, sql.c_str()), PQclear);
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
34
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
35 if (PQresultStatus(ptr.get()) != PGRES_TUPLES_OK && PQresultStatus(ptr.get()) != PGRES_COMMAND_OK)
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
36 throw std::runtime_error(PQresultErrorMessage(ptr.get()));
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
37
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
38 return ptr;
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 }
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
40
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
41 std::string escape(const std::string &input)
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
42 {
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
43 auto text = PQescapeLiteral(connection, input.c_str(), input.length());
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
44
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
45 if (!text)
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
46 throw std::runtime_error(PQerrorMessage(connection));
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
47
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
48 std::string result(text);
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
49
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
50 PQfreemem(text);
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
51
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
52 return result;
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 }
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
54
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
55 } // !pgsql
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
56
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
57 namespace {
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
58
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 std::string parameters(const std::unordered_map<std::string, std::string> &params)
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 {
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
61 std::ostringstream oss;
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
62 std::unordered_map<std::string, std::string>::const_iterator it;
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
63
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
64 // Host.
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
65 if ((it = params.find("host")) == params.end())
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
66 throw std::runtime_error("missing 'host' parameter");
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
67
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
68 oss << "host = " << it->second << " ";
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
69
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
70 // Database.
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
71 if ((it = params.find("database")) == params.end())
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
72 throw std::runtime_error("missing 'database' parameter");
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
73
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
74 oss << "dbname = " << it->second << " ";
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
75
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
76 // User.
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
77 if ((it = params.find("user")) == params.end())
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
78 throw std::runtime_error("missing 'user' parameter");
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
79
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
80 oss << "user = " << it->second << " ";
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
81
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
82 // Port (optional).
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
83 if ((it = params.find("port")) != params.end())
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
84 oss << "port = " << it->second << " ";
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
85
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
86 // Password (optional).
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
87 if ((it = params.find("password")) != params.end())
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
88 oss << "password = " << it->second << " ";
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
89
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
90 return oss.str();
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 }
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
92
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 } // !namespace
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
94
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 extern "C" {
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
96
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
97 DYNLIB_EXPORT void malikania_driver_load(const std::unordered_map<std::string, std::string> &params)
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 {
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
99 pgsql::connection = PQconnectdb(parameters(params).c_str());
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
100
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
101 if (!pgsql::connection)
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
102 throw std::runtime_error(PQerrorMessage(pgsql::connection));
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 }
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
104
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
105 DYNLIB_EXPORT void malikania_driver_unload()
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
106 {
30
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
107 if (pgsql::connection) {
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
108 PQfinish(pgsql::connection);
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
109 pgsql::connection = nullptr;
a1e80d991968 Misc: convert to spaces, #519
David Demelier <markand@malikania.fr>
parents: 29
diff changeset
110 }
29
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 }
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
112
99792c6c8b06 Server: add initial postgresql account management, #475
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 } // !C