Replace raw mysql_query calls with the zmDb* functions

With this we can make sure we have proper locking of our DB connection at all times.
This commit is contained in:
Peter Keresztes Schmidt 2021-03-05 09:31:10 +01:00 committed by Peter Keresztes Schmidt
parent c96cb1dd8d
commit 9e77324de4
6 changed files with 67 additions and 145 deletions

View File

@ -340,16 +340,11 @@ Config::~Config() {
}
void Config::Load() {
if ( mysql_query(&dbconn, "SELECT `Name`, `Value`, `Type` FROM `Config` ORDER BY `Id`") ) {
Error("Can't run query: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
MYSQL_RES *result = zmDbFetch("SELECT `Name`, `Value`, `Type` FROM `Config` ORDER BY `Id`");
if (!result) {
exit(-1);
}
MYSQL_RES *result = mysql_store_result(&dbconn);
if ( !result ) {
Error("Can't use query result: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
}
n_items = mysql_num_rows(result);
if ( n_items <= ZM_MAX_CFG_ID ) {
@ -362,7 +357,6 @@ void Config::Load() {
items[i] = new ConfigItem(dbrow[0], dbrow[1], dbrow[2]);
}
mysql_free_result(result);
result = nullptr;
}
void Config::Assign() {

View File

@ -41,22 +41,14 @@ const std::string EventStream::StreamMode_Strings[4] = {
};
bool EventStream::loadInitialEventData(int monitor_id, time_t event_time) {
static char sql[ZM_SQL_SML_BUFSIZ];
snprintf(sql, sizeof(sql), "SELECT `Id` FROM `Events` WHERE "
std::string sql = stringtf("SELECT `Id` FROM `Events` WHERE "
"`MonitorId` = %d AND unix_timestamp(`EndDateTime`) > %ld "
"ORDER BY `Id` ASC LIMIT 1", monitor_id, event_time);
if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
}
MYSQL_RES *result = zmDbFetch(sql.c_str());
if (!result)
exit(-1);
MYSQL_RES *result = mysql_store_result(&dbconn);
if ( !result ) {
Error("Can't use query result: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
}
MYSQL_ROW dbrow = mysql_fetch_row(result);
if ( mysql_errno(&dbconn) ) {
@ -115,23 +107,15 @@ bool EventStream::loadInitialEventData(
}
bool EventStream::loadEventData(uint64_t event_id) {
static char sql[ZM_SQL_MED_BUFSIZ];
snprintf(sql, sizeof(sql),
std::string sql = stringtf(
"SELECT `MonitorId`, `StorageId`, `Frames`, unix_timestamp( `StartDateTime` ) AS StartTimestamp, "
"unix_timestamp( `EndDateTime` ) AS EndTimestamp, "
"(SELECT max(`Delta`)-min(`Delta`) FROM `Frames` WHERE `EventId`=`Events`.`Id`) AS FramesDuration, "
"`DefaultVideo`, `Scheme`, `SaveJPEGs`, `Orientation`+0 FROM `Events` WHERE `Id` = %" PRIu64, event_id);
if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
}
MYSQL_RES *result = mysql_store_result(&dbconn);
MYSQL_RES *result = zmDbFetch(sql.c_str());
if (!result) {
Error("Can't use query result: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
exit(-1);
}
if ( !mysql_num_rows(result) ) {
@ -228,17 +212,12 @@ bool EventStream::loadEventData(uint64_t event_id) {
updateFrameRate((event_data->frame_count and event_data->duration) ? (double)event_data->frame_count/event_data->duration : 1);
snprintf(sql, sizeof(sql), "SELECT `FrameId`, unix_timestamp(`TimeStamp`), `Delta` "
sql = stringtf("SELECT `FrameId`, unix_timestamp(`TimeStamp`), `Delta` "
"FROM `Frames` WHERE `EventId` = %" PRIu64 " ORDER BY `FrameId` ASC", event_id);
if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
}
result = mysql_store_result(&dbconn);
result = zmDbFetch(sql.c_str());
if (!result) {
Error("Can't use query result: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
exit(-1);
}
event_data->n_frames = mysql_num_rows(result);
@ -604,10 +583,10 @@ void EventStream::processCommand(const CmdMsg *msg) {
} // void EventStream::processCommand(const CmdMsg *msg)
bool EventStream::checkEventLoaded() {
static char sql[ZM_SQL_SML_BUFSIZ];
std::string sql;
if ( curr_frame_id <= 0 ) {
snprintf(sql, sizeof(sql),
sql = stringtf(
"SELECT `Id` FROM `Events` WHERE `MonitorId` = %d AND `Id` < %" PRIu64 " ORDER BY `Id` DESC LIMIT 1",
event_data->monitor_id, event_data->event_id);
} else if ( (unsigned int)curr_frame_id > event_data->last_frame_id ) {
@ -618,7 +597,7 @@ bool EventStream::checkEventLoaded() {
curr_frame_id = event_data->last_frame_id;
return false;
}
snprintf(sql, sizeof(sql),
sql = stringtf(
"SELECT `Id` FROM `Events` WHERE `MonitorId` = %d AND `Id` > %" PRIu64 " ORDER BY `Id` ASC LIMIT 1",
event_data->monitor_id, event_data->event_id);
} else {
@ -630,19 +609,15 @@ bool EventStream::checkEventLoaded() {
// Event change required.
if ( forceEventChange || ( (mode != MODE_SINGLE) && (mode != MODE_NONE) ) ) {
Debug(1, "Checking for next event %s", sql);
if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
Debug(1, "Checking for next event %s", sql.c_str());
MYSQL_RES *result = zmDbFetch(sql.c_str());
if (!result) {
exit(-1);
}
MYSQL_RES *result = mysql_store_result(&dbconn);
if ( !result ) {
Error("Can't use query result: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
}
if ( mysql_num_rows(result) != 1 ) {
Debug(1, "No rows returned for %s", sql);
Debug(1, "No rows returned for %s", sql.c_str());
}
MYSQL_ROW dbrow = mysql_fetch_row(result);
@ -664,7 +639,7 @@ bool EventStream::checkEventLoaded() {
Debug(2, "New frame id = %d", curr_frame_id);
return true;
} else {
Debug(2, "No next event loaded using %s. Pausing", sql);
Debug(2, "No next event loaded using %s. Pausing", sql.c_str());
if ( curr_frame_id <= 0 )
curr_frame_id = 1;
else

View File

@ -2391,25 +2391,19 @@ void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors) {
for ( int i = 0; i < n_link_ids; i++ ) {
Debug(1, "Checking linked monitor %d", link_ids[i]);
std::lock_guard<std::mutex> lck(db_mutex);
static char sql[ZM_SQL_SML_BUFSIZ];
snprintf(sql, sizeof(sql),
std::string sql = stringtf(
"SELECT `Id`, `Name` FROM `Monitors`"
" WHERE `Id` = %d"
" AND `Function` != 'None'"
" AND `Function` != 'Monitor'"
" AND `Enabled`=1",
link_ids[i]);
if (mysql_query(&dbconn, sql)) {
Error("Can't run query: %s", mysql_error(&dbconn));
MYSQL_RES *result = zmDbFetch(sql.c_str());
if (!result) {
continue;
}
MYSQL_RES *result = mysql_store_result(&dbconn);
if ( !result ) {
Error("Can't use query result: %s", mysql_error(&dbconn));
continue;
}
int n_monitors = mysql_num_rows(result);
if ( n_monitors == 1 ) {
MYSQL_ROW dbrow = mysql_fetch_row(result);

View File

@ -94,33 +94,25 @@ bool User::canAccess(int monitor_id) {
// Function to load a user from username and password
// Please note that in auth relay mode = none, password is NULL
User *zmLoadUser(const char *username, const char *password) {
char sql[ZM_SQL_MED_BUFSIZ] = "";
int username_length = strlen(username);
char *safer_username = new char[(username_length * 2) + 1];
// According to docs, size of safer_whatever must be 2*length+1
// due to unicode conversions + null terminator.
mysql_real_escape_string(&dbconn, safer_username, username, username_length);
std::string escaped_username((username_length * 2) + 1, '\0');
snprintf(sql, sizeof(sql),
"SELECT `Id`, `Username`, `Password`, `Enabled`,"
size_t escaped_len = mysql_real_escape_string(&dbconn, &escaped_username[0], username, username_length);
escaped_username.resize(escaped_len);
std::string sql = stringtf("SELECT `Id`, `Username`, `Password`, `Enabled`,"
" `Stream`+0, `Events`+0, `Control`+0, `Monitors`+0, `System`+0,"
" `MonitorIds`"
" FROM `Users` WHERE `Username` = '%s' AND `Enabled` = 1",
safer_username);
delete[] safer_username;
safer_username = nullptr;
escaped_username.c_str());
if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
}
MYSQL_RES *result = mysql_store_result(&dbconn);
if ( !result ) {
Error("Can't use query result: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
}
MYSQL_RES *result = zmDbFetch(sql.c_str());
if (!result)
return nullptr;
if ( mysql_num_rows(result) == 1 ) {
MYSQL_ROW dbrow = mysql_fetch_row(result);
@ -165,22 +157,13 @@ User *zmLoadTokenUser(std::string jwt_token_str, bool use_remote_addr) {
return nullptr;
}
char sql[ZM_SQL_MED_BUFSIZ] = "";
snprintf(sql, sizeof(sql),
"SELECT `Id`, `Username`, `Password`, `Enabled`, `Stream`+0, `Events`+0,"
std::string sql = stringtf("SELECT `Id`, `Username`, `Password`, `Enabled`, `Stream`+0, `Events`+0,"
" `Control`+0, `Monitors`+0, `System`+0, `MonitorIds`, `TokenMinExpiry`"
" FROM `Users` WHERE `Username` = '%s' AND `Enabled` = 1", username.c_str());
if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
MYSQL_RES *result = zmDbFetch(sql.c_str());
if (!result)
return nullptr;
}
MYSQL_RES *result = mysql_store_result(&dbconn);
if ( !result ) {
Error("Can't use query result: %s", mysql_error(&dbconn));
return nullptr;
}
int n_users = mysql_num_rows(result);
if ( n_users != 1 ) {
@ -227,22 +210,14 @@ User *zmLoadAuthUser(const char *auth, bool use_remote_addr) {
}
Debug(1, "Attempting to authenticate user from auth string '%s', remote addr(%s)", auth, remote_addr);
char sql[ZM_SQL_SML_BUFSIZ] = "";
snprintf(sql, sizeof(sql),
"SELECT `Id`, `Username`, `Password`, `Enabled`,"
std::string sql = "SELECT `Id`, `Username`, `Password`, `Enabled`,"
" `Stream`+0, `Events`+0, `Control`+0, `Monitors`+0, `System`+0,"
" `MonitorIds` FROM `Users` WHERE `Enabled` = 1");
" `MonitorIds` FROM `Users` WHERE `Enabled` = 1";
if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
exit(mysql_errno(&dbconn));
}
MYSQL_RES *result = mysql_store_result(&dbconn);
if ( !result ) {
Error("Can't use query result: %s", mysql_error(&dbconn));
MYSQL_RES *result = zmDbFetch(sql.c_str());
if (!result)
return nullptr;
}
int n_users = mysql_num_rows(result);
if ( n_users < 1 ) {
mysql_free_result(result);

View File

@ -819,28 +819,18 @@ bool Zone::ParseZoneString(const char *zone_string, int &zone_id, int &colour, P
} // end bool Zone::ParseZoneString(const char *zone_string, int &zone_id, int &colour, Polygon &polygon)
int Zone::Load(Monitor *monitor, Zone **&zones) {
static char sql[ZM_SQL_MED_BUFSIZ];
MYSQL_RES *result;
{ // scope for lock
std::lock_guard<std::mutex> lck(db_mutex);
snprintf(sql, sizeof(sql), "SELECT Id,Name,Type+0,Units,Coords,AlarmRGB,CheckMethod+0,"
std::string sql = stringtf("SELECT Id,Name,Type+0,Units,Coords,AlarmRGB,CheckMethod+0,"
"MinPixelThreshold,MaxPixelThreshold,MinAlarmPixels,MaxAlarmPixels,"
"FilterX,FilterY,MinFilterPixels,MaxFilterPixels,"
"MinBlobPixels,MaxBlobPixels,MinBlobs,MaxBlobs,"
"OverloadFrames,ExtendAlarmFrames"
" FROM Zones WHERE MonitorId = %d ORDER BY Type, Id", monitor->Id());
if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
MYSQL_RES *result = zmDbFetch(sql.c_str());
if (!result) {
return 0;
}
result = mysql_store_result(&dbconn);
}
if (!result) {
Error("Can't use query result: %s", mysql_error(&dbconn));
return 0;
}
int n_zones = mysql_num_rows(result);
Debug(1, "Got %d zones for monitor %s", n_zones, monitor->Name());
delete[] zones;

View File

@ -726,15 +726,9 @@ int main(int argc, char *argv[]) {
}
sql += " ORDER BY Id ASC";
if ( mysql_query(&dbconn, sql.c_str()) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
exit_zmu(mysql_errno(&dbconn));
}
MYSQL_RES *result = mysql_store_result(&dbconn);
MYSQL_RES *result = zmDbFetch(sql.c_str());
if (!result) {
Error("Can't use query result: %s", mysql_error(&dbconn));
exit_zmu(mysql_errno(&dbconn));
exit_zmu(-1);
}
Debug(1, "Got %d monitors", mysql_num_rows(result));