summaryrefslogtreecommitdiff
path: root/worker.js
blob: 7cefbdb94ccbe9ab7aa2cb13081b741adc5e7cad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#!/usr/bin/node
/* jshint esnext:true */
'use strict';

var amqp = require("amqplib"),
    Seq = require("sequelize");

var RABBITMQ_URI = process.env.RABBITMQ_URI || "amqp://localhost",
    DATABASE_URI = process.env.DATABASE_URI || "sqlite:///db.sqlite";

(async () => {
    let seq = new Seq(DATABASE_URI),
        model = require("./model")(seq, Seq),
        rabbit = await amqp.connect(RABBITMQ_URI),
        ch = await rabbit.createChannel();

    /* recreate for debugging
    await seq.query("SET FOREIGN_KEY_CHECKS=0");
    await seq.sync({force: true});
    */
    //await seq.sync();

    await ch.assertQueue("process", {durable: true});
    await ch.prefetch(1);

    ch.consume("process", async (msg) => {
        let match = JSON.parse(msg.content);

        // TODO commit less often if possible, avoid deadlocks
        let transaction = await seq.transaction({ autocommit: false });

        function flatten(obj) {
            let attrs = obj.attributes || {},
                stats = attrs.stats || {},
                o = Object.assign({}, obj, attrs, stats);
            o.api_id = o.id;  // rename
            delete o.id;
            delete o.type;
            delete o.attributes;
            delete o.stats;
            delete o.relationships;
            return o;
        }

        /* bring jsonapi nested response into our db structure-like shape */
        match.rosters = match.rosters.map((roster) => {
            roster.participants = roster.participants.map((participant) => {
                participant.player = flatten(participant.player);
                return flatten(participant);
            });
            return flatten(roster);
        });
        match = flatten(match);
        console.log(match);

        /* upsert everything */
        await match.rosters.forEach(async (roster) => {
            await roster.participants.forEach(async (participant) => {
                await model.Player.upsert(participant.player);

                participant.roster_api_id = roster.api_id;
                participant.player_api_id = participant.player.api_id;
                await model.Participant.upsert(participant, {
                    include: [ model.Player ]
                });
            });

            //if (roster.team != null) model.Team.upsert(roster.team);

            roster.match_api_id = match.api_id;
            await model.Roster.upsert(roster, {
                include: [ model.Participant/*, model.Team*/ ]
            });
        });

        /*match.assets.forEach((asset) => {
            model.Asset.upsert(asset);
        });*/

        await model.Match.upsert(match, {
            include: [ model.Roster/*, model.Asset*/ ]
        });

        await transaction.commit();  // TODO rollback on err
        ch.ack(msg);
    }, { noAck: false });
})();