使用 Genie 打印 select 查询的结果
Printing the results from a select query with Genie
我有 (列出、添加、删除记录)。此时我正在尝试使用准备好的语句 step() 函数列出数据库中的内容。但是,我无法遍历数据库中的行和列。
我怀疑这是因为我没有正确处理这一行中的语句:
stmt:Sqlite.Statement = null
如果是这样,如何将语句从 main (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之前还是之后?我注意到如果我在 init 之后将它们全部保留,它们将不会被调用。但是在开始时留下 raw_input 错误就消失了。
出于教学原因,我试图在 class 中定义 PrintAllRecipes()。但我最终 "invisible" 进入了主例程。
非常感谢,
是的,您需要将准备好的语句分配给 stmt
,而不是 null
。例如:
// 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
前还是后易于阅读
- A class 是一种数据类型,是的,它可以具有函数,但通常您需要在 class 中定义一些数据,并编写函数来处理该数据。 class 中的函数通常称为 'method',过去在面向对象编程中,classes 被定义为将方法组合在一起。这些方法没有可操作的数据,被定义为 'static' 方法。现代的做法是主要使用静态方法来创建更复杂的对象构造函数,查找 'factory' 方法和创建设计模式。我们使用名称空间来代替对函数和其他语法进行分组。我在示例中使用了几个名称空间。通常一个命名空间被赋予它自己的一个或多个文件。如果您正在考虑将 Genie 项目拆分为更多源文件,请查看 https://wiki.gnome.org/Projects/Genie#A_Simple_Build_Script
- 主键应该是数据库内部的,不会呈现给用户,只有数据库管理员才会对这些东西感兴趣。所以我将输出中的 'item' 更改为显示条目数的计数
- Genie 和 Vala 绑定 SQLite C 接口。如果您需要有关特定功能的更多详细信息,请查看 C-language Interface Specification for SQLite
我有
我怀疑这是因为我没有正确处理这一行中的语句:
stmt:Sqlite.Statement = null
如果是这样,如何将语句从 main (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之前还是之后?我注意到如果我在 init 之后将它们全部保留,它们将不会被调用。但是在开始时留下 raw_input 错误就消失了。
出于教学原因,我试图在 class 中定义 PrintAllRecipes()。但我最终 "invisible" 进入了主例程。
非常感谢,
是的,您需要将准备好的语句分配给 stmt
,而不是 null
。例如:
// 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
前还是后易于阅读 - A class 是一种数据类型,是的,它可以具有函数,但通常您需要在 class 中定义一些数据,并编写函数来处理该数据。 class 中的函数通常称为 'method',过去在面向对象编程中,classes 被定义为将方法组合在一起。这些方法没有可操作的数据,被定义为 'static' 方法。现代的做法是主要使用静态方法来创建更复杂的对象构造函数,查找 'factory' 方法和创建设计模式。我们使用名称空间来代替对函数和其他语法进行分组。我在示例中使用了几个名称空间。通常一个命名空间被赋予它自己的一个或多个文件。如果您正在考虑将 Genie 项目拆分为更多源文件,请查看 https://wiki.gnome.org/Projects/Genie#A_Simple_Build_Script
- 主键应该是数据库内部的,不会呈现给用户,只有数据库管理员才会对这些东西感兴趣。所以我将输出中的 'item' 更改为显示条目数的计数
- Genie 和 Vala 绑定 SQLite C 接口。如果您需要有关特定功能的更多详细信息,请查看 C-language Interface Specification for SQLite