2015-10-17 25 views
0

我有created the database in SQL lite and improved the little program to handle it(列表,添加,删除记录)。在这一点上,我试图使用准备语句step()函数列出数据库中的内容。但是,我无法遍历数据库上的行和列。从Genie打印选择查询的结果

我怀疑其中的原因是,我不妥善处理本声明这一行:

stmt:Sqlite.Statement = null

如果是这样的情况下,如何从主通过的声明(INIT)功能的儿童功能?

这是整个代码至今:

// Trying to do a cookbook program 
// raw_imput for Genie included, compile with valac --pkg sqlite3 cookbook.gs 
[indent=4] 
uses Sqlite 

def raw_input (query:string = ""):string 
    stdout.printf ("%s", query) 
    return stdin.read_line() 


init 
    db : Sqlite.Database? = null 
    if (Sqlite.Database.open ("cookbook.db3", out db) != Sqlite.OK) 
     stderr.printf ("Error: %d: %s \n", db.errcode(), db.errmsg()) 
     Process.exit (-1) 

    loop:bool = true 
    while loop = true 
     print "===================================================" 
     print "     RECIPE DATABASE " 
     print " 1 - Show All Recipes" 
     print " 2 - Search for a recipe" 
     print " 3 - Show a Recipe" 
     print " 4 - Delete a recipe" 
     print " 5 - Add a recipe" 
     print " 6 - Print a recipe" 
     print " 0 - Exit" 
     print "===================================================" 
     response:string = raw_input("Enter a selection -> ") 
     if response == "1" // Show All Recipes 
      PrintAllRecipes() 
     else if response is "2" // Search for a recipe 
      pass 
     else if response is "3" //Show a Recipe 
      pass 
     else if response is "4"//Delete a recipe 
      pass 
     else if response is "5" //Add a recipe 
      pass 
     else if response is "6" //Print a recipe 
      pass 
     else if response is "0" //Exit 
      print "Goodbye" 
      Process.exit (-1) 
     else 
      print "Unrecognized command. Try again." 


def PrintAllRecipes() 
    print "%-5s%-30s%-20s%-30s", "Item", "Name", "Serves", "Source" 
    print "--------------------------------------------------------------------------------------" 
    stmt:Sqlite.Statement = null 
    param_position:int = stmt.bind_parameter_index ("$UID") 
    //assert (param_position > 0) 

    stmt.bind_int (param_position, 1) 
    cols:int = stmt.column_count() 
    while stmt.step() == Sqlite.ROW 
     for i:int = 0 to cols 
      i++ 
      col_name:string = stmt.column_name (i) 
      val:string = stmt.column_text (i) 
      type_id:int = stmt.column_type (i) 
      stdout.printf ("column: %s\n", col_name) 
      stdout.printf ("value: %s\n", val) 
      stdout.printf ("type: %d\n", type_id) 


/* while stmt.step() == Sqlite.ROW 
      col_item:string = stmt.column_name (1) 
      col_name:string = stmt.column_name (2) 
      col_serves:string = stmt.column_name (3) 
      col_source:string = stmt.column_name (4) 
      print "%-5s%-30s%-20s%-30s", col_item, col_name, col_serves, col_source */ 

额外的问题是:

  • 是否功能的定义应该来之前或初始化后?我注意到,如果我在初始化后全部离开,他们将不会被调用。但通过在开始时保留raw_input,错误消失了。

  • 我试图在一个类中定义PrintAllRecipes(),用于说教的原因。但是我最终使它对主程序“不可见”。

非常感谢,

回答

1

是的,你需要指定一个事先准备好的声明,没有null,以stmt。例如:

// Trying to do a cookbook program 
// raw_input for Genie included, compile with 
// valac --pkg sqlite3 --pkg gee-0.8 cookbook.gs 
[indent=4] 
uses Sqlite 

init 
    db:Database 
    if (Database.open ("cookbook.db3", out db) != OK) 
     stderr.printf ("Error: %d: %s \n", db.errcode(), db.errmsg()) 
     Process.exit (-1) 

    while true 
     response:string = UserInterface.get_input_from_menu() 
     if response is "1" // Show All Recipes 
      PrintAllRecipes(db) 
     else if response is "2" // Search for a recipe 
      pass 
     else if response is "3" //Show a Recipe 
      pass 
     else if response is "4"//Delete a recipe 
      pass 
     else if response is "5" //Add a recipe 
      pass 
     else if response is "6" //Print a recipe 
      pass 
     else if response is "0" //Exit 
      print "Goodbye" 
      break 
     else 
      print "Unrecognized command. Try again." 

namespace UserInterface 
    def get_input_from_menu():string 
     show_menu() 
     return raw_input("Enter a selection -> ") 

    def raw_input (query:string = ""):string 
     stdout.printf ("%s", query) 
     return stdin.read_line() 

    def show_menu() 
     print """=================================================== 
       RECIPE DATABASE 
1 - Show All Recipes 
2 - Search for a recipe 
3 - Show a Recipe 
4 - Delete a recipe 
5 - Add a recipe 
6 - Print a recipe 
0 - Exit 
===================================================""" 

namespace PreparedStatements 
    def select_all(db:Database):Statement 
     statement:Statement 
     db.prepare_v2(""" 
select name, servings as serves, source from Recipes 
""", -1, out statement) 
     return statement 

def PrintAllRecipes (db:Database) 
    print "%-5s%-30s%-20s%-30s", "Item", "Name", "Serves", "Source" 
    print "--------------------------------------------------------------------------------------" 
    stmt:Statement = PreparedStatements.select_all(db) 
    cols:int = stmt.column_count() 
    var row = new dict of string, string 
    item:int = 1 
    while stmt.step() == ROW 
     for i:int = 0 to (cols - 1) 
      row[ stmt.column_name(i) ] = stmt.column_text(i) 
     stdout.printf("%-5s", item.to_string("%03i")) 
     stdout.printf("%-30s", row[ "name" ]) 
     stdout.printf("%-20s", row[ "serves" ]) 
     stdout.printf("%-30s\n", row[ "source" ]) 
     item++ 

几个指针

  • 通常你想避免分配nullnull是没有价值的。例如一个布尔值可以是truefalse,没有别的,但可以有一个变量没有值,使事情变得更加复杂。

    a:bool? = null 
    if a == null 
        print "I'm a boolean variable, but I am neither true nor false???" 
    

    如果您正在寻找调用与out参数的函数时指定值之前宣布在精灵的变量,例如,不指定任何东西。我已更改db:Database以显示此内容

  • Process.exit(-1)可能应该谨慎使用,而且仅适用于要发信号给调用命令行脚本的错误情况。我不认为用户选择退出程序是这样的错误条件,所以我已经将Process.exit(-1)更改为break
  • 功能的定义并不重要,无论是在init之前还是之后,我都倾向于他们经过这么被调用的第一个函数,即init,是在顶部,易于阅读
  • 类是一种数据类型,是的,它可以有功能,但通常你需要在类和定义的一些数据函数被写入以处理该数据。在A类函数通常被称为面向对象的编程类被定义为组的方法在一起的“方法”和在过去。这些方法没有数据采取行动,并定义为“静态”的方法。现代的做法是主要使用静态方法来创建更复杂的对象构造函数,查看“工厂”方法和创建设计模式。我们使用名称空间,而不是分组函数和其他语法。我在示例中使用了几个名称空间。通常一个命名空间被赋予它自己的一个或多个文件。如果您正在考虑将您的Genie项目拆分为更多源文件,请参阅https://wiki.gnome.org/Projects/Genie#A_Simple_Build_Script
  • 主键应该在数据库内部,不会呈现给用户,只有数据库管理员才会对此类事物感兴趣。因此,我将输出中的'item'更改为显示条目数
  • Genie和Vala绑定了SQLite C接口。如果您需要更多关于特定功能的详细信息,请看 C-language Interface Specification for SQLite