-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cb8582b
commit 40a78a3
Showing
22 changed files
with
323 additions
and
115 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
116 changes: 25 additions & 91 deletions
116
server/app/src/main/kotlin/mu/muse/application/muse/PersistenceConfiguration.kt
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,112 +1,46 @@ | ||
package mu.muse.application.muse | ||
|
||
import mu.muse.domain.IdGenerator | ||
import mu.muse.domain.instrument.Country | ||
import mu.muse.domain.instrument.Instrument | ||
import mu.muse.domain.instrument.InstrumentId | ||
import mu.muse.domain.instrument.InstrumentName | ||
import mu.muse.domain.instrument.Manufacturer | ||
import mu.muse.domain.instrument.ManufacturerDate | ||
import mu.muse.domain.instrument.Material | ||
import mu.muse.domain.instrument.ReleaseDate | ||
import mu.muse.domain.user.FullName | ||
import mu.muse.domain.user.Password | ||
import mu.muse.domain.user.Role | ||
import mu.muse.domain.user.User | ||
import mu.muse.domain.user.UserId | ||
import mu.muse.domain.user.Username | ||
import mu.muse.persistence.instrument.InMemoryInstrumentIdGenerator | ||
import mu.muse.persistence.instrument.InMemoryInstrumentRepository | ||
import mu.muse.persistence.user.InMemoryUserRepository | ||
import mu.muse.persistence.user.InMemoryUsernameIdGenerator | ||
import com.zaxxer.hikari.HikariConfig | ||
import com.zaxxer.hikari.HikariDataSource | ||
import mu.muse.persistence.instrument.postgres.PostgresInstrumentIdGenerator | ||
import mu.muse.persistence.instrument.postgres.PostgresInstrumentRepository | ||
import mu.muse.persistence.user.postgres.PostgresUserIdGenerator | ||
import mu.muse.persistence.user.postgres.PostgresUserRepository | ||
import org.springframework.context.annotation.Bean | ||
import org.springframework.context.annotation.Configuration | ||
import org.springframework.security.crypto.password.PasswordEncoder | ||
import java.time.Instant | ||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate | ||
import javax.sql.DataSource | ||
|
||
@Configuration | ||
class PersistenceConfiguration { | ||
|
||
@Bean | ||
fun usernameIdGenerator() = InMemoryUsernameIdGenerator() | ||
fun dataSource(): DataSource { | ||
val hikariConfig = HikariConfig() | ||
hikariConfig.username = System.getenv("POSTGRES_USER") | ||
hikariConfig.password = System.getenv("POSTGRES_PASSWORD") | ||
val pgDb = System.getenv("POSTGRES_DB") | ||
hikariConfig.jdbcUrl = "jdbc:postgresql://localhost:5432/${pgDb}" | ||
val hikariDatasource = HikariDataSource(hikariConfig) | ||
// 25 is a good enough data pool size, it is a database in a container after all | ||
hikariDatasource.maximumPoolSize = 25 | ||
return hikariDatasource | ||
} | ||
|
||
@Bean | ||
fun users(idGenerator: IdGenerator<UserId>, passwordEncoder: PasswordEncoder): Set<User> { | ||
val user = User.create( | ||
id = idGenerator.generate(), | ||
username = Username.from("user"), | ||
password = Password.from(passwordEncoder.encode("123")), | ||
role = Role.user(), | ||
fullName = FullName.from("User Userov"), | ||
) | ||
|
||
val editor = User.create( | ||
id = idGenerator.generate(), | ||
username = Username.from("editor"), | ||
password = Password.from(passwordEncoder.encode("321")), | ||
role = Role.editor(), | ||
fullName = FullName.from("Editor Editorov"), | ||
) | ||
|
||
return setOf(user, editor) | ||
fun namedTemplate(dataSource: DataSource): NamedParameterJdbcTemplate { | ||
return NamedParameterJdbcTemplate(dataSource) | ||
} | ||
|
||
@Bean | ||
fun userRepository(users: Set<User>) = InMemoryUserRepository(users.associateBy { it.username }.toMutableMap()) | ||
fun userIdGenerator() = PostgresUserIdGenerator() | ||
|
||
@Bean | ||
fun instrumentIdGenerator() = InMemoryInstrumentIdGenerator() | ||
fun userRepository(namedTemplate: NamedParameterJdbcTemplate) = PostgresUserRepository(namedTemplate) | ||
|
||
@Bean | ||
fun instruments(idGenerator: IdGenerator<InstrumentId>): Set<Instrument> { | ||
val releasedGuitar = Instrument.create( | ||
id = idGenerator.generate(), | ||
name = InstrumentName.from("Fender Stratocaster"), | ||
type = Instrument.Type.STRINGED, | ||
manufacturer = Manufacturer.YAMAHA, | ||
manufactureDate = ManufacturerDate.from(Instant.parse("2024-07-01T00:00:00Z")), | ||
releaseDate = ReleaseDate.from(Instant.parse("2024-08-01T00:00:00Z")), | ||
country = Country.CYPRUS, | ||
materials = listOf(Material.WOOD), | ||
) | ||
|
||
val notYetReleasedGuitar = Instrument.create( | ||
id = idGenerator.generate(), | ||
name = InstrumentName.from("Fidel Telecastro"), | ||
type = Instrument.Type.STRINGED, | ||
manufacturer = Manufacturer.FENDER, | ||
manufactureDate = ManufacturerDate.from(Instant.parse("2024-07-01T00:00:00Z")), | ||
releaseDate = ReleaseDate.from(Instant.parse("2100-01-01T00:00:00Z")), | ||
country = Country.CYPRUS, | ||
materials = listOf(Material.WOOD), | ||
) | ||
|
||
val saxophone = Instrument.create( | ||
id = idGenerator.generate(), | ||
name = InstrumentName.from("SaxoStar"), | ||
type = Instrument.Type.WIND, | ||
manufacturer = Manufacturer.SIGMA, | ||
manufactureDate = ManufacturerDate.from(Instant.parse("2007-01-01T00:00:00Z")), | ||
releaseDate = ReleaseDate.from(Instant.parse("2008-07-01T00:00:00Z")), | ||
country = Country.USA, | ||
materials = listOf(Material.METALL), | ||
) | ||
|
||
val piano = Instrument.create( | ||
id = idGenerator.generate(), | ||
name = InstrumentName.from("Yamaha CLP-745B"), | ||
type = Instrument.Type.KEYBOARD, | ||
manufacturer = Manufacturer.YAMAHA, | ||
manufactureDate = ManufacturerDate.from(Instant.parse("2007-01-01T00:00:00Z")), | ||
releaseDate = ReleaseDate.from(Instant.parse("2008-07-01T00:00:00Z")), | ||
country = Country.USA, | ||
materials = listOf(Material.WOOD), | ||
) | ||
|
||
return setOf(notYetReleasedGuitar, releasedGuitar, saxophone, piano) | ||
} | ||
fun instrumentIdGenerator() = PostgresInstrumentIdGenerator() | ||
|
||
@Bean | ||
fun instrumentRepository(instruments: Set<Instrument>) = | ||
InMemoryInstrumentRepository(instruments.associateBy { it.id }.toMutableMap()) | ||
fun instrumentRepository(namedTemplate: NamedParameterJdbcTemplate) = PostgresInstrumentRepository(namedTemplate) | ||
} |
This file contains 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
This file contains 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
2 changes: 1 addition & 1 deletion
2
...strument/InMemoryInstrumentIdGenerator.kt → ...inmemory/InMemoryInstrumentIdGenerator.kt
This file contains 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
This file contains 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
13 changes: 13 additions & 0 deletions
13
.../src/main/kotlin/mu/muse/persistence/instrument/postgres/PostgresInstrumentIdGenerator.kt
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package mu.muse.persistence.instrument.postgres | ||
|
||
import mu.muse.domain.IdGenerator | ||
import mu.muse.domain.instrument.InstrumentId | ||
import org.springframework.jdbc.support.GeneratedKeyHolder | ||
|
||
class PostgresInstrumentIdGenerator : IdGenerator<InstrumentId> { | ||
private val keyHolder = GeneratedKeyHolder() | ||
|
||
override fun generate(): InstrumentId { | ||
return InstrumentId.from(keyHolder.key!!.toString()) | ||
} | ||
} |
124 changes: 124 additions & 0 deletions
124
...p/src/main/kotlin/mu/muse/persistence/instrument/postgres/PostgresInstrumentRepository.kt
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package mu.muse.persistence.instrument.postgres | ||
|
||
import mu.muse.common.types.Version | ||
import mu.muse.domain.instrument.Country | ||
import mu.muse.domain.instrument.Instrument | ||
import mu.muse.domain.instrument.InstrumentId | ||
import mu.muse.domain.instrument.InstrumentName | ||
import mu.muse.domain.instrument.Manufacturer | ||
import mu.muse.domain.instrument.ManufacturerDate | ||
import mu.muse.domain.instrument.Material | ||
import mu.muse.domain.instrument.ReleaseDate | ||
import mu.muse.persistence.instrument.inmemory.matches | ||
import mu.muse.usecase.access.instrument.InstrumentExtractor | ||
import mu.muse.usecase.access.instrument.InstrumentPersister | ||
import mu.muse.usecase.access.instrument.InstrumentRemover | ||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource | ||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate | ||
import org.springframework.jdbc.support.GeneratedKeyHolder | ||
import java.sql.ResultSet | ||
|
||
class PostgresInstrumentRepository( | ||
private val namedTemplate: NamedParameterJdbcTemplate, | ||
) : InstrumentExtractor, InstrumentRemover, InstrumentPersister { | ||
|
||
private val keyHolder = GeneratedKeyHolder() | ||
|
||
override fun findAll(): List<Instrument> { | ||
val sql = "select " + | ||
"instrument_id, " + | ||
"instrument_name, " + | ||
"instrument_type, " + | ||
"manufacturer_name, " + | ||
"manufacturer_date, " + | ||
"release_date, " + | ||
"country, " + | ||
"materials " + | ||
"from instruments" | ||
return namedTemplate.query(sql) { rs, _ -> rs.toInstrument() } | ||
} | ||
|
||
override fun findById(id: InstrumentId): Instrument? { | ||
val sql = "select " + | ||
"instrument_id, " + | ||
"instrument_name, " + | ||
"instrument_type, " + | ||
"manufacturer_name, " + | ||
"manufacturer_date, " + | ||
"release_date, " + | ||
"country, " + | ||
"materials " + | ||
"from instruments " + | ||
"where instrument_id = :instrument_id" | ||
val params = MapSqlParameterSource().addValue("instrument_id", id.toLongValue()) | ||
return namedTemplate.queryForObject(sql, params) { rs, _ -> rs.toInstrument() } | ||
} | ||
|
||
override fun findByIds(ids: List<InstrumentId>): List<Instrument> { | ||
val sql = "select " + | ||
"instrument_id, " + | ||
"instrument_name, " + | ||
"instrument_type, " + | ||
"manufacturer_name, " + | ||
"manufacturer_date, " + | ||
"release_date, " + | ||
"country, " + | ||
"materials " + | ||
"from instruments " + | ||
"where instrument_id in :instrument_ids" | ||
val params = MapSqlParameterSource().addValue("instrument_ids", ids) | ||
return namedTemplate.query(sql, params) { rs, _ -> rs.toInstrument() } | ||
} | ||
|
||
override fun findByCriteria(criteria: InstrumentExtractor.Criteria): List<Instrument> { | ||
val sql = "select " + | ||
"instrument_id, " + | ||
"instrument_name, " + | ||
"instrument_type, " + | ||
"manufacturer_name, " + | ||
"manufacturer_date, " + | ||
"release_date, " + | ||
"country, " + | ||
"materials " + | ||
"from instruments" | ||
val instruments = namedTemplate.query(sql) { rs, _ -> rs.toInstrument() } | ||
return instruments.filter { it matches criteria } | ||
} | ||
|
||
override fun totalElements(): Long { | ||
val sql = "select count(*) from instruments" | ||
return namedTemplate.queryForObject(sql, mapOf<String, Any>(), Long::class.java)!! | ||
} | ||
|
||
override fun removeInstrument(id: InstrumentId) { | ||
val sql = "delete from instruments where instrument_id = :instrument_id" | ||
val params = MapSqlParameterSource().addValue("instrument_id", id.toLongValue()) | ||
namedTemplate.update(sql, params, keyHolder) | ||
} | ||
|
||
override fun save(instrument: Instrument) { | ||
val sql = "insert into instruments (instrument_name, instrument_type, manufacturer_name, manufacturer_date, release_date, country, materials) " + | ||
"values (:instrument_name, :instrument_type, :manufacturer_name, :manufacturer_date, :release_date, :country, :materials)" | ||
val params = MapSqlParameterSource() | ||
.addValue("instrument_name", instrument.name.toStringValue()) | ||
.addValue("instrument_type", instrument.type.name) | ||
.addValue("manufacturer_name", instrument.manufacturer.name) | ||
.addValue("manufacturer_date", instrument.manufactureDate.toInstantValue()) | ||
.addValue("release_date", instrument.releaseDate.toInstantValue()) | ||
.addValue("country", instrument.country.name) | ||
.addValue("materials", instrument.materials) | ||
namedTemplate.update(sql, params) | ||
} | ||
} | ||
|
||
fun ResultSet.toInstrument() = Instrument( | ||
id = InstrumentId.from(this.getLong("instrument_id")), | ||
name = InstrumentName.from(this.getString("instrument_name")), | ||
type = Instrument.Type.valueOf(this.getString("instrument_type")), | ||
manufacturer = Manufacturer.valueOf(this.getString("manufacturer_name")), | ||
manufactureDate = ManufacturerDate.from(this.getTimestamp("manufacturer_date").toInstant()), | ||
releaseDate = ReleaseDate.from(this.getTimestamp("release_date").toInstant()), | ||
country = Country.valueOf(this.getString("country")), | ||
materials = (this.getArray("materials").getArray() as Array<String>).toList().map { Material.valueOf(it) }, | ||
version = Version.new(), | ||
) |
2 changes: 1 addition & 1 deletion
2
...ersistence/user/InMemoryUserRepository.kt → ...e/user/inmemory/InMemoryUserRepository.kt
This file contains 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
2 changes: 1 addition & 1 deletion
2
...tence/user/InMemoryUsernameIdGenerator.kt → ...r/inmemory/InMemoryUsernameIdGenerator.kt
This file contains 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
14 changes: 14 additions & 0 deletions
14
server/app/src/main/kotlin/mu/muse/persistence/user/postgres/PostgresUserIdGenerator.kt
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package mu.muse.persistence.user.postgres | ||
|
||
import mu.muse.domain.IdGenerator | ||
import mu.muse.domain.user.UserId | ||
import org.springframework.jdbc.support.GeneratedKeyHolder | ||
|
||
class PostgresUserIdGenerator : IdGenerator<UserId> { | ||
private val keyHolder = GeneratedKeyHolder() | ||
|
||
override fun generate(): UserId { | ||
return UserId.from(keyHolder.key!!.toLong()) | ||
} | ||
|
||
} |
Oops, something went wrong.