Commit | Line | Data |
---|---|---|
8d7e2786 BA |
1 | var db = require("../utils/database"); |
2 | ||
3 | /* | |
00f2759e BA |
4 | * Structure table Challenges: |
5 | * id: integer | |
6 | * added: datetime | |
7 | * uid: user id (int) | |
8 | * vid: variant id (int) | |
9 | * nbPlayers: integer | |
ab4f4bf2 | 10 | * fen: varchar (optional) |
052d17ea | 11 | * timeControl: string (3m+2s, 7d+1d ...) |
00f2759e BA |
12 | * |
13 | * Structure table WillPlay: | |
14 | * cid: ref challenge id | |
15 | * uid: ref user id | |
1f49533d | 16 | * yes: boolean (false means "not decided yet") |
8d7e2786 BA |
17 | */ |
18 | ||
ab4f4bf2 | 19 | const ChallengeModel = |
8d7e2786 | 20 | { |
98db2082 BA |
21 | checkChallenge: function(c) |
22 | { | |
052d17ea BA |
23 | if (!c.vid.match(/^[0-9]+$/)) |
24 | return "Wrong variant ID"; | |
98db2082 | 25 | |
052d17ea BA |
26 | if (!c.timeControl.match(/^[0-9dhms +]+$/)) |
27 | return "Wrong characters in time control"; | |
98db2082 | 28 | |
052d17ea | 29 | if (!c.fen.match(/^[a-zA-Z0-9, /-]+$/)) |
98db2082 BA |
30 | return "Bad FEN string"; |
31 | }, | |
32 | ||
1f49533d BA |
33 | initializeWillPlay: function(uids, cid, cb) |
34 | { | |
35 | let query = "INSERT INTO WillPlay VALUES "; | |
36 | for (let i=0; i<uids.length; i++) | |
37 | { | |
38 | query += "(false," + cid + "," + uids[i] + ")"; | |
39 | if (i < uids.length-1) | |
40 | query += ","; | |
41 | } | |
42 | db.run(query, cb); | |
43 | }, | |
44 | ||
052d17ea | 45 | // fen cannot be undefined |
ab4f4bf2 BA |
46 | create: function(c, cb) |
47 | { | |
48 | db.serialize(function() { | |
49 | let query = | |
74ea2e8d | 50 | "INSERT INTO Challenges " + |
052d17ea | 51 | "(added, uid, vid, nbPlayers, fen, timeControl) VALUES " + |
74ea2e8d | 52 | "(" + Date.now() + "," + c.uid + "," + c.vid + "," + c.nbPlayers + |
052d17ea | 53 | ",'" + c.fen + "'," + c.timeControl + ")"; |
ab4f4bf2 BA |
54 | db.run(query, err => { |
55 | if (!!err) | |
56 | return cb(err); | |
57 | db.get("SELECT last_insert_rowid() AS rowid", (err2,lastId) => { | |
052d17ea | 58 | query = |
ab4f4bf2 | 59 | "INSERT INTO WillPlay VALUES " + |
052d17ea | 60 | "(true," + lastId["rowid"] + "," + c.uid + ")"; |
1f49533d BA |
61 | db.run(query, (err,ret) => { |
62 | cb(err, lastId); //all we need is the challenge ID | |
63 | }); | |
ab4f4bf2 BA |
64 | }); |
65 | }); | |
66 | }); | |
67 | }, | |
68 | ||
69 | getOne: function(id, cb) | |
70 | { | |
71 | db.serialize(function() { | |
72 | let query = | |
73 | "SELECT * " + | |
74 | "FROM Challenges c " + | |
75 | "JOIN Variants v " + | |
76 | " ON c.vid = v.id " | |
77 | "WHERE id = " + id; | |
78 | db.get(query, (err,challengeInfo) => { | |
79 | if (!!err) | |
80 | return cb(err); | |
00f2759e | 81 | query = |
ab4f4bf2 BA |
82 | "SELECT w.uid AS id, u.name " + |
83 | "FROM WillPlay w " + | |
84 | "JOIN Users u " + | |
85 | " ON w.uid = u.id " + | |
86 | "WHERE w.cid = " + id; | |
87 | db.run(query, (err2,players) => { | |
88 | if (!!err2) | |
89 | return cb(err2); | |
90 | const challenge = { | |
91 | id: id, | |
74ea2e8d | 92 | uid: challengeInfo.uid, |
ab4f4bf2 BA |
93 | vname: challengeInfo.name, |
94 | added: challengeInfo.added, | |
95 | nbPlayers: challengeInfo.nbPlayers, | |
96 | players: players, //currently in | |
97 | fen: challengeInfo.fen, | |
052d17ea | 98 | timeControl: challengeInfo.timeControl, |
ab4f4bf2 BA |
99 | }; |
100 | return cb(null, challenge); | |
00f2759e BA |
101 | }); |
102 | }); | |
103 | }); | |
ab4f4bf2 | 104 | }, |
8d7e2786 | 105 | |
ab4f4bf2 BA |
106 | getByUser: function(uid, cb) |
107 | { | |
108 | db.serialize(function() { | |
109 | const query = | |
110 | "SELECT cid " + | |
111 | "FROM WillPlay " + | |
112 | "WHERE uid = " + uid; | |
113 | db.run(query, (err,challIds) => { | |
114 | if (!!err) | |
115 | return cb(err); | |
116 | let challenges = []; | |
117 | challIds.forEach(cidRow => { | |
118 | ChallengeModel.getOne(cidRow["cid"], (err2,chall) => { | |
119 | if (!!err2) | |
120 | return cb(err2); | |
121 | challenges.push(chall); | |
122 | }); | |
123 | }); | |
124 | return cb(null, challenges); | |
00f2759e BA |
125 | }); |
126 | }); | |
ab4f4bf2 | 127 | }, |
8d7e2786 | 128 | |
4edfed6c BA |
129 | getSeatCount: function(id, cb) |
130 | { | |
131 | db.serialize(function() { | |
132 | let query = | |
133 | "SELECT COUNT(*) AS scount " + | |
134 | "FROM WillPlay " + | |
135 | "WHERE cid = " + id; | |
136 | db.get(query, (err,scRow) => { | |
137 | if (!!err) | |
138 | return cb(err); | |
139 | query = | |
140 | "SELECT nbPlayers " + | |
141 | "FROM Challenges " + | |
142 | "WHERE id = " + id; | |
143 | db.get(query, (err2,chRow) => { | |
144 | if (!!err2) | |
145 | return cb(err2); | |
146 | cb(chRow["nbPlayers"] - scRow["scount"]); | |
147 | }); | |
148 | }); | |
149 | }); | |
150 | }, | |
151 | ||
152 | setSeat: function(id, uid) | |
153 | { | |
154 | // TODO: remove extra "db.serialize" (parallelize by default) | |
155 | //db.serialize(function() { | |
156 | const query = | |
157 | "INSERT OR REPLACE INTO WillPlay " + | |
158 | "VALUES (true," + id + "," + uid +")"; | |
159 | db.run(query); | |
160 | //}); | |
161 | }, | |
162 | ||
1f49533d | 163 | remove: function(id, uid) |
ab4f4bf2 | 164 | { |
1f49533d | 165 | db.serialize(function() { |
ab4f4bf2 | 166 | let query = |
4edfed6c BA |
167 | "SELECT 1 " + |
168 | "FROM Challenges " + | |
169 | "WHERE id = " + id + " AND uid = " + uid; | |
170 | db.run(query, (err,rows) => { | |
171 | if (rows.length > 0) //it's my challenge | |
36093eba | 172 | { |
4edfed6c BA |
173 | db.parallelize(function() { |
174 | query = | |
175 | "DELETE FROM Challenges " + | |
176 | "WHERE id = " + id; | |
177 | db.run(query); | |
178 | // Also remove matching WillPlay entries if a challenge was deleted | |
179 | query = | |
180 | "DELETE FROM WillPlay " + | |
181 | "WHERE cid = " + id; | |
182 | db.run(query); | |
183 | }); | |
36093eba BA |
184 | } |
185 | }); | |
ab4f4bf2 BA |
186 | }); |
187 | }, | |
8d7e2786 | 188 | } |
ab4f4bf2 BA |
189 | |
190 | module.exports = ChallengeModel; |