4e54075078
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
97 lines
2.5 KiB
Nim
97 lines
2.5 KiB
Nim
import ../../ormin / [serverws]
|
|
import ../../ormin
|
|
|
|
import json
|
|
|
|
# Ormin needs to know about our SQL model:
|
|
importModel(DbBackend.sqlite, "chat_model")
|
|
|
|
# Currently Ormin assumes a global database connection that needs to be
|
|
# annotated as '.global' for technical reasons. Later versions will improve.
|
|
var db {.global.} = open("chat.db", "", "", "")
|
|
|
|
# Ormin produces the file "chatclient.nim" for our frontend:
|
|
protocol "chatclient.nim":
|
|
# A 'common' code section is shared by both the client and the server:
|
|
common:
|
|
when not defined(js):
|
|
type kstring = string
|
|
type
|
|
inetType = kstring
|
|
varcharType = kstring
|
|
timestampType = kstring
|
|
intType = int
|
|
|
|
|
|
server "get recent messages":
|
|
let lastMessages = query:
|
|
select messages(content, creation, author)
|
|
join users(name)
|
|
orderby desc(creation)
|
|
limit 100
|
|
send(lastMessages)
|
|
|
|
client "get recent messages":
|
|
type TextMessage* = ref object
|
|
# Ormin fills in the fields of 'TextMessage' for us, based on the
|
|
# query in the 'server' part.
|
|
var allMessages*: seq[TextMessage] = @[]
|
|
proc getRecentMessages*()
|
|
allMessages = recv()
|
|
|
|
|
|
server "send chat message":
|
|
let userId = arg["author"].num
|
|
# unregistered users cannot send anything:
|
|
if userId == 0: return
|
|
query:
|
|
insert messages(content = %arg["content"], author = ?userId)
|
|
query:
|
|
update users(lastOnline = !!"DATETIME('now')")
|
|
where id == ?userId
|
|
|
|
let lastMessage = query:
|
|
select messages(content, creation, author)
|
|
join users(name)
|
|
orderby desc(creation)
|
|
limit 1
|
|
|
|
broadcast(lastMessage)
|
|
|
|
client "send chat message":
|
|
proc sendMessage*(m: TextMessage)
|
|
allMessages.add recv(TextMessage)
|
|
|
|
|
|
# This is the request to register/login a new user:
|
|
server "register/login a new user":
|
|
var candidates = query:
|
|
produce nim
|
|
select users(id, password)
|
|
where name == %arg["name"]
|
|
if candidates.len == 0:
|
|
let userId = query:
|
|
produce nim
|
|
insert users(name = %arg["name"], password = %arg["password"])
|
|
returning id
|
|
send(%userId)
|
|
else:
|
|
block search:
|
|
for c in candidates:
|
|
if c[1] == arg["password"].str:
|
|
send(%c[0])
|
|
echo "login found!"
|
|
break search
|
|
# invalid login:
|
|
send(%0)
|
|
echo "no such user!"
|
|
|
|
client "register/login a new user":
|
|
proc registerUser*(u: User)
|
|
var userId: int
|
|
userId = recv()
|
|
if userId == 0: setError(username, "invalid login!")
|
|
|
|
|
|
serve "orminchat", dispatch
|