diff options
author | Jakob Odersky <jakob@odersky.com> | 2018-10-27 18:45:06 -0700 |
---|---|---|
committer | Jakob Odersky <jakob@odersky.com> | 2018-10-27 18:45:06 -0700 |
commit | de095d377859887352c7380e52ea89bcabf662a0 (patch) | |
tree | 6cee6eb17c1977b85e01078e926499b33854047d /src/main/scala/byspel/app | |
download | byspel-de095d377859887352c7380e52ea89bcabf662a0.tar.gz byspel-de095d377859887352c7380e52ea89bcabf662a0.tar.bz2 byspel-de095d377859887352c7380e52ea89bcabf662a0.zip |
Initial commit
Diffstat (limited to 'src/main/scala/byspel/app')
-rw-r--r-- | src/main/scala/byspel/app/App.scala | 57 | ||||
-rw-r--r-- | src/main/scala/byspel/app/config.scala | 16 | ||||
-rw-r--r-- | src/main/scala/byspel/app/modules.scala | 51 |
3 files changed, 124 insertions, 0 deletions
diff --git a/src/main/scala/byspel/app/App.scala b/src/main/scala/byspel/app/App.scala new file mode 100644 index 0000000..65b3c3f --- /dev/null +++ b/src/main/scala/byspel/app/App.scala @@ -0,0 +1,57 @@ +package byspel +package app + +import akka.actor.ActorSystem +import akka.stream.{ActorMaterializer, Materializer} +import java.nio.file.{Files, Paths} +import scala.concurrent.ExecutionContext +import toml.Toml + +trait App { + + implicit lazy val system: ActorSystem = ActorSystem() + + implicit lazy val materializer: Materializer = ActorMaterializer() + + implicit lazy val executionContext: ExecutionContext = system.dispatcher + + def start(): Unit = {} + def stop(): Unit = {} + + def log(msg: String) = System.err.println(msg) + + private var _args: List[String] = Nil + def args = _args + + lazy val config = args match { + case Nil => + log("fatal: no config file given as first argument") + sys.exit(1) + case head :: _ if Files.isReadable(Paths.get(head)) => + log(s"loading config from '${args(0)}'") + import toml.Codecs._ + Toml.parseAs[Config](Files.readString(Paths.get(head))) match { + case Left(err) => + log(s"fatal: syntax error in config file: $err") + sys.exit(1) + case Right(value) => value + } + case head :: _ => + log(s"fatal: config file '$head' is not readable or does not exist") + sys.exit(1) + } + + def main(args: Array[String]): Unit = { + log("starting application") + _args = args.toList + config + sys.addShutdownHook { + log("stopping application") + stop() + log("bye") + } + start() + log("ready") + } + +} diff --git a/src/main/scala/byspel/app/config.scala b/src/main/scala/byspel/app/config.scala new file mode 100644 index 0000000..6ba9f80 --- /dev/null +++ b/src/main/scala/byspel/app/config.scala @@ -0,0 +1,16 @@ +package byspel +package app + +case class Config( + http: HttpConfig, + database: DatabaseConfig +) + +case class HttpConfig( + address: String, + port: Int +) +case class DatabaseConfig( + file: String, + sqitch_base: String +) diff --git a/src/main/scala/byspel/app/modules.scala b/src/main/scala/byspel/app/modules.scala new file mode 100644 index 0000000..a4b85ae --- /dev/null +++ b/src/main/scala/byspel/app/modules.scala @@ -0,0 +1,51 @@ +package byspel +package app + +import akka.http.scaladsl.Http +import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport +import akka.http.scaladsl.server.{Directives, Route} +import spray.json.DefaultJsonProtocol +import scala.concurrent.Await +import scala.concurrent.duration._ + +trait HttpApi + extends Directives + with SprayJsonSupport + with DefaultJsonProtocol { + def route: Route +} + +trait HttpApp extends App { self: HttpApi => + + override def start() = { + super.start() + log("binding to interface") + val future = + Http().bindAndHandle(route, config.http.address, config.http.port) + Await.result(future, 2.seconds) + } + +} + +trait DatabaseApi extends Tables { + val profile = Tables.profile + import profile.api._ + + def database: Database + +} + +trait DatabaseApp extends App { self: DatabaseApi => + import profile.api.Database + + lazy val database: Database = Database.forURL( + s"jdbc:sqlite:${config.database.file}", + driver = "org.sqlite.JDBC" + ) + + override def start() = { + super.start() + log("initializing database") + database + } +} |