/// <summary> /// /// </summary> /// <param name="mapId"></param> /// <returns>Beatmap object with data, or null on not found</returns> public Beatmap GetBeatmap(int mapId) { lock (_sqlConnector) { return(_sqlConnector.GetBeatmap(mapId)); } }
/// <summary> /// Used for inserting beatmaps/invoking a large number of (no result)queries at once instead of one-by-one with is way slower. /// </summary> public void StartMassStoring() { if (_sqlConnector.MassInsertIsActive) { return; } lock (_sqlConnector) { string sql = "SELECT Md5, MapId, BeatmapChecksum FROM (SELECT Md5, MapId, BeatmapChecksum FROM `withID` UNION SELECT Md5, MapId, BeatmapChecksum FROM `withoutID`)"; SQLiteDataReader reader; try { reader = _sqlConnector.Query(sql); } catch (SQLiteException e) { if (e.ResultCode == SQLiteErrorCode.Corrupt) { _sqlConnector.ResetDatabase(); StartMassStoring(); return; } throw; } _beatmapChecksums = new Dictionary <string, MapIdMd5Pair>(); while (reader.Read()) { var hash = reader.GetString(0); var mapId = reader.GetInt32(1); var checksum = reader.GetString(2); if (_beatmapChecksums.ContainsKey(checksum)) { //REALLY..? I don't think so. var map1 = _sqlConnector.GetBeatmap(hash); var map2 = _sqlConnector.GetBeatmap(_beatmapChecksums[checksum].Md5); var map1Checksum = map1.GetChecksum(); var map2Checksum = map2.GetChecksum(); if (map1Checksum == map2Checksum) { //:( fair enough var ex = new SQLiteException(SQLiteErrorCode.Constraint, "uh, oh... beatmap checksum collision"); ex.Data.Add("mapId1", map1.MapId); ex.Data.Add("hash1", map1.Md5); ex.Data.Add("mapId2", map2.MapId); ex.Data.Add("hash2", map2.Md5); ex.Data.Add("checksum", map1Checksum); throw ex; } _beatmapChecksums.Remove(map1Checksum); _beatmapChecksums.Remove(map2Checksum); _beatmapChecksums.Add(map1Checksum, new MapIdMd5Pair(map1.MapId, map1.Md5)); _beatmapChecksums.Add(map2Checksum, new MapIdMd5Pair(map2.MapId, map2.Md5)); } else { _beatmapChecksums.Add(checksum, new MapIdMd5Pair(mapId, hash)); } } reader.Dispose(); _sqlConnector.StartMassStoring(); } }