NodeJS - sqlite3,数据同步

时间:2014-07-07 05:56:29

标签: node.js sqlite express synchronization

我正在尝试用nodejs,socket.io和sqlite作为数据库编写一个简单的应用程序。 这主要是为了培训目的,了解nodejs如何工作,看看它是否适合其他项目。

该应用是一个简单的页面,只有一个按钮。 数据库用于存储按钮的状态(开/关)。 //这是一项要求,因为其他服务可以访问此数据库 基本上,页面显示当前状态(数据库中的最后一条记录) 单击该按钮时,状态将更改,并且新状态将添加到数据库中。 这似乎有效,数据库已更新。

现在,我想通过使用按钮的颜色来显示当前状态,从而使这些更改可视化。 例如,当它为OFF时为蓝色,在为ON时为红色。 我尝试使用socket.io来处理click事件,似乎我可以在点击它时更改按钮的颜色。

但是如果页面被刷新,颜色就消失了(似乎我需要刷新页面以查看数据库中的更新值)

如何保持页面内容(显示的数据和按钮的颜色)与数据库同步?

我希望有人能指出我正确的方向。 谢谢,

app.js

var express = require('express');
var sqlite3 = require('sqlite3').verbose();
var http = require('http');
var path = require('path');
var mainDB = 'data/mydb';
var hbs = require('hbs');

var app = express();
//all environments
app.set('port', 3000);
app.set('view engine', 'html');
app.engine('html', hbs.__express);
app.use(express.bodyParser());
app.use(express.static(path.join(__dirname, 'public')));

function getStatus(database, callback){
    var db = new sqlite3.Database(database);
    // Get the last record
    db.get("SELECT * FROM status ORDER BY id DESC LIMIT 1", function(err, all) {
        console.log("Current status..."+all.status);
        callback(err, all);
    });
    db.close();
}
function setStatus(database, status){
    console.log("Set Status..."+status);
    var db = new sqlite3.Database(database);
    db.run("INSERT INTO status(status, time) VALUES(?,?)", status, Date.now());
    db.close();
}

app.get('/', function(req, res) {
    getStatus(mainDB,function(err, json_value) {
        res.render('index',{title:"Test", status:json_value.status,time:json_value.time});
    });

});


var server = http.createServer(app);
var io = require('socket.io').listen(server);

io.sockets.on('connection', function(socket){
    socket.on('click', function(htmlID){
        getStatus(mainDB,function(err, json_value) {
            console.log("Button clicked, current status: "+json_value.status)
            setStatus(mainDB, !json_value.status);
            io.sockets.emit('updateButton',htmlID); 
        });
    });

});

server.listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

Client.js:

$(document).ready(function () {

    var socket = io.connect();

    $('.box').click(function () {
        var selectedID = $(this).attr("id");
        socket.emit('click', selectedID);
        updateButton(selectedID);
    });


    function updateButton(selectedID) {
        $("#" + selectedID).css({
            "background": "red"
        });
    }

    socket.on('updateButton', function (selectedID) {
        updateButton(selectedID);
    });
});

视图/ index.html中:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Test</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="css/style.css">
        <script src="js/jquery.min.js"></script>
        <script src="js/client.js"></script>
        <script src="/socket.io/socket.io.js"></script>
    </head>
    <body>
        <div class="container">
            <h1>{{title}}</h1>
            <p>Status: {{status}}</p>
            <p>Time: {{time}}</p>
              <div class="box" id="alarm">{{status}}</div>
        </div>
    </body>
</html>

创建虚拟数据库的.py:

#!/usr/bin/env python
from datetime import date, datetime
import sqlite3
import time

tables = {
    'status' : '''
    CREATE TABLE status(id INTEGER PRIMARY KEY, 
    status INTEGER,
    time  TIMESTAMP)
    '''
    }

def create_db():
    db = sqlite3.connect("data/mydb")
    with db:
        cursor = db.cursor()
        for tb_name, create_statement in tables.iteritems():
            cursor.execute('drop table if exists %s'%tb_name)
            print "Creating table : %s"%tb_name
            cursor.execute(create_statement)
            db.commit()

        # fake up some data
        status = 0
        for i in range(10):
            status = not status
            default_values = [status, datetime.now() ]
            cursor.execute('INSERT INTO status(status, time) values(?,?)', default_values)
            time.sleep(0.5)
        db.commit()
    db.close()

if __name__ == "__main__":
    create_db()

1 个答案:

答案 0 :(得分:0)

据我所知,Sqlite模块是在内存数据库&#34;中编写的,所以当你编写任何INSERT语句时,它不会被提交,直到你把它写入磁盘。

我正在使用电子和sql.js(sqlite3节点不能用于电子) 我发现的唯一解决方案是运行查询(INSERT ...),导出db(sql.js有db.export()方法),然后使用文件系统覆盖文件。