Skip to content

Instantly share code, notes, and snippets.

@pedantix
Created March 26, 2018 17:24
Show Gist options
  • Save pedantix/0b500f6b2c88e0af56eff062dca00e5f to your computer and use it in GitHub Desktop.
Save pedantix/0b500f6b2c88e0af56eff062dca00e5f to your computer and use it in GitHub Desktop.
Counter Cache In Vapor 3
final class MyUser: PostgreSQLModel {
static let idKey: WritableKeyPath<MyUser, Int?> = \MyUser.id
var id: Int?
var myParticipationsCount: Int = 0
init(id: Int? = nil) {
self.id = id
}
}
final class MyParticipation: PostgreSQLModel {
static let idKey: WritableKeyPath<MyParticipation, Int?> = \MyParticipation.id
var id: Int?
var userId: MyUser.ID
init(id: Int? = nil, userId: MyUser.ID) {
self.id = id
self.userId = userId
}
var user: Parent<MyParticipation, MyUser> {
return parent(\.userId)
}
func didCreate(on connection: PostgreSQLConnection) throws -> EventLoopFuture<MyParticipation> {
try updateCounterCache(connection)
return Future.map(on: connection, { self })
}
func didUpdate(on connection: PostgreSQLConnection) throws -> EventLoopFuture<MyParticipation> {
try updateCounterCache(connection)
return Future.map(on: connection, { self })
}
func willDelete(on connection: PostgreSQLConnection) throws -> EventLoopFuture<MyParticipation> {
try updateCounterCache(connection, willDelete: true)
return Future.map(on: connection, { self })
}
func updateCounterCache(_ connection: PostgreSQLConnection, willDelete: Bool = false) throws {
_ = try user.get(on: connection).flatMap(to: MyUser.self, { myUser in
return try MyParticipation
.query(on: connection)
.filter(\MyParticipation.userId == self.userId)
.count()
.flatMap(to: MyUser.self, { participationCount in
if(willDelete) {
myUser.myParticipationsCount = participationCount
} else {
myUser.myParticipationsCount = participationCount - 1
}
return myUser.save(on: connection)
})
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment