Listing the records on a SQL lite database with Ge

2020-04-23 07:50发布

问题:

Now that I have created the SQL database (1, 2), I want to do something with it. I have started a small function to handle the printing of the dataset contents, however I am unable to figure out how to:

  • adjust space between strings on a print command, in order to it become properly justified? One can do it in python using ljust(), but how to make something similar with Genie?
  • iterate across all entries on the dataset? As far as I understand there is no equivalent of a cursor in Genie (maybe I am wrong here, though).
  • connect to the created database? How to open it?
  • Extra point: how to create a stub with genie? I wanted to create empty functions and classes,to give an empty structure to the code, however there is no pass command in genie and it seems that the compiler do not accept empty if statements or functions.

This is the python code I am trying to mimic:

  def PrintAllRecipes(self):
    print '%s %s %s %s' % ('Item'.ljust(5),'Name'.ljust(30),'Serves'.ljust(20),'Source'.ljust(30))
    print '--------------------------------------------------------------------------------------'
    sql = 'SELECT * FROM Recipes'
    cntr = 0
    for x in cursor.execute(sql):
      cntr += 1
      print '%s %s %s %s' % (str(x[0]).rjust(5),x[1].ljust(30),x[2].ljust(20),x[3].ljust(30))
      print '--------------------------------------------------------------------------------------'
      self.totalcount = cntr

This is how far I have got:

[indent=4]

class Cookbook
    def PrintAllRecipes()
        print "%s %s %s %s" % ("Item".ljust(5),"Name".ljust(30),"Serves".ljust(20),"Source".ljust(30))
        print "--------------------------------------------------------------------------------------"
        var sql = "SELECT * FROM Recipes"
        var cntr = 0
            for x in cursor.execute(sql)
                cntr += 1
                print "%s %s %s %s" % (str(x[0]).rjust(5),x[1].ljust(30),x[2].ljust(20),x[3].ljust(30))
                print "--------------------------------------------------------------------------------------"
                self.totalcount = cntr


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

init
    //def Menu()
        //cbk = Cookbook()
    //var 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 -> ")

回答1:

Genie `print` Formatting

The Genie print command uses printf formatting - see https://en.wikipedia.org/wiki/Printf_format_string In your example the first line would be:

print "%-5s%-30s%-20s%-30s", "Item", "Name", "Serves", "Source"

The minus sign serves to left justify, then the number is the width.

Opening an SQLite Database

To open an SQLite database you use:

Database.open( "database_name.sqlite", out database )

Just as you do to create the database file. SQLite will create the database file if it does not exist. So open and create are the same command.

Genie `pass` Statement

A stub if statement:

if true
    pass

A stub function:

def stub_example()
    pass

The pass statement could also be extended to classes and namespaces, but this has not been implemented. So if you get to the stage of hacking on the Genie parser it could be a useful task. For now you have to add a dummy value/function to the class:

class placeholder
    dummy:string = ""

Avoid `null`, Use Sensible Defaults

Assigning null to an identifier means it does not have a value, the identifier is a null pointer. Trying to access a null pointer, such as in arithmetic expressions, will cause the program to crash. This lead C.A.R.Hoare to call his invention of null his "billion-dollar mistake" - see https://en.wikipedia.org/wiki/Null_pointer#History for the quote. C programmers tend to use null a lot so Genie maintains null for compatibility with C interfaces. It is better, however, to use a sensible default value. For your raw_input function if no prompt is passed then an empty string is fine or a default prompt such "> ". This also avoids your null check, which is another disadvantage of using null. You have to constantly check an identifier is not null. stdin.readline also waits until a string is entered. Even if it is an empty string when the user just presses enter, so it never returns null. Your function could be re-written as:

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

Getting the Results of Select Query

Valadoc has examples for using either exec() or a prepared statement. Although they are in Vala.

For exec() you pass in a callback function that gets called for each row in the result. The callback function will be passed the number of columns in the result, an array of values as text and an array of column names. See http://valadoc.org/#!api=sqlite3/Sqlite.Database.exec

For a prepared statement the step() function returns Sqlite.ROWS until there are no more rows in the result. So you loop over that and read the columns from the prepared statement. See http://valadoc.org/#!api=sqlite3/Sqlite.Statement

P.S. For your menu you could have used a verbatim string