控制台应用程序 Scala 中的有状态用户

Stateful user in console application Scala

我需要在 Scala 中创建一个控制台界面应用程序作为待办事项列表。我已经创建了数据访问层,其中我有我的数据库对象并通过 Slick 3 查询它们。此外,我正在尝试使用 StdIn 创建一个简单的接口来读取 Scala 中的输入。 这是我的界面代码:

    object Main {

      val db = Database.forConfig("scalaxdb")
      val userRepository = new UserRepository(db)
      val taskRepository = new TaskRepository(db)

      def main(args: Array[String]): Unit = {
        println("Main menu:" + " \n1 - Login" + "\n2 - Exit")
        println("\nChoose the operation you want to perform:")
        val inputMainMenu = readInt()
        buildMainMenu(inputMainMenu)
      }

      def buildMainMenu(inputNumber: Int) =  inputNumber match {
          case 1 => enterSystem()
          case 2 => System.exit(0)
          case _ => println("Your input was wrong. Try again"); System.exit(0)
      }

      def enterSystem(): Unit ={

        println("Input you login, please:")
    val inputLogin = readLine()
    println("Input you password, please:")
    val inputPassword = readLine()

    val checkLogin = Await.result(DAO.checkUserLogin(inputLogin, inputPassword), Duration.Inf).toString
    val userId = DAO.selectUserId(inputLogin)

    def changeOutputs(checkLogin: String):Unit = checkLogin match {
      case "true" => println("You have successfully entered"); 
      displayMenu(); buildMenu(userId)
      case "false" => println("Your input for login or password is 
      wrong"); System.exit(1)
      case _ => println("Your input is wrong"); System.exit(1)
    }
    changeOutputs(checkLogin)
      }

      def displayMenu(): Unit ={
        println("TODO List:" + "\n1 - Display tasks" + "\n2 - Display finished tasks" + "\n3 - Display unfinished tasks"
          + "\n4 - Add task" + "\n5 - Delete task" + "\n6 - Mark task as finished")
        println("\nChoose the operation you want to perform:")
      }
     val inputNum = readInt()
    inputNum
  }   

    def displayUnfinishedTasks(id: Long) = {
        println()
        println("User's unfinished tasks:\n" + Await.result(DAO.selectUnfinishedTasks(id), Duration.Inf).toList.toString)
        displayMenu()
      }

问题是我需要以用户身份进入系统,然后输出、创建、删除特定用户的任务。所以在这里我决定将用户 ID 作为参数传递给我所有的操作方法。所以我尝试使用此接口执行此操作,但是,我收到运行时错误 java.lang.NumberFormatException: For input string: "Vector(1)" 我知道要修复此错误,我可能会以不同方式安排我的方法,但我将无法传递我的 userId。

为了清楚起见,这就是我的一种数据访问层方法的样子:

 def getUserId(login: String) = {
    val queryToGetUserId = (for {
      user <- UserTable.table if user.login === login
    } yield (user.idUser))
    db.run(queryToGetUserId.result)
  }

那么如何更改此代码中的接口方法或用户状态保留的整体逻辑?如有任何帮助,我将不胜感激!

更新! 代码改变了一点(方法 buildMenu、displayMenu)。另外,我在我的 dao 中创建了这个走道方法而不是 getUserId。所以接口可以工作,但我想知道我如何仍然可以更改我的 getUserId 方法或应该调用它以将 id 传递给 displayFinishedTasks 等方法的方式。 这是走动方法:

def selectUserId(login: String) = login match {
      case "data" => 1
      case "root" => 2
  }

上面的代码很乱,我们可以得到 github link 或其他更新吗? 丢进IntelliJ我都不会格式化

似乎还有未完成的行:changeOutputs(checkLogin)=

在上面的评论中,您提到以下行失败:

val userId = Await.result(DAO.getUserId(inputLogin), Duration.Inf).toString.toLong

抛出的异常是:

java.lang.NumberFormatException: For input string: "Vector(1)"

这表明 DAO.getUserId 正在 returning Vector 而不是 Int。查看该方法的代码:

 def getUserId(login: String) = {
   val queryToGetUserId = (for {
     user <- UserTable.table if user.login === login
   } yield (user.idUser))
   db.run(queryToGetUserId.result)
 }

我们可以看到此方法没有指定的 return 类型。 return 类型很可能是 Future[Seq[Int]]。由于您只想要一个结果,因此您应该通过调用 head:

将其更改为 Future[Int]
 def getUserId(login: String): Future[Long] = {
   val queryToGetUserId = (for {
     user <- UserTable.table if user.login === login
   } yield (user.idUser)).head // Will throw exception if empty result
   db.run(queryToGetUserId.result)
 }

 ...

 val userId = Await.result(DAO.getUserId(inputLogin), Duration.Inf)

这里我假设 idUser 已经是 Long。如果不是,那么您需要添加一个 .toLong——但这次应该可以!