Skip to content

Commit

Permalink
Merge pull request #14 from bb30/persistence-mongo-db
Browse files Browse the repository at this point in the history
Persistence: MongoDB
  • Loading branch information
DonatJR authored Nov 4, 2018
2 parents 8f8f6e6 + a1c492f commit 2420d10
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 39 deletions.
33 changes: 0 additions & 33 deletions .vscode/tasks.json

This file was deleted.

2 changes: 2 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.2.3"
libraryDependencies += "com.typesafe.akka" %% "akka-http" % "10.0.0"

libraryDependencies += "com.typesafe.scala-logging" %% "scala-logging" % "3.9.0"

libraryDependencies += "org.mongodb.scala" %% "mongo-scala-driver" % "2.3.0"
4 changes: 3 additions & 1 deletion src/main/resources/logback.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>

<logger name="org.mongodb.driver" level="INFO" />
</configuration>
26 changes: 23 additions & 3 deletions src/main/scala/de/htwg/se/sudoku/SudokuModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ class SudokuModule extends AbstractModule with ScalaModule {
bind[GridInterface].annotatedWithName("normal").toInstance(new Grid(9))

bind[FileIOInterface].to[fileIoJsonImpl.FileIO]

}

}
Expand All @@ -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]
Expand All @@ -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 defaultMongoDBPort: Int = 27017

override def configure(): Unit = {
bindConstant().annotatedWith(Names.named("DefaultSize")).to(defaultSize)
bind[GridInterface].to[Grid]
bind[ControllerInterface].to[controllerBaseImpl.Controller]

}
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(defaultMongoDBPort)

bind[FileIOInterface].to[fileIoMongoDBImpl.FileIO]
}
}
2 changes: 1 addition & 1 deletion src/main/scala/de/htwg/se/sudoku/aview/gui/SwingGui.scala
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,4 @@ class SwingGui(controller: ControllerInterface) extends Frame with Observer{
}

override def update: Unit = redraw
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.{MicroSudokuModule, MongoDBModule}
import de.htwg.se.sudoku.controller.controllerComponent.GameStatus._
import de.htwg.se.sudoku.controller.controllerComponent._
import de.htwg.se.sudoku.model.fileIoComponent.FileIOInterface
Expand All @@ -23,6 +23,7 @@ class Controller @Inject()(var grid: GridInterface)
var showAllCandidates: Boolean = false
private val undoManager = new UndoManager
val injector: Injector = Guice.createInjector(new MicroSudokuModule)
// val injector: Injector = Guice.createInjector(new MongoDBModule) // can only be used with mongo db installed and configured
val fileIo: FileIOInterface = injector.instance[FileIOInterface]

def createEmptyGrid: Unit = {
Expand Down
Original file line number Diff line number Diff line change
@@ -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.{MongoDBModule, 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 resultFuture = collection.find().projection(Projections.excludeId()).toFuture()
val result = Await.result(resultFuture, Duration.Inf)

var gridOption: Option[GridInterface] = None

Try {
val json: JsValue = Json.parse(result.head.toJson())
val size = (json \ "grid" \ "size").get.toString.toInt
val injector = Guice.createInjector(new MongoDBModule)

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 resultFuture = collection.insertOne(gameStateDoc).toFuture()
Await.result(resultFuture, Duration.Inf)
}
}

def gridToJson(grid: GridInterface) = grid.toJson

override def unbind(): Unit = {}
}

0 comments on commit 2420d10

Please sign in to comment.