Mercurial > malikania
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 |
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> ¶ms) |
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> ¶ms) |
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 |