1 /*
2 Bacula(R) - The Network Backup Solution
3
4 Copyright (C) 2000-2020 Kern Sibbald
5
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
8
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
13
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
16
17 Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20 * Generic catalog class methods.
21 *
22 * Note: at one point, this file was assembled from parts of other files
23 * by a programmer, and other than "wrapping" in a class, which is a trivial
24 * change for a C++ programmer, nothing substantial was done, yet all the
25 * code was recommitted under this programmer's name. Consequently, we
26 * undo those changes here.
27 */
28
29 #include "bacula.h"
30
31 #if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL
32
33 #include "cats.h"
34
bdb_match_database(const char * db_driver,const char * db_name,const char * db_address,int db_port)35 bool BDB::bdb_match_database(const char *db_driver, const char *db_name,
36 const char *db_address, int db_port)
37 {
38 BDB *mdb = this;
39 bool match;
40
41 if (db_driver) {
42 match = strcasecmp(mdb->m_db_driver, db_driver) == 0 &&
43 bstrcmp(mdb->m_db_name, db_name) &&
44 bstrcmp(mdb->m_db_address, db_address) &&
45 mdb->m_db_port == db_port &&
46 mdb->m_dedicated == false;
47 } else {
48 match = bstrcmp(mdb->m_db_name, db_name) &&
49 bstrcmp(mdb->m_db_address, db_address) &&
50 mdb->m_db_port == db_port &&
51 mdb->m_dedicated == false;
52 }
53 return match;
54 }
55
bdb_clone_database_connection(JCR * jcr,bool mult_db_connections)56 BDB *BDB::bdb_clone_database_connection(JCR *jcr, bool mult_db_connections)
57 {
58 BDB *mdb = this;
59 /*
60 * See if its a simple clone e.g. with mult_db_connections set to false
61 * then we just return the calling class pointer.
62 */
63 if (!mult_db_connections) {
64 mdb->m_ref_count++;
65 return mdb;
66 }
67
68 /*
69 * A bit more to do here just open a new session to the database.
70 */
71 return db_init_database(jcr, mdb->m_db_driver, mdb->m_db_name,
72 mdb->m_db_user, mdb->m_db_password, mdb->m_db_address,
73 mdb->m_db_port, mdb->m_db_socket,
74 mdb->m_db_ssl_mode, mdb->m_db_ssl_key,
75 mdb->m_db_ssl_cert, mdb->m_db_ssl_ca,
76 mdb->m_db_ssl_capath, mdb->m_db_ssl_cipher,
77 true, mdb->m_disabled_batch_insert);
78 }
79
bdb_get_engine_name(void)80 const char *BDB::bdb_get_engine_name(void)
81 {
82 BDB *mdb = this;
83 switch (mdb->m_db_driver_type) {
84 case SQL_DRIVER_TYPE_MYSQL:
85 return "MySQL";
86 case SQL_DRIVER_TYPE_POSTGRESQL:
87 return "PostgreSQL";
88 case SQL_DRIVER_TYPE_SQLITE3:
89 return "SQLite3";
90 default:
91 return "Unknown";
92 }
93 }
94
95 /*
96 * Lock database, this can be called multiple times by the same
97 * thread without blocking, but must be unlocked the number of
98 * times it was locked using db_unlock().
99 */
bdb_lock(const char * file,int line)100 void BDB::bdb_lock(const char *file, int line)
101 {
102 int errstat;
103 BDB *mdb = this;
104
105 if ((errstat = rwl_writelock_p(&mdb->m_lock, file, line)) != 0) {
106 berrno be;
107 e_msg(file, line, M_FATAL, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
108 errstat, be.bstrerror(errstat));
109 }
110 }
111
112 /*
113 * Unlock the database. This can be called multiple times by the
114 * same thread up to the number of times that thread called
115 * db_lock()/
116 */
bdb_unlock(const char * file,int line)117 void BDB::bdb_unlock(const char *file, int line)
118 {
119 int errstat;
120 BDB *mdb = this;
121
122 if ((errstat = rwl_writeunlock(&mdb->m_lock)) != 0) {
123 berrno be;
124 e_msg(file, line, M_FATAL, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
125 errstat, be.bstrerror(errstat));
126 }
127 }
128
bdb_sql_query(const char * query,int flags)129 bool BDB::bdb_sql_query(const char *query, int flags)
130 {
131 bool retval;
132 BDB *mdb = this;
133
134 bdb_lock();
135 retval = sql_query(query, flags);
136 if (!retval) {
137 Mmsg(mdb->errmsg, _("Query failed: %s: ERR=%s\n"), query, sql_strerror());
138 }
139 bdb_unlock();
140 return retval;
141 }
142
print_lock_info(FILE * fp)143 void BDB::print_lock_info(FILE *fp)
144 {
145 BDB *mdb = this;
146 if (mdb->m_lock.valid == RWLOCK_VALID) {
147 fprintf(fp, "\tRWLOCK=%p w_active=%i w_wait=%i\n",
148 &mdb->m_lock, mdb->m_lock.w_active, mdb->m_lock.w_wait);
149 }
150 }
151
152 #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL */
153