在中间件之外创建co-sqlite3数据库对象的正确方法

时间:2016-04-30 04:56:17

标签: node.js sqlite koa co

我正在尝试在我的koa应用程序中实现数据库访问层。这很好用:

var sqlite3 = require('co-sqlite3');
var services = require('./services/services');

app.use(function *(next){
    this.db = yield sqlite3(services.file);
    yield next
});

但我不想将数据库公开给应用程序中的每个中间件。为了防止这种情况,我尝试在中间件之外运行.setup()services.setup();,定义为:

var models = require('../models/models');
var path = require('path');
var sqlite3 = require('co-sqlite3');


module.exports = {
    file: path.join(__dirname, '../data/db.db'),
    setup: function () {
        var database = yield sqlite3(this.file);
        console.log('Database connected...');
        database.run("PRAGMA foreign_keys = ON;");
        database.run("DROP TABLE IF EXISTS BLOG_POST_BODIES; DROP TABLE IF EXISTS BLOG_POSTS;");
        database.run(models.blog_posts);
        database.run(models.users);
        console.log('database created...');

        database.run("INSERT INTO BLOG_POST_BODIES(BODY) VALUES('HELLO WORLD');");
        var x = database.run("SELECT * FROM BLOG_POST_BODIES");
        console.log(x);
    }
};

models个对象只需要运行脚本来创建博客帖子和用户表。

给我带来麻烦的一行是var database = yield sqlite3(this.file); 它给了我以下错误:

var database = yield sqlite3(this.file);
                     ^^^^^^^
SyntaxError: Unexpected identifier

我认为这是正确的,因为yield没有向前发展。但是当我使setup()生成器函数时,它不会执行。同样,当我删除yield语句时,它会告诉我database.run is not a function

我坚持这个,无法弄清楚如何正确实施它。

编辑:

如果我使.setup()成为生成器函数并且拥有所有database次调用yield,那么它会创建表并按预期执行所有内容...

app.use(function *(next){
    this.db = yield services.setup();
    yield next
});

但是我不想将db暴露给所有其他中间件,所以我回到了同样的原始问题。

如何设置co-sqlite3数据库而不将其包含在我的中间件中?

1 个答案:

答案 0 :(得分:1)

假设service.setup()是生成器函数。

更清洁的解决方案是:

app.use(function *() {
  if (!this.db) {                   // this is application context in KoaJS
    this.db = yield service.setup();
  }
  yield next;
});

app.use(function *businessLogic() {});

其他可能的方式是:

app.use(function *() { });
app.use(function *() { });
co(services.setup).then(function(val) {
  var service = val;
  app.listen(3000);     // use the service variable inside
});