A few fixes, drop planned problems support (replaced by forum + mode analyze)
[vchess.git] / server / models / Game.js
CommitLineData
00f2759e
BA
1var db = require("../utils/database");
2
3/*
4 * Structure table Games:
5 * id: game id (int)
6 * vid: integer (variant id)
ab4f4bf2
BA
7 * fenStart: varchar (initial position)
8 * fen: varchar (current position)
a9b131f1 9 * timeControl: string
00f2759e
BA
10 * score: varchar (result)
11 *
12 * Structure table Players:
13 * gid: ref game id
14 * uid: ref user id
15 * color: character
16 *
17 * Structure table Moves:
ab4f4bf2 18 * gid: ref game id
f41ce580 19 * squares: varchar (description)
ab4f4bf2 20 * message: text
00f2759e
BA
21 * played: datetime
22 * idx: integer
00f2759e
BA
23 */
24
ab4f4bf2 25const GameModel =
00f2759e 26{
a9b131f1 27 create: function(vid, fen, timeControl, players, cb)
ab4f4bf2 28 {
88667455 29 db.serialize(function() {
ab4f4bf2 30 let query =
f41ce580
BA
31 "INSERT INTO Games (vid, fenStart, fen, score, timeControl) VALUES " +
32 "(" + vid + ",'" + fen + "','" + fen + "','*','" + timeControl + "')";
8c564f46 33 db.run(query, function(err) {
cf742aaf
BA
34 if (!!err)
35 return cb(err);
8c564f46
BA
36 players.forEach((p,idx) => {
37 const color = (idx==0 ? "w" : "b");
2be5d614
BA
38 query =
39 "INSERT INTO Players VALUES " +
f41ce580 40 "(" + this.lastID + "," + p.id + ",'" + color + "')";
2be5d614
BA
41 db.run(query);
42 });
43 cb(null, {gid: this.lastID});
00f2759e
BA
44 });
45 });
ab4f4bf2 46 },
00f2759e 47
ab4f4bf2
BA
48 // TODO: queries here could be async, and wait for all to complete
49 getOne: function(id, cb)
50 {
51 db.serialize(function() {
f41ce580 52 // TODO: optimize queries?
ab4f4bf2 53 let query =
f41ce580
BA
54 "SELECT g.id, g.vid, g.fen, g.fenStart, g.timeControl, g.score, " +
55 "v.name AS vname " +
56 "FROM Games g " +
57 "JOIN Variants v " +
58 " ON g.vid = v.id " +
59 "WHERE g.id = " + id;
ab4f4bf2
BA
60 db.get(query, (err,gameInfo) => {
61 if (!!err)
62 return cb(err);
00f2759e 63 query =
f41ce580
BA
64 "SELECT p.uid, p.color, u.name " +
65 "FROM Players p " +
66 "JOIN Users u " +
67 " ON p.uid = u.id " +
68 "WHERE p.gid = " + id;
fd7aea36 69 db.all(query, (err2,players) => {
ab4f4bf2
BA
70 if (!!err2)
71 return cb(err2);
72 query =
92b82def 73 "SELECT squares, message, played, idx " +
ab4f4bf2
BA
74 "FROM Moves " +
75 "WHERE gid = " + id;
fd7aea36 76 db.all(query, (err3,moves) => {
ab4f4bf2
BA
77 if (!!err3)
78 return cb(err3);
fd7aea36
BA
79 const game = Object.assign({},
80 gameInfo,
81 {
82 players: players,
83 moves: moves
84 }
85 );
ab4f4bf2
BA
86 return cb(null, game);
87 });
00f2759e
BA
88 });
89 });
90 });
ab4f4bf2 91 },
00f2759e 92
5d04793e 93 getByUser: function(uid, excluded, cb)
ab4f4bf2
BA
94 {
95 db.serialize(function() {
96 // Next query is fine because a player appear at most once in a game
97 const query =
98 "SELECT gid " +
99 "FROM Players " +
5d04793e 100 "WHERE uid " + (excluded ? "<>" : "=") + " " + uid;
afd3240d 101 db.all(query, (err,gameIds) => {
ab4f4bf2
BA
102 if (!!err)
103 return cb(err);
098cd7f1 104 gameIds = gameIds || []; //might be empty
ab4f4bf2 105 let gameArray = [];
afd3240d
BA
106 for (let i=0; i<gameIds.length; i++)
107 {
108 GameModel.getOne(gameIds[i]["gid"], (err2,game) => {
ab4f4bf2
BA
109 if (!!err2)
110 return cb(err2);
111 gameArray.push(game);
afd3240d
BA
112 // Call callback function only when gameArray is complete:
113 if (i == gameIds.length - 1)
114 return cb(null, gameArray);
ab4f4bf2 115 });
afd3240d 116 }
ab4f4bf2
BA
117 });
118 });
119 },
120
411d23cd
BA
121 getPlayers: function(id, cb)
122 {
123 db.serialize(function() {
124 const query =
125 "SELECT id " +
126 "FROM Players " +
127 "WHERE gid = " + id;
128 db.all(query, (err,players) => {
129 return cb(err, players);
130 });
131 });
132 },
133
3d55deea 134 // obj can have fields move, fen and/or score
f41ce580 135 update: function(id, obj)
3d55deea 136 {
f41ce580 137 db.parallelize(function() {
3d55deea
BA
138 let query =
139 "UPDATE Games " +
140 "SET ";
3d55deea 141 if (!!obj.fen)
afc42601 142 query += "fen = '" + obj.fen + "',";
3d55deea 143 if (!!obj.score)
afc42601 144 query += "score = '" + obj.score + "',";
3d55deea 145 query = query.slice(0,-1); //remove last comma
afc42601 146 query += " WHERE id = " + id;
f41ce580
BA
147 db.run(query);
148 if (!!obj.move)
149 {
afc42601 150 const m = obj.move;
f41ce580 151 query =
92b82def 152 "INSERT INTO Moves (gid, squares, message, played, idx) VALUES " +
f41ce580 153 "(" + id + ",'" + JSON.stringify(m.squares) + "','" + m.message +
92b82def 154 "'," + m.played + "," + m.idx + ")";
f41ce580
BA
155 db.run(query);
156 }
3d55deea
BA
157 });
158 },
159
ab4f4bf2
BA
160 remove: function(id)
161 {
162 db.parallelize(function() {
163 let query =
164 "DELETE FROM Games " +
165 "WHERE id = " + id;
166 db.run(query);
167 query =
168 "DELETE FROM Players " +
169 "WHERE gid = " + id;
170 db.run(query);
171 query =
172 "DELETE FROM Moves " +
173 "WHERE gid = " + id;
174 db.run(query);
175 });
176 },
00f2759e 177}
ab4f4bf2
BA
178
179module.exports = GameModel;