Fix pronlems edit by admins
[vchess.git] / server / models / Problem.js
index a1f9903..9978d76 100644 (file)
@@ -1,81 +1,94 @@
-var db = require("../utils/database");
+const db = require("../utils/database");
 
 /*
  * Structure:
- *   id: problem number (int)
+ *   id: integer
+ *   added: datetime
  *   uid: user id (int)
  *   vid: variant id (int)
- *   added: timestamp
- *   instructions: text
+ *   fen: varchar (optional)
+ *   instruction: text
  *   solution: text
  */
 
-const ProblemModel =
-{
-       create: function(uid, vid, fen, instructions, solution, cb)
-       {
-               db.serialize(function() {
-                       const insertQuery =
-                               "INSERT INTO Problems (added, uid, vid, fen, instructions, solution) " +
-                               "VALUES (" + Date.now() + "," + uid + "," + vid + ",'" + fen + "',?,?)";
-                       db.run(insertQuery, [instructions, solution], err => {
-                               if (!!err)
-                                       return cb(err);
-                               db.get("SELECT last_insert_rowid() AS rowid", cb);
-                       });
-               });
-       },
+const ProblemModel = {
+  checkProblem: function(p) {
+    return (
+      p.id.toString().match(/^[0-9]+$/) &&
+      p.vid.toString().match(/^[0-9]+$/) &&
+      p.fen.match(/^[a-zA-Z0-9, /-]*$/)
+    );
+  },
 
-       getOne: function(id, callback)
-       {
-               db.serialize(function() {
-                       const query =
-                               "SELECT * " +
-                               "FROM Problems " +
-                               "WHERE id = " + id;
-                       db.get(query, callback);
-               });
-       },
+  create: function(p, cb) {
+    db.serialize(function() {
+      const query =
+        "INSERT INTO Problems " +
+        "(added, uid, vid, fen, instruction, solution) " +
+          "VALUES " +
+        "(" + Date.now() + "," + p.uid + "," + p.vid + ",'" + p.fen  + "',?,?)";
+      db.run(query, [p.instruction,p.solution], function(err) {
+        cb(err, { id: this.lastID });
+      });
+    });
+  },
 
-       fetchN: function(vid, uid, type, directionStr, lastDt, MaxNbProblems, callback)
-       {
-               db.serialize(function() {
-                       let typeLine = "";
-                       if (uid > 0)
-                               typeLine = "AND uid " + (type=="others" ? "!=" : "=") + " " + uid;
-                       const query =
-                               "SELECT * FROM Problems " +
-                               "WHERE vid = " + vid +
-                               "  AND added " + directionStr + " " + lastDt + " " + typeLine + " " +
-                               "ORDER BY added " + (directionStr=="<" ? "DESC " : "") +
-                               "LIMIT " + MaxNbProblems;
-                       db.all(query, callback);
-               });
-       },
+  getNext: function(uid, onlyMine, cursor, cb) {
+    let condition = "";
+    if (onlyMine) condition = "AND uid = " + uid + " ";
+    else if (!!uid) condition = "AND uid <> " + uid + " ";
+    db.serialize(function() {
+      const query =
+        "SELECT * " +
+        "FROM Problems " +
+        "WHERE added < " + cursor + " " +
+        condition +
+        "ORDER BY added DESC " +
+        "LIMIT 20"; //TODO: 20 is arbitrary
+      db.all(query, (err, problems) => {
+        cb(err, problems);
+      });
+    });
+  },
 
-       // TODO: update fails (but insert is OK)
-       update: function(id, uid, fen, instructions, solution, cb)
-       {
-               db.serialize(function() {
-                       const query =
-                               "UPDATE Problems SET " +
-                                       "fen = '" + fen + "', " +
-                                       "instructions = ?, " +
-                                       "solution = ? " +
-                               "WHERE id = " + id + " AND uid = " + uid;
-                       db.run(query, [instructions,solution], cb);
-               });
-       },
+  getOne: function(id, cb) {
+    db.serialize(function() {
+      const query =
+        "SELECT * " +
+        "FROM Problems " +
+        "WHERE id = " + id;
+      db.get(query, (err, problem) => {
+        cb(err, problem);
+      });
+    });
+  },
 
-       remove: function(id, uid)
-       {
-               db.serialize(function() {
-                       const query =
-                               "DELETE FROM Problems " +
-                               "WHERE id = " + id + " AND uid = " + uid;
-                       db.run(query);
-               });
-       },
+  safeUpdate: function(prob, uid, devs) {
+    db.serialize(function() {
+      let whereClause = "WHERE id = " + prob.id;
+      if (!devs.includes(uid)) whereClause += " AND uid = " + uid;
+      const query =
+        "UPDATE Problems " +
+        "SET " +
+          "vid = " + prob.vid + "," +
+          "fen = '" + prob.fen + "'," +
+          "instruction = ?," +
+          "solution = ? " +
+        whereClause;
+      db.run(query, [prob.instruction, prob.solution]);
+    });
+  },
+
+  safeRemove: function(id, uid, devs) {
+    db.serialize(function() {
+      let whereClause = "WHERE id = " + prob.id;
+      if (!devs.includes(uid)) whereClause += " AND uid = " + uid;
+      const query =
+        "DELETE FROM Problems " +
+        whereClause;
+      db.run(query);
+    });
+  },
 }
 
 module.exports = ProblemModel;