DatabaseResult.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /*
  2. EQ2Emulator: Everquest II Server Emulator
  3. Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
  4. This file is part of EQ2Emulator.
  5. EQ2Emulator is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. EQ2Emulator is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include "Log.h"
  19. #include "DatabaseResult.h"
  20. //enforced by MySQL...couldn't find a #define in their headers though
  21. #define FIELD_NAME_MAX 64
  22. //return this instead of NULL for certain functions to prevent crashes from coding errors
  23. static const char *empty_str = "";
  24. DatabaseResult::DatabaseResult() {
  25. result = NULL;
  26. field_names = NULL;
  27. num_fields = 0;
  28. row = 0;
  29. }
  30. DatabaseResult::~DatabaseResult() {
  31. unsigned int i;
  32. if (result != NULL)
  33. mysql_free_result(result);
  34. if (field_names != NULL) {
  35. for (i = 0; i < num_fields; i++)
  36. free(field_names[i]);
  37. free(field_names);
  38. }
  39. }
  40. bool DatabaseResult::StoreResult(MYSQL_RES *res) {
  41. unsigned int i, j;
  42. MYSQL_FIELD *field;
  43. //clear any previously stored result
  44. if (result != NULL)
  45. mysql_free_result(result);
  46. //clear any field names from a previous result
  47. if (field_names != NULL) {
  48. for (i = 0; i < num_fields; i++)
  49. free(field_names[i]);
  50. free(field_names);
  51. }
  52. //store the new result
  53. result = res;
  54. num_fields = mysql_num_fields(res);
  55. //allocate enough space for each field's name
  56. if ((field_names = (char **)malloc(sizeof(char *) * num_fields)) == NULL) {
  57. LogWrite(DATABASE__ERROR, 0, "Database Result", "Unable to allocate %u bytes when storing database result and fetching field names\nNumber of fields=%u\n", sizeof(char *) * num_fields, num_fields);
  58. mysql_free_result(result);
  59. result = NULL;
  60. num_fields = 0;
  61. return false;
  62. }
  63. //store each field's name
  64. i = 0;
  65. while ((field = mysql_fetch_field(result)) != NULL) {
  66. if ((field_names[i] = (char *)calloc(field->name_length + 1, sizeof(char))) == NULL) {
  67. LogWrite(DATABASE__ERROR, 0, "Database Result", "Unable to allocate %u bytes when storing databse result and copying field name %s\n", field->name_length + 1, field->name);
  68. mysql_free_result(result);
  69. result = NULL;
  70. for (j = 0; j < i; j++)
  71. free(field_names[j]);
  72. free(field_names);
  73. field_names = NULL;
  74. num_fields = 0;
  75. return false;
  76. }
  77. strncpy(field_names[i], field->name, field->name_length);
  78. i++;
  79. }
  80. return true;
  81. }
  82. const char * DatabaseResult::GetFieldValue(unsigned int index) {
  83. if (index >= num_fields) {
  84. LogWrite(DATABASE__ERROR, 0, "Database Result", "Attempt to access field at index %u but there %s only %u field%s", index, num_fields == 1 ? "is" : "are", num_fields, num_fields == 1 ? "" : "s");
  85. return NULL;
  86. }
  87. return row[index];
  88. }
  89. const char * DatabaseResult::GetFieldValueStr(const char *field_name) {
  90. unsigned int i;
  91. for (i = 0; i < num_fields; i++) {
  92. if (strncmp(field_name, field_names[i], FIELD_NAME_MAX) == 0)
  93. return row[i];
  94. }
  95. LogWrite(DATABASE__ERROR, 0, "Database Result", "Unknown field name '%s'", field_name);
  96. return NULL;
  97. }
  98. bool DatabaseResult::Next() {
  99. return (result != NULL && (row = mysql_fetch_row(result)) != NULL);
  100. }
  101. bool DatabaseResult::IsNull(unsigned int index) {
  102. const char *value = GetFieldValue(index);
  103. return value == NULL;
  104. }
  105. bool DatabaseResult::IsNullStr(const char *field_name) {
  106. const char *value = GetFieldValueStr(field_name);
  107. return value == NULL;
  108. }
  109. int8 DatabaseResult::GetInt8(unsigned int index) {
  110. const char *value = GetFieldValue(index);
  111. return value == NULL ? 0 : atoi(value);
  112. }
  113. int8 DatabaseResult::GetInt8Str(const char *field_name) {
  114. const char *value = GetFieldValueStr(field_name);
  115. return value == NULL ? 0 : atoi(value);
  116. }
  117. sint8 DatabaseResult::GetSInt8(unsigned int index) {
  118. const char *value = GetFieldValue(index);
  119. return value == NULL ? 0 : atoi(value);
  120. }
  121. sint8 DatabaseResult::GetSInt8Str(const char *field_name) {
  122. const char *value = GetFieldValueStr(field_name);
  123. return value == NULL ? 0 : atoi(value);
  124. }
  125. int16 DatabaseResult::GetInt16(unsigned int index) {
  126. const char *value = GetFieldValue(index);
  127. return value == NULL ? 0 : atoi(value);
  128. }
  129. int16 DatabaseResult::GetInt16Str(const char *field_name) {
  130. const char *value = GetFieldValueStr(field_name);
  131. return value == NULL ? 0 : atoi(value);
  132. }
  133. sint16 DatabaseResult::GetSInt16(unsigned int index) {
  134. const char *value = GetFieldValue(index);
  135. return value == NULL ? 0 : atoi(value);
  136. }
  137. sint16 DatabaseResult::GetSInt16Str(const char *field_name) {
  138. const char *value = GetFieldValueStr(field_name);
  139. return value == NULL ? 0 : atoi(value);
  140. }
  141. int32 DatabaseResult::GetInt32(unsigned int index) {
  142. const char *value = GetFieldValue(index);
  143. return value == NULL ? 0U : strtoul(value, NULL, 10);
  144. }
  145. int32 DatabaseResult::GetInt32Str(const char *field_name) {
  146. const char *value = GetFieldValueStr(field_name);
  147. return value == NULL ? 0U : strtoul(value, NULL, 10);
  148. }
  149. sint32 DatabaseResult::GetSInt32(unsigned int index) {
  150. const char *value = GetFieldValue(index);
  151. return value == NULL ? 0 : atoi(value);
  152. }
  153. sint32 DatabaseResult::GetSInt32Str(const char *field_name) {
  154. const char *value = GetFieldValueStr(field_name);
  155. return value == NULL ? 0 : atoi(value);
  156. }
  157. uint64 DatabaseResult::GetInt64(unsigned int index) {
  158. const char *value = GetFieldValue(index);
  159. #ifdef _WIN32
  160. return value == NULL ? 0UL : _strtoui64(value, NULL, 10);
  161. #else
  162. return value == NULL ? 0UL : strtoull(value, NULL, 10);
  163. #endif
  164. }
  165. uint64 DatabaseResult::GetInt64Str(const char *field_name) {
  166. const char *value = GetFieldValueStr(field_name);
  167. #ifdef _WIN32
  168. return value == NULL ? 0UL : _strtoui64(value, NULL, 10);
  169. #else
  170. return value == NULL ? 0UL : strtoull(value, NULL, 10);
  171. #endif
  172. }
  173. sint64 DatabaseResult::GetSInt64(unsigned int index) {
  174. const char *value = GetFieldValue(index);
  175. #ifdef _WIN32
  176. return value == NULL ? 0L : _strtoi64(value, NULL, 10);
  177. #else
  178. return value == NULL ? 0L : strtoll(value, NULL, 10);
  179. #endif
  180. }
  181. sint64 DatabaseResult::GetSInt64Str(const char *field_name) {
  182. const char *value = GetFieldValueStr(field_name);
  183. #ifdef _WIN32
  184. return value == NULL ? 0L : _strtoi64(value, NULL, 10);
  185. #else
  186. return value == NULL ? 0L : strtoll(value, NULL, 10);
  187. #endif
  188. }
  189. float DatabaseResult::GetFloat(unsigned int index) {
  190. const char *value = GetFieldValue(index);
  191. return value == NULL ? 0.0F : atof(value);
  192. }
  193. float DatabaseResult::GetFloatStr(const char *field_name) {
  194. const char *value = GetFieldValueStr(field_name);
  195. return value == NULL ? 0.0F : atof(value);
  196. }
  197. char DatabaseResult::GetChar(unsigned int index) {
  198. const char *value = GetFieldValue(index);
  199. return value == NULL ? '\0' : value[0];
  200. }
  201. char DatabaseResult::GetCharStr(const char *field_name) {
  202. const char *value = GetFieldValueStr(field_name);
  203. return value == NULL ? '\0' : value[0];
  204. }
  205. const char * DatabaseResult::GetString(unsigned int index) {
  206. const char *value = GetFieldValue(index);
  207. return value == NULL ? empty_str : value;
  208. }
  209. const char * DatabaseResult::GetStringStr(const char *field_name) {
  210. const char *value = GetFieldValueStr(field_name);
  211. return value == NULL ? empty_str : value;
  212. }