diff --git a/nawak/app.nim b/nawak/app.nim new file mode 100644 index 00000000000..62a51e52362 --- /dev/null +++ b/nawak/app.nim @@ -0,0 +1,68 @@ +import strtabs, strutils, math, algorithm +import nawak_mongrel, jdump +import fortunes_tmpl +when defined(postgre_model): + import model_postgre + +get "/json": + var j: THello + j.message = "Hello, World!" + # jdump serialize the tuples of the model as json + return response(jdump(j), "application/json") + +get "/plaintext": + return response("Hello, World!", "text/plain") + +get "/db": + let w = getWorld(random(10_000)+1) + return response(jdump(w), "application/json") + +get "/fortunes": + var fortunes = getAllFortunes() + let new_fortune: TFortune = + (id: 0, + message: "Additional fortune added at request time.") + fortunes.add new_fortune + sort(fortunes, proc(x, y: TFortune): int = + return cmp(x.message, y.message)) + + return response(fortunes_tmpl(fortunes), "text/html; charset=utf-8") + + +proc limit_queries(query_params: PStringTable): int = + result = 1 + if query_params.hasKey("queries"): + try: + result = parseInt(query_params["queries"]) + except EInvalidValue: discard + # clamp the number of queries + if result < 1: result = 1 + elif result > 500: result = 500 + +get "/queries": + let queries = limit_queries(request.query) + + var world: seq[TWorld] + world.newSeq(queries) + for i in 0.. + Here's a 404 Page Not Found error for you.""") + +run(init=init_db, nb_threads=256) diff --git a/nawak/fortunes_tmpl.nim b/nawak/fortunes_tmpl.nim index 53991303821..c9b82c28b09 100644 --- a/nawak/fortunes_tmpl.nim +++ b/nawak/fortunes_tmpl.nim @@ -1,6 +1,6 @@ #! stdtmpl | standard #import lib/escape -#from nawak_app import TFortune +#import model #proc fortunes_tmpl*(fortunes: openArray[TFortune]): string = # result = "" diff --git a/nawak/model.nim b/nawak/model.nim new file mode 100644 index 00000000000..b1ef0807299 --- /dev/null +++ b/nawak/model.nim @@ -0,0 +1,3 @@ +type THello* = tuple[message: string] +type TWorld* = tuple[id: int, randomNumber: int] +type TFortune* = tuple[id: int, message: string] diff --git a/nawak/model_postgre.nim b/nawak/model_postgre.nim new file mode 100644 index 00000000000..1654fcba6ee --- /dev/null +++ b/nawak/model_postgre.nim @@ -0,0 +1,43 @@ +import strutils +# The following import belongs to the stdlib, but has been updated to support +# queries with parameters (that are safer to counter SQL injections) and +# prepared queries. +# It will be merged eventually. For now, I included it in the repository. +import lib/db_postgres_redone + +import model +export model + +const qworld = "SELECT id, randomNumber FROM World WHERE id = $1" +const qfortunes = "SELECT id, message FROM Fortune" +const qupdates = "UPDATE World SET randomNumber = $1 WHERE id = $2" + +var db {.threadvar.}: TDbConn +var qworld_prepared {.threadvar.}: TPreparedId +var qfortunes_prepared {.threadvar.}: TPreparedId +var qupdates_prepared {.threadvar.}: TPreparedId + +proc init_db*() {.procvar.} = + db = open("", "benchmarkdbuser", "benchmarkdbpass", + "host=localhost port=5432 dbname=hello_world") + # prepare queries + qworld_prepared = db.prepare("world", qworld, 1) + qfortunes_prepared = db.prepare("fortunes", qfortunes, 0) + qupdates_prepared = db.prepare("updates", qupdates, 2) + + +proc getWorld*(n: int): TWorld = + #let row = db.getRow(qworld, n) + ## Yes, prepared queries are faster than unprepared ones + let row = db.getPRow(qworld_prepared, n) + result.id = parseInt(row[0]) + result.randomNumber = parseInt(row[1]) + +proc updateWorld*(w: TWorld) = + db.Exec(qupdates_prepared, $w.randomNumber, $w.id) + +proc getAllFortunes*(): seq[TFortune] = + let rows = db.getAllPRows(qfortunes_prepared) + result.newSeq(rows.len) + for j, row in rows.pairs: + result[j] = (row[0].parseInt, row[1]) diff --git a/nawak/nawak_app.nim b/nawak/nawak_app.nim deleted file mode 100644 index c5778a83d69..00000000000 --- a/nawak/nawak_app.nim +++ /dev/null @@ -1,103 +0,0 @@ -import strtabs, strutils, math, algorithm -import nawak_mongrel, jdump - -# The following import belongs to the stdlib, but has been updated to support -# queries with parameters (that are safer to counter SQL injections) and -# prepared queries. -# It will be merged eventually. For now, I included it in the repository. -import lib/db_postgres_redone - -type THello = tuple[message: string] -type TWorld = tuple[id: int, randomNumber: int] -type TFortune* = tuple[id: int, message: string] - -proc unrowTWorld(x: TRow): TWorld = - result.id = parseInt(x[0]) - result.randomNumber = parseInt(x[1]) -proc unrowTFortune(x: TRow): TFortune = - return (x[0].parseInt, x[1]) - -import fortunes_tmpl # Needs TFortune to be defined first - -var db = open("", "benchmarkdbuser", "benchmarkdbpass", "host=localhost port=5432 dbname=hello_world") - -const qworld = "SELECT id, randomNumber FROM World WHERE id = $1" -const qfortunes = "SELECT id, message FROM Fortune" -const qupdates = "UPDATE World SET randomNumber = $1 WHERE id = $2" - -# prepare queries -let qworld_prepared = db.prepare("world", qworld, 1) -let qfortunes_prepared = db.prepare("fortunes", qfortunes, 0) -let qupdates_prepared = db.prepare("updates", qupdates, 2) - - -get "/json": - var j: THello - j.message = "Hello, World!" - # jdump serialize any tuple as json - return response(jdump(j), "application/json") - -get "/plaintext": - return response("Hello, World!", "text/plain") - - -get "/db": - let row = db.getPRow(qworld_prepared, random(10_000)+1) - var r = unrowTWorld(row) - return response(jdump(r), "application/json") - -#get "/db_unprepared": -# ## Yes, prepared queries are faster than unprepared ones -# var r = unrowTWorld( db.getRow(qworld, random(10_000) + 1) ) -# return response(jdump(r), "application/json") - -get "/queries": - var queries = 1 - if request.query.hasKey("queries"): - try: - queries = parseInt(request.query["queries"]) - except EInvalidValue: discard - if queries < 1: queries = 1 - elif queries > 500: queries = 500 - - var world: seq[TWorld] - world.newSeq(queries) - for i in 0.. 500: queries = 500 - - var world: seq[TWorld] - world.newSeq(queries) - for i in 0..