]> git.sesse.net Git - pkanalytics/blob - players.cpp
Support filtering passes by thrower and receiver.
[pkanalytics] / players.cpp
1 #include <algorithm>
2 #include <string>
3 #include <vector>
4 #include <sqlite3.h>
5 #include "players.h"
6
7 using namespace std;
8
9 string format_timestamp(uint64_t pos);
10
11 PlayersModel::PlayersModel(sqlite3 *db) : db(db)
12 {
13         players = load_data();
14 }
15
16 QVariant PlayersModel::headerData(int section, Qt::Orientation orientation, int role) const
17 {
18         if (role != Qt::DisplayRole) {
19                 return QVariant();
20         }
21         if (orientation == Qt::Horizontal) {
22                 if (section == 0) {
23                         return "#";
24                 } else if (section == 1) {
25                         return "";  // Gender
26                 } else if (section == 2) {
27                         return "Name";
28                 } else {
29                         return QVariant();
30                 }
31         } else {
32                 return "";
33         }
34 }
35
36 QVariant PlayersModel::data(const QModelIndex &index, int role) const
37 {
38         if (role == Qt::TextAlignmentRole) {
39                 if (index.column() == 0) {
40                         return (Qt::AlignHCenter | Qt::AlignVCenter).toInt();
41                 } else if (index.column() == 1) {
42                         return (Qt::AlignHCenter | Qt::AlignVCenter).toInt();
43                 } else {
44                         return (Qt::AlignLeft | Qt::AlignVCenter).toInt();
45                 }
46         }
47         if (role != Qt::DisplayRole) {
48                 return QVariant();
49         }
50         if (index.column() == 0) {
51                 return QString::fromUtf8(players[index.row()].number);
52         } else if (index.column() == 1) {
53                 return QString::fromUtf8(players[index.row()].gender);
54         } else if (index.column() == 2) {
55                 return QString::fromUtf8(players[index.row()].name);
56         }
57         return QVariant();
58 }
59
60 string PlayersModel::get_player_name_by_id(unsigned player_id)
61 {
62         auto it = find_if(players.begin(), players.end(), [player_id](const Player &p) { return p.player_id == int(player_id); });
63         return it->name;
64 }
65
66 string PlayersModel::get_player_gender_by_id(unsigned player_id)
67 {
68         auto it = find_if(players.begin(), players.end(), [player_id](const Player &p) { return p.player_id == int(player_id); });
69         return it->gender;
70 }
71
72 void PlayersModel::edit_player(int player_id, const string &number, const string &gender, const string &name)
73 {
74         auto it = find_if(players.begin(), players.end(), [player_id](const Player &p) { return p.player_id == int(player_id); });
75         int old_row = distance(players.begin(), it);
76
77         sqlite3_stmt *stmt;
78         int ret = sqlite3_prepare_v2(db, "UPDATE player SET number=?, gender=?, name=? WHERE player=?", -1, &stmt, 0);
79         if (ret != SQLITE_OK) {
80                 fprintf(stderr, "UPDATE prepare: %s\n", sqlite3_errmsg(db));
81                 abort();
82         }
83
84         sqlite3_bind_text(stmt, 1, number.data(), number.size(), SQLITE_STATIC);
85         sqlite3_bind_text(stmt, 2, gender.data(), gender.size(), SQLITE_STATIC);
86         sqlite3_bind_text(stmt, 3, name.data(), name.size(), SQLITE_STATIC);
87         sqlite3_bind_int64(stmt, 4, player_id);
88
89         ret = sqlite3_step(stmt);
90         if (ret != SQLITE_DONE) {
91                 fprintf(stderr, "UPDATE step: %s\n", sqlite3_errmsg(db));
92                 abort();
93         }
94
95         ret = sqlite3_finalize(stmt);
96         if (ret != SQLITE_OK) {
97                 fprintf(stderr, "SELECT finalize: %s\n", sqlite3_errmsg(db));
98                 abort();
99         }
100
101         vector<Player> new_players = load_data();
102         it = find_if(new_players.begin(), new_players.end(), [player_id](const Player &p) { return p.player_id == int(player_id); });
103         int new_row = distance(new_players.begin(), it);
104
105         if (old_row == new_row) {
106                 players = std::move(new_players);
107                 emit dataChanged(createIndex(old_row, 0), createIndex(old_row, 2));
108         } else {
109                 emit beginMoveRows(QModelIndex(), old_row, old_row, QModelIndex(), new_row);
110                 players = std::move(new_players);
111                 emit endInsertRows();
112         }
113 }
114
115 std::vector<PlayersModel::Player> PlayersModel::load_data()
116 {
117         std::vector<Player> new_players;
118
119         // Read the players.
120         sqlite3_stmt *stmt;
121         int ret = sqlite3_prepare_v2(db, "SELECT player, number, name, gender FROM player ORDER BY (number+0), number", -1, &stmt, 0);
122         if (ret != SQLITE_OK) {
123                 fprintf(stderr, "SELECT prepare: %s\n", sqlite3_errmsg(db));
124                 abort();
125         }
126         for ( ;; ) {
127                 ret = sqlite3_step(stmt);
128                 if (ret == SQLITE_ROW) {
129                         Player p;
130                         p.player_id = sqlite3_column_int(stmt, 0);
131                         p.number = (const char *)sqlite3_column_text(stmt, 1);
132                         p.name = (const char *)sqlite3_column_text(stmt, 2);
133                         p.gender = (const char *)sqlite3_column_text(stmt, 3);
134                         new_players.push_back(p);
135                 } else if (ret == SQLITE_DONE) {
136                         break;
137                 } else {
138                         fprintf(stderr, "SELECT step: %s\n", sqlite3_errmsg(db));
139                         abort();
140                 }
141         }
142         ret = sqlite3_finalize(stmt);
143         if (ret != SQLITE_OK) {
144                 fprintf(stderr, "SELECT finalize: %s\n", sqlite3_errmsg(db));
145                 abort();
146         }
147
148         return new_players;
149 }