Проблема с таблицей лидеров SQL nodejs discord.js - PullRequest
0 голосов
/ 05 марта 2019

Я создал простой бот разногласий в комплекте с прослушивателем сообщений и т. Д., Который добавляет данные в базу данных MySQL по определенным событиям.

Мой код для добавления +1 балла к сообщению в канал (полностью работает):

//If message is sent add points to scores table

    con.query(`SELECT * FROM scores WHERE user="${message.author.id}" AND guild= "${message.guild.id}"`, (err, rows) => {
        if (err) throw err;

        let sql;
        if (rows.length < 1) {
            sql = `INSERT INTO scores (user, guild, points) VALUES ('${message.author.id}', '${message.guild.id}', '1')`, (err, rows) => {
                if (err) throw err;
            };

        } else {
            let score = rows[0].scores;
            sql = `UPDATE scores SET points = points +1 WHERE user="${message.author.id}" AND guild= "${message.guild.id}"`;
        };

        con.query(sql);

    });

Как только команда списка лидеров введена в канал;Я хотел бы взять данные, которые находятся в таблице результатов, отсортировать их в топ-10 и распечатать их раздельно (используя message.channel.send или message.channel.send (embed).

Ниже кодаэто то, что у меня так далеко:

const Discord = require("discord.js");

module.exports.run = async (bot, message, args, con) => {
    
const top10 = `SELECT user, points, lstmsg FROM scores WHERE guild = '${message.guild.id}' ORDER BY cast(points as SIGNED) ASC LIMIT 10`;
//user, points, lstmsg from scores WHERE guild= '${message.guild.id}' ORDER BY points DESC LIMIT 10`;

con.query(top10, function(err, rows, fields) {
  if (err) throw err;

  //    const embed = new Discord.RichEmbed()
  //   .setTitle("Leaderboard")
  //   .setAuthor(bot.user.username,)
  //   .setDescription("Inactive..... Boooooo!")
  //   .addField(rows[1])
  //   .setColor(0x00AE86)


return message.channel.send(rows);

});


}
module.exports.help = {
    name: "top10",
    usage: "``prefix`` top10",
    description: "top 10 points",
}

Но он отправляет следующее в разногласии:

[object Object]
[object Object]
[object Object]
[object Object]
[object Object]
[object Object]
[object Object]
[object Object]
[object Object]
[object Object]

Есть идеи?Заранее спасибо

Использование JSON.Stringify возвращает такие результаты:

[{"user":"123456789876587659","points":"2","lstmsg":"2019-03-04T22:40:40.000Z"},{"user":"378976806730203147","points":"80","lstmsg":"2019-03-05T10:10:18.000Z"},{"user":"123456789101112131","points":"93","lstmsg":"2019-03-04T22:40:29.000Z"},{"user":"378976806730203147","points":"168","lstmsg":"2019-03-05T10:10:18.000Z"},{"user":"456567676767867677","points":"289","lstmsg":"2019-03-04T22:41:01.000Z"}]

Я бы хотел, чтобы данные отображались как:

User:
Points:
Last Message: 

Для каждой записи в БД (ограничено 10).

Я также попробовал следующее из ресурса: Система точек на основе SQLite

Код:

const Discord = require("discord.js");

module.exports.run = async (bot, message, args, con) => {
  {
    var top10query = "SELECT * FROM scores WHERE guild = ? ORDER BY points DESC LIMIT 10"
    const top10 = con.query(top10query)

    // Now shake it and show it! (as a nice embed, too!)
    const embed = new Discord.RichEmbed()
      .setTitle("Leaderboard")
      .setAuthor(bot.user.username, bot.user.avatarURL)
      .setDescription("Our top 10 points leaders!")
      .setColor(0x00AE86);

    for (const data of top10) {
      embed.addField(bot.users.get(data.user).tag, `${data.points} points (last message ${data.lstmsg})`);
    }
    return message.channel.send({ embed });
  }





}
module.exports.help = {
  name: "inactive",
  usage: "``prefix`` inactive",
  description: "Bottom 30 inactive & last message date for current weeks",
}

но я получаю ошибку (скорее всего потому, что пример был для SQLlite и адаптирован для MySQL):

(узел: 2880) UnhandledPromiseRejectionWarning: TypeError: top10 не повторяется

Ответы [ 3 ]

0 голосов
/ 05 марта 2019

Попробуйте использовать JSON.stringify();, документы для этого здесь для этого.

var o = {
  a: 2, 
  b: 3
}
console.log(JSON.stringify(o));  //"{"a":2,"b":3}"
0 голосов
/ 15 марта 2019

Я использовал карту, чтобы отобразить результаты.

const Discord = require("discord.js");

module.exports.run = async (bot, message, args, con) => {

  const top10query = `SELECT user, points, lstmsg FROM scores WHERE guild = '${message.guild.id}' ORDER BY cast(points as SIGNED) DESC LIMIT 10`

  const query = querytxt => {
    return new Promise((resolve, reject) => {
      con.query(querytxt, (err, results, fields) => {
        if (err) reject(err);
        resolve([results, fields]);
      });
    });
  };
  const [results, fields] = await query(top10query);

  const map1 = results.map(results => ` ** User:** ${bot.users.get(results.user).username} \n **Messages:** ${results.points} \n **Last message:** ${results.lstmsg} \n`);
  message.channel.send(map1)
}
module.exports.help = {
  name: "top10",
  usage: "``prefix`` top10",
  description: "top 10 points",
}
0 голосов
/ 05 марта 2019

Я бы посоветовал, если это еще не так, что user, guild являются составным первичным ключом (или уникальным ключом) таблицы результатов.Это может быть сделано в SQL с помощью:

ALTER TABLE scores DROP PRIMARY KEY, ADD PRIMARY KEY (user, guide)

Для ваших операторов SQL INSERT ON DUPLICATE KEY UPDATE является распространенным запросом для этого.Он опирается на уникальный или первичный ключ, приведенный выше.

INSERT INTO scores (user, guild, points) VALUES ('${message.author.id}', '${message.guild.id}', '1')
ON DUPLICATE KEY UPDATE points=points+1

Также см. Предотвращение внедрения SQL в Node.js

...