Add Ormin ORM support for BaraDB (Nim client)
CI / test (push) Has been cancelled
CI / verify (push) Has been cancelled
Clients CI / build-server (push) Has been cancelled
Clients CI / test-python (push) Has been cancelled
Clients CI / test-javascript (push) Has been cancelled
Clients CI / test-nim (push) Has been cancelled
Clients CI / test-rust (push) Has been cancelled
CI / test (push) Has been cancelled
CI / verify (push) Has been cancelled
Clients CI / build-server (push) Has been cancelled
Clients CI / test-python (push) Has been cancelled
Clients CI / test-javascript (push) Has been cancelled
Clients CI / test-nim (push) Has been cancelled
Clients CI / test-rust (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,822 @@
|
||||
import unittest, strformat, sequtils, algorithm, sugar, json, tables, random
|
||||
import os
|
||||
import ormin
|
||||
import ormin/db_utils
|
||||
when NimVersion < "1.2.0": import ./compat
|
||||
|
||||
|
||||
let testDir = currentSourcePath.parentDir()
|
||||
|
||||
when defined postgre:
|
||||
when defined(macosx):
|
||||
{.passL: "-Wl,-rpath,/opt/homebrew/lib/postgresql@14".}
|
||||
from db_connector/db_postgres import exec, getValue
|
||||
|
||||
const backend = DbBackend.postgre
|
||||
importModel(backend, "forum_model_postgres")
|
||||
const sqlFileName = "forum_model_postgres.sql"
|
||||
let db {.global.} = open("localhost", "test", "test", "test_ormin")
|
||||
else:
|
||||
from db_connector/db_sqlite import exec, getValue
|
||||
|
||||
const backend = DbBackend.sqlite
|
||||
importModel(backend, "forum_model_sqlite")
|
||||
const sqlFileName = "forum_model_sqlite.sql"
|
||||
var memoryPath = testDir & "/" & ":memory:"
|
||||
let db {.global.} = open(memoryPath, "", "", "")
|
||||
|
||||
var sqlFilePath = Path(testDir & "/" & sqlFileName)
|
||||
|
||||
type
|
||||
Person = tuple[id: int,
|
||||
name: string,
|
||||
password: string,
|
||||
email: string,
|
||||
salt: string,
|
||||
status: string]
|
||||
Thread = tuple[id: int,
|
||||
name: string,
|
||||
views: int]
|
||||
Post = tuple[id: int,
|
||||
author: int,
|
||||
ip: string,
|
||||
header: string,
|
||||
content: string,
|
||||
thread: int]
|
||||
Antibot = tuple[id: int,
|
||||
ip: string,
|
||||
answer: string]
|
||||
|
||||
const
|
||||
personcount = 5
|
||||
threadcount = 5
|
||||
postcount = 10
|
||||
antibotcount = 5
|
||||
var
|
||||
persondata: seq[Person]
|
||||
threaddata: seq[Thread]
|
||||
postdata: seq[Post]
|
||||
antibotdata: seq[Antibot]
|
||||
|
||||
|
||||
suite &"Test ormin features of {backend}":
|
||||
discard
|
||||
|
||||
suite "query":
|
||||
db.dropTable(sqlFilePath)
|
||||
db.createTable(sqlFilePath)
|
||||
|
||||
static:
|
||||
doAssert compiles(block:
|
||||
discard query:
|
||||
select post(author)
|
||||
crossjoin person(name)
|
||||
)
|
||||
doAssert compiles(block:
|
||||
discard query:
|
||||
select post(author)
|
||||
outerjoin person(name) on author == id
|
||||
)
|
||||
doAssert compiles(block:
|
||||
discard query:
|
||||
select post(author)
|
||||
leftjoin person(name) on author == id
|
||||
)
|
||||
doAssert compiles(block:
|
||||
discard query:
|
||||
select post(author)
|
||||
leftouterjoin person(name) on author == id
|
||||
)
|
||||
doAssert compiles(block:
|
||||
discard query:
|
||||
select post(author)
|
||||
rightjoin person(name) on author == id
|
||||
)
|
||||
doAssert compiles(block:
|
||||
discard query:
|
||||
select post(author)
|
||||
rightouterjoin person(name) on author == id
|
||||
)
|
||||
doAssert compiles(block:
|
||||
discard query:
|
||||
select post(author)
|
||||
fulljoin person(name) on author == id
|
||||
)
|
||||
doAssert compiles(block:
|
||||
discard query:
|
||||
select post(author)
|
||||
fullouterjoin person(name) on author == id
|
||||
)
|
||||
|
||||
# prepare data to insert
|
||||
for i in 1..personcount:
|
||||
persondata.add((id: i,
|
||||
name: fmt"john{i}",
|
||||
password: fmt"pass{i}",
|
||||
email: fmt"john{i}@mail.com",
|
||||
salt: fmt"abcd{i}",
|
||||
status: fmt"ok{i}"))
|
||||
|
||||
for i in 1..threadcount:
|
||||
threaddata.add((id: i,
|
||||
name: fmt"thread{i}",
|
||||
views: i))
|
||||
|
||||
for i in 1..postcount:
|
||||
postdata.add((id: i,
|
||||
author: sample({1..personcount}),
|
||||
ip: "",
|
||||
header: fmt"title{i}",
|
||||
content: fmt"content{i}",
|
||||
thread: sample({1..threadcount})))
|
||||
|
||||
for i in 1..antibotcount:
|
||||
antibotdata.add((id: i,
|
||||
ip: "",
|
||||
answer: fmt"answer{i}"))
|
||||
|
||||
# insert data into database
|
||||
let
|
||||
insertperson = sql"insert into person (id, name, password, email, salt, status) values (?, ?, ?, ?, ?, ?)"
|
||||
insertthread = sql"insert into thread (id, name, views) values (?, ?, ?)"
|
||||
insertpost = sql"insert into post (id, author, ip, header, content, thread) values (?, ?, ?, ?, ?, ?)"
|
||||
insertantibot = sql"insert into antibot (id, ip, answer) values (?, ?, ?)"
|
||||
|
||||
for p in persondata:
|
||||
db.exec(insertperson, p.id, p.name, p.password, p.email, p.salt, p.status)
|
||||
|
||||
for t in threaddata:
|
||||
db.exec(insertthread, t.id, t.name, t.views)
|
||||
|
||||
for p in postdata:
|
||||
db.exec(insertpost, p.id, p.author, p.ip, p.header, p.content, p.thread)
|
||||
|
||||
for a in antibotdata:
|
||||
db.exec(insertantibot, a.id, a.ip, a.answer)
|
||||
|
||||
# check data in database
|
||||
let personexpected = db.getValue(sql"select count(*) from person")
|
||||
assert personexpected == $personcount
|
||||
|
||||
let threadexpected = db.getValue(sql"select count(*) from thread")
|
||||
assert threadexpected == $threadcount
|
||||
|
||||
let postexpected = db.getValue(sql"select count(*) from post")
|
||||
assert postexpected == $postcount
|
||||
|
||||
let antibotexpected = db.getValue(sql"select count(*) from antibot")
|
||||
assert antibotexpected == $antibotcount
|
||||
|
||||
test "table":
|
||||
let res = query:
|
||||
select person(id, name, password, email, salt, status)
|
||||
check res == persondata
|
||||
|
||||
test "all_column":
|
||||
let res = query:
|
||||
select person(_)
|
||||
check res.mapIt((it.id, it.name, it.password, it.email, it.salt, it.status)) == persondata
|
||||
|
||||
test "column_alias":
|
||||
let res = query:
|
||||
select person(id as personid, name as personname)
|
||||
check res == persondata.mapIt((personid: it.id, personname: it.name))
|
||||
|
||||
test "arithmetic":
|
||||
let res = query:
|
||||
select person(id * 4 / 2 + 2 - 1 as id)
|
||||
check res == persondata.mapIt(int(it.id * 4 / 2 + 2 - 1))
|
||||
|
||||
test "comparison":
|
||||
let id = 1
|
||||
let res = query:
|
||||
select person(id, name, password, email, salt, status)
|
||||
where id == ?id
|
||||
check res == [persondata[id - 1]]
|
||||
|
||||
test "comparison_ne":
|
||||
let id = 1
|
||||
let res = query:
|
||||
select person(id, name, password, email, salt, status)
|
||||
where id != ?id
|
||||
check res == persondata.filterIt(it.id != id)
|
||||
|
||||
test "comparison_ge":
|
||||
let id = 3
|
||||
let res = query:
|
||||
select person(id, name, password, email, salt, status)
|
||||
where id >= ?id
|
||||
check res == persondata.filterIt(it.id >= id)
|
||||
|
||||
test "comparison_le":
|
||||
let id = 3
|
||||
let res = query:
|
||||
select person(id, name, password, email, salt, status)
|
||||
where id <= ?id
|
||||
check res == persondata.filterIt(it.id <= id)
|
||||
|
||||
test "comparison_gt":
|
||||
let id = 3
|
||||
let res = query:
|
||||
select person(id, name, password, email, salt, status)
|
||||
where id > ?id
|
||||
check res == persondata.filterIt(it.id > id)
|
||||
|
||||
test "comparison_lt":
|
||||
let id = 3
|
||||
let res = query:
|
||||
select person(id, name, password, email, salt, status)
|
||||
where id < ?id
|
||||
check res == persondata.filterIt(it.id < id)
|
||||
|
||||
test "logical_not":
|
||||
let id = 3
|
||||
let res = query:
|
||||
select person(id, name, password, email, salt, status)
|
||||
where not (id > ?id)
|
||||
check res == persondata.filterIt(it.id <= id)
|
||||
|
||||
test "logical_and":
|
||||
let
|
||||
id1 = 2
|
||||
id2 = 4
|
||||
let res = query:
|
||||
select person(id, name, password, email, salt, status)
|
||||
where id >= ?id1 and id <= ?id2
|
||||
check res == persondata.filterIt(it.id >= id1 and it.id <= id2)
|
||||
|
||||
test "logical_or":
|
||||
let
|
||||
id1 = 2
|
||||
id2 = 4
|
||||
let res = query:
|
||||
select person(id, name, password, email, salt, status)
|
||||
where id == ?id1 or id == ?id2
|
||||
check res == persondata.filterIt(it.id == id1 or it.id == id2)
|
||||
|
||||
test "logical_complex":
|
||||
let
|
||||
id1 = 2
|
||||
id2 = 3
|
||||
id3 = 4
|
||||
let res = query:
|
||||
select person(id, name, password, email, salt, status)
|
||||
where id > ?id2 and (id == ?id1 or id == ?id3)
|
||||
check res == persondata.filterIt(it.id == id3)
|
||||
|
||||
test "predicate_in":
|
||||
let
|
||||
id1 = 2
|
||||
id2 = 4
|
||||
let res = query:
|
||||
select person(id, name, password, email, salt, status)
|
||||
where id in ?id1 .. ?id2
|
||||
check res == persondata.filterIt(it.id in id1..id2)
|
||||
|
||||
test "predicate_not_in":
|
||||
let
|
||||
id1 = 2
|
||||
id2 = 4
|
||||
let res = query:
|
||||
select person(id, name, password, email, salt, status)
|
||||
where id notin ?id1 .. ?id2
|
||||
check res == persondata.filterIt(it.id < id1 or it.id > id2)
|
||||
|
||||
test "predicate_like":
|
||||
let pattern = "john1%"
|
||||
let res = query:
|
||||
select person(id, name)
|
||||
where name `like` ?pattern
|
||||
check res == persondata.filterIt(it.name.startsWith("john1")).mapIt((it.id, it.name))
|
||||
|
||||
test "predicate_ilike":
|
||||
let pattern = "JOHN1%"
|
||||
let res = query:
|
||||
select person(id, name)
|
||||
where name `ilike` ?pattern
|
||||
check res == persondata.filterIt(it.name.startsWith("john1")).mapIt((it.id, it.name))
|
||||
|
||||
test "predicate_not_like":
|
||||
let pattern = "john1%"
|
||||
let res = query:
|
||||
select person(id, name)
|
||||
where not (name `like` ?pattern)
|
||||
check res == persondata.filterIt(not it.name.startsWith("john1")).mapIt((it.id, it.name))
|
||||
|
||||
test "distinct":
|
||||
var res = query:
|
||||
select `distinct` post(author)
|
||||
res.sort()
|
||||
let expected = postdata.mapIt(it.author).deduplicate().sortedByIt(it)
|
||||
check res == expected
|
||||
|
||||
test "count_distinct":
|
||||
let res = query:
|
||||
select post(count(distinct author))
|
||||
check res == @[postdata.mapIt(it.author).deduplicate().len]
|
||||
|
||||
test "window_row_number":
|
||||
let res = query:
|
||||
select post(author, id, over(row_number(), partitionby(author), orderby(id)) as rn)
|
||||
orderby author, id
|
||||
var expected: seq[(int, int, int)] = @[]
|
||||
var counters = initCountTable[int]()
|
||||
for p in postdata.sortedByIt((it.author, it.id)):
|
||||
counters.inc(p.author)
|
||||
expected.add((p.author, p.id, counters[p.author]))
|
||||
check res == expected
|
||||
|
||||
test "window_running_sum":
|
||||
let res = query:
|
||||
select post(author, id, over(sum(id), partitionby(author), orderby(id)) as running)
|
||||
orderby author, id
|
||||
var expected: seq[(int, int, int)] = @[]
|
||||
var sums = initTable[int, int]()
|
||||
for p in postdata.sortedByIt((it.author, it.id)):
|
||||
sums[p.author] = sums.getOrDefault(p.author) + p.id
|
||||
expected.add((p.author, p.id, sums[p.author]))
|
||||
check res == expected
|
||||
|
||||
test "limit":
|
||||
let id = 1
|
||||
let res = query:
|
||||
select person(id, name, password, email, salt, status)
|
||||
limit 1
|
||||
static:
|
||||
echo "LIMIT TEST: ", typeof(res)
|
||||
check res == persondata[id - 1]
|
||||
|
||||
test "offset":
|
||||
let res = query:
|
||||
select person(id, name)
|
||||
limit 2
|
||||
offset 2
|
||||
check res == persondata[2..3].mapIt((it.id, it.name))
|
||||
|
||||
test "match_assignment":
|
||||
let id = 1
|
||||
let (name, password, email, salt, status) = query:
|
||||
select person(name, password, email, salt, status)
|
||||
where id == ?id
|
||||
limit 1
|
||||
check:
|
||||
name == persondata[id - 1].name
|
||||
password == persondata[id - 1].password
|
||||
email == persondata[id - 1].email
|
||||
salt == persondata[id - 1].salt
|
||||
status == persondata[id - 1].status
|
||||
|
||||
test "groupby":
|
||||
let res = query:
|
||||
select post(author, count(id))
|
||||
groupby author
|
||||
let counttable = postdata.mapIt(it.author).toCountTable()
|
||||
for (author, c) in res:
|
||||
check counttable[author] == c
|
||||
|
||||
test "groupby_aggregate":
|
||||
let author = 3
|
||||
let res = query:
|
||||
select post(count(id))
|
||||
where author == ?author
|
||||
groupby author
|
||||
let c = postdata.mapIt(it.author).toCountTable()[author]
|
||||
check res == [c]
|
||||
|
||||
test "orderby":
|
||||
let res = query:
|
||||
select person(id, name)
|
||||
orderby id
|
||||
check res == persondata.mapIt((it.id, it.name)).sortedByIt(it[0])
|
||||
|
||||
test "orderby_asc":
|
||||
let res = query:
|
||||
select person(id, name)
|
||||
orderby asc(id)
|
||||
check res == persondata.mapIt((it.id, it.name)).sortedByIt(it[0])
|
||||
|
||||
test "orderby_desc":
|
||||
let res = query:
|
||||
select person(id, name)
|
||||
orderby desc(id)
|
||||
let expected = persondata.mapIt((it.id, it.name))
|
||||
.sorted((x, y) => system.cmp(x[0], y[0]), Descending)
|
||||
check res == expected
|
||||
|
||||
test "orderby_key_select":
|
||||
let res = query:
|
||||
select person(id as personid, name)
|
||||
orderby personid
|
||||
check res == persondata.mapIt((it.id, it.name)).sortedByIt(it[0])
|
||||
|
||||
test "orderby_key_not_select":
|
||||
let res = query:
|
||||
select person(name)
|
||||
orderby id
|
||||
check res == persondata.sortedByIt(it.id).mapIt(it.name)
|
||||
|
||||
test "orderby_mulitple":
|
||||
# test fix #30 Incorrect handling of multiple sort keys in orderby
|
||||
let res = query:
|
||||
select post(author, id)
|
||||
orderby author, desc(id)
|
||||
check res == postdata.mapIt((it.author, it.id))
|
||||
.sorted((x, y) => system.cmp(x[1], y[1]), Descending)
|
||||
.sortedByIt(it[0])
|
||||
|
||||
test "having":
|
||||
let id = 4
|
||||
let res = query:
|
||||
select post(author, count(_) as count)
|
||||
groupby author
|
||||
having author == ?id
|
||||
let expected = collect(newSeq):
|
||||
for p in postdata.mapIt(it.author).toCountTable().pairs():
|
||||
if p[0] == id: p
|
||||
check res == expected
|
||||
|
||||
test "having_aggregate":
|
||||
let countvalue = 2
|
||||
let res = query:
|
||||
select post(author, count(id) as count)
|
||||
groupby author
|
||||
having count(id) >= ?countvalue
|
||||
let expected = collect(newSeq):
|
||||
for p in postdata.mapIt(it.author).toCountTable().pairs():
|
||||
if p[1] >= countvalue: p
|
||||
check res.sortedByIt(it[0]) == expected.sortedByIt(it[0])
|
||||
|
||||
test "having_complex":
|
||||
let
|
||||
authorid1 = 1
|
||||
authorid2 = 3
|
||||
countvalue = 2
|
||||
let res = query:
|
||||
select post(author, count(id) as count)
|
||||
groupby author
|
||||
having count(id) >= ?countvalue and (author == ?authorid1 or author == ?authorid2)
|
||||
let expected = collect(newSeq):
|
||||
for p in postdata.mapIt(it.author).toCountTable().pairs():
|
||||
if p[0] in [authorid1, authorid2] and p[1] >= countvalue: p
|
||||
check res == expected
|
||||
|
||||
test "subquery":
|
||||
let res = query:
|
||||
select post(id)
|
||||
where author in
|
||||
(select person(id))
|
||||
check res.sortedByIt(it) == postdata.mapIt(it.id)
|
||||
|
||||
test "subquery_nest2":
|
||||
let
|
||||
personid1 = 1
|
||||
personid2 = 2
|
||||
expectedpost = postdata.filterIt(it.author in [personid1, personid2])
|
||||
.mapIt(it.id)
|
||||
let res = query:
|
||||
select post(id)
|
||||
where author in
|
||||
(select person(id) where id == ?personid1 or id == ?personid2)
|
||||
check res.sortedByIt(it) == expectedpost.sortedByIt(it)
|
||||
|
||||
test "subquery_nest3":
|
||||
var res = query:
|
||||
select thread(id)
|
||||
where id in (select post(thread) where author in
|
||||
(select person(id) where id in {1, 2}))
|
||||
res.sort()
|
||||
check res == postdata.filterIt(it.author in [1, 2])
|
||||
.mapIt(it.thread)
|
||||
.sortedByIt(it)
|
||||
|
||||
test "subquery_having":
|
||||
# feature for having in subquery
|
||||
let id = 4
|
||||
let res = query:
|
||||
select person(id)
|
||||
where id in (
|
||||
select post(author) groupby author having author == ?id)
|
||||
check res == @[id]
|
||||
|
||||
test "exists":
|
||||
let authorid = postdata[0].author
|
||||
let res = query:
|
||||
select person(id)
|
||||
where exists(select post(id) where author == ?authorid)
|
||||
check res.sortedByIt(it) == persondata.mapIt(it.id)
|
||||
|
||||
test "not_exists":
|
||||
let missingAuthor = personcount + postcount
|
||||
let res = query:
|
||||
select person(id)
|
||||
where not exists(select post(id) where author == ?missingAuthor)
|
||||
check res.sortedByIt(it) == persondata.mapIt(it.id)
|
||||
|
||||
test "with_cte":
|
||||
let res = query:
|
||||
with recent(select post(id, author) where id <= 3)
|
||||
select recent(author)
|
||||
orderby id
|
||||
check res == postdata.filterIt(it.id <= 3).sortedByIt(it.id).mapIt(it.author)
|
||||
|
||||
test "with_cte_chain":
|
||||
let res = query:
|
||||
with recent(select post(id, author) where id <= 3)
|
||||
with authors(select recent(author))
|
||||
select authors(author)
|
||||
check res.sortedByIt(it) == postdata.filterIt(it.id <= 3).mapIt(it.author).sortedByIt(it)
|
||||
|
||||
test "with_cte_subquery":
|
||||
let res = query:
|
||||
with recent(select post(id, author) where id <= 3)
|
||||
select person(id)
|
||||
where id in (select recent(author))
|
||||
check res.sortedByIt(it) == postdata.filterIt(it.id <= 3).mapIt(it.author).deduplicate().sortedByIt(it)
|
||||
|
||||
test "union":
|
||||
var res = query:
|
||||
select person(id) where id <= 2
|
||||
union
|
||||
select person(id) where id >= 4
|
||||
res.sort()
|
||||
check res == @[1, 2, 4, 5]
|
||||
|
||||
res = query:
|
||||
union(
|
||||
select person(id) where id <= 2,
|
||||
select person(id) where id >= 4
|
||||
)
|
||||
res.sort()
|
||||
check res == @[1, 2, 4, 5]
|
||||
|
||||
test "intersect":
|
||||
var res = query:
|
||||
select person(id) where id <= 3
|
||||
intersect
|
||||
select person(id) where id >= 2
|
||||
res.sort()
|
||||
check res == @[2, 3]
|
||||
|
||||
res = query:
|
||||
intersect(
|
||||
select person(id) where id <= 3,
|
||||
select person(id) where id >= 2
|
||||
)
|
||||
res.sort()
|
||||
check res == @[2, 3]
|
||||
|
||||
test "except":
|
||||
var res = query:
|
||||
select person(id) where id <= 4
|
||||
`except`
|
||||
select person(id) where id in {2, 3}
|
||||
res.sort()
|
||||
check res == @[1, 4]
|
||||
|
||||
res = query:
|
||||
`except`(
|
||||
select person(id) where id <= 4,
|
||||
select person(id) where id in {2, 3}
|
||||
)
|
||||
res.sort()
|
||||
check res == @[1, 4]
|
||||
|
||||
test "complex_query_subquery_having":
|
||||
let
|
||||
id1 = 2
|
||||
id2 = 3
|
||||
let res = query:
|
||||
select thread(count(_))
|
||||
where id in (
|
||||
select post(thread) where (author == ?id1 or author == ?id2) and id in (
|
||||
select post(min(id)) groupby thread having min(id) > 3))
|
||||
limit 1
|
||||
|
||||
let threadinpost = postdata.mapIt(it.thread).deduplicate().sortedByIt(it)
|
||||
var postminids: seq[int]
|
||||
for id in threadinpost:
|
||||
let group = collect(newSeq):
|
||||
for p in postdata:
|
||||
if p.thread == id: p.id
|
||||
postminids.add(group.min())
|
||||
let threadids = postdata.filterIt(it.author in [id1, id2] and
|
||||
it.id in postminids.filterIt(it > 3))
|
||||
.mapIt(it.thread)
|
||||
check res == threadids.len()
|
||||
|
||||
test "auto_join":
|
||||
let postid = 1
|
||||
let res = query:
|
||||
select post(author)
|
||||
join person(name)
|
||||
where id == ?postid
|
||||
let (author, name) = res[0]
|
||||
check name == persondata[author - 1].name
|
||||
|
||||
test "join_on":
|
||||
# test fix #29 Cannot handle join on condition correctly
|
||||
let postid = 1
|
||||
let res = query:
|
||||
select post(author)
|
||||
join person(name) on author == id
|
||||
where id == ?postid
|
||||
let (author, name) = res[0]
|
||||
check name == persondata[author - 1].name
|
||||
|
||||
test "leftjoin_on":
|
||||
let postid = 1
|
||||
let res = query:
|
||||
select post(author)
|
||||
leftjoin person(name) on author == id
|
||||
where id == ?postid
|
||||
let (author, name) = res[0]
|
||||
check name == persondata[author - 1].name
|
||||
|
||||
test "leftouterjoin_on":
|
||||
let postid = 1
|
||||
let res = query:
|
||||
select post(author)
|
||||
leftouterjoin person(name) on author == id
|
||||
where id == ?postid
|
||||
let (author, name) = res[0]
|
||||
check name == persondata[author - 1].name
|
||||
|
||||
test "casewhen":
|
||||
# need more test, only number
|
||||
# has problem with string or expression in condition
|
||||
let res = query:
|
||||
select person(name, (if id == 1: 10 elif id == 2: 20 else: 30) as pid)
|
||||
check res == persondata.mapIt((
|
||||
name: it.name,
|
||||
pid: if it.id == 1: 10 elif it.id == 2: 20 else: 30))
|
||||
|
||||
test "produce_json":
|
||||
# test fix #27 Error: type mismatch: got <typeof(nil)>
|
||||
let threadjson = query:
|
||||
select thread(id, name)
|
||||
produce json
|
||||
let expected = threaddata.map do (it: tuple) -> JsonNode:
|
||||
result = newJObject()
|
||||
result["id"] = %it.id
|
||||
result["name"] = %it.name
|
||||
check threadjson == %expected
|
||||
|
||||
test "produce_nim":
|
||||
let threadnim = query:
|
||||
select thread(id, name)
|
||||
produce nim
|
||||
check threadnim == threaddata.mapIt((it.id, it.name))
|
||||
|
||||
test "tryquery":
|
||||
# unknow use, only not raise dbError?
|
||||
let res = tryQuery:
|
||||
select thread(id)
|
||||
check res == threaddata.mapIt(it.id)
|
||||
|
||||
test "createproc":
|
||||
createProc getAllThreadIds:
|
||||
select thread(id)
|
||||
check db.getAllThreadIds() == threaddata.mapIt(it.id)
|
||||
|
||||
test "createiter":
|
||||
createIter allThreadIdsIter:
|
||||
select thread(id)
|
||||
let res = collect(newSeq):
|
||||
for id in db.allThreadIdsIter:
|
||||
id
|
||||
check res.sortedByIt(it) == threaddata.mapIt(it.id)
|
||||
|
||||
test "update_concat_op":
|
||||
let
|
||||
id = 3
|
||||
name = persondata[id - 1].name
|
||||
appendstr = "updated"
|
||||
nameupdated = name & appendstr
|
||||
query:
|
||||
update person(name = name & ?appendstr)
|
||||
where id == ?id
|
||||
let res = query:
|
||||
select person(name)
|
||||
where id == ?id
|
||||
check res[0] == nameupdated
|
||||
|
||||
test "delete_one":
|
||||
# test fix #14: delete not return value
|
||||
let id = 1
|
||||
query:
|
||||
delete antibot
|
||||
where id == ?id
|
||||
let res = query:
|
||||
select antibot(_)
|
||||
where id == ?id
|
||||
check res == []
|
||||
|
||||
test "delete_all":
|
||||
query:
|
||||
delete antibot
|
||||
let res = query:
|
||||
select antibot(_)
|
||||
check res == []
|
||||
|
||||
test "insert_return_id":
|
||||
# test fix #28 returning id fail under postgresql
|
||||
let expectedid = 6
|
||||
let id = query:
|
||||
insert antibot(id = ?expectedid, ip = "", answer = "just insert")
|
||||
returning id
|
||||
check id == expectedid
|
||||
|
||||
test "insert_return_answer":
|
||||
# test returning non-id parameter
|
||||
let expectedanswer = "just insert another"
|
||||
let answer = query:
|
||||
insert antibot(id = 9, ip = "", answer = ?expectedanswer)
|
||||
returning answer
|
||||
check answer == expectedanswer
|
||||
|
||||
test "insert_return_id_auto":
|
||||
# test returning id column
|
||||
when defined(postgre):
|
||||
# fix postgres sequence so next nextval returns 10
|
||||
discard db.getValue(sql"select setval('antibot_id_seq', ?, ?)", 10, false)
|
||||
let answer = query:
|
||||
insert antibot(ip = "", answer = "just auto insert")
|
||||
returning id
|
||||
check answer == 10
|
||||
|
||||
test "insert_returning_uuid":
|
||||
# test returning uuid column
|
||||
let expecteduuid = "123e4567-e89b-12d3-a456-426614174000"
|
||||
let uuid = query:
|
||||
insert error(uuid = ?expecteduuid, message = "just insert")
|
||||
returning uuid
|
||||
check uuid == expecteduuid
|
||||
|
||||
test "where_json":
|
||||
let
|
||||
id = 1
|
||||
p = %*{"id": id}
|
||||
let res = query:
|
||||
select person(id)
|
||||
where id == %p["id"]
|
||||
check res == [id]
|
||||
|
||||
test "insert_json":
|
||||
let
|
||||
id = 7
|
||||
answer = "json answer"
|
||||
a = %*{"answer": answer}
|
||||
query:
|
||||
insert antibot(id = ?id, ip = "", answer = %a["answer"])
|
||||
let res = query:
|
||||
select antibot(answer)
|
||||
where id == ?id
|
||||
check res[0] == answer
|
||||
|
||||
test "update_json":
|
||||
let
|
||||
id = 3
|
||||
name = "json"
|
||||
p = %*{"name": name}
|
||||
query:
|
||||
update person(name = %p["name"])
|
||||
where id == ?id
|
||||
let res = query:
|
||||
select person(name)
|
||||
where id == ?id
|
||||
check res[0] == name
|
||||
|
||||
test "insert_rawsql":
|
||||
let id = 8
|
||||
query:
|
||||
insert antibot(id = ?id, ip = "", answer = !!"'raw sql'",
|
||||
created = !!"CURRENT_TIMESTAMP")
|
||||
let res = query:
|
||||
select antibot(_)
|
||||
where id == ?id
|
||||
check res[0].answer == "raw sql"
|
||||
|
||||
test "update_rawsql":
|
||||
let id = 3
|
||||
let res = query:
|
||||
select person(name)
|
||||
where id == ?id
|
||||
query:
|
||||
update person(name = !!"UPPER(name)")
|
||||
where id == ?id
|
||||
let res2 = query:
|
||||
select person(name)
|
||||
where id == ?id
|
||||
check res[0] != res2[0]
|
||||
check res[0].toUpper() == res2[0]
|
||||
test "empty_string":
|
||||
db.exec(insertthread, 6, "", 77)
|
||||
|
||||
createProc getAllThreads:
|
||||
select thread(id, name, views)
|
||||
where id >= 5
|
||||
|
||||
let rows = db.getAllThreads
|
||||
check rows[1].id == 6
|
||||
check rows[1].views == 77
|
||||
check rows[1].name == ""
|
||||
Reference in New Issue
Block a user