source: network-game/server/DataAccess.cpp@ e708305

Last change on this file since e708305 was 95d7add, checked in by Dmitry Portnoy <dmp1488@…>, 11 years ago

more rebust error handling in the data-access code, specifically in cases where the initial database connection failes

  • Property mode set to 100644
File size: 4.8 KB
Line 
1#include "DataAccess.h"
2
3#include <iostream>
4#include <sstream>
5#include <cstdlib>
6#include <crypt.h>
7
8using namespace std;
9
10DataAccess::DataAccess()
11{
12 mysql_init(&mysql);
13 connection = mysql_real_connect(&mysql, "localhost", "pythonAdmin", "pyMaster09*", "pythondb", 0, 0, 0);
14
15 if (connection == NULL) {
16 cout << mysql_error(&mysql) << endl;
17 }else
18 cout << "Connection successful" << endl;
19}
20
21DataAccess::~DataAccess()
22{
23 mysql_close(connection);
24 mysql_close(&mysql);
25}
26
27int DataAccess::insertPlayer(string username, string password, Player::PlayerClass playerClass)
28{
29 ostringstream oss;
30
31 string salt = "$1$";
32 int random;
33 char chr;
34 for(int i=0; i<8; i++)
35 {
36 random = rand() % 62;
37 if (random < 26)
38 chr = (char)('a'+random);
39 else if (random < 52)
40 chr = (char)('A'+random-26);
41 else
42 chr = (char)('0'+random-52);
43 salt += chr;
44 }
45 salt += '$';
46
47 string encrypted(crypt(password.c_str(), salt.c_str()));
48
49 oss << "'" << username << "', '" << encrypted << "', " << playerClass;
50
51 return insert("users", "name, password, class", oss.str());
52}
53
54int DataAccess::updatePlayer(string username, string password)
55{
56 ostringstream values, where;
57
58 values << "password='" << password << "'";
59
60 where << "name='" << username << "'";
61
62 return update("users", values.str(), where.str());
63}
64
65Player *DataAccess::getPlayer(string username)
66{
67 MYSQL_RES *result;
68 MYSQL_ROW row;
69 Player *p;
70 ostringstream oss;
71
72 oss << "name='" << username << "'";
73
74 result = select("users", oss.str().c_str());
75
76 cout << "Got result" << endl;
77
78 if (result == NULL) {
79 cout << "Error occured" << endl;
80 cout << mysql_error(connection) << endl;
81 return NULL;
82 }
83
84 if ( ( row = mysql_fetch_row(result)) != NULL ) {
85 cout << "Creating a new player" << endl;
86 p = new Player(string(row[1]), string(row[2]));
87 if (row[3] == NULL) {
88 p->setClass(Player::CLASS_NONE);
89 cout << "Class from db was NULL" << endl;
90 }else {
91 p->setClass((Player::PlayerClass)atoi(row[3]));
92 cout << "Class from db: " << atoi(row[3]) << endl;
93 }
94 cout << "Player class: " << p->playerClass << endl;
95 cout << "Created new player" << endl;
96 }else {
97 cout << "Returned no results for some reason" << endl;
98 p = NULL;
99 }
100
101 mysql_free_result(result);
102
103 return p;
104}
105
106// need to make sure this list is freed
107// since we need to create a DataAccess class
108// when calling these functions,
109// we could free this list in the destructor
110list<Player*>* DataAccess::getPlayers()
111{
112 MYSQL_RES *result;
113 MYSQL_ROW row;
114 ostringstream oss;
115
116 result = select("users", "");
117
118 if (result == NULL) {
119 cout << mysql_error(connection) << endl;
120 return NULL;
121 }
122
123 list<Player*>* lstPlayers = new list<Player*>();
124 while ( ( row = mysql_fetch_row(result)) != NULL ) {
125 cout << row[0] << ", " << row[1] << ", " << row[2] << endl;
126 lstPlayers->push_back(new Player(row[1], row[2]));
127 }
128
129 mysql_free_result(result);
130
131 return lstPlayers;
132}
133
134bool DataAccess::verifyPassword(string password, string encrypted)
135{
136 string test(crypt(password.c_str(), encrypted.c_str()));
137
138 return encrypted.compare(test) == 0;
139}
140
141int DataAccess::insert(string table, string columns, string values)
142{
143 int query_state;
144 ostringstream oss;
145
146 if (connection == NULL) {
147 cout << "Error: non database connection exists" << endl;
148 return -1;
149 }
150
151 oss << "INSERT into " << table << " (" << columns << ") VALUES (" << values << ")";
152 cout << "query: " << oss.str() << endl;
153
154 query_state = mysql_query(connection, oss.str().c_str());
155
156 if (query_state != 0) {
157 cout << mysql_error(connection) << endl;
158 return 1;
159 }
160
161 return 0;
162}
163
164int DataAccess::update(string table, string values, string where)
165{
166 int query_state;
167 ostringstream oss;
168
169 if (connection == NULL) {
170 cout << "Error: non database connection exists" << endl;
171 return -1;
172 }
173
174 oss << "UPDATE " << table << " SET " << values << " WHERE " << where;
175 cout << "query: " << oss.str() << endl;
176
177 query_state = mysql_query(connection, oss.str().c_str());
178
179 if (query_state != 0) {
180 cout << mysql_error(connection) << endl;
181 return 1;
182 }
183
184 return 0;
185}
186
187MYSQL_RES *DataAccess::select(string table, string filter)
188{
189 int query_state;
190 ostringstream oss;
191
192 if (connection == NULL) {
193 cout << "Error: non database connection exists" << endl;
194 return NULL;
195 }
196
197 oss << "SELECT * FROM " << table;
198 if (!filter.empty())
199 oss << " WHERE " << filter;
200
201 query_state = mysql_query(connection, oss.str().c_str());
202
203 if (query_state != 0) {
204 cout << mysql_error(connection) << endl;
205 return NULL;
206 }
207
208 return mysql_store_result(connection);
209}
Note: See TracBrowser for help on using the repository browser.