Improve notification system after a move or at new game
[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
ab4f4bf2 16 * rtime: real (remaining time)
00f2759e
BA
17 *
18 * Structure table Moves:
ab4f4bf2 19 * gid: ref game id
00f2759e 20 * move: varchar (description)
ab4f4bf2 21 * message: text
00f2759e
BA
22 * played: datetime
23 * idx: integer
24 * color: character
25 */
26
ab4f4bf2 27const GameModel =
00f2759e 28{
a9b131f1 29 create: function(vid, fen, timeControl, players, cb)
ab4f4bf2 30 {
88667455 31 db.serialize(function() {
ab4f4bf2 32 let query =
fd7aea36
BA
33 "INSERT INTO Games (vid, fenStart, score, timeControl) " +
34 "VALUES (" + vid + ",'" + fen + "','*','" + timeControl + "')";
8c564f46 35 db.run(query, function(err) {
ab4f4bf2
BA
36 if (!!err)
37 return cb(err);
8c564f46
BA
38 players.forEach((p,idx) => {
39 const color = (idx==0 ? "w" : "b");
2be5d614
BA
40 query =
41 "INSERT INTO Players VALUES " +
42 // Remaining time = -1 means "unstarted"
8c564f46 43 "(" + this.lastID + "," + p.id + ",'" + color + "', -1)";
2be5d614
BA
44 db.run(query);
45 });
46 cb(null, {gid: this.lastID});
00f2759e
BA
47 });
48 });
ab4f4bf2 49 },
00f2759e 50
ab4f4bf2
BA
51 // TODO: queries here could be async, and wait for all to complete
52 getOne: function(id, cb)
53 {
54 db.serialize(function() {
55 let query =
fd7aea36
BA
56 "SELECT * " +
57 "FROM Games " +
ab4f4bf2
BA
58 "WHERE id = " + id;
59 db.get(query, (err,gameInfo) => {
60 if (!!err)
61 return cb(err);
00f2759e 62 query =
fd7aea36
BA
63 "SELECT uid, color, rtime " +
64 "FROM Players " +
65 "WHERE gid = " + id;
66 db.all(query, (err2,players) => {
ab4f4bf2
BA
67 if (!!err2)
68 return cb(err2);
69 query =
fd7aea36 70 "SELECT move, message, played, idx, color " +
ab4f4bf2
BA
71 "FROM Moves " +
72 "WHERE gid = " + id;
fd7aea36 73 db.all(query, (err3,moves) => {
ab4f4bf2
BA
74 if (!!err3)
75 return cb(err3);
fd7aea36
BA
76 const game = Object.assign({},
77 gameInfo,
78 {
79 players: players,
80 moves: moves
81 }
82 );
ab4f4bf2
BA
83 return cb(null, game);
84 });
00f2759e
BA
85 });
86 });
87 });
ab4f4bf2 88 },
00f2759e 89
5d04793e 90 getByUser: function(uid, excluded, cb)
ab4f4bf2
BA
91 {
92 db.serialize(function() {
93 // Next query is fine because a player appear at most once in a game
94 const query =
95 "SELECT gid " +
96 "FROM Players " +
5d04793e 97 "WHERE uid " + (excluded ? "<>" : "=") + " " + uid;
ab4f4bf2
BA
98 db.run(query, (err,gameIds) => {
99 if (!!err)
100 return cb(err);
098cd7f1 101 gameIds = gameIds || []; //might be empty
ab4f4bf2
BA
102 let gameArray = [];
103 gameIds.forEach(gidRow => {
104 GameModel.getOne(gidRow["gid"], (err2,game) => {
105 if (!!err2)
106 return cb(err2);
107 gameArray.push(game);
108 });
109 });
110 return cb(null, gameArray);
111 });
112 });
113 },
114
411d23cd
BA
115 getPlayers: function(id, cb)
116 {
117 db.serialize(function() {
118 const query =
119 "SELECT id " +
120 "FROM Players " +
121 "WHERE gid = " + id;
122 db.all(query, (err,players) => {
123 return cb(err, players);
124 });
125 });
126 },
127
3d55deea
BA
128 // obj can have fields move, fen and/or score
129 update: function(id, obj, cb)
130 {
131 db.serialize(function() {
132 let query =
133 "UPDATE Games " +
134 "SET ";
135 if (!!obj.move)
136 query += "move = " + obj.move + ","; //TODO: already stringified?!
137 if (!!obj.fen)
138 query += "fen = " + obj.fen + ",";
139 if (!!obj.score)
140 query += "score = " + obj.score + ",";
141 query = query.slice(0,-1); //remove last comma
142 query += " WHERE gameId = " + id;
143 db.run(query, (err) => {
144 cb(err);
145 });
146 });
147 },
148
ab4f4bf2
BA
149 remove: function(id)
150 {
151 db.parallelize(function() {
152 let query =
153 "DELETE FROM Games " +
154 "WHERE id = " + id;
155 db.run(query);
156 query =
157 "DELETE FROM Players " +
158 "WHERE gid = " + id;
159 db.run(query);
160 query =
161 "DELETE FROM Moves " +
162 "WHERE gid = " + id;
163 db.run(query);
164 });
165 },
00f2759e 166}
ab4f4bf2
BA
167
168module.exports = GameModel;