/RIOTDB/src/clib/handle_matrix_views.c

https://github.com/GunioRobot/riotdb · C · 420 lines · 285 code · 87 blank · 48 comment · 57 complexity · 10214c8a6545cf6d4965ef5fc5281f96 MD5 · raw file

  1. /*****************************************************************************
  2. * Contains functions for handling matrix views (i.e create, drop,
  3. * materialize views and keep track of view references)
  4. *
  5. * Author: Herodotos Herodotou
  6. * Date: Sep 17, 2008
  7. ****************************************************************************/
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <mysql.h>
  12. #include "basics.h"
  13. #include "handle_vector_views.h"
  14. #include "handle_vector_tables.h"
  15. #include "handle_matrix_views.h"
  16. #include "handle_matrix_tables.h"
  17. #include "handle_metadata.h"
  18. /* --------------------- Functions to create views -------------------- */
  19. int createNewIntegerMatrixView(MYSQL * sqlConn, rdbMatrix * viewMatrix,
  20. char sqlString[])
  21. {
  22. viewMatrix->sxp_type = SXP_TYPE_INTEGER;
  23. return internalCreateNewMatrixView(sqlConn, viewMatrix,
  24. sqlTemplateCreateMatrixView, sqlString);
  25. }
  26. int createNewDoubleMatrixView(MYSQL * sqlConn, rdbMatrix * viewMatrix,
  27. char sqlString[])
  28. {
  29. viewMatrix->sxp_type = SXP_TYPE_DOUBLE;
  30. return internalCreateNewMatrixView(sqlConn, viewMatrix,
  31. sqlTemplateCreateMatrixView, sqlString);
  32. }
  33. int internalCreateNewMatrixView(MYSQL * sqlConn, rdbMatrix * matrixInfo,
  34. char sqlTemplate[], char sqlString[])
  35. {
  36. /* Build the name of the new view */
  37. if( !buildUniqueMatrixViewName(sqlConn, &(matrixInfo->tableName)) )
  38. return 0;
  39. /* Build the sql string */
  40. int length = strlen(sqlTemplate) + strlen(matrixInfo->tableName) +
  41. strlen(sqlString) + 1;
  42. char strCreateViewSQL[length];
  43. sprintf( strCreateViewSQL, sqlTemplate, matrixInfo->tableName, sqlString );
  44. /* Execute the query */
  45. int success = mysql_query(sqlConn, strCreateViewSQL);
  46. if( success != 0 )
  47. return 0;
  48. /* Insert info into Metadata table */
  49. success = insertMatrixMetadataInfo(sqlConn, matrixInfo);
  50. return success;
  51. }
  52. /* ------------------ Functions for naming views ------------------- */
  53. int buildUniqueMatrixViewName(MYSQL * sqlConn, char ** newViewName)
  54. {
  55. int next = 0;
  56. if( !getNextTableID(sqlConn, &next) )
  57. return 0;
  58. /* Build the name of the new view */
  59. if( *newViewName != NULL )
  60. free(*newViewName);
  61. int length = strlen(sqlTemplateMatrixViewName) + MAX_INT_LENGTH;
  62. *newViewName = (char*) malloc(length * sizeof(char));
  63. sprintf( *newViewName, sqlTemplateMatrixViewName, next);
  64. return 1;
  65. }
  66. /* -------------- Functions to manage view references -------------- */
  67. int createReferences(MYSQL *sqlConn,
  68. unsigned long int resultMetadataID,
  69. unsigned long int input1MetadataID,
  70. unsigned long int input2MetadataID,
  71. int *input1RefCounter,
  72. int *input2RefCounter) {
  73. /* Build the sql string and create references */
  74. char sql[strlen(sqlTemplateCreateViewReferences) + 3*MAX_INT_LENGTH + 1];
  75. sprintf(sql, sqlTemplateCreateViewReferences,
  76. resultMetadataID, input1MetadataID, input2MetadataID);
  77. int status = mysql_query(sqlConn, sql);
  78. if (status != 0)
  79. return FALSE;
  80. (*input1RefCounter)++;
  81. (*input2RefCounter)++;
  82. return TRUE;
  83. }
  84. int createMatrixViewReferencesToVectors(MYSQL * sqlConn, rdbMatrix * viewMatrix,
  85. rdbVector * leftInput, rdbVector * rightInput) {
  86. return createReferences(sqlConn, viewMatrix->metadataID,
  87. leftInput->metadataID, rightInput->metadataID,
  88. &(leftInput->refCounter), &(rightInput->refCounter));
  89. }
  90. int createMatrixViewReferences(MYSQL * sqlConn, rdbMatrix * viewMatrix,
  91. rdbMatrix * leftInput, rdbMatrix * rightInput)
  92. {
  93. return createReferences(sqlConn, viewMatrix->metadataID,
  94. leftInput->metadataID, rightInput->metadataID,
  95. &(leftInput->refCounter), &(rightInput->refCounter));
  96. }
  97. int getMatrixViewReferences(MYSQL * sqlConn, rdbMatrix * viewMatrix,
  98. rdbObject *leftInput, rdbObject *rightInput)
  99. {
  100. /* Build the sql string and execute the query */
  101. int length = strlen(sqlTemplateGetViewReferences) + MAX_INT_LENGTH + 1;
  102. char strGetRefsSQL[length];
  103. sprintf(strGetRefsSQL, sqlTemplateGetViewReferences, viewMatrix->metadataID);
  104. int success = mysql_query(sqlConn, strGetRefsSQL);
  105. if( success != 0 )
  106. return 0;
  107. /* Get the references */
  108. unsigned long int leftID, rightID;
  109. MYSQL_RES *sqlRes;
  110. MYSQL_ROW sqlRow;
  111. sqlRes = mysql_use_result(sqlConn);
  112. sqlRow = mysql_fetch_row(sqlRes);
  113. if( sqlRow != NULL )
  114. {
  115. leftID = atoi(sqlRow[0]);
  116. rightID = atoi(sqlRow[1]);
  117. success = 1;
  118. }
  119. /* C API requires to clean the result set */
  120. while( (sqlRow = mysql_fetch_row(sqlRes)) != NULL );
  121. mysql_free_result(sqlRes);
  122. if( success != 1 )
  123. return 0;
  124. /* Load the rdbObjects from the Metadata table */
  125. success *= loadRDBObject(sqlConn, leftInput, leftID);
  126. success *= loadRDBObject(sqlConn, rightInput, rightID);
  127. return success;
  128. }
  129. int getMatrixViewRefCount(MYSQL * sqlConn, rdbMatrix * matrixInfo, int * count)
  130. {
  131. /* Build the sql string and execute the query */
  132. int length = strlen(sqlTemplateGetViewRefCount) + 2*MAX_INT_LENGTH + 1;
  133. char strGetRefsSQL[length];
  134. sprintf(strGetRefsSQL, sqlTemplateGetViewRefCount,
  135. matrixInfo->metadataID, matrixInfo->metadataID);
  136. int success = mysql_query(sqlConn, strGetRefsSQL);
  137. if( success != 0 )
  138. return 0;
  139. /* Get how many times this matrix is referenced in views */
  140. MYSQL_RES *sqlRes;
  141. MYSQL_ROW sqlRow;
  142. sqlRes = mysql_use_result(sqlConn);
  143. sqlRow = mysql_fetch_row(sqlRes);
  144. if( sqlRow != NULL )
  145. {
  146. *count = atoi(sqlRow[0]);
  147. success = 1;
  148. }
  149. /* C API requires to clean the result set */
  150. while( (sqlRow = mysql_fetch_row(sqlRes)) != NULL );
  151. mysql_free_result(sqlRes);
  152. return success;
  153. }
  154. int updateMatrixViewReferences(MYSQL * sqlConn, rdbMatrix * viewMatrix,
  155. rdbMatrix * newMatrix)
  156. {
  157. /* Build the sql strings */
  158. int length = strlen(sqlTemplateUpdateViewReferences1) + 2*MAX_INT_LENGTH + 1;
  159. char strUpdateRefs1SQL[length];
  160. sprintf(strUpdateRefs1SQL, sqlTemplateUpdateViewReferences1,
  161. newMatrix->metadataID, viewMatrix->metadataID);
  162. length = strlen(sqlTemplateUpdateViewReferences2) + 2*MAX_INT_LENGTH + 1;
  163. char strUpdateRefs2SQL[length];
  164. sprintf(strUpdateRefs2SQL, sqlTemplateUpdateViewReferences2,
  165. newMatrix->metadataID, viewMatrix->metadataID);
  166. /* Execute the queries */
  167. int success1 = mysql_query(sqlConn, strUpdateRefs1SQL);
  168. int success2 = mysql_query(sqlConn, strUpdateRefs2SQL);
  169. return ( success1 == 0 && success2 == 0 )? 1 : 0;
  170. }
  171. int removeMatrixViewReferences(MYSQL * sqlConn, rdbMatrix * viewMatrix)
  172. {
  173. /* Get the references */
  174. rdbObject *leftInput = newRDBObject();
  175. rdbObject *rightInput = newRDBObject();
  176. int success = getMatrixViewReferences(sqlConn, viewMatrix,
  177. leftInput, rightInput);
  178. if( success == 0 )
  179. return 0;
  180. /* Build the sql string and remove references from table */
  181. int length = strlen(sqlTemplateRemoveViewReferences) + MAX_INT_LENGTH + 1;
  182. char strRemoveRefsSQL[length];
  183. sprintf( strRemoveRefsSQL, sqlTemplateRemoveViewReferences,
  184. viewMatrix->metadataID);
  185. success = mysql_query(sqlConn, strRemoveRefsSQL);
  186. if( success != 0 )
  187. return 0;
  188. /* Reccursively delete the references */
  189. success = deleteRDBObject(sqlConn, leftInput);
  190. if( getMetadataIDInRDBObject(leftInput) != getMetadataIDInRDBObject(rightInput) )
  191. success *= deleteRDBObject(sqlConn, rightInput);
  192. /* Clean up */
  193. clearRDBObject(&leftInput);
  194. clearRDBObject(&rightInput);
  195. return success;
  196. }
  197. /* ---------------- Functions to delete matrix views ---------------- */
  198. int dropMatrixView(MYSQL * sqlConn, rdbMatrix * matrixInfo)
  199. {
  200. /* Safe guard - only drop view if num references == 0 */
  201. int refCounter = 0;
  202. getMatrixViewRefCount(sqlConn, matrixInfo, &refCounter);
  203. if( refCounter != 0 )
  204. {
  205. matrixInfo->refCounter = refCounter;
  206. return setRefCounter(sqlConn, matrixInfo->metadataID, refCounter);
  207. }
  208. /* Build the sql string and drop the view */
  209. int length = strlen(sqlTemplateDropMatrixView) +
  210. strlen(matrixInfo->tableName) + 1;
  211. char strDropViewSQL[length];
  212. sprintf( strDropViewSQL, sqlTemplateDropMatrixView, matrixInfo->tableName );
  213. int success = mysql_query(sqlConn, strDropViewSQL);
  214. if( success != 0 )
  215. return 0;
  216. /* Delete corresponding metadata info */
  217. success = deleteMetadataInfo(sqlConn, matrixInfo->metadataID);
  218. success *= removeMatrixViewReferences(sqlConn, matrixInfo);
  219. return success;
  220. }
  221. /* ----------------- Functions to materialize views ----------------- */
  222. int ensureMatrixMaterialization(MYSQL * sqlConn, rdbMatrix * matrixInfo)
  223. {
  224. /* Build the sql string */
  225. int length = strlen(sqlTemplateGetReferredViews) + 2*MAX_INT_LENGTH + 1;
  226. char strGetRefViewsSQL[length];
  227. sprintf( strGetRefViewsSQL, sqlTemplateGetReferredViews,
  228. matrixInfo->metadataID, matrixInfo->metadataID );
  229. /* Execute the query */
  230. int success = mysql_query(sqlConn, strGetRefViewsSQL);
  231. if( success != 0 )
  232. return 0;
  233. /* Get the referenced views' ids */
  234. MYSQL_RES *sqlRes;
  235. MYSQL_ROW sqlRow;
  236. sqlRes = mysql_store_result(sqlConn);
  237. unsigned long int numRes = (unsigned long int)mysql_num_rows(sqlRes);
  238. unsigned long int viewIDs[numRes];
  239. int i = 0 ;
  240. if( numRes != 0 )
  241. {
  242. /* Get the view ids from the SQl result*/
  243. while( (sqlRow = mysql_fetch_row(sqlRes)) != NULL )
  244. {
  245. viewIDs[i] = atoi(sqlRow[0]);
  246. i++;
  247. }
  248. mysql_free_result(sqlRes);
  249. }
  250. else
  251. {
  252. while( (sqlRow = mysql_fetch_row(sqlRes)) != NULL );
  253. mysql_free_result(sqlRes);
  254. }
  255. /* Materialize current matrix if a view */
  256. success = 1;
  257. if( matrixInfo->isView )
  258. success *= materializeMatrixView(sqlConn, matrixInfo);
  259. /* Materialize all referenced views */
  260. for( i = 0 ; i < numRes ; i++ )
  261. {
  262. rdbMatrix *viewMatrix = newRDBMatrix();
  263. int loadSuccess = loadRDBMatrix(sqlConn, viewMatrix, viewIDs[i]);
  264. if( loadSuccess )
  265. {
  266. success = materializeMatrixView(sqlConn, viewMatrix);
  267. clearRDBMatrix(&viewMatrix);
  268. }
  269. }
  270. return success;
  271. }
  272. int materializeMatrixView(MYSQL * sqlConn, rdbMatrix * viewMatrix)
  273. {
  274. if( !viewMatrix->isView )
  275. return 0;
  276. if( viewMatrix->sxp_type == SXP_TYPE_INTEGER )
  277. return materializeIntegerMatrixView(sqlConn, viewMatrix);
  278. if( viewMatrix->sxp_type == SXP_TYPE_DOUBLE )
  279. return materializeDoubleMatrixView(sqlConn, viewMatrix);
  280. return 0;
  281. }
  282. int materializeIntegerMatrixView(MYSQL * sqlConn, rdbMatrix * viewMatrix)
  283. {
  284. /* Create the new table */
  285. rdbMatrix * newMatrix = newRDBMatrix();
  286. if( !createNewIntMatrixTable(sqlConn, newMatrix) )
  287. return 0;
  288. int success = internalMaterializeMatrixView(sqlConn, viewMatrix, newMatrix);
  289. clearRDBMatrix(&newMatrix);
  290. return success;
  291. }
  292. int materializeDoubleMatrixView(MYSQL * sqlConn, rdbMatrix * viewMatrix)
  293. {
  294. /* Create the new table */
  295. rdbMatrix * newMatrix = newRDBMatrix();
  296. newMatrix->isView = 0;
  297. if( !createNewDoubleMatrixTable(sqlConn, newMatrix) )
  298. return 0;
  299. int success = internalMaterializeMatrixView(sqlConn, viewMatrix, newMatrix);
  300. clearRDBMatrix(&newMatrix);
  301. return success;
  302. }
  303. int internalMaterializeMatrixView(MYSQL * sqlConn, rdbMatrix * viewMatrix,
  304. rdbMatrix * newMatrix)
  305. {
  306. /* Build the sql string and add the data from the view */
  307. int length = strlen(sqlTemplateMaterializeMatrixView)
  308. + strlen(newMatrix->tableName)
  309. + strlen(viewMatrix->tableName) + 1;
  310. char strMaterializeViewSQL[length];
  311. sprintf( strMaterializeViewSQL, sqlTemplateMaterializeMatrixView,
  312. newMatrix->tableName, viewMatrix->tableName );
  313. int success = mysql_query(sqlConn, strMaterializeViewSQL);
  314. if( success != 0 )
  315. return 0;
  316. /* Remove the current view */
  317. length = strlen(sqlTemplateDropMatrixView) + strlen(viewMatrix->tableName) + 1;
  318. char strDropViewSQL[length];
  319. sprintf( strDropViewSQL, sqlTemplateDropMatrixView, viewMatrix->tableName );
  320. success = mysql_query(sqlConn, strDropViewSQL);
  321. if( success != 0 )
  322. return 0;
  323. /* Delete corresponding references */
  324. success = removeMatrixViewReferences(sqlConn, viewMatrix);
  325. /* Rename new matrix table to the view's name*/
  326. success *= renameTable(sqlConn, newMatrix->tableName, viewMatrix->tableName);
  327. /* Update the metadata info of the view table */
  328. viewMatrix->isView = 0;
  329. success *= updateMatrixMetadataInfo(sqlConn, viewMatrix);
  330. /* Delete Metadata info of new table */
  331. success *= deleteMetadataInfo(sqlConn, newMatrix->metadataID);
  332. return success;
  333. }