v2 / vlib / x / sessions / db_store.v
100 lines · 85 sloc · 2.15 KB · 37255767290c243b71f0e78d77c3bd5e875748e6
Raw
1module sessions
2
3import json
4import orm
5import time
6
7// DBStoreSessions is the table that is created in your database and represents a session data record.
8pub struct DBStoreSessions {
9pub mut:
10 session_id string @[primary]
11 created_at time.Time
12 data string
13}
14
15// DBStore stores sessions in a database.
16@[noinit]
17pub struct DBStore[T] {
18pub mut:
19 db orm.Connection @[required]
20}
21
22// create a new Database store with a connection to a database.
23pub fn DBStore.create[T](db orm.Connection) !DBStore[T] {
24 sql db {
25 create table DBStoreSessions
26 }!
27
28 return DBStore[T]{
29 db: db
30 }
31}
32
33// all gets the data from all sessions.
34pub fn (mut store DBStore[T]) all() ![]T {
35 rows := sql store.db {
36 select from DBStoreSessions
37 }!
38
39 // decode should never fail
40 return rows.map(json.decode(T, it.data)!)
41}
42
43// get session for session id `sid`. The session can be `max_age` old.
44// `max_age` will be ignored when set to `0`
45pub fn (mut store DBStore[T]) get(sid string, max_age time.Duration) !T {
46 rows := sql store.db {
47 select from DBStoreSessions where session_id == sid
48 }!
49
50 if rows.len == 1 {
51 record := rows[0]
52 // session is expired
53 if max_age != 0 && record.created_at.add(max_age) < time.now() {
54 store.destroy(sid)!
55 return error('session is expired')
56 }
57
58 return json.decode(T, record.data)!
59 } else {
60 return error('session does not exist')
61 }
62}
63
64// destroy data for session id `sid`.
65pub fn (mut store DBStore[T]) destroy(sid string) ! {
66 sql store.db {
67 delete from DBStoreSessions where session_id == sid
68 }!
69}
70
71// clear all sessions.
72pub fn (mut store DBStore[T]) clear() ! {
73 sql store.db {
74 delete from DBStoreSessions where session_id != ''
75 }!
76}
77
78// set session data for session id `sid`.
79pub fn (mut store DBStore[T]) set(sid string, val T) ! {
80 count := sql store.db {
81 select count from DBStoreSessions where session_id == sid
82 }!
83
84 if count == 1 {
85 stringified := json.encode(val)
86 sql store.db {
87 update DBStoreSessions set data = stringified where session_id == sid
88 }!
89 } else {
90 record := DBStoreSessions{
91 session_id: sid
92 created_at: time.now()
93 data: json.encode(val)
94 }
95
96 sql store.db {
97 insert record into DBStoreSessions
98 }!
99 }
100}
101