Skip to content

Commit

Permalink
将 User._id 字段改成 ObjectId 类型
Browse files Browse the repository at this point in the history
  • Loading branch information
Taskeren committed Sep 22, 2023
1 parent ab42a6e commit 64c3c5a
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 90 deletions.
3 changes: 2 additions & 1 deletion booster/src/main/kotlin/explode2/booster/util/MeasureTime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ private fun putAvgDuration(subject: String, duration: Duration) {

private fun getAvgDuration(subject: String): Duration {
val durations = subjectDurations[subject] ?: return 0.seconds
val avgMs = durations.map { it.inWholeNanoseconds }.average()
// toList(), to clone the list, to avoid ConcurrentModificationException
val avgMs = durations.toList().map { it.inWholeNanoseconds }.average()
return avgMs.nanoseconds
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class MongoManager(private val provider: LabyrinthMongoBuilder = LabyrinthMongoB
introduction,
coinPrice,
noterName,
noterUser?.id,
noterUser?.id?.let { ObjectId(it) },
charts,
publishTime,
state.category,
Expand Down Expand Up @@ -302,72 +302,6 @@ class MongoManager(private val provider: LabyrinthMongoBuilder = LabyrinthMongoB
return measureTimedValueAndPrint("Get User") { collUser.findOneById(ObjectId(id)) }?.let(::GameUserDelegate)
}

override fun getGameUserByIdThin(id: String): GameUser? {
// FIXME: chore
data class GameUserThin(
val id: ObjectId,
val username: String,
)

class GameUserThinDelegate(val delegate: GameUserThin): GameUser {
override val id: String
get() = delegate.id.toHexString()
override var username: String
get() = delegate.username
set(_) {}
override var coin: Int = 0
override var diamond: Int = 0
override var ppTime: OffsetDateTime = OffsetDateTime.now()
@Deprecated("Use Permission System instead")
override var isReviewer: Boolean = false
override val SongSet.isOwned: Boolean
get() = false
override val ownedSets: List<SongSet> = emptyList()

override fun calculateR(): Int {
data class MiddleObject(val data: Any)
data class AggregatedSumAcc(val sumAcc: Double)

return measureTimedValueAndPrint("Calc R") {
collGameRec.aggregate<AggregatedSumAcc>(
match(MongoGameRecord::playerId eq id),
sort(descending(MongoGameRecord::playedChartId, MongoGameRecord::r, MongoGameRecord::uploadTime)),
group(MongoGameRecord::playedChartId, Accumulators.first("data", ThisDocument)),
Aggregates.replaceWith(MiddleObject::data),
sort(descending(MongoGameRecord::r, MongoGameRecord::uploadTime)),
limit(20),
group(null, Accumulators.sum("sumAcc", MongoGameRecord::r))
)
}.firstOrNull()?.sumAcc?.toInt() ?: 0
}

override fun calculateHighestGoldenMedal(): Int {
// FIXME: 需要修复性能问题
return 0
}

override fun changePassword(password: String) {}
override fun validatePassword(password: String): Boolean = false
override fun giveSet(setId: String) {}
override fun calculateLastRecords(limit: Int): List<GameRecord> = emptyList()
override fun calculateBestRecords(limit: Int, sortedBy: ScoreOrRanking): List<GameRecord> = emptyList()
override fun getAllRecords(limit: Int, skip: Int): List<GameRecord> = emptyList()
override val omegaCount: Int = 0
override fun hasPermission(permissionKey: String): Boolean = false
override fun hasPermission(permission: Permission): Boolean = false
override fun grantPermission(permissionKey: String) {}
override fun revokePermission(permissionKey: String) {}
override fun resetPermission(permissionKey: String) {}
}

return measureTimedValueAndPrint("Get User Thin") {
collUser.aggregate<GameUserThin>(
match(GameUserThin::id eq ObjectId(id)),
project(GameUserThin::id, GameUserThin::username)
)
}.firstOrNull()?.let(::GameUserThinDelegate)
}

override fun getGameUserByName(username: String): GameUser? {
return collUser.findOne(MongoGameUser::username eq username)?.let(::GameUserDelegate)
}
Expand Down Expand Up @@ -446,7 +380,7 @@ class MongoManager(private val provider: LabyrinthMongoBuilder = LabyrinthMongoB
group(MongoGameRecord::playerId, Accumulators.first("data", ThisDocument)),
Aggregates.replaceWith(MiddleObject<MongoGameRecord>::data),
Aggregates.setWindowFields(null, descending(MongoGameRecord::score), WindowOutputFields.rank("ranking")),
match(MongoGameRecord::playerId eq playerId)
match(MongoGameRecord::playerId eq ObjectId(playerId))
).firstOrNull()?.let(::GameRecordRankedWrap)
}

Expand All @@ -463,7 +397,7 @@ class MongoManager(private val provider: LabyrinthMongoBuilder = LabyrinthMongoB
val actualId = id ?: createNewRandomUUID()
val rec = MongoGameRecord(
actualId,
playerId,
ObjectId(playerId),
chartId,
score,
RecordDetail(perfect, good, miss),
Expand Down Expand Up @@ -529,7 +463,7 @@ class MongoManager(private val provider: LabyrinthMongoBuilder = LabyrinthMongoB
group(MongoAssessRecord::playerId, Accumulators.first("data", ThisDocument)),
Aggregates.replaceWith(MiddleObject::data),
Aggregates.setWindowFields(null, descending(MiddleObject::sumAccuracy), WindowOutputFields.rank("ranking")),
match(MongoAssessRecord::playerId eq playerId)
match(MongoAssessRecord::playerId eq ObjectId(playerId))
).firstOrNull()?.let(::AssessmentRecordRankedWrap)
}

Expand All @@ -544,7 +478,7 @@ class MongoManager(private val provider: LabyrinthMongoBuilder = LabyrinthMongoB
val actualId = id ?: createNewRandomUUID()
val rec = MongoAssessRecord(
actualId,
playerId,
ObjectId(playerId),
assessmentId,
records.map { AssessmentRecordDetail(it.perfect, it.good, it.miss, it.score, it.accuracy) },
exRecord?.let { AssessmentRecordDetail(it.perfect, it.good, it.miss, it.score, it.accuracy) },
Expand Down Expand Up @@ -606,9 +540,9 @@ class MongoManager(private val provider: LabyrinthMongoBuilder = LabyrinthMongoB
delegate = updateMongoSongSet(id, delegate.copy(noterName = value))
}
override var noterUserId: String?
get() = delegate.noterUserId
get() = delegate.noterUserId?.toHexString()
set(value) {
delegate = updateMongoSongSet(id, delegate.copy(noterUserId = value))
delegate = updateMongoSongSet(id, delegate.copy(noterUserId = ObjectId(value)))
}
override var chartIds: List<String>
get() = delegate.chartIds
Expand Down Expand Up @@ -720,7 +654,7 @@ class MongoManager(private val provider: LabyrinthMongoBuilder = LabyrinthMongoB

return measureTimedValueAndPrint("Calc R") {
collGameRec.aggregate<AggregatedSumAcc>(
match(MongoGameRecord::playerId eq id),
match(MongoGameRecord::playerId eq ObjectId(id)),
sort(descending(MongoGameRecord::playedChartId, MongoGameRecord::r, MongoGameRecord::uploadTime)),
group(MongoGameRecord::playedChartId, Accumulators.first("data", ThisDocument)),
Aggregates.replaceWith(MiddleObject::data),
Expand Down Expand Up @@ -762,7 +696,7 @@ class MongoManager(private val provider: LabyrinthMongoBuilder = LabyrinthMongoB

override fun calculateLastRecords(limit: Int): List<GameRecord> {
return collGameRec.aggregate<MongoGameRecord>(
match(MongoGameRecord::playerId eq id),
match(MongoGameRecord::playerId eq ObjectId(id)),
sort(descending(MongoGameRecord::uploadTime)),
limit(limit)
).toList().map(::GameRecordWrap)
Expand All @@ -774,7 +708,7 @@ class MongoManager(private val provider: LabyrinthMongoBuilder = LabyrinthMongoB
val sortingField = if(sortedBy == ScoreOrRanking.Ranking) MongoGameRecord::r else MongoGameRecord::score

return collGameRec.aggregate<MongoGameRecord>(
match(MongoGameRecord::playerId eq id),
match(MongoGameRecord::playerId eq ObjectId(id)),
sort(descending(MongoGameRecord::playedChartId, sortingField, MongoGameRecord::uploadTime)),
group(MongoGameRecord::playedChartId, Accumulators.first("data", ThisDocument)),
Aggregates.replaceWith(MiddleObject::data),
Expand All @@ -792,7 +726,7 @@ class MongoManager(private val provider: LabyrinthMongoBuilder = LabyrinthMongoB
data class Omegas(val omegas: Int)

return collGameRec.aggregate<Omegas>(
match(MongoGameRecord::playerId eq id),
match(MongoGameRecord::playerId eq ObjectId(id)),
match(MongoGameRecord::score eq 1_000_000),
group(MongoGameRecord::playedChartId, Accumulators.first("data", ThisDocument)),
Aggregates.count("omegas")
Expand Down Expand Up @@ -864,7 +798,7 @@ class MongoManager(private val provider: LabyrinthMongoBuilder = LabyrinthMongoB
override val id: String
get() = value.id
override val playerId: String
get() = value.playerId
get() = value.playerId.toHexString()
override val playedChartId: String
get() = value.playedChartId
override val perfect: Int
Expand Down Expand Up @@ -909,7 +843,7 @@ class MongoManager(private val provider: LabyrinthMongoBuilder = LabyrinthMongoB
override val ranking: Int?
get() = value.ranking
override val player: GameUser
get() = getGameUserByIdThin(playerId).nn("getGameUserById($playerId)")
get() = getGameUserById(playerId).nn("getGameUserById($playerId)")

override fun toString(): String = value.toString()
}
Expand All @@ -918,7 +852,7 @@ class MongoManager(private val provider: LabyrinthMongoBuilder = LabyrinthMongoB
override val id: String
get() = value.id
override val playerId: String
get() = value.playerId
get() = value.playerId.toHexString()
override val assessmentId: String
get() = value.assessmentId
override val records: List<AssessmentRecord.AssessmentRecordEntry>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package explode2.labyrinth.mongo.po

import org.bson.codecs.pojo.annotations.BsonId
import org.bson.types.ObjectId
import java.time.OffsetDateTime

data class MongoAssessRecord(
@BsonId
val id: String,
val playerId: String,
val playerId: ObjectId,
val assessmentId: String,
val records: List<AssessmentRecordDetail>,
val exRecord: AssessmentRecordDetail?,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package explode2.labyrinth.mongo.po

import org.bson.codecs.pojo.annotations.BsonId
import org.bson.types.ObjectId
import java.time.OffsetDateTime

data class MongoGameRecord(
@BsonId
val id: String,
val playerId: String,
val playerId: ObjectId,
val playedChartId: String,
val score: Int,
val detail: RecordDetail,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package explode2.labyrinth.mongo.po

import org.bson.codecs.pojo.annotations.BsonId
import org.bson.types.ObjectId
import java.time.OffsetDateTime

data class MongoSongSet(
Expand All @@ -11,7 +12,7 @@ data class MongoSongSet(
val introduction: String,
val coinPrice: Int,
val noterName: String,
val noterUserId: String?,
val noterUserId: ObjectId?,
val chartIds: List<String>,
val publishTime: OffsetDateTime,
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ interface GameUserRepository {

fun getGameUserById(id: String): GameUser?

fun getGameUserByIdThin(id: String): GameUser?

fun getGameUserByName(username: String): GameUser?

fun createGameUser(username: String, password: String, id: String? = null): GameUser
Expand Down
23 changes: 19 additions & 4 deletions migration_scripts/migration-userid-uuid-to-objectid.mongodb.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
1. Modify config below this text
2. Copy the whole script and run in Mongo Shell
3. Replace Users collection with UsersMigrated collection manually
Author: Taskeren
This script changes a lot of things, as you should be careful about it!
Expand All @@ -16,13 +16,15 @@
// edit here ->
const config = {
db_name: "expX",
remove_invalid_users: true,
auto_rename_migrated_collection: true,
}
// <- edit end

use(config.db_name)

var success_count = 0
var error_count = 0
let success_count = 0;
let error_count = 0;

db.Users.find().forEach(user => {
try {
Expand Down Expand Up @@ -64,7 +66,20 @@ db.Users.find().forEach(user => {
error_count++
console.log(`Error to update User(old=${user_id}, new=${new_id}, name=${user.username})`)
}

})

if(config.auto_rename_migrated_collection) {
db.Users.renameCollection("UsersOld")
db.UsersMigrated.renameCollection("Users")
}

if(config.remove_invalid_users) {
console.log("Removing invalid noter of sets")
db.Sets.updateMany({noterUserId: {$type: "string"}}, {$set:{noterUserId: null}})
console.log("Removing records of invalid users")
db.GameRecords.deleteMany({playerId:{$type:"string"}})
console.log("Removing assessment records of invalid users")
db.AssessRecords.deleteMany({playerId:{$type:"string"}})
}

console.log(`Finished migration, ${success_count} successes, ${error_count} failures.`)

0 comments on commit 64c3c5a

Please sign in to comment.