2015-10-17 90 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