首页 > 解决方案 > Discord JS - 从 sqlite 检索信息并存储在数组中

问题描述

所以,这个问题已经让我发疯了一段时间了,我终于屈服了,在这里问这个问题。作为应该发生的事情的概述:

  1. 根据特定文本在 Discord 频道中收到的消息
  2. 从消息中提取的信息(正则表达式/查找的组合)
  3. 写入 sqlite db 的信息(3 列)
  4. 查询 sqlite db 以查找该成员在过去一小时内提出的所有声明

步骤 1-3 似乎工作正常,信息被捕获并写入数据库。但是,我已经尝试了无数种方法来拉回信息,并且搜索/研究的次数超出了我愿意承认的范围——我似乎无法让它发挥作用。

问题...... 结果应该总是至少有一个结果(这将是刚刚写入数据库的结果)所以永远不应该有机会这是 0。有时,在以前的方法中,结果已经出现返回并已存储在数组中 - 其他时候数组返回空白。

client.on('message', async message => {
    if (message.channel.id === chan_role.channels.register) {
        // The post is in the register channel
        if (message.content.includes('doing business with you')) {
            // it's a successful claim
            Rclaimedby = message.content.match(/\*\*(.*?)\*\*/)[1];
            let serverMembers = client.guilds.cache.get(chan_role.serverID).members;
            let Ruser = serverMembers.cache.find(m => m.displayName == Rclaimedby);
            Rdatetime = moment(message.createdAt);

            // Update the database with the win information
            await update_customer_db(message.channel.id, Ruser.id, message.createdTimestamp)
                .then(console.log(`Updated DB (Channel: ${message.channel.id} | Winner: ${Ruser.id} | WinTime: ${Rdatetime})`))
                .catch(console.error)
            
            // Check if the member is a Customer Booster and highlight accordingly
            if (Ruser.roles.cache.has(chan_role.roles.custboost)) {
                custboost = "<:qsoisnotresponsiblefornolife:800654013300736030> Customer Booster";
            } else {
                custboost = "Normal Member";
            }

            // Now we want to try to bring the information back from the database to check if
            // they have had multiple claims within the last 60 minutes.
            //claims = await get_customer_claims(`${Ruser.user.id}`,`${message.createdTimestamp}`);
            await get_customer_claims(`${Ruser.user.id}`, `${message.createdTimestamp}`)
                .then(results => {
                    if (results.length > 0) {
                        console.log(results.length)
                        console.log(results)
                    } else {
                        console.log(`It's empty apparently`)
                        console.log(results)
                    }
                })
                .catch(error => {
                    console.log(error)
                });

            REmbed = generate_customer_embed(message.channel.id, `${Ruser.user.id}`, `${custboost}`);
            client.channels.cache.get(chan_role.testchannels.botroom).send(REmbed);
            console.log(`${message.createdAt} - #Register - ${Rclaimedby} - ${custboost}`);
            //console.log(claims)
        }
    }

});

这是代码的最新版本 - 以下函数是当前函数(不起作用)

async function update_customer_db(chan, win, timestamp) {
    // This function will update the customer table within the database so that we
    // can query that later for repeat winners.
    let db = new sqlite.Database('./chezbot.db', sqlite.OPEN_READWRITE);
    let insertdata = db.prepare(`INSERT INTO customer VALUES (?,?,?)`);
    insertdata.run(win, chan, timestamp);
    insertdata.finalize();
    db.close();
}

//function get_customer_claims(winner, timestamp, callback)

async function get_customer_claims(winner, timestamp) {
    hourago = timestamp - 3600000
    let db = new sqlite.Database('./chezbot.db', sqlite.OPEN_READONLY);
    sql = "SELECT * FROM customer WHERE userid = \"" + winner + "\" AND wintime BETWEEN " + hourago + " AND " + timestamp + " ORDER BY wintime ASC"
    console.log(sql);
    return new Promise((resolve, reject) => {
        db.all(sql,(err, results) => {
            if (err) return reject(err);
            return resolve(results);
        });
    });
    
}

我也尝试过类似的事情:

 // Update the database with the win information
            await update_customer_db(message.channel.id, Ruser.id, message.createdTimestamp)
                .then(await get_customer_claims(Ruser.id,message.createdTimestamp,function(claims){
                    console.log(claims);
                }))
                .catch(console.error)

功能如下:

async function get_customer_claims(winner, timestamp, callback) {
    console.log(`Winner: ${winner} | Timestamp: ${timestamp}`);
    let db = new sqlite.Database('./chezbot.db', sqlite.OPEN_READONLY);
    var claims = []; // we'll return the customer claims in here

    db.serialize(function() {
        db.each("SELECT * FROM customer WHERE userid = \"" + winner + "\" AND wintime BETWEEN (" + timestamp + "-3600000) AND " + timestamp + " ORDER BY wintime ASC", function(err,row) {
            claims.push(row);
        }, function() {
            db.close();
            callback(claims);
        });
    });
}

在我尝试过的各种选项中 - 它似乎要么显示某些成员的数组信息,要么只是一个空白数组。如上所述,永远不应该有返回 null 的机会,因为我们已经在其中写入了一条记录。

期望的结果... 对于第一部分,我实际上只关心找到了多少结果,然后将导致另一个决定(如果他们是普通成员,那么他们被允许 2 个索赔...如果他们'是一个助推器,他们被允许 4 次索赔......任何更多 - 他们被静音一段时间)。但是 - 由于它不是每次都返回结果 - 我不能确信它会在正确的时间静音。

它运行的示例 SS: 最终结果

在前两个矩形中,它返回了结果(每个成员在那个小时只有一个) - 但对于第三个,它返回为空白。

数据库浏览器结果

第二个 ss 显示该成员的结果实际上已写入数据库 - 因此应该在查询中返回。

作为另一个问题 - 有时它不会返回所有结果,如下面的屏幕截图所示。第一个矩形显示这为该成员返回了一个 [](即使它已经存储了它) - 第二个矩形显示他们在大约 5 分钟后又花了一个......但是返回的结果(查看 wintime)是最初的声明 - 所以这次不包括第二个。

在此处输入图像描述

标签: javascriptnode.jssqlitediscorddiscord.js

解决方案


推荐阅读