feat(clients): add nim-allographer client with BaraDB driver support
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
- Pure Nim wire protocol client (async + sync, no C FFI) - Query Builder: fluent API, SQL generator, execution, transactions - Schema Builder: create/alter/drop tables, column operations - Connection pool with aging and timeout handling - ORM integration via compile-time DB_BARADB switch - Tests: test_open, test_query - Documentation: README.md, PLAN_BARADB.md
This commit is contained in:
@@ -0,0 +1,507 @@
|
||||
discard """
|
||||
cmd: "nim c -d:reset $file"
|
||||
"""
|
||||
|
||||
# nim c -r -d:reset tests/surrealdb/test_query.nim
|
||||
|
||||
import std/unittest
|
||||
import std/asyncdispatch
|
||||
import std/json
|
||||
import std/options
|
||||
import std/strformat
|
||||
import std/times
|
||||
import ../../src/allographer/schema_builder
|
||||
import ../../src/allographer/query_builder
|
||||
import ./connections
|
||||
import ../clear_tables
|
||||
|
||||
|
||||
let rdb = surreal
|
||||
|
||||
|
||||
proc isNullish(node: JsonNode, key: string): bool =
|
||||
not node.hasKey(key) or node[key].kind == JNull
|
||||
|
||||
# =============================================================================
|
||||
# test
|
||||
# =============================================================================
|
||||
|
||||
proc setup(rdb:SurrealConnections) =
|
||||
# rdb.raw("REMOVE TABLE auth; REMOVE TABLE user").exec().waitFor
|
||||
# rdb.raw("DEFINE TABLE auth SCHEMAFULL; DEFINE TABLE user SCHEMAFULL").exec().waitFor
|
||||
rdb.create([
|
||||
table("auth",[
|
||||
Column.increments("index"),
|
||||
Column.string("name")
|
||||
]),
|
||||
table("user",[
|
||||
Column.increments("index"),
|
||||
Column.string("name").nullable(),
|
||||
Column.string("email").nullable(),
|
||||
Column.string("address").nullable(),
|
||||
Column.date("submit_on"),
|
||||
Column.datetime("submit_at"),
|
||||
Column.foreign("auth").reference("id").onTable("auth").onDelete(SET_NULL).nullable()
|
||||
])
|
||||
])
|
||||
|
||||
# seeder
|
||||
var adminId, userId:SurrealId
|
||||
seeder(rdb, "auth"):
|
||||
adminId = rdb.table("auth").insertId(%*{"name":"admin"}).waitFor()
|
||||
userId = rdb.table("auth").insertId(%*{"name":"user"}).waitFor()
|
||||
|
||||
seeder(rdb, "user"):
|
||||
var users: seq[JsonNode]
|
||||
for i in 1..10:
|
||||
let authId = if i mod 2 == 0: userId else: adminId
|
||||
let month = if i > 9: $i else: &"0{i}"
|
||||
users.add(
|
||||
%*{
|
||||
"name": &"user{i}",
|
||||
"email": &"user{i}@example.com",
|
||||
"address": newJNull(),
|
||||
"auth": authId,
|
||||
"submit_on": &"2020-{month}-01",
|
||||
"submit_at": &"2020-{month}-01T00:00:00Z",
|
||||
}
|
||||
)
|
||||
|
||||
rdb.table("user").insert(users).waitFor()
|
||||
|
||||
|
||||
setup(rdb)
|
||||
|
||||
suite($rdb & " get"):
|
||||
test("get"):
|
||||
let t = rdb.table("user").orderBy("name", Asc).get().waitFor()
|
||||
echo t[0]
|
||||
check t[0]["index"].getInt() == 1
|
||||
check t[0]["name"].getStr() == "user1"
|
||||
check t[0]["email"].getStr() == "user1@example.com"
|
||||
check isNullish(t[0], "address")
|
||||
check t[0]["submit_on"].getStr().parse("yyyy-MM-dd'T'hh:mm:ss'Z'").format("yyyy-MM-dd") == "2020-01-01"
|
||||
check t[0]["submit_at"].getStr() == "2020-01-01T00:00:00Z"
|
||||
|
||||
|
||||
test("first"):
|
||||
var t = rdb.table("user").where("name", "=", "user1").orderBy("name", Asc).first().waitFor().get()
|
||||
check t["index"].getInt() == 1
|
||||
check t["name"].getStr() == "user1"
|
||||
check t["email"].getStr() == "user1@example.com"
|
||||
check isNullish(t, "address")
|
||||
check t["submit_on"].getStr().parse("yyyy-MM-dd'T'hh:mm:ss'Z'").format("yyyy-MM-dd") == "2020-01-01"
|
||||
check t["submit_at"].getStr() == "2020-01-01T00:00:00Z"
|
||||
|
||||
|
||||
test("find"):
|
||||
var t = rdb.table("user").where("name", "=", "user1").orderBy("name", Asc).first().waitFor().get()
|
||||
let id = SurrealId.new(t["id"].getStr())
|
||||
t = rdb.table("user").find(id).waitFor().get()
|
||||
check t["index"].getInt() == 1
|
||||
check t["name"].getStr() == "user1"
|
||||
check t["email"].getStr() == "user1@example.com"
|
||||
check isNullish(t, "address")
|
||||
check t["submit_on"].getStr().parse("yyyy-MM-dd'T'hh:mm:ss'Z'").format("yyyy-MM-dd") == "2020-01-01"
|
||||
check t["submit_at"].getStr() == "2020-01-01T00:00:00Z"
|
||||
|
||||
|
||||
test("columns"):
|
||||
let columns = rdb.table("user").columns().waitFor()
|
||||
check columns == @["address", "auth", "email", "index", "name", "submit_at", "submit_on"]
|
||||
|
||||
|
||||
test("select"):
|
||||
var t = rdb.select("name", "email").table("user").orderBy("name", Asc).get().waitFor()
|
||||
check t[0] == %*{"name": "user1", "email": "user1@example.com"}
|
||||
|
||||
|
||||
test("selectAs"):
|
||||
var t = rdb.select("name as user_name", "email").table("user").orderBy("user_name", Asc).get().waitFor()
|
||||
check t[0] == %*{"user_name": "user1", "email": "user1@example.com"}
|
||||
|
||||
|
||||
test("selectLike"):
|
||||
let users = rdb.table("user").where("email", "CONTAINS", "10").get().waitFor()
|
||||
check users[0]["email"].getStr() == "user10@example.com"
|
||||
|
||||
var user10 = rdb.raw("SELECT * FROM user WHERE string::starts_with(email, \"user10\")").first().waitFor()
|
||||
check user10.get()["email"].getStr() == "user10@example.com"
|
||||
|
||||
user10 = rdb.raw("SELECT * FROM user WHERE string::ends_with(email, \"10@example.com\")").first().waitFor()
|
||||
check user10.get()["email"].getStr() == "user10@example.com"
|
||||
|
||||
|
||||
test("select count"):
|
||||
var t = rdb.raw("SELECT count(`id`) as `count` FROM `user` GROUP ALL").get().waitFor
|
||||
echo t
|
||||
check t[0]["count"].getInt() == 10
|
||||
|
||||
|
||||
test("select max"):
|
||||
var t = rdb.raw("SELECT math::max(`index`) as `max` FROM `user` GROUP ALL").get().waitFor
|
||||
echo t
|
||||
check t[0]["max"].getInt() == 10
|
||||
|
||||
|
||||
test("where string"):
|
||||
let admin = rdb.table("auth").where("name", "=", "admin").first().waitFor().get()
|
||||
let adminId = SurrealId.new(admin["id"].getStr())
|
||||
|
||||
var t = rdb.table("user").where("auth", "=", adminId.rawId()).orderBy("index", Asc).get().waitFor()
|
||||
const ids = [1,3,5,7,9]
|
||||
for i, row in t:
|
||||
check row["index"].getInt() == ids[i]
|
||||
check row["name"].getStr() == &"user{ids[i]}"
|
||||
check row["email"].getStr() == &"user{ids[i]}@example.com"
|
||||
check isNullish(row, "address")
|
||||
check row["submit_on"].getStr() == &"2020-0{ids[i]}-01T00:00:00Z"
|
||||
|
||||
|
||||
test("where int"):
|
||||
var t = rdb.table("user").where("index", "=", 1).orderBy("index", Asc).first().waitFor().get()
|
||||
check t["index"].getInt() == 1
|
||||
check t["name"].getStr() == "user1"
|
||||
check t["email"].getStr() == "user1@example.com"
|
||||
check isNullish(t, "address")
|
||||
check t["submit_on"].getStr() == "2020-01-01T00:00:00Z"
|
||||
|
||||
|
||||
test("orWhere"):
|
||||
let admin = rdb.table("auth").where("name", "=", "admin").first().waitFor().get()
|
||||
let adminId = SurrealId.new(admin["id"].getStr())
|
||||
|
||||
var t = rdb.table("user").where("auth", "=", adminId).orWhere("name", "=", "user2").orderBy("index", Asc).get().waitFor()
|
||||
const ids = [1,2,3,5,7,9]
|
||||
for i, row in t:
|
||||
check row["index"].getInt() == ids[i]
|
||||
check row["name"].getStr() == &"user{ids[i]}"
|
||||
check row["email"].getStr() == &"user{ids[i]}@example.com"
|
||||
check isNullish(row, "address")
|
||||
check row["submit_on"].getStr() == &"2020-0{ids[i]}-01T00:00:00Z"
|
||||
|
||||
|
||||
test("whereBetween"):
|
||||
var t = rdb
|
||||
.table("user")
|
||||
.whereBetween("index", [6, 9])
|
||||
.orderBy("index", Asc)
|
||||
.get()
|
||||
.waitFor()
|
||||
|
||||
const ids = [6,7,8,9]
|
||||
for i, row in t:
|
||||
check row["index"].getInt() == ids[i]
|
||||
check row["name"].getStr() == &"user{ids[i]}"
|
||||
check row["email"].getStr() == &"user{ids[i]}@example.com"
|
||||
check isNullish(row, "address")
|
||||
check row["submit_on"].getStr() == &"2020-0{ids[i]}-01T00:00:00Z"
|
||||
|
||||
|
||||
test("whereNotBetween"):
|
||||
var t = rdb
|
||||
.table("user")
|
||||
.whereNotBetween("index", [2, 6])
|
||||
.orderBy("index", Asc)
|
||||
.get()
|
||||
.waitFor()
|
||||
|
||||
const ids = [1,7,8,9]
|
||||
for i, row in t:
|
||||
check row["index"].getInt() == ids[i]
|
||||
check row["name"].getStr() == &"user{ids[i]}"
|
||||
check row["email"].getStr() == &"user{ids[i]}@example.com"
|
||||
check isNullish(row, "address")
|
||||
check row["submit_on"].getStr() == &"2020-0{ids[i]}-01T00:00:00Z"
|
||||
|
||||
|
||||
test("whereIn"):
|
||||
var t = rdb
|
||||
.table("user")
|
||||
.whereIn("index", @[5, 6, 7])
|
||||
.orderBy("index", Asc)
|
||||
.get()
|
||||
.waitFor()
|
||||
|
||||
const ids = [5,6,7]
|
||||
for i, row in t:
|
||||
check row["index"].getInt() == ids[i]
|
||||
check row["name"].getStr() == &"user{ids[i]}"
|
||||
check row["email"].getStr() == &"user{ids[i]}@example.com"
|
||||
check isNullish(row, "address")
|
||||
check row["submit_on"].getStr() == &"2020-0{ids[i]}-01T00:00:00Z"
|
||||
|
||||
|
||||
test("whereNotIn"):
|
||||
var t = rdb
|
||||
.table("user")
|
||||
.whereNotIn("index", @[4, 5, 6, 7, 10])
|
||||
.orderBy("index", Asc)
|
||||
.get()
|
||||
.waitFor()
|
||||
|
||||
const ids = [1,2,3,8,9]
|
||||
for i, row in t:
|
||||
check row["index"].getInt() == ids[i]
|
||||
check row["name"].getStr() == &"user{ids[i]}"
|
||||
check row["email"].getStr() == &"user{ids[i]}@example.com"
|
||||
check isNullish(row, "address")
|
||||
check row["submit_on"].getStr() == &"2020-0{ids[i]}-01T00:00:00Z"
|
||||
|
||||
|
||||
test("whereNull"):
|
||||
rdb.table("user").insert(%*{"email": "user11@example.com"}).waitFor()
|
||||
var t = rdb
|
||||
.table("user")
|
||||
.whereNull("name")
|
||||
.first()
|
||||
.waitFor()
|
||||
check t.get()["index"].getInt() == 11
|
||||
|
||||
setUp(rdb)
|
||||
|
||||
# TODO: not work
|
||||
# test("groupBy"):
|
||||
# var t = rdb
|
||||
# .select("auth.name")
|
||||
# .table("user")
|
||||
# .groupBy("auth.name")
|
||||
# .get()
|
||||
# .waitFor()
|
||||
# echo t
|
||||
|
||||
|
||||
test("orderBy"):
|
||||
var res = rdb.table("user").orderBy("name", Asc).get().waitFor()
|
||||
check res[0]["name"].getStr() == "user1"
|
||||
|
||||
res = rdb.table("user").orderBy("name", Desc).get().waitFor()
|
||||
check res[0]["name"].getStr() == "user9"
|
||||
|
||||
res = rdb.table("user").orderBy("index", Numeric, Asc).get().waitFor()
|
||||
check res[0]["name"].getStr() == "user1"
|
||||
|
||||
res = rdb.table("user").orderBy("index", Numeric, Desc).get().waitFor()
|
||||
check res[0]["name"].getStr() == "user10"
|
||||
|
||||
res = rdb.table("user").orderBy("name", Collate, Asc).get().waitFor()
|
||||
check res[0]["name"].getStr() == "user1"
|
||||
|
||||
res = rdb.table("user").orderBy("name", Collate, Desc).get().waitFor()
|
||||
check res[0]["name"].getStr() == "user9"
|
||||
|
||||
|
||||
test("fetch"):
|
||||
var res = rdb.table("user").where("name", "=", "user1").fetch("auth").first().waitFor().get()
|
||||
check res["auth"]["name"].getStr() == "admin"
|
||||
res = rdb.table("user").where("name", "=", "user2").fetch("auth").first().waitFor().get()
|
||||
check res["auth"]["name"].getStr() == "user"
|
||||
|
||||
|
||||
test("resultIsNull"):
|
||||
check rdb.table("user").where("id", "=", 50).first().waitFor().isSome() == false
|
||||
check newSeq[JsonNode](0) == rdb.table("user").where("id", "=", 50).get().waitFor()
|
||||
|
||||
|
||||
suite($rdb & " insert"):
|
||||
setup:
|
||||
setup(rdb)
|
||||
|
||||
test("insert row"):
|
||||
rdb.table("user").insert(%*{"name": "Alice"}).waitFor
|
||||
let t = rdb.table("user").orderBy("index", Desc).first().waitFor().get()
|
||||
check t["name"].getStr() == "Alice"
|
||||
|
||||
|
||||
test("insert rows"):
|
||||
rdb.table("user").insert(@[
|
||||
%*{"name": "Alice"},
|
||||
%*{"name": "Bob"},
|
||||
]).waitFor
|
||||
let t = rdb.table("user").orderBy("index", Desc).limit(2).get().waitFor()
|
||||
check t[0]["name"].getStr() == "Bob"
|
||||
check t[1]["name"].getStr() == "Alice"
|
||||
|
||||
|
||||
test("insertId row"):
|
||||
var id = rdb.table("user").insertId(%*{"name": "Alice"}).waitFor
|
||||
echo id
|
||||
let t = rdb.table("user").find(id).waitFor().get()
|
||||
check t["name"].getStr() == "Alice"
|
||||
|
||||
|
||||
test("insertId rows"):
|
||||
let ids = rdb.table("user").insertId(@[
|
||||
%*{"name": "Alice"},
|
||||
%*{"name": "Bob"},
|
||||
]).waitFor
|
||||
|
||||
var t = rdb.table("user").find(ids[0]).waitFor().get()
|
||||
check t["name"].getStr == "Alice"
|
||||
|
||||
t = rdb.table("user").find(ids[1]).waitFor().get()
|
||||
check t["name"].getStr == "Bob"
|
||||
|
||||
|
||||
test("insertNil"):
|
||||
var id = rdb.table("user").insertId(%*{
|
||||
"name": "Alice",
|
||||
"email": nil,
|
||||
"address": ""
|
||||
})
|
||||
.waitFor
|
||||
|
||||
var res = rdb.table("user").find(id).waitFor
|
||||
check not res.get.hasKey("email") or res.get["email"].kind == JNull
|
||||
|
||||
res = rdb.table("user").whereNull("email").first().waitFor
|
||||
check not res.get.hasKey("email") or res.get["email"].kind == JNull
|
||||
|
||||
|
||||
|
||||
test("insert [T]"):
|
||||
type User = object
|
||||
name:string
|
||||
|
||||
let user = User(name: "Alice")
|
||||
rdb.table("user").insert(user).waitFor
|
||||
|
||||
let row = rdb.table("user").orderBy("index", Desc).first().waitFor().get()
|
||||
check row["name"].getStr() == "Alice"
|
||||
|
||||
|
||||
test("insert seq[T]"):
|
||||
type User = object
|
||||
name:string
|
||||
|
||||
let users = @[
|
||||
User(name: "Alice"),
|
||||
User(name: "Bob"),
|
||||
]
|
||||
|
||||
rdb.table("user").insert(users).waitFor
|
||||
let t = rdb.table("user").orderBy("index", Desc).limit(2).get().waitFor()
|
||||
check t[0]["name"].getStr() == "Bob"
|
||||
check t[1]["name"].getStr() == "Alice"
|
||||
|
||||
|
||||
suite($rdb & " update"):
|
||||
setup:
|
||||
setup(rdb)
|
||||
|
||||
|
||||
test("update"):
|
||||
var user1 = rdb.table("user").where("index", "=", 1).first().waitFor().get()
|
||||
let user1Id = SurrealId.new(user1["id"].getStr())
|
||||
rdb.table("user").where("id", "=", user1Id).update(%*{"name": "Alice"}).waitFor()
|
||||
user1 = rdb.table("user").find(user1Id).waitFor().get()
|
||||
check user1["name"].getStr() == "Alice"
|
||||
|
||||
|
||||
test("update [T]"):
|
||||
type User = object
|
||||
name:string
|
||||
|
||||
let user = User(name: "Alice")
|
||||
var user1 = rdb.table("user").where("index", "=", 1).first().waitFor().get()
|
||||
let user1Id = SurrealId.new(user1["id"].getStr())
|
||||
rdb.table("user").where("id", "=", user1Id).update(user).waitFor()
|
||||
user1 = rdb.table("user").find(user1Id).waitFor().get()
|
||||
check user1["name"].getStr() == "Alice"
|
||||
|
||||
|
||||
test("update merge"):
|
||||
var user1 = rdb.table("user").where("index", "=", 1).first().waitFor().get()
|
||||
let user1Id = SurrealId.new(user1["id"].getStr())
|
||||
rdb.update(user1Id, %*{"name": "updated"}).waitFor()
|
||||
user1 = rdb.table("user").find(user1Id).waitFor().get()
|
||||
check user1["name"].getStr() == "updated"
|
||||
|
||||
|
||||
test("update merge [T]"):
|
||||
type User = object
|
||||
name:string
|
||||
|
||||
|
||||
var user1 = rdb.table("user").where("index", "=", 1).first().waitFor().get()
|
||||
let user1Id = SurrealId.new(user1["id"].getStr())
|
||||
let user = User(name: "updated")
|
||||
rdb.update(user1Id, user).waitFor()
|
||||
user1 = rdb.table("user").find(user1Id).waitFor().get()
|
||||
check user1["name"].getStr() == "updated"
|
||||
|
||||
|
||||
suite($rdb & " delete"):
|
||||
setup:
|
||||
setup(rdb)
|
||||
|
||||
test("delete"):
|
||||
let user1 = rdb.table("user").where("index", "=", 1).first().waitFor().get()
|
||||
let user1Id = SurrealId.new(user1["id"].getStr())
|
||||
rdb.table("user").where("name", "=", "user1").delete().waitFor()
|
||||
check rdb.table("user").find(user1Id).waitFor().isSome() == false
|
||||
|
||||
test("delete id"):
|
||||
let user1 = rdb.table("user").where("index", "=", 1).first().waitFor().get()
|
||||
let user1Id = SurrealId.new(user1["id"].getStr())
|
||||
rdb.table("user").delete(user1Id).waitFor
|
||||
check rdb.table("user").find(user1Id).waitFor().isSome() == false
|
||||
|
||||
|
||||
suite($rdb & " rawQuery"):
|
||||
setup(rdb)
|
||||
|
||||
test("get"):
|
||||
let sql = &"SELECT * FROM `user` WHERE `index` = ?"
|
||||
let res = rdb.raw(sql, %*[1]).get().waitFor
|
||||
check res[0]["name"].getStr == "user1"
|
||||
|
||||
|
||||
test("first"):
|
||||
let sql = &"SELECT * FROM `user` WHERE `index` = ?"
|
||||
let res = rdb.raw(sql, %*[1]).first().waitFor().get()
|
||||
check res["name"].getStr() == "user1"
|
||||
|
||||
|
||||
test("exec"):
|
||||
var sql = "SELECT * FROM `user` WHERE `index` = ?"
|
||||
let user1 = rdb.raw(sql, %*[1]).first().waitFor().get()
|
||||
let user1Id = SurrealId.new(user1["id"].getStr())
|
||||
|
||||
sql = "UPDATE `user` SET `name` = ? WHERE `id` = ?"
|
||||
rdb.raw(sql, %*["updated", user1Id.rawId()]).exec().waitFor
|
||||
|
||||
sql = &"SELECT * FROM `user` WHERE `id` = ?"
|
||||
let res = rdb.raw(sql, %[user1Id.rawId()]).get().waitFor
|
||||
check res[0]["name"].getStr == "updated"
|
||||
|
||||
|
||||
setup(rdb)
|
||||
suite($rdb & " aggregates"):
|
||||
|
||||
test("count"):
|
||||
var t = rdb.table("user").count().waitFor()
|
||||
check t == 10
|
||||
|
||||
test("max"):
|
||||
var t = rdb.table("user").max("name", Collate).waitFor()
|
||||
check t == "user9"
|
||||
var t2 = rdb.table("user").max("index", Numeric).waitFor()
|
||||
check t2 == "10"
|
||||
|
||||
test("min"):
|
||||
var t = rdb.table("user").min("name", Collate).waitFor()
|
||||
check t == "user1"
|
||||
var t2 = rdb.table("user").min("index", Numeric).waitFor()
|
||||
check t2 == "1"
|
||||
|
||||
test("avg"):
|
||||
let t = rdb.table("user").avg("index").waitFor()
|
||||
check t == 5.5
|
||||
|
||||
test("sum"):
|
||||
let t = rdb.table("user").sum("index").waitFor()
|
||||
check t == 55.0
|
||||
|
||||
|
||||
clearTables(rdb).waitFor()
|
||||
Reference in New Issue
Block a user