]> git.sesse.net Git - pkanalytics/blob - json.cpp
Export formations to the JSON.
[pkanalytics] / json.cpp
1 #include <QJsonArray>
2 #include <QJsonDocument>
3 #include <QJsonObject>
4 #include <sqlite3.h>
5 #include "json.h"
6
7 QJsonArray export_players_to_json(sqlite3 *db)
8 {
9         QJsonArray players;
10
11         sqlite3_stmt *stmt;
12         int ret = sqlite3_prepare_v2(db, "SELECT player, number, name, gender FROM player ORDER BY (number+0), number", -1, &stmt, 0);
13         if (ret != SQLITE_OK) {
14                 fprintf(stderr, "SELECT prepare: %s\n", sqlite3_errmsg(db));
15                 abort();
16         }
17         for ( ;; ) {
18                 ret = sqlite3_step(stmt);
19                 if (ret == SQLITE_ROW) {
20                         QJsonObject p;
21                         p.insert("player_id", sqlite3_column_int(stmt, 0));
22                         p.insert("number", (const char *)sqlite3_column_text(stmt, 1));
23                         p.insert("name", (const char *)sqlite3_column_text(stmt, 2));
24                         p.insert("gender", (const char *)sqlite3_column_text(stmt, 3));
25                         players.push_back(std::move(p));
26                 } else if (ret == SQLITE_DONE) {
27                         break;
28                 } else {
29                         fprintf(stderr, "SELECT step: %s\n", sqlite3_errmsg(db));
30                         abort();
31                 }
32         }
33         ret = sqlite3_finalize(stmt);
34         if (ret != SQLITE_OK) {
35                 fprintf(stderr, "SELECT finalize: %s\n", sqlite3_errmsg(db));
36                 abort();
37         }
38
39         return players;
40 }
41
42 QJsonArray export_formations_to_json(sqlite3 *db)
43 {
44         QJsonArray formations;
45
46         sqlite3_stmt *stmt;
47         int ret = sqlite3_prepare_v2(db, "SELECT formation, offense, name FROM formation ORDER BY name", -1, &stmt, 0);
48         if (ret != SQLITE_OK) {
49                 fprintf(stderr, "SELECT prepare: %s\n", sqlite3_errmsg(db));
50                 abort();
51         }
52         for ( ;; ) {
53                 ret = sqlite3_step(stmt);
54                 if (ret == SQLITE_ROW) {
55                         QJsonObject f;
56                         f.insert("formation_id", sqlite3_column_int(stmt, 0));
57                         f.insert("offense", bool(sqlite3_column_int(stmt, 1)));
58                         f.insert("name", (const char *)sqlite3_column_text(stmt, 2));
59                         formations.push_back(std::move(f));
60                 } else if (ret == SQLITE_DONE) {
61                         break;
62                 } else {
63                         fprintf(stderr, "SELECT step: %s\n", sqlite3_errmsg(db));
64                         abort();
65                 }
66         }
67         ret = sqlite3_finalize(stmt);
68         if (ret != SQLITE_OK) {
69                 fprintf(stderr, "SELECT finalize: %s\n", sqlite3_errmsg(db));
70                 abort();
71         }
72
73         return formations;
74 }
75
76 QJsonArray export_matches_to_json(sqlite3 *db)
77 {
78         QJsonArray matches;
79
80         // Load the events, splitting them into matches as we go.
81         std::map<int, QJsonArray *> events_per_match;
82         sqlite3_stmt *stmt;
83         int ret = sqlite3_prepare_v2(db, "SELECT match, t, player, type FROM event ORDER BY t", -1, &stmt, 0);
84         if (ret != SQLITE_OK) {
85                 fprintf(stderr, "SELECT prepare: %s\n", sqlite3_errmsg(db));
86                 abort();
87         }
88         for ( ;; ) {
89                 ret = sqlite3_step(stmt);
90                 if (ret == SQLITE_ROW) {
91                         int match = sqlite3_column_int(stmt, 0);
92                         if (events_per_match.count(match) == 0) {
93                                 events_per_match[match] = new QJsonArray;
94                         }
95
96                         QJsonObject e;
97                         e.insert("t", sqlite3_column_int(stmt, 1));
98                         if (sqlite3_column_type(stmt, 2) == SQLITE_INTEGER) {
99                                 e.insert("player", sqlite3_column_int(stmt, 2));
100                         } else {
101                                 e.insert("player", QJsonValue());  // null
102                         }
103                         e.insert("type", (const char *)sqlite3_column_text(stmt, 3));
104                         events_per_match[match]->push_back(std::move(e));
105                 } else if (ret == SQLITE_DONE) {
106                         break;
107                 } else {
108                         fprintf(stderr, "SELECT step: %s\n", sqlite3_errmsg(db));
109                         abort();
110                 }
111         }
112         ret = sqlite3_finalize(stmt);
113         if (ret != SQLITE_OK) {
114                 fprintf(stderr, "SELECT finalize: %s\n", sqlite3_errmsg(db));
115                 abort();
116         }
117
118         // Load the matches themselves.
119         ret = sqlite3_prepare_v2(db, "SELECT match, description FROM match ORDER BY match", -1, &stmt, 0);
120         if (ret != SQLITE_OK) {
121                 fprintf(stderr, "SELECT prepare: %s\n", sqlite3_errmsg(db));
122                 abort();
123         }
124         for ( ;; ) {
125                 ret = sqlite3_step(stmt);
126                 if (ret == SQLITE_ROW) {
127                         int match = sqlite3_column_int(stmt, 0);
128                         QJsonObject m;
129                         m.insert("match_id", match);
130                         m.insert("description", (const char *)sqlite3_column_text(stmt, 1));
131                         if (events_per_match.count(match)) {
132                                 m.insert("events", std::move(*events_per_match[match]));
133                                 delete events_per_match[match];
134                         } else {
135                                 m.insert("events", QJsonArray());
136                         }
137                         matches.push_back(std::move(m));
138                 } else if (ret == SQLITE_DONE) {
139                         break;
140                 } else {
141                         fprintf(stderr, "SELECT step: %s\n", sqlite3_errmsg(db));
142                         abort();
143                 }
144         }
145         ret = sqlite3_finalize(stmt);
146         if (ret != SQLITE_OK) {
147                 fprintf(stderr, "SELECT finalize: %s\n", sqlite3_errmsg(db));
148                 abort();
149         }
150
151         return matches;
152 }
153
154 void export_to_json(sqlite3 *db, const char *filename)
155 {
156         QJsonObject obj;
157         obj.insert("players", export_players_to_json(db));
158         obj.insert("formations", export_formations_to_json(db));
159         obj.insert("matches", export_matches_to_json(db));
160
161         QByteArray serialized = QString(QJsonDocument(obj).toJson(QJsonDocument::Compact)).toUtf8();
162         FILE *fp = fopen("ultimate.json", "w");
163         if (fp == nullptr) {
164                 perror("ultimate.json");
165                 exit(1);
166         }
167         if (fwrite(serialized.data(), serialized.size(), 1, fp) != 1) {
168                 perror("fwrite");
169                 exit(1);
170         }
171         if (fclose(fp) != 0) {
172                 perror("fclose");
173                 exit(1);
174         }
175 }