Last active
December 24, 2024 17:20
-
-
Save jubishop/cb0032b1c1ad2728369363d1395ddd92 to your computer and use it in GitHub Desktop.
queue management
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// MARK: - Queue Management | |
func dequeue(_ episodeID: Int64) async throws { | |
try await appDB.db.write { db in | |
guard let oldPosition = try _fetchOldPosition(db, for: episodeID) else { | |
return | |
} | |
try _moveInQueue(db, episodeID: episodeID, from: oldPosition, to: Int.max) | |
try Episode.filter(id: episodeID) | |
.updateAll(db, queueColumn.set(to: nil)) | |
} | |
} | |
func insertToQueue(_ episodeID: Int64, at newPosition: Int) async throws { | |
try await appDB.db.write { db in | |
try _insertToQueue(db, episodeID: episodeID, at: newPosition) | |
} | |
} | |
func appendToQueue(_ episodeID: Int64) async throws { | |
try await appDB.db.write { db in | |
let newPosition = | |
(try Episode | |
.select(max(queueColumn), as: Int.self) | |
.fetchOne(db) ?? 0) + 1 | |
try _insertToQueue(db, episodeID: episodeID, at: newPosition) | |
} | |
} | |
//MARK: - Private Queue Helpers | |
private let queueColumn = Column("queueOrder") | |
private func _fetchOldPosition(_ db: Database, for episodeID: Int64) throws | |
-> Int? | |
{ | |
precondition( | |
db.isInsideTransaction, | |
"fetchOldPosition method requires a transaction" | |
) | |
return | |
try Episode | |
.filter(id: episodeID) | |
.select(queueColumn, as: Int.self) | |
.fetchOne(db) | |
} | |
private func _insertToQueue( | |
_ db: Database, | |
episodeID: Int64, | |
at newPosition: Int | |
) throws { | |
precondition( | |
db.isInsideTransaction, | |
"insertToQueue method requires a transaction" | |
) | |
let oldPosition = try _fetchOldPosition(db, for: episodeID) ?? Int.max | |
let computedNewPosition = | |
newPosition > oldPosition ? newPosition - 1 : newPosition | |
try _moveInQueue( | |
db, | |
episodeID: episodeID, | |
from: oldPosition, | |
to: computedNewPosition | |
) | |
try Episode | |
.filter(id: episodeID) | |
.updateAll(db, queueColumn.set(to: computedNewPosition)) | |
} | |
private func _moveInQueue( | |
_ db: Database, | |
episodeID: Int64, | |
from oldPosition: Int, | |
to newPosition: Int | |
) throws { | |
guard newPosition != oldPosition else { return } | |
precondition( | |
db.isInsideTransaction, | |
"moveInQueue method requires a transaction" | |
) | |
if newPosition > oldPosition { | |
try Episode.filter( | |
queueColumn > oldPosition && queueColumn <= newPosition | |
) | |
.updateAll(db, queueColumn.set(to: queueColumn - 1)) | |
} else { | |
try Episode.filter( | |
queueColumn >= newPosition && queueColumn < oldPosition | |
) | |
.updateAll(db, queueColumn.set(to: queueColumn + 1)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment