Change expr/stmt in examples to untyped (#6734)

This commit is contained in:
Lynn C. Rees 2017-11-15 13:58:11 -07:00 • committed by Andreas Rumpf
commit ac5dff2e04
16 changed files with 56 additions and 119 deletions

View file

@ -4,9 +4,8 @@
import db_sqlite, parseutils, strutils, times
type
TTodo* = object
Todo* = object
## A todo object holding the information serialized to the database.
id: int64 ## Unique identifier of the object in the
## database, use the getId() accessor to read it.
@ -17,7 +16,7 @@ type
## outside of this module, use the
## getModificationDate accessor.
TPagedParams* = object
PagedParams* = object
## Contains parameters for a query, initialize default values with
## initDefaults().
pageSize*: int64 ## Lines per returned query page, -1 for
@ -27,11 +26,10 @@ type
showUnchecked*: bool ## Get unchecked objects.
showChecked*: bool ## Get checked objects.
# - General procs
#
proc initDefaults*(params: var TPagedParams) =
## Sets sane defaults for a TPagedParams object.
proc initDefaults*(params: var PagedParams) =
## Sets sane defaults for a PagedParams object.
##
## Note that you should always provide a non zero pageSize, either a specific
## positive value or negative for unbounded query results.
@ -41,7 +39,6 @@ proc initDefaults*(params: var TPagedParams) =
params.showUnchecked = true
params.showChecked = false
proc openDatabase*(path: string): DbConn =
## Creates or opens the sqlite3 database.
##
@ -56,16 +53,14 @@ proc openDatabase*(path: string): DbConn =
desc TEXT NOT NULL,
modification_date INTEGER NOT NULL,
CONSTRAINT Todos UNIQUE (id))"""
db_sqlite.exec(conn, query)
result = conn
# - Procs related to Todo objects
# - Procs related to TTodo objects
#
proc initFromDB(id: int64; text: string; priority: int, isDone: bool;
modificationDate: Time): TTodo =
## Returns an initialized TTodo object created from database parameters.
modificationDate: Time): Todo =
## Returns an initialized Todo object created from database parameters.
##
## The proc assumes all values are right. Note this proc is NOT exported.
assert(id >= 0, "Identity identifiers should not be negative")
@ -75,29 +70,25 @@ proc initFromDB(id: int64; text: string; priority: int, isDone: bool;
result.isDone = isDone
result.modificationDate = modificationDate
proc getId*(todo: TTodo): int64 =
proc getId*(todo: Todo): int64 =
## Accessor returning the value of the private id property.
return todo.id
proc getModificationDate*(todo: TTodo): Time =
## Returns the last modification date of a TTodo entry.
proc getModificationDate*(todo: Todo): Time =
## Returns the last modification date of a Todo entry.
return todo.modificationDate
proc update*(todo: var TTodo; conn: DbConn): bool =
proc update*(todo: var Todo; conn: DbConn): bool =
## Checks the database for the object and refreshes its variables.
##
## Use this method if you (or another entity) have modified the database and
## want to update the object you have with whatever the database has stored.
## Returns true if the update succeeded, or false if the object was not found
## in the database any more, in which case you should probably get rid of the
## TTodo object.
## Todo object.
assert(todo.id >= 0, "The identifier of the todo entry can't be negative")
let query = sql"""SELECT desc, priority, is_done, modification_date
FROM Todos WHERE id = ?"""
try:
let rows = conn.getAllRows(query, $todo.id)
if len(rows) < 1:
@ -111,8 +102,7 @@ proc update*(todo: var TTodo; conn: DbConn): bool =
except:
echo("Something went wrong selecting for id " & $todo.id)
proc save*(todo: var TTodo; conn: DbConn): bool =
proc save*(todo: var Todo; conn: DbConn): bool =
## Saves the current state of text, priority and isDone to the database.
##
## Returns true if the database object was updated (in which case the
@ -127,15 +117,13 @@ proc save*(todo: var TTodo; conn: DbConn): bool =
WHERE id = ?"""
rowsUpdated = conn.execAffectedRows(query, $todo.text,
$todo.priority, $todo.isDone, $int(currentDate), $todo.id)
if 1 == rowsUpdated:
todo.modificationDate = currentDate
result = true
# - Procs dealing directly with the database
#
proc addTodo*(conn: DbConn; priority: int; text: string): TTodo =
proc addTodo*(conn: DbConn; priority: int; text: string): Todo =
## Inserts a new todo into the database.
##
## Returns the generated todo object. If there is an error EDb will be raised.
@ -145,10 +133,8 @@ proc addTodo*(conn: DbConn; priority: int; text: string): TTodo =
(priority, is_done, desc, modification_date)
VALUES (?, 'false', ?, ?)"""
todoId = conn.insertId(query, priority, text, $int(currentDate))
result = initFromDB(todoId, text, priority, false, currentDate)
proc deleteTodo*(conn: DbConn; todoId: int64): int64 {.discardable.} =
## Deletes the specified todo identifier.
##
@ -156,7 +142,6 @@ proc deleteTodo*(conn: DbConn; todoId: int64): int64 {.discardable.} =
let query = sql"""DELETE FROM Todos WHERE id = ?"""
result = conn.execAffectedRows(query, $todoId)
proc getNumEntries*(conn: DbConn): int =
## Returns the number of entries in the Todos table.
##
@ -170,38 +155,30 @@ proc getNumEntries*(conn: DbConn): int =
echo("Something went wrong retrieving number of Todos entries")
result = -1
proc getPagedTodos*(conn: DbConn; params: TPagedParams;
page = 0'i64): seq[TTodo] =
proc getPagedTodos*(conn: DbConn; params: PagedParams; page = 0'i64): seq[Todo] =
## Returns the todo entries for a specific page.
##
## Pages are calculated based on the params.pageSize parameter, which can be
## set to a negative value to specify no limit at all. The query will be
## affected by the TPagedParams, which should have sane values (call
## affected by the PagedParams, which should have sane values (call
## initDefaults).
assert(page >= 0, "You should request a page zero or bigger than zero")
result = @[]
# Well, if you don't want to see anything, there's no point in asking the db.
if not params.showUnchecked and not params.showChecked: return
let
order_by = [
if params.priorityAscending: "ASC" else: "DESC",
if params.dateAscending: "ASC" else: "DESC"]
query = sql("""SELECT id, desc, priority, is_done, modification_date
FROM Todos
WHERE is_done = ? OR is_done = ?
ORDER BY priority $1, modification_date $2, id DESC
LIMIT ? * ?,?""" % order_by)
args = @[$params.showChecked, $(not params.showUnchecked),
$params.pageSize, $page, $params.pageSize]
#echo("Query " & string(query))
#echo("args: " & args.join(", "))
var newId: BiggestInt
for row in conn.fastRows(query, args):
let numChars = row[0].parseBiggestInt(newId)
@ -209,10 +186,9 @@ proc getPagedTodos*(conn: DbConn; params: TPagedParams;
result.add(initFromDB(int64(newId), row[1], row[2].parseInt,
row[3].parseBool, Time(row[4].parseInt)))
proc getTodo*(conn: DbConn; todoId: int64): ref TTodo =
## Returns a reference to a TTodo or nil if the todo could not be found.
var tempTodo: TTodo
proc getTodo*(conn: DbConn; todoId: int64): ref Todo =
## Returns a reference to a Todo or nil if the todo could not be found.
var tempTodo: Todo
tempTodo.id = todoId
if tempTodo.update(conn):
new(result)

View file

@ -2,8 +2,7 @@
import backend, db_sqlite, strutils, times
proc showPagedResults(conn: DbConn; params: TPagedParams) =
proc showPagedResults(conn: DbConn; params: PagedParams) =
## Shows the contents of the database in pages of specified size.
##
## Hmm... I guess this is more of a debug proc which should be moved outside,
@ -11,7 +10,6 @@ proc showPagedResults(conn: DbConn; params: TPagedParams) =
var
page = 0'i64
rows = conn.getPagedTodos(params)
while rows.len > 0:
echo("page " & $page)
for row in rows:
@ -25,7 +23,6 @@ proc showPagedResults(conn: DbConn; params: TPagedParams) =
else:
break
proc dumTest() =
let conn = openDatabase("todo.sqlite3")
try:
@ -35,10 +32,8 @@ proc dumTest() =
# Fill some dummy rows if there are not many entries yet.
discard conn.addTodo(3, "Filler1")
discard conn.addTodo(4, "Filler2")
var todo = conn.addTodo(2, "Testing")
echo("New todo added with id " & $todo.getId)
# Try changing it and updating the database.
var clonedTodo = conn.getTodo(todo.getId)[]
assert(clonedTodo.text == todo.text, "Should be equal")
@ -49,13 +44,11 @@ proc dumTest() =
echo("Updated priority $1, done $2" % [$todo.priority, $todo.isDone])
else:
assert(false, "Uh oh, I wasn't expecting that!")
# Verify our cloned copy is different but can be updated.
assert(clonedTodo.text != todo.text, "Should be different")
discard clonedTodo.update(conn)
assert(clonedTodo.text == todo.text, "Should be equal")
var params: TPagedParams
var params: PagedParams
params.initDefaults
conn.showPagedResults(params)
conn.deleteTodo(todo.getId)
@ -66,7 +59,6 @@ proc dumTest() =
echo("Later priority $1, done $2" % [$todo.priority, $todo.isDone])
else:
echo("Can't update object $1 from db!" % $todo.getId)
# Try to list content in a different way.
params.pageSize = 5
params.priorityAscending = true
@ -77,7 +69,6 @@ proc dumTest() =
conn.close
echo("Database closed")
# Code that will be run only on the commandline.
when isMainModule:
dumTest()