Last active
November 4, 2019 13:05
-
-
Save moigagoo/23d48dc277192b5b6559c3d8ab0f9190 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/changelog.md b/changelog.md | |
index 5dfd2f5..91cf0c9 100755 | |
--- a/changelog.md | |
+++ b/changelog.md | |
@@ -14,6 +14,7 @@ | |
- [+] Add `createTable` and `dropTable`. | |
- [+] SQLite: Add means to write migrations: `addColumn`, `dropUnusedColumns`, `renameColumnFrom`, and `renameTableFrom`. | |
- [+] PostgreSQL: Add means to writemigrations: `addColumn`, `dropColumns`, `dropUnusedColumns`, `renameColumnFrom`, and `renameTableFrom`. | |
+- [+] Add `getAll` template to get all records without limit or offset. | |
- [r] Rewrite table schema generation so that schemas are generated from typed nodes rather than untyped modes. | |
- [f] Fixed "unreachable statement" compile error for certain SQLite use cases. | |
diff --git a/src/norm/postgres.nim b/src/norm/postgres.nim | |
index ea19314..2c394b9 100755 | |
--- a/src/norm/postgres.nim | |
+++ b/src/norm/postgres.nim | |
@@ -252,32 +252,26 @@ template genWithDb(connection, user, password, database: string, dbTypeNames: op | |
result.setLen limit | |
result.getMany(limit, offset, cond, params) | |
- proc getAll(objs: var seq[object], cond = "TRUE", params: varargs[DbValue, dbValue]) {.used.} = | |
- ##[ Read all records from DB into an existing open array of objects. | |
- This is a dangerous operation as you don't control the amount of data received. | |
+ template getAll(T: typedesc, cond = "TRUE", params: varargs[DbValue, dbValue]): seq[T] {.used.} = | |
+ ##[ Read all records from DB into a sequence of objects, create the sequence on the fly. | |
Filter using ``cond`` condition. | |
+ | |
+ Warning! This is a dangerous operation since you don't control the amount of data received. Consider using ``getMany`` for more deterministic data retrieval. | |
]## | |
- let getAllQuery = genGetAllQuery(objs[0], cond) | |
+ let getAllQuery = genGetAllQuery(T, cond) | |
debug getAllQuery, " <- ", params.join(", ") | |
let rows = dbConn.getAllRows(getAllQuery, params) | |
- objs.setLen rows.len | |
+ var objs: seq[T] | |
+ objs.setLen len(rows) | |
rows.to(objs) | |
- proc getAll(T: typedesc, cond = "TRUE", params: varargs[DbValue, dbValue]): seq[T] {.used.} = | |
- ##[ Read all records from DB into a sequence of objects, create the sequence on the fly. | |
- This is a dangerous operation as you don't control the amount of data received. | |
- | |
- Filter using ``cond`` condition. | |
- ]## | |
- | |
- result.setLen 1 | |
- result.getAll(cond, params) | |
+ objs | |
template update(obj: object, force = false) {.used.} = | |
##[ Update DB record with object field values. | |
diff --git a/src/norm/postgres/sqlgen.nim b/src/norm/postgres/sqlgen.nim | |
index b988700..2366c89 100644 | |
--- a/src/norm/postgres/sqlgen.nim | |
+++ b/src/norm/postgres/sqlgen.nim | |
@@ -232,12 +232,10 @@ proc genGetManyQuery*(obj: object, condition: string, paramCount = 0): SqlQuery | |
$(paramCount+2) | |
] | |
-proc genGetAllQuery*(obj: object, condition: string): SqlQuery = | |
+template genGetAllQuery*(T: typedesc, condition: string): SqlQuery = | |
## Generate ``SELECT`` query to fetch all records for an object. | |
- sql "SELECT $# FROM $# WHERE $#" % [obj.getColumns(force=true).join(", "), | |
- type(obj).getTable(), condition] | |
- | |
+ sql "SELECT $# FROM $# WHERE $#" % [T.getColumns(force=true).join(", "), T.getTable(), condition] | |
proc genUpdateQuery*(obj: object, force: bool): SqlQuery = | |
## Generate ``UPDATE`` query for an object. | |
diff --git a/src/norm/sqlite.nim b/src/norm/sqlite.nim | |
index a48a3ea..fcfd633 100755 | |
--- a/src/norm/sqlite.nim | |
+++ b/src/norm/sqlite.nim | |
@@ -252,32 +252,26 @@ template genWithDb(connection, user, password, database: string, dbTypeNames: op | |
result.setLen limit | |
result.getMany(limit, offset, cond, params) | |
- proc getAll(objs: var seq[object], cond = "1", params: varargs[DbValue, dbValue]) {.used.} = | |
- ##[ Read all records from DB into an existing open array of objects. | |
- This is a dangerous operation as you don't control the amount of data received. | |
+ template getAll(T: typedesc, cond = "1", params: varargs[DbValue, dbValue]): seq[T] {.used.} = | |
+ ##[ Read all records from DB into a sequence of objects, create the sequence on the fly. | |
Filter using ``cond`` condition. | |
+ | |
+ Warning! This is a dangerous operation since you don't control the amount of data received. Consider using ``getMany`` for more deterministic data retrieval. | |
]## | |
- let getAllQuery = genGetAllQuery(objs[0], cond) | |
+ let getAllQuery = genGetAllQuery(T, cond) | |
debug getAllQuery, " <- ", params.join(", ") | |
let rows = dbConn.getAllRows(getAllQuery, params) | |
- objs.setLen rows.len | |
+ var objs: seq[T] | |
+ objs.setLen len(rows) | |
rows.to(objs) | |
- proc getAll(T: typedesc, cond = "1", params: varargs[DbValue, dbValue]): seq[T] {.used.} = | |
- ##[ Read all records from DB into a sequence of objects, create the sequence on the fly. | |
- This is a dangerous operation as you don't control the amount of data received. | |
- | |
- Filter using ``cond`` condition. | |
- ]## | |
- | |
- result.setLen 1 | |
- result.getAll(cond, params) | |
+ objs | |
template update(obj: object, force = false) {.used.} = | |
##[ Update DB record with object field values. | |
diff --git a/src/norm/sqlite/sqlgen.nim b/src/norm/sqlite/sqlgen.nim | |
index 8c0719d..e756ab8 100644 | |
--- a/src/norm/sqlite/sqlgen.nim | |
+++ b/src/norm/sqlite/sqlgen.nim | |
@@ -217,11 +217,10 @@ proc genGetManyQuery*(obj: object, condition: string): SqlQuery = | |
sql "SELECT $# FROM $# WHERE $# LIMIT ? OFFSET ?" % [obj.getColumns(force=true).join(", "), | |
type(obj).getTable(), condition] | |
-proc genGetAllQuery*(obj: object, condition: string): SqlQuery = | |
+template genGetAllQuery*(T: typedesc, condition: string): SqlQuery = | |
## Generate ``SELECT`` query to fetch all records for an object. | |
- sql "SELECT $# FROM $# WHERE $#" % [obj.getColumns(force=true).join(", "), | |
- type(obj).getTable(), condition] | |
+ sql "SELECT $# FROM $# WHERE $#" % [T.getColumns(force=true).join(", "), T.getTable(), condition] | |
proc genUpdateQuery*(obj: object, force: bool): SqlQuery = | |
## Generate ``UPDATE`` query for an object. | |
diff --git a/tests/tpostgres.nim b/tests/tpostgres.nim | |
index f921e21..5c6272f 100644 | |
--- a/tests/tpostgres.nim | |
+++ b/tests/tpostgres.nim | |
@@ -173,6 +173,18 @@ suite "Creating and dropping tables, CRUD": | |
expect KeyError: | |
let notExistingBook {.used.} = Book.getOne("title = $1", "Does not exist") | |
+ withDb: | |
+ let | |
+ allBooks = Book.getAll() | |
+ someBooks = Book.getAll(cond="title IN ($1, $2) ORDER BY title DESC", | |
+ params=[?"Book 1", ?"Book 5"]) | |
+ | |
+ check len(allBooks) == 9 | |
+ | |
+ check len(someBooks) == 2 | |
+ check someBooks[0].title == "Book 5" | |
+ check someBooks[1].authorEmail == "test-1@example.com" | |
+ | |
test "Update records": | |
withDb: | |
var | |
diff --git a/tests/tsqlite.nim b/tests/tsqlite.nim | |
index 19cac8b..ccfd92a 100644 | |
--- a/tests/tsqlite.nim | |
+++ b/tests/tsqlite.nim | |
@@ -191,6 +191,18 @@ suite "Creating and dropping tables, CRUD": | |
expect KeyError: | |
let notExistingBook {.used.} = Book.getOne("title=?", "Does not exist") | |
+ withDb: | |
+ let | |
+ allBooks = Book.getAll() | |
+ someBooks = Book.getAll(cond="title IN (?, ?) ORDER BY title DESC", | |
+ params=[?"Book 1", ?"Book 5"]) | |
+ | |
+ check len(allBooks) == 9 | |
+ | |
+ check len(someBooks) == 2 | |
+ check someBooks[0].title == "Book 5" | |
+ check someBooks[1].authorEmail == "test-1@example.com" | |
+ | |
test "Update records": | |
withDb: | |
var |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment