PageRenderTime 27ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/src/query.c

http://github.com/breckinloggins/ZombieSQL
C | 279 lines | 197 code | 57 blank | 25 comment | 36 complexity | afd30be0dd0b6979602a88b8358f51c9 MD5 | raw file
  1. //
  2. // query.c
  3. // ZombieSQL
  4. //
  5. // Created by Benjamin Loggins on 4/25/11.
  6. // Copyright 2011 __MyCompanyName__. All rights reserved.
  7. //
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include "types.h"
  12. #include "query.h"
  13. struct _ZdbQueryCondition
  14. {
  15. ZdbQueryConditionType type;
  16. int columnIndex;
  17. void* value;
  18. };
  19. struct _ZdbQuery
  20. {
  21. ZdbDatabase* database; /* The database this query will operate on */
  22. ZdbTable* table; /* Query subject table */
  23. ZdbQueryCondition condition; /* The condition we will evaluate for each row */
  24. };
  25. struct _ZdbRecordset
  26. {
  27. ZdbQuery* query; /* The query that created this recordset */
  28. int rowIndex;
  29. };
  30. /*
  31. * Internal functions
  32. */
  33. int _compareValues(ZdbType* type, void* value1, void* value2, ZdbQueryConditionType conditionType)
  34. {
  35. int result = 0;
  36. ZdbTypeCompare(type, value1, value2, &result);
  37. return result;
  38. }
  39. int _matchesQuery(ZdbRecordset* recordset)
  40. {
  41. void* value1 = NULL;
  42. void* value2 = NULL;
  43. ZdbType* type;
  44. if (recordset->query->condition.type == ZDB_QUERY_CONDITION_NONE)
  45. {
  46. /* No condition, always match */
  47. return 1;
  48. }
  49. value1 = recordset->query->condition.value;
  50. type = recordset->query->table->columns[recordset->query->condition.columnIndex]->type;
  51. ZdbQueryGetValue(recordset, recordset->query->condition.columnIndex, type, &value2);
  52. int result = _compareValues(type, value1, value2, recordset->query->condition.type);
  53. printf("RESULT!! %d %d %d\n", *(int*)value1, *(int*)value2, result);
  54. switch(recordset->query->condition.type)
  55. {
  56. case ZDB_QUERY_CONDITION_EQ:
  57. return result == 0;
  58. case ZDB_QUERY_CONDITION_NE:
  59. return result != 0;
  60. case ZDB_QUERY_CONDITION_LT:
  61. return result > 0;
  62. case ZDB_QUERY_CONDITION_GT:
  63. return result < 0;
  64. case ZDB_QUERY_CONDITION_LTE:
  65. return result >= 0;
  66. case ZDB_QUERY_CONDITION_GTE:
  67. return result <= 0;
  68. }
  69. return result;
  70. }
  71. /*
  72. * Public functions
  73. */
  74. int ZdbQueryCreate(ZdbDatabase* database, ZdbQuery** query)
  75. {
  76. ZdbQuery* q = malloc(sizeof(ZdbQuery));
  77. q->database = database;
  78. q->table = NULL;
  79. q->condition.type = ZDB_QUERY_CONDITION_NONE; /* ALL rows */
  80. q->condition.value = NULL;
  81. *query = q;
  82. return ZDB_RESULT_SUCCESS;
  83. }
  84. int ZdbQueryAddTable(ZdbQuery* query, ZdbTable* table)
  85. {
  86. if (query->table != NULL)
  87. {
  88. // Multiple tables in query is not currently supported
  89. return ZDB_RESULT_UNSUPPORTED;
  90. }
  91. query->table = table;
  92. return ZDB_RESULT_SUCCESS;
  93. }
  94. int ZdbQueryAddCondition(ZdbQuery* query, ZdbQueryConditionType type, int column, ZdbType* valueType, const char* str)
  95. {
  96. if (query->database == NULL || query->table == NULL)
  97. {
  98. /* The query must be initialized and a table selected before adding a condition */
  99. return ZDB_RESULT_INVALID_NULL;
  100. }
  101. if (column < 0 || column >= query->table->columnCount)
  102. {
  103. /* The column index is out of range for this query */
  104. return ZDB_RESULT_INVALID_OPERATION;
  105. }
  106. ZdbType* columnType = query->table->columns[column]->type;
  107. if (columnType != valueType)
  108. {
  109. /* The types do not match */
  110. return ZDB_RESULT_INVALID_CAST;
  111. }
  112. void* value;
  113. if (ZdbTypeNewValue(valueType, str, &value) != ZDB_RESULT_SUCCESS)
  114. {
  115. /* There was an error creating the value from the string */
  116. return ZDB_RESULT_INVALID_OPERATION;
  117. }
  118. query->condition.type = type;
  119. query->condition.columnIndex = column;
  120. query->condition.value = value;
  121. return ZDB_RESULT_SUCCESS;
  122. }
  123. int ZdbQueryExecute(ZdbQuery* query, ZdbRecordset** recordset)
  124. {
  125. ZdbRecordset* rs = malloc(sizeof(recordset));
  126. rs->query = query;
  127. rs->rowIndex = -1;
  128. *recordset = rs;
  129. return ZDB_RESULT_SUCCESS;
  130. }
  131. int ZdbQueryFree(ZdbQuery* query)
  132. {
  133. if (query == NULL)
  134. {
  135. /* Can't free a NULL query */
  136. return ZDB_RESULT_INVALID_NULL;
  137. }
  138. if (query->condition.value)
  139. {
  140. free(query->condition.value);
  141. }
  142. free(query);
  143. return ZDB_RESULT_SUCCESS;
  144. }
  145. int ZdbQueryNextResult(ZdbRecordset* recordset)
  146. {
  147. while (1)
  148. {
  149. ++recordset->rowIndex;
  150. if (recordset->rowIndex >= recordset->query->table->rowCount)
  151. {
  152. /* No more rows */
  153. return 0;
  154. }
  155. if (_matchesQuery(recordset))
  156. {
  157. break;
  158. }
  159. }
  160. /* There are more rows available */
  161. return 1;
  162. }
  163. int ZdbQueryGetValue(ZdbRecordset* recordset, int column, ZdbType* type, void** value)
  164. {
  165. if (column < 0 || column >= recordset->query->table->columnCount)
  166. {
  167. /* Invalid column specified */
  168. return ZDB_RESULT_INVALID_OPERATION;
  169. }
  170. if (type != recordset->query->table->columns[column]->type)
  171. {
  172. /* Attempt to cast result to an incompatible type */
  173. return ZDB_RESULT_INVALID_CAST;
  174. }
  175. ZdbRow* resultRow = recordset->query->table->rows[recordset->rowIndex];
  176. if (ZdbEngineGetValue(recordset->query->table, resultRow, column, value) != ZDB_RESULT_SUCCESS)
  177. {
  178. /* Error getting the value for this row */
  179. return ZDB_RESULT_INVALID_OPERATION;
  180. }
  181. return ZDB_RESULT_SUCCESS;
  182. }
  183. int ZdbQueryGetInt(ZdbRecordset* recordset, int column, int* value)
  184. {
  185. int* v;
  186. int result = ZdbQueryGetValue(recordset, column, ZdbStandardTypes->intType, (void**)&v);
  187. if (result == ZDB_RESULT_SUCCESS)
  188. {
  189. *value = *v;
  190. }
  191. return result;
  192. }
  193. int ZdbQueryGetBoolean(ZdbRecordset* recordset, int column, int* value)
  194. {
  195. int* v;
  196. int result = ZdbQueryGetValue(recordset, column, ZdbStandardTypes->booleanType, (void**)&v);
  197. if (result == ZDB_RESULT_SUCCESS)
  198. {
  199. *value = *v;
  200. }
  201. return result;
  202. }
  203. int ZdbQueryGetString(ZdbRecordset* recordset, int column, char** value)
  204. {
  205. char* v;
  206. int result = ZdbQueryGetValue(recordset, column, ZdbStandardTypes->varcharType, (void**)&v);
  207. if (result == ZDB_RESULT_SUCCESS)
  208. {
  209. *value = v;
  210. }
  211. return result;
  212. }
  213. int ZdbQueryGetFloat(ZdbRecordset* recordset, int column, float* value)
  214. {
  215. float *v;
  216. int result = ZdbQueryGetValue(recordset, column, ZdbStandardTypes->floatType, (void**)&v);
  217. if (result == ZDB_RESULT_SUCCESS)
  218. {
  219. *value = *v;
  220. }
  221. return result;
  222. }