控制台应用程序 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
——但这次应该可以!
我需要在 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
——但这次应该可以!