Improve code for merging an old and new master index together

Signed-off-by: Graham <gpe@openrs2.org>
pull/132/head
Graham 3 years ago
parent b410b69771
commit 4fa67c37fc
  1. 117
      archive/src/main/kotlin/org/openrs2/archive/cache/CacheImporter.kt

@ -76,7 +76,7 @@ public class CacheImporter @Inject constructor(
// import master index
val masterIndex = createMasterIndex(store)
try {
addMasterIndex(connection, masterIndex, gameId, build, timestamp, name, description)
addMasterIndex(connection, masterIndex, gameId, build, timestamp, name, description, false)
} finally {
masterIndex.release()
}
@ -140,7 +140,7 @@ public class CacheImporter @Inject constructor(
prepare(connection)
val gameId = getGameId(connection, game)
addMasterIndex(connection, masterIndex, gameId, build, timestamp, name, description)
addMasterIndex(connection, masterIndex, gameId, build, timestamp, name, description, false)
}
}
}
@ -169,7 +169,7 @@ public class CacheImporter @Inject constructor(
stmt.execute()
}
addMasterIndex(connection, MasterIndex(masterIndex, buf), gameId, build, timestamp, name, null)
addMasterIndex(connection, MasterIndex(masterIndex, buf), gameId, build, timestamp, name, null, true)
connection.prepareStatement(
"""
@ -320,49 +320,126 @@ public class CacheImporter @Inject constructor(
build: Int?,
timestamp: Instant?,
name: String?,
description: String?
description: String?,
overwrite: Boolean
) {
val containerId = addContainer(connection, masterIndex)
var exists: Boolean
var newBuild: Int?
var newTimestamp: Instant?
var newName: String?
var newDescription: String?
connection.prepareStatement(
"""
SELECT game_id, build, timestamp, name, description
FROM master_indexes
WHERE container_id = ?
FOR UPDATE
""".trimIndent()
).use { stmt ->
stmt.setLong(1, containerId)
stmt.executeQuery().use { rows ->
exists = rows.next()
if (exists && !overwrite) {
val oldGameId = rows.getInt(1)
var oldBuild: Int? = rows.getInt(2)
if (rows.wasNull()) {
oldBuild = null
}
val oldTimestamp: Instant? = rows.getTimestamp(3)?.toInstant()
val oldName: String? = rows.getString(4)
val oldDescription: String? = rows.getString(5)
check(oldGameId == gameId)
if (oldBuild != null && build != null) {
check(oldBuild == build)
newBuild = oldBuild
} else if (oldBuild != null) {
newBuild = oldBuild
} else {
newBuild = build
}
if (oldTimestamp != null && timestamp != null) {
newTimestamp = if (oldTimestamp.isBefore(timestamp)) {
oldTimestamp
} else {
timestamp
}
} else if (oldTimestamp != null) {
newTimestamp = oldTimestamp
} else {
newTimestamp = timestamp
}
if (oldName != null && name != null) {
newName = "$oldName/$name"
} else if (oldName != null) {
newName = oldName
} else {
newName = name
}
if (oldDescription != null && description != null) {
newDescription = "$oldDescription\n\n$description"
} else if (oldDescription != null) {
newDescription = oldDescription
} else {
newDescription = description
}
} else {
newBuild = build
newTimestamp = timestamp
newName = name
newDescription = description
}
}
}
// TODO(gpe): combine name/description instead of overwriting one with the other?
// or a mechanism to control priority?
connection.prepareStatement(
"""
INSERT INTO master_indexes (container_id, game_id, build, timestamp, name, description)
VALUES (?, ?, ?, ?, ?, ?)
ON CONFLICT (container_id) DO UPDATE SET
build = COALESCE(EXCLUDED.build, master_indexes.build),
timestamp = COALESCE(
LEAST(EXCLUDED.timestamp, master_indexes.timestamp),
EXCLUDED.timestamp,
master_indexes.timestamp
),
name = COALESCE(EXCLUDED.name, master_indexes.name),
description = COALESCE(EXCLUDED.description, master_indexes.description)
game_id = EXCLUDED.game_id,
build = EXCLUDED.build,
timestamp = EXCLUDED.timestamp,
name = EXCLUDED.name,
description = EXCLUDED.description
""".trimIndent()
).use { stmt ->
stmt.setLong(1, containerId)
stmt.setInt(2, gameId)
stmt.setObject(3, build, Types.INTEGER)
stmt.setObject(3, newBuild, Types.INTEGER)
if (timestamp != null) {
val offsetDateTime = OffsetDateTime.ofInstant(timestamp, ZoneOffset.UTC)
if (newTimestamp != null) {
val offsetDateTime = OffsetDateTime.ofInstant(newTimestamp, ZoneOffset.UTC)
stmt.setObject(4, offsetDateTime, Types.TIMESTAMP_WITH_TIMEZONE)
} else {
stmt.setNull(4, Types.TIMESTAMP_WITH_TIMEZONE)
}
stmt.setString(5, name)
stmt.setString(6, description)
stmt.setString(5, newName)
stmt.setString(6, newDescription)
stmt.execute()
}
if (exists) {
return
}
connection.prepareStatement(
"""
INSERT INTO master_index_archives (container_id, archive_id, crc32, version)
VALUES (?, ?, ?, ?)
ON CONFLICT DO NOTHING
""".trimIndent()
).use { stmt ->
for ((i, entry) in masterIndex.index.entries.withIndex()) {

Loading…
Cancel
Save