package com.evolutiongaming.kafka.journal.eventual.cassandra import cats.Monad import cats.data.{NonEmptyList => Nel} import cats.effect.Concurrent import cats.implicits._ import com.evolutiongaming.catshelper.LogOf import com.evolutiongaming.scassandra.TableName object CreateSchema { type Fresh = Boolean def apply[F[_] : Concurrent : CassandraCluster : CassandraSession : CassandraSync : LogOf]( config: SchemaConfig ): F[(Schema, Fresh)] = { for { createTables <- CreateTables.of[F] createKeyspace = CreateKeyspace[F] result <- apply[F](config, createKeyspace, createTables) } yield result } def apply[F[_] : Monad]( config: SchemaConfig, createKeyspace: CreateKeyspace[F], createTables: CreateTables[F] ): F[(Schema, Fresh)] = { def createTables1 = { val keyspace = config.keyspace.name def tableName(table: CreateTables.Table) = TableName(keyspace = keyspace, table = table.name) def table(name: String, query: TableName => Nel[String]) = { val tableName = TableName(keyspace = keyspace, table = name) CreateTables.Table(name = name, queries = query(tableName)) } val journal = table(config.journalTable, a => Nel.of(JournalStatements.createTable(a))) val metadata = table(config.metadataTable, a => Nel.of(MetadataStatements.createTable(a))) val metaJournal = table(config.metaJournalTable, a => MetaJournalStatements.createTable(a)) val pointer = table(config.pointerTable, a => Nel.of(PointerStatements.createTable(a))) val setting = table(config.settingTable, a => Nel.of(SettingStatements.createTable(a))) val schema = Schema( journal = tableName(journal), metadata = tableName(metadata), metaJournal = tableName(metaJournal), pointer = tableName(pointer), setting = tableName(setting)) if (config.autoCreate) { for { result <- createTables(keyspace, Nel.of(journal, metadata, pointer, setting, metaJournal)) } yield { (schema, result) } } else { (schema, false).pure[F] } } for { _ <- createKeyspace(config.keyspace) result <- createTables1 } yield result } }