Some advances in challenge handling (server+client)
[vchess.git] / server / models / Challenge.js
1 var db = require("../utils/database");
2
3 /*
4 * Structure table Challenges:
5 * id: integer
6 * added: datetime
7 * uid: user id (int)
8 * vid: variant id (int)
9 * nbPlayers: integer
10 * fen: varchar (optional)
11 * timeControl: string (3m+2s, 7d+1d ...)
12 *
13 * Structure table WillPlay:
14 * cid: ref challenge id
15 * uid: ref user id
16 */
17
18 const ChallengeModel =
19 {
20 checkChallenge: function(c)
21 {
22 if (!c.vid.match(/^[0-9]+$/))
23 return "Wrong variant ID";
24
25 if (!c.timeControl.match(/^[0-9dhms +]+$/))
26 return "Wrong characters in time control";
27
28 if (!c.nbPlayers.match(/^[0-9]+$/))
29 return "Wrong number of players";
30
31 if (!c.fen.match(/^[a-zA-Z0-9, /-]+$/))
32 return "Bad FEN string";
33 },
34
35 // fen cannot be undefined
36 create: function(c, cb)
37 {
38 db.serialize(function() {
39 let query =
40 "INSERT INTO Challenges " +
41 "(added, uid, vid, nbPlayers, fen, timeControl) VALUES " +
42 "(" + Date.now() + "," + c.uid + "," + c.vid + "," + c.nbPlayers +
43 ",'" + c.fen + "'," + c.timeControl + ")";
44 db.run(query, err => {
45 if (!!err)
46 return cb(err);
47 db.get("SELECT last_insert_rowid() AS rowid", (err2,lastId) => {
48
49 // TODO: also insert "will play" "no" for other players ?
50 // willplay = "maybe" by default ?
51
52 query =
53 "INSERT INTO WillPlay VALUES " +
54 "(true," + lastId["rowid"] + "," + c.uid + ")";
55 db.run(query, (err,ret) => {
56 cb(err, lastId); //all we need is the challenge ID
57 });
58 });
59 });
60 });
61 },
62
63 getOne: function(id, cb)
64 {
65 db.serialize(function() {
66 let query =
67 "SELECT * " +
68 "FROM Challenges c " +
69 "JOIN Variants v " +
70 " ON c.vid = v.id "
71 "WHERE id = " + id;
72 db.get(query, (err,challengeInfo) => {
73 if (!!err)
74 return cb(err);
75 query =
76 "SELECT w.uid AS id, u.name " +
77 "FROM WillPlay w " +
78 "JOIN Users u " +
79 " ON w.uid = u.id " +
80 "WHERE w.cid = " + id;
81 db.run(query, (err2,players) => {
82 if (!!err2)
83 return cb(err2);
84 const challenge = {
85 id: id,
86 uid: challengeInfo.uid,
87 vname: challengeInfo.name,
88 added: challengeInfo.added,
89 nbPlayers: challengeInfo.nbPlayers,
90 players: players, //currently in
91 fen: challengeInfo.fen,
92 timeControl: challengeInfo.timeControl,
93 };
94 return cb(null, challenge);
95 });
96 });
97 });
98 },
99
100 getByUser: function(uid, cb)
101 {
102 db.serialize(function() {
103 const query =
104 "SELECT cid " +
105 "FROM WillPlay " +
106 "WHERE uid = " + uid;
107 db.run(query, (err,challIds) => {
108 if (!!err)
109 return cb(err);
110 let challenges = [];
111 challIds.forEach(cidRow => {
112 ChallengeModel.getOne(cidRow["cid"], (err2,chall) => {
113 if (!!err2)
114 return cb(err2);
115 challenges.push(chall);
116 });
117 });
118 return cb(null, challenges);
119 });
120 });
121 },
122
123 remove: function(id)
124 {
125 db.parallelize(function() {
126 let query =
127 "DELETE FROM Challenges " +
128 "WHERE id = " + id;
129 db.run(query);
130 query =
131 "DELETE FROM WillPlay " +
132 "WHERE cid = " + id;
133 db.run(query);
134 });
135 },
136 }
137
138 module.exports = ChallengeModel;