2015-10-17 2 views
0

У меня есть created the database in SQL lite and improved the little program to handle it (список, добавить, удалить записи). На этом этапе я пытаюсь перечислить содержимое из базы данных с помощью подготовленной функции step() оператора. Однако я не могу перебирать строки и столбцы в базе данных.Печать результатов запроса select с помощью 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 */ 

Дополнительные вопросы:

  • ли должен прийти определения функций до или после инициализации? Я заметил, что их не вызывают, если я оставлю их после init. Но, оставив 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++ 

Несколько указателей

  • Как правило, вы хотите, чтобы избежать назначения null. null - это не значение. Например, логическое значение может быть либо true, либо false, и ничего больше, но переменная, которая не может иметь значения, усложняет ситуацию.

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

    Если вы хотите, чтобы объявить переменную в Genie перед присвоением значения, например, при вызове функции с параметром out, ничего не назначить. Я изменил db:Database, чтобы показать это

  • Process.exit(-1) следует, вероятно, использовать экономно и действительно только для условий ошибок, которые вы хотите передать сценарию командной строки вызова. Я не думаю, что пользователь выбрал выход из программы, это условие ошибки, поэтому я изменил Process.exit(-1) на break за это
  • Определение функций не имеет значения, до или после init, я предпочитаю их после того, как первая вызванная функция, то есть init, находится наверху и легко читается
  • Класс является типом данных, и да, он может иметь функции, но обычно вам нужны некоторые данные, определенные в классе и функция записывается для выполнения этих данных. Функция в классе часто называется «методом», а в прошлом с объектно-ориентированными классами программирования были определены групповые методы вместе. У этих методов не было данных, которые могли бы действовать и определялись как «статические» методы.Современная практика заключается в основном использовании статических методов для создания более сложных конструкторов объектов, поиска «фабричных» методов и шаблонов разработки. Вместо того чтобы группировать функции и другой синтаксис, мы используем пространства имен. В примере я использовал пару пространств имен. Обычно пространству имен предоставляется собственный файл или файлы. Если вы думаете о разделении проекта Genie на более исходные файлы, посмотрите на https://wiki.gnome.org/Projects/Genie#A_Simple_Build_Script
  • Первичный ключ должен быть внутренним для базы данных и не будет представлен пользователю, только администратор базы данных будет интересоваться такими вещами , Поэтому я изменил «элемент» на выходе, чтобы подсчитать количество отображаемых записей.
  • Genie и Vala связывают интерфейс SQLite C. Если вам нужна дополнительная информация о конкретной функции, см. C-language Interface Specification for SQLite