package space.luminic.finance.repos import org.springframework.jdbc.core.RowMapper import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate import org.springframework.stereotype.Repository import space.luminic.finance.models.Token import java.sql.Timestamp import java.time.Instant @Repository class TokenRepoImpl( private val userRepo: UserRepo, private val jdbcTemplate: NamedParameterJdbcTemplate ) : TokenRepo { private fun tokenRowMapper() = RowMapper { rs, _ -> Token( id = rs.getInt("id"), token = rs.getString("token"), user = userRepo.findById(rs.getInt("user_id")) ?: throw IllegalArgumentException("User not found"), issuedAt = rs.getTimestamp("issued_at").toInstant(), expiresAt = rs.getTimestamp("expires_at").toInstant(), status = Token.TokenStatus.valueOf(rs.getString("status")), ) } override fun findByToken(token: String): Token? { val sql = "SELECT * FROM finance.tokens WHERE token = :token" val params = mapOf( "token" to token, ) return jdbcTemplate.query(sql, params, tokenRowMapper()).firstOrNull() } override fun deleteByExpiresAtBefore(dateTime: Instant) { val sql = """ update finance.tokens set status = :status where expires_at <= :dateTime """.trimIndent() val params = mapOf( "status" to Token.TokenStatus.ACTIVE, "dateTime" to dateTime ) jdbcTemplate.update(sql, params) } override fun create(token: Token): Token { val sql = """ insert into finance.tokens(token, user_id, expires_at, status) values (:token, :userId, :expiresAt, :status) """.trimIndent() val params = mapOf( "token" to token.token, "userId" to token.user.id, "expiresAt" to Timestamp.from(token.expiresAt), "status" to Token.TokenStatus.ACTIVE.name, ) val createdTokenId = jdbcTemplate.update(sql, params) token.id = createdTokenId return token } override fun update(token: Token): Token { val sql = """ update finance.tokens set status = :status where token = :token """.trimIndent() val params = mapOf( "token" to token, "status" to token.status ) jdbcTemplate.update(sql, params) return token } override fun delete(id: Int) { val sql = """ update finance.tokens set status = :status where id = :id """.trimIndent() val params = mapOf( "id" to id, "status" to Token.TokenStatus.REVOKED ) jdbcTemplate.update(sql, params) } }