代码之家  ›  专栏  ›  技术社区  ›  Cassie

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

  •  0
  • Cassie  · 技术社区  · 7 年前

    我需要在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)" 我知道,为了修复这个错误,我可能会以不同的方式安排我的方法,但这样我就无法传递我的用户ID。

    为了清楚起见,这就是我的数据访问层方法之一的外观:

     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之类的方法。 以下是walkaway方法:

    def selectUserId(login: String) = login match {
          case "data" => 1
          case "root" => 2
      }
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   Rich Dougherty    7 年前

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

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

    引发的异常是:

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

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

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

    我们可以看到这个方法没有指定的返回类型。返回类型很可能是 Future[Seq[Int]] . 因为您只需要一个结果,所以应该将其更改为 Future[Int] 通过呼叫 head :

     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 -但这一次应该有效!

        2
  •  0
  •   Nigel Benns    7 年前

    上面的代码相当混乱,我们可以获得github链接或其他更新吗? 当我把它放入IntelliJ时,我甚至不会格式化。

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