0

我目前有一个用 Perl 编写的网站,使用MojoliciousMojo::Pg。它所做的其中一件事是从我的 Ninja Block 的温度传感器中提取并显示数据。我在 Postgres 中有四张桌子outdoor_temperature,, outdoor_humidity, 和室内的桌子也是一样的。表格如下所示:

 Column |  Type   | Modifiers 
--------+---------+-----------
 time   | bigint  | not null
 value  | numeric | not null
 date   | date    | not null

哪里time是以毫秒为单位的纪元值(每分钟一条记录),value是温度或湿度,date就是这样(因此,给定日期的每条记录在date列中都有相同的值)。

我正在使用 Node 和 Sails.js 重写网站,主要是为了学习机会,我有点坚持在这里做事的最佳方式。在其 Perl 化身中,我为每个与 Ninja Block 相关的功能(显示今天的当前温度,显示给定日期的最高/最低等)设置了一个子例程,然后我传递了它的位置(室内或室外) ) 一切都从那里开始,如下所示:

sub current {
    my ( $self, $table ) = @_;
    return $self->pg->db->query( "select time, value from $table where time = (select max(time) from $table)" )->hash;
}

但是对于 Sails/Waterline,模型似乎只包含一张桌子。在我的 Perl 版本中的任何表之间没有连接,只是在每个单独的表上进行一些半复杂的 SQL 查询,我可以在 Sails 中完成这些查询.query,但我不确定如何在 Sails 下保留相同的设置而不需要复制检查室内和室外桌子时的一堆代码。

还是我完全错误地考虑了这一点,并且有更好的方法来完成这一切?

4

1 回答 1

0

我最终选择了一个位于控制器和模型之间的服务。控制器函数如下所示(使用与上面相同的示例):

currentTemperature: function(req, res) {
    ninjaBlockService.getCurrentTemperature(req.param('location'), function(data) {
        return res.json(data);
    });
}

以及服务功能:

getCurrentTemperature: function(location, callback) {
    var query = "select time, value from " + location + "_temperature where time = (select max(time) from " + location + "_temperature)";

    var locations = {
        outdoor: function() {
            NinjaBlockOutdoorTemperature.query(query, function(err, results) {
                return callback(results.rows);
            });
        },
        indoor: function() {
            NinjaBlockIndoorTemperature.query(query, function(err, results) {
                return callback(results.rows);
            });
        }
    };

    locations[location]();
}

它可能会更优雅一些,但对我来说效果很好。

事实证明,如果您使用的是 Waterline 的 PostgreSQL native .query,您甚至不需要多个表的多个模型。我添加了一个名为的新模型NinjaBlock,它没有属性或任何东西,并且可以运行我的查询,而不管它们在哪个表中。所以上面的函数现在看起来像这样:

getCurrentTemperature: function(location, callback) {
    var query = "select time, value from " + location + "_temperature where time = (select max(time) from " + location + "_temperature)";

    NinjaBlock.query(query, function(err, results) {
                return callback(results.rows);
    });
}

简单的!

于 2016-02-06T09:53:21.320 回答