X-Git-Url: https://git.auder.net/?p=vchess.git;a=blobdiff_plain;f=server%2Fmodels%2FGame.js;h=02e3194b130ae3e84cf9ec4e8e29ddcdc7401b83;hp=fa4aea02c73e55b8be4eb887a2728773d3e833d0;hb=dcd68c4108412f45b8ce119ae80ce8f6e296800b;hpb=b7cbbda10f16c2419f9a4d49e219fcface5e5658 diff --git a/server/models/Game.js b/server/models/Game.js index fa4aea02..02e3194b 100644 --- a/server/models/Game.js +++ b/server/models/Game.js @@ -1,4 +1,5 @@ var db = require("../utils/database"); +const UserModel = require("./User"); /* * Structure table Games: @@ -8,7 +9,9 @@ var db = require("../utils/database"); * fen: varchar (current position) * timeControl: string * score: varchar (result) + * scoreMsg: varchar ("Time", "Mutual agreement"...) * created: datetime + * drawOffer: boolean * * Structure table Players: * gid: ref game id @@ -18,13 +21,36 @@ var db = require("../utils/database"); * Structure table Moves: * gid: ref game id * squares: varchar (description) - * message: text * played: datetime * idx: integer + * + * Structure table Chats: + * gid: game id (int) + * msg: varchar + * name: varchar + * added: datetime */ const GameModel = { + checkGameInfo: function(g) { + if (!g.id.toString().match(/^[0-9]+$/)) + return "Wrong game ID"; + if (!g.vid.toString().match(/^[0-9]+$/)) + return "Wrong variant ID"; + if (!g.vname.match(/^[a-zA-Z0-9]+$/)) + return "Wrong variant name"; + if (!g.timeControl.match(/^[0-9dhms +]+$/)) + return "Wrong characters in time control"; + if (!g.fen.match(/^[a-zA-Z0-9, /-]*$/)) + return "Bad FEN string"; + if (g.players.length != 2) + return "Need exactly 2 players"; + if (g.players.some(p => !p.id.toString().match(/^[0-9]+$/))) + return "Wrong characters in player ID"; + return ""; + }, + create: function(vid, fen, timeControl, players, cb) { db.serialize(function() { @@ -54,8 +80,10 @@ const GameModel = db.serialize(function() { // TODO: optimize queries? let query = + // NOTE: g.scoreMsg can be NULL + // (in this case score = "*" and no reason to look at it) "SELECT g.id, g.vid, g.fen, g.fenStart, g.timeControl, g.score, " + - "v.name AS vname " + + "g.scoreMsg, v.name AS vname " + "FROM Games g " + "JOIN Variants v " + " ON g.vid = v.id " + @@ -73,20 +101,29 @@ const GameModel = if (!!err2) return cb(err2); query = - "SELECT squares, message, played, idx " + + "SELECT squares, played, idx " + "FROM Moves " + "WHERE gid = " + id; db.all(query, (err3,moves) => { if (!!err3) return cb(err3); - const game = Object.assign({}, - gameInfo, - { - players: players, - moves: moves - } - ); - return cb(null, game); + query = + "SELECT msg, name, added " + + "FROM Chats " + + "WHERE gid = " + id; + db.all(query, (err4,chats) => { + if (!!err4) + return cb(err4); + const game = Object.assign({}, + gameInfo, + { + players: players, + moves: moves, + chats: chats, + } + ); + return cb(null, game); + }); }); }); }); @@ -134,30 +171,65 @@ const GameModel = }); }, - // obj can have fields move, fen, drawOffer and/or score + checkGameUpdate: function(obj) + { + // Check all that is possible (required) in obj: + if (!!obj.move) + { + if (!obj.move.played.toString().match(/^[0-9]+$/)) + return "Wrong move played time"; + if (!obj.move.idx.toString().match(/^[0-9]+$/)) + return "Wrong move index"; + } + if (!!obj.fen && !obj.fen.match(/^[a-zA-Z0-9, /-]*$/)) + return "Wrong FEN string"; + if (!!obj.score && !obj.score.match(/^[012?*\/-]+$/)) + return "Wrong characters in score"; + if (!!obj.scoreMsg && !obj.scoreMsg.match(/^[a-zA-Z ]+$/)) + return "Wrong characters in score message"; + if (!!obj.chat) + return UserModel.checkNameEmail({name: obj.chat.name}); + return ""; + }, + + // obj can have fields move, chat, fen, drawOffer and/or score update: function(id, obj) { db.parallelize(function() { let query = "UPDATE Games " + "SET "; - if (!!obj.drawOffer) - query += "drawOffer = " + obj.drawOffer + ","; + let modifs = ""; + if (!!obj.message) + modifs += "message = message || ' ' || '" + obj.message + "',"; + if ([true,false].includes(obj.drawOffer)) + modifs += "drawOffer = " + obj.drawOffer + ","; if (!!obj.fen) - query += "fen = '" + obj.fen + "',"; + modifs += "fen = '" + obj.fen + "',"; if (!!obj.score) - query += "score = '" + obj.score + "',"; - query = query.slice(0,-1); //remove last comma - query += " WHERE id = " + id; - db.run(query); + modifs += "score = '" + obj.score + "',"; + if (!!obj.scoreMsg) + modifs += "scoreMsg = '" + obj.scoreMsg + "',"; + modifs = modifs.slice(0,-1); //remove last comma + if (modifs.length > 0) + { + query += modifs + " WHERE id = " + id; + db.run(query); + } if (!!obj.move) { const m = obj.move; query = - "INSERT INTO Moves (gid, squares, message, played, idx) VALUES " + - "(" + id + ",'" + JSON.stringify(m.squares) + "','" + m.message + - "'," + m.played + "," + m.idx + ")"; - db.run(query); + "INSERT INTO Moves (gid, squares, played, idx) VALUES " + + "(" + id + ",?," + m.played + "," + m.idx + ")"; + db.run(query, JSON.stringify(m.squares)); + } + if (!!obj.chat) + { + query = + "INSERT INTO Chats (gid, msg, name, added) VALUES (" + + id + ",?,'" + obj.chat.name + "'," + "," + Date.now() + ")"; + db.run(query, obj.chat.msg); } }); }, @@ -177,6 +249,10 @@ const GameModel = "DELETE FROM Moves " + "WHERE gid = " + id; db.run(query); + query = + "DELETE FROM Chats " + + "WHERE gid = " + id; + db.run(query); }); },