diff --git a/common/database_instances.cpp b/common/database_instances.cpp index 17badf6da..1015c763d 100644 --- a/common/database_instances.cpp +++ b/common/database_instances.cpp @@ -139,27 +139,79 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id) return false; } - // initial query - get max unused id above reserved - auto query = fmt::format( - "SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}", - max_reserved_instance_id, - max_reserved_instance_id - ); - - // recycle instances - change query to get first unused id above reserved + // recycle instances if (RuleB(Instances, RecycleInstanceIds)) { + + //query to get first unused id above reserved + auto query = fmt::format( + SQL( + SELECT id + FROM instance_list + WHERE id = {}; + ), + max_reserved_instance_id + 1 + ); + + auto results = QueryDatabase(query); + + // could not successfully query - bail out + if (!results.Success()) { + instance_id = 0; + return false; + } + + // first id is available + if (results.RowCount() == 0) { + instance_id = max_reserved_instance_id + 1; + return true; + } + + // now look for next available above reserved query = fmt::format( SQL( SELECT MIN(i.id + 1) AS next_available FROM instance_list i LEFT JOIN instance_list i2 ON i.id + 1 = i2.id - WHERE i.id > {} + WHERE i.id >= {} AND i2.id IS NULL; ), - RuleI(Instances, ReservedInstances) + max_reserved_instance_id ); + + results = QueryDatabase(query); + + // could not successfully query - bail out + if (!results.Success()) { + instance_id = 0; + return false; + } + + // did not retrieve any rows - bail out + if (results.RowCount() == 0) { + instance_id = 0; + return false; + } + + auto row = results.begin(); + + // check that id is within limits + if (row[0] && Strings::ToInt(row[0]) <= max_instance_id) { + instance_id = Strings::ToInt(row[0]); + return true; + } + + // no available instance ids + instance_id = 0; + return false; } + // get max unused id above reserved + auto query = fmt::format( + "SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}", + max_reserved_instance_id, + max_reserved_instance_id + ); + auto results = QueryDatabase(query); // could not successfully query - bail out @@ -168,21 +220,27 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id) return false; } - // no instances running - assign first id above reserved + // did not retrieve any rows - bail out if (results.RowCount() == 0) { + instance_id = 0; + return false; + } + + auto row = results.begin(); + + // no instances currently used + if (!row[0]) { instance_id = max_reserved_instance_id + 1; return true; } - for (auto row : results) { - // check that id is within limits - if (row[0] && Strings::ToInt(row[0]) <= max_instance_id) { - instance_id = Strings::ToInt(row[0]); - return true; - } + // check that id is within limits + if (Strings::ToInt(row[0]) <= max_instance_id) { + instance_id = Strings::ToInt(row[0]); + return true; } - // unhandled situation - should not reach here + // no available instance ids instance_id = 0; return false; }