我正在编写一个简单的服务器/客户端来跟踪用户登录的次数.用户可以创建一个帐户并将其计数设置为1.登录后将增加后端SQLITE3数据库的计数.
在下面的示例中,我运行"add"函数,该函数正确检查用户是否已存在,如果不存在,则将用户名,密码和1添加到用户表中.
正如您在输出中看到的那样,这正确地返回1,但为什么最后会出错?我没有打任何其他电话,但是它返回了一个no such table错误.我做的唯一一个电话console.log(UsersModel.add('kpam', '123'));是在代码的最后一行.我尝试了第72行events.js,但它并没有给我太多帮助.我添加了print语句以使其跟踪更加明显,但我感觉幕后会发生一些事情?
基本上,我很困惑为什么如果我只调用一个函数,并且该函数返回成功,那么执行结束时会出现错误?
这是返回的错误:
:$ node warmup.js 
Creating DB file.
making table!
adding user!
1
events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: SQLITE_ERROR: no such table: Users
:$ 
这是我的代码:
var http = require('http');
var fs = require('fs');
var file = 'data.db';
var exists = fs.existsSync(file);
if (!exists) {
    console.log("Creating DB file.");
    fs.openSync(file, 'w');
}
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database(file);
var UsersModel = {
    // success, no errors/problems
    SUCCESS: 1, 
    // cannot find the user/password pair in the database (for 'login' only)
    ERR_BAD_CREDENTIALS: -1,
    // trying to add a user that already exists (for 'add' only)
    ERR_USER_EXISTS: -2,
    // invalid user name (empty or longer than MAX_USERNAME_LENGTH) (for 'add'/'login')
    ERR_BAD_USERNAME: -3,
    // invalid password name (longer than MAX_PASSWORD_LENGTH) (for 'add')
    ERR_BAD_PASSWORD: -4,
    // maximum user name length
    MAX_USERNAME_LENGTH: 128,
    // maximum password length
    MAX_PASSWORD_LENGTH: 128,
    login: function(user, password) {
        if (!UsersModel.userExists(user, false)) {
            return UsersModel.ERR_BAD_CREDENTIALS;
        }
        if (!UsersModel.checkPassword(user, password)) {
            return UsersModel.ERR_BAD_CREDENTIALS;
        }
        count = UsersModel.increaseCount(user);
        return count;
    },
    add: function(user, password) {
        if (UsersModel.userExists(user, true)) {
            return UsersModel.ERR_USER_EXISTS;
        }
        if (!UsersModel.isValidUsername(user)) {
            return UsersModel.ERR_BAD_USERNAME;
        }
        if (!UsersModel.isValidPassword(password)) {
            return UsersModel.ERR_BAD_PASSWORD;
        }
        UsersModel.addUser(user, password);
        return 1;
    },
    userExists: function(user, makeTable) {
        if (!exists) {
            if (makeTable) {
                console.log('making table!');
                db.run('CREATE TABLE Users (name TEXT, password TEXT, count INT)');
            }
            return false;
        } 
        db.serialize(function() {
            console.log('checking user!');
            row = db.get("SELECT name FROM Users WHERE name = '" + user + "'");
        });
        return !(typeof(row.name) === 'undefined');
    },
    increaseCount: function(user) {
        db.serialize(function() {
            console.log('increasing count!');
            count = db.get("SELECT count FROM Users WHERE name = '" + user + "'") + 1;
            db.run("UPDATE Users SET count = '" + count + "' WHERE name = '" + user + "'");
            return count;
        });
    },
    addUser: function(user, password) {
        count = 0;
        console.log('adding user!');
        db.run("INSERT INTO Users (name, password, count) VALUES ('" + user + "','" + password + "','" + 0 + "')");
    },
    checkPassword: function(user, password) {
        db.serialize(function() {
            console.log('checking pw!');
            row = db.get("SELECT password FROM Users WHERE name = '" + user + "'");
        });
        return row.password == password;
    },
    isValidUsername: function(user) {
        return user.length < 129;
    },
    isValidPassword: function(password) {
        return password.length < 129;
    }
}
console.log(UsersModel.add('kpam', '123'));
小智 7
db.run(...)调用是异步的.所以他们立即返回,看起来像你的代码成功.然而,他们仍然在后台运行.因此,SELECT语句可能在CREATE TABLE完成之前开始运行.这就是你得到那个错误的原因.
我注意到SELECT语句在db.serialize(...)调用中.不幸的是,该调用仅序列化其范围内的语句.序列化块外部的所有调用继续并行运行(这包括稍后出现的INSERT语句).
您的代码需要重新构建,以使用节点sqlite3模块所依赖的回调.看一下这个简单的例子:https: //github.com/mapbox/node-sqlite3/blob/master/examples/simple-chaining.js
请注意每个db操作的最后一个参数是如何在操作完成后调用的函数的名称.
| 归档时间: | 
 | 
| 查看次数: | 8648 次 | 
| 最近记录: |