-
-
Notifications
You must be signed in to change notification settings - Fork 179
Expand file tree
/
Copy pathdatabases_component.cpp
More file actions
171 lines (155 loc) · 5.07 KB
/
databases_component.cpp
File metadata and controls
171 lines (155 loc) · 5.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/.
*
* The original code is copyright (c) 2022, open.mp team and contributors.
*/
#include "databases_component.hpp"
DatabasesComponent::DatabasesComponent()
{
}
/// Creates a result set
/// @returns Result set if successful, otherwise "nullptr"
IDatabaseResultSet* DatabasesComponent::createResultSet()
{
int result_set_index(databaseResultSets.claim());
return databaseResultSets.get(result_set_index);
}
/// Called for every component after components have been loaded
/// Should be used for storing the core interface, registering player/core event handlers
/// Should NOT be used for interacting with other components as they might not have been initialised yet
void DatabasesComponent::onLoad(ICore* c)
{
core_ = c;
logSQLite_ = core_->getConfig().getBool("logging.log_sqlite");
logSQLiteQueries_ = core_->getConfig().getBool("logging.log_sqlite_queries");
SQLiteTimeout_ = core_->getConfig().getInt("sqlite_timeout");
}
/// To optionally log things from connections.
void DatabasesComponent::log(LogLevel level, const char* fmt, ...) const
{
if (core_ && logSQLite_ && *logSQLite_)
{
va_list args;
va_start(args, fmt);
core_->vlogLn(level, fmt, args);
va_end(args);
}
}
/// To optionally log queries from connections.
void DatabasesComponent::logQuery(const char* fmt, ...) const
{
if (core_ && logSQLiteQueries_ && *logSQLiteQueries_)
{
va_list args;
va_start(args, fmt);
core_->vlogLn(LogLevel::Message, fmt, args);
va_end(args);
}
}
/// Opens a new database connection
/// @param path Path to the database
/// @returns Database if successful, otherwise "nullptr"
IDatabaseConnection* DatabasesComponent::open(StringView path, int flags)
{
if (flags == 0)
{
// Defaults.
flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
}
DatabaseConnection* ret(nullptr);
sqlite3* database_connection_handle(nullptr);
if (sqlite3_open_v2(path.data(), &database_connection_handle, flags, nullptr) == SQLITE_OK)
{
if(SQLiteTimeout_ && *SQLiteTimeout_)
{
sqlite3_busy_timeout(database_connection_handle, *SQLiteTimeout_);
}
ret = databaseConnections.emplace(this, database_connection_handle);
if (!ret)
{
sqlite3_close_v2(database_connection_handle);
}
}
else
{
this->log(LogLevel::Error, "[log_sqlite]: Cannot open database '%s'. %s", path.data(), sqlite3_errmsg(database_connection_handle));
sqlite3_close_v2(database_connection_handle);
}
return ret;
}
/// Closes the specified database connection
/// @param databaseConnection Database connection
/// @returns "true" if database connection has been successfully closed, otherwise "false"
bool DatabasesComponent::close(IDatabaseConnection& connection)
{
int database_connection_index(connection.getID());
DatabaseConnection* res = databaseConnections.get(database_connection_index);
if (res)
{
res->close();
databaseConnections.remove(database_connection_index);
return true;
}
return false;
}
/// Frees the specified result set
/// @param resultSet Result set
/// @returns "true" if result set has been successfully freed, otherwise "false"
bool DatabasesComponent::freeResultSet(IDatabaseResultSet& resultSet)
{
return databaseResultSets.remove(resultSet.getID()).first;
}
/// Gets the number of database connections
/// @returns Number of database connections
std::size_t DatabasesComponent::getDatabaseConnectionCount() const
{
return databaseConnections.entries().size();
}
/// Is database connection ID valid
/// @param databaseConnectionID Database connection ID
/// @returns "true" if database connection ID is valid, otherwise "false"
bool DatabasesComponent::isDatabaseConnectionIDValid(int databaseConnectionID) const
{
if (databaseConnectionID == 0)
{
return false;
}
return databaseConnections.get(databaseConnectionID) != nullptr;
}
/// Gets a database connection by ID
/// @param databaseConnectionID Database connection ID
/// @returns Database connection
IDatabaseConnection& DatabasesComponent::getDatabaseConnectionByID(int databaseConnectionID)
{
return *databaseConnections.get(databaseConnectionID);
}
/// Gets the number of database result sets
/// @returns Number of result sets
std::size_t DatabasesComponent::getDatabaseResultSetCount() const
{
return databaseResultSets.entries().size();
}
/// Is database result set ID valid
/// @param databaseResultSetID Database result set ID
/// @returns "true" if database result set ID is valid, otherwise "false"
bool DatabasesComponent::isDatabaseResultSetIDValid(int databaseResultSetID) const
{
if (databaseResultSetID == 0)
{
return false;
}
return databaseResultSets.get(databaseResultSetID) != nullptr;
}
/// Gets a database result set by ID
/// @param databaseResultSetID Database result set ID
/// @returns Database result set
IDatabaseResultSet& DatabasesComponent::getDatabaseResultSetByID(int databaseResultSetID)
{
return *databaseResultSets.get(databaseResultSetID);
}
COMPONENT_ENTRY_POINT()
{
return new DatabasesComponent();
}