diff --git a/src/main/scala/de/htwg/se/sudoku/SudokuModule.scala b/src/main/scala/de/htwg/se/sudoku/SudokuModule.scala index 538d676..2b33392 100644 --- a/src/main/scala/de/htwg/se/sudoku/SudokuModule.scala +++ b/src/main/scala/de/htwg/se/sudoku/SudokuModule.scala @@ -22,7 +22,6 @@ class SudokuModule extends AbstractModule with ScalaModule { bind[GridInterface].annotatedWithName("normal").toInstance(new Grid(9)) bind[FileIOInterface].to[fileIoJsonImpl.FileIO] - } } @@ -33,7 +32,7 @@ class MicroSudokuModule extends AbstractModule with ScalaModule { val defaultHostname: String = "localhost" val defaultFilePort: Int = 8089 - def configure(): Unit = { + override def configure(): Unit = { bindConstant().annotatedWith(Names.named("DefaultSize")).to(defaultSize) bind[GridInterface].to[Grid] bind[ControllerInterface].to[controllerBaseImpl.Controller] @@ -47,5 +46,26 @@ class MicroSudokuModule extends AbstractModule with ScalaModule { bind[FileIOInterface].to[fileIoMicroImpl.FileIO] } +} + +class MongoDBModule extends AbstractModule with ScalaModule { + + val defaultSize: Int = 9 + val defaultHostname: String = "localhost" + val defaultFilePort: Int = 27017 + + override def configure(): Unit = { + bindConstant().annotatedWith(Names.named("DefaultSize")).to(defaultSize) + bind[GridInterface].to[Grid] + bind[ControllerInterface].to[controllerBaseImpl.Controller] -} \ No newline at end of file + bind[GridInterface].annotatedWithName("tiny").toInstance(new Grid(1)) + bind[GridInterface].annotatedWithName("small").toInstance(new Grid(4)) + bind[GridInterface].annotatedWithName("normal").toInstance(new Grid(9)) + + bindConstant().annotatedWith(Names.named("MongoDBHost")).to(defaultHostname) + bindConstant().annotatedWith(Names.named("MongoDBPort")).to(defaultFilePort) + + bind[FileIOInterface].to[fileIoMongoDBImpl.FileIO] + } +} diff --git a/src/main/scala/de/htwg/se/sudoku/aview/gui/SwingGui.scala b/src/main/scala/de/htwg/se/sudoku/aview/gui/SwingGui.scala index 0e7b80f..d88ecea 100644 --- a/src/main/scala/de/htwg/se/sudoku/aview/gui/SwingGui.scala +++ b/src/main/scala/de/htwg/se/sudoku/aview/gui/SwingGui.scala @@ -128,4 +128,4 @@ class SwingGui(controller: ControllerInterface) extends Frame with Observer{ } override def update: Unit = redraw -} \ No newline at end of file +} diff --git a/src/main/scala/de/htwg/se/sudoku/controller/controllerComponent/controllerBaseImpl/Controller.scala b/src/main/scala/de/htwg/se/sudoku/controller/controllerComponent/controllerBaseImpl/Controller.scala index 101bca1..a692806 100644 --- a/src/main/scala/de/htwg/se/sudoku/controller/controllerComponent/controllerBaseImpl/Controller.scala +++ b/src/main/scala/de/htwg/se/sudoku/controller/controllerComponent/controllerBaseImpl/Controller.scala @@ -3,7 +3,7 @@ package de.htwg.se.sudoku.controller.controllerComponent.controllerBaseImpl import com.google.inject.name.Names import com.google.inject.{Guice, Inject, Injector} import com.typesafe.scalalogging.LazyLogging -import de.htwg.se.sudoku.MicroSudokuModule +import de.htwg.se.sudoku.{MongoDBModule} import de.htwg.se.sudoku.controller.controllerComponent.GameStatus._ import de.htwg.se.sudoku.controller.controllerComponent._ import de.htwg.se.sudoku.model.fileIoComponent.FileIOInterface @@ -13,8 +13,6 @@ import net.codingwell.scalaguice.InjectorExtensions._ import play.api.libs.json.JsValue import scala.util.{Failure, Success} -import com.typesafe.scalalogging.{LazyLogging, Logger} -import org.mongodb.scala.{MongoClient, MongoDatabase} class Controller @Inject()(var grid: GridInterface) extends ControllerInterface @@ -24,17 +22,9 @@ class Controller @Inject()(var grid: GridInterface) var gameStatus: GameStatus = IDLE var showAllCandidates: Boolean = false private val undoManager = new UndoManager - val injector: Injector = Guice.createInjector(new MicroSudokuModule) + val injector: Injector = Guice.createInjector(new MongoDBModule) val fileIo: FileIOInterface = injector.instance[FileIOInterface] - // database connection (could be injected later if database is running on another server) - // connects to the default server localhost on port 27017 - private val mongoClient: MongoClient = MongoClient() - private val db: MongoDatabase = mongoClient.getDatabase("sudoku-in-scala") - private val collection = db.getCollection("sudoku-in-scala-col") - // uncomment to delete the current database - //Await.result(collection.drop().toFuture(), Duration.Inf) - def createEmptyGrid: Unit = { grid.size match { case 1 => grid = injector.instance[GridInterface](Names.named("tiny")) diff --git a/src/main/scala/de/htwg/se/sudoku/model/fileIoComponent/fileIoMongoDBImpl/FileIO.scala b/src/main/scala/de/htwg/se/sudoku/model/fileIoComponent/fileIoMongoDBImpl/FileIO.scala new file mode 100644 index 0000000..e601b71 --- /dev/null +++ b/src/main/scala/de/htwg/se/sudoku/model/fileIoComponent/fileIoMongoDBImpl/FileIO.scala @@ -0,0 +1,80 @@ +package de.htwg.se.sudoku.model.fileIoComponent.fileIoMongoDBImpl + +import com.google.inject.{Guice, Inject} +import com.google.inject.name.{Named, Names} +import de.htwg.se.sudoku.SudokuModule +import de.htwg.se.sudoku.model.fileIoComponent.FileIOInterface +import de.htwg.se.sudoku.model.gridComponent.GridInterface +import net.codingwell.scalaguice.InjectorExtensions.ScalaInjector +import org.mongodb.scala.model.Projections +import org.mongodb.scala.{Document, MongoClient, MongoDatabase} +import play.api.libs.json.{JsValue, Json} + +import scala.concurrent.Await +import scala.concurrent.duration.Duration +import scala.util.Try + +class FileIO @Inject()(@Named("MongoDBHost") host: String, @Named("MongoDBPort") port: Int) extends FileIOInterface { + + private val mongoClient: MongoClient = MongoClient(s"mongodb://$host:$port") + private val db: MongoDatabase = mongoClient.getDatabase("sudoku-in-scala") + private val collection = db.getCollection("sudoku-in-scala-col") + + override def load: Try[Option[GridInterface]] = { + val resF = collection.find().projection(Projections.excludeId()).toFuture() + val res = Await.result(resF, Duration.Inf) + + var gridOption: Option[GridInterface] = None + + Try { + val json: JsValue = Json.parse(res.head.toJson()) + val size = (json \ "grid" \ "size").get.toString.toInt + val injector = Guice.createInjector(new SudokuModule) + + size match { + case 1 => + gridOption = + Some(injector.instance[GridInterface](Names.named("tiny"))) + case 4 => + gridOption = + Some(injector.instance[GridInterface](Names.named("small"))) + case 9 => + gridOption = + Some(injector.instance[GridInterface](Names.named("normal"))) + case _ => + } + gridOption match { + case Some(grid) => { + var _grid = grid + for (index <- 0 until size * size) { + val row = (json \\ "row") (index).as[Int] + val col = (json \\ "col") (index).as[Int] + val cell = (json \\ "cell") (index) + val value = (cell \ "value").as[Int] + _grid = _grid.set(row, col, value) + val given = (cell \ "given").as[Boolean] + val showCandidates = (cell \ "showCandidates").as[Boolean] + if (given) _grid = _grid.setGiven(row, col, value) + if (showCandidates) _grid = _grid.setShowCandidates(row, col) + } + gridOption = Some(_grid) + } + case None => + } + gridOption + } + } + + override def save(grid: GridInterface): Try[Unit] = { + Try { + Await.result(collection.drop().toFuture(), Duration.Inf) + val gameStateDoc = Document.apply(gridToJson(grid).toString()) + val resF = collection.insertOne(gameStateDoc).toFuture() + Await.result(resF, Duration.Inf) + } + } + + def gridToJson(grid: GridInterface) = grid.toJson + + override def unbind(): Unit = {} +}