index.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /**
  2. * \file index.c
  3. *
  4. * \brief Low level SQLite database index functions.
  5. *
  6. * This program is free software under the GNU General Public License
  7. * (>=v2). Read the file COPYING that comes with GRASS for details.
  8. *
  9. * \author Radim Blazek
  10. * \author Support for multiple connections by Markus Metz
  11. *
  12. * \date 2005-2011
  13. */
  14. #include <grass/dbmi.h>
  15. #include <grass/glocale.h>
  16. #include "globals.h"
  17. #include "proto.h"
  18. /**
  19. * \fn int db__driver_create_index (dbIndex *index)
  20. *
  21. * \brief Create SQLite database index.
  22. *
  23. * \param[in] index index to be created
  24. * \return int DB_FAILED on error; DB_OK on success
  25. */
  26. int db__driver_create_index(dbIndex * index)
  27. {
  28. int i, ncols;
  29. sqlite3_stmt *statement;
  30. dbString sql;
  31. const char *rest;
  32. int ret;
  33. G_debug(3, "db__create_index()");
  34. db_init_string(&sql);
  35. ncols = db_get_index_number_of_columns(index);
  36. db_set_string(&sql, "create");
  37. if (db_test_index_type_unique(index))
  38. db_append_string(&sql, " unique");
  39. db_append_string(&sql, " index ");
  40. db_append_string(&sql, "if not exists ");
  41. db_append_string(&sql, db_get_index_name(index));
  42. db_append_string(&sql, " on ");
  43. db_append_string(&sql, db_get_index_table_name(index));
  44. db_append_string(&sql, " ( ");
  45. for (i = 0; i < ncols; i++) {
  46. if (i > 0)
  47. db_append_string(&sql, ", ");
  48. db_append_string(&sql, db_get_index_column_name(index, i));
  49. }
  50. db_append_string(&sql, " )");
  51. G_debug(3, " SQL: %s", db_get_string(&sql));
  52. /* SQLITE bug?
  53. * If the database schema has changed, sqlite can prepare a statement,
  54. * but sqlite can not step, the statement needs to be prepared anew again */
  55. while (1) {
  56. ret = sqlite3_prepare(sqlite, db_get_string(&sql), -1, &statement, &rest);
  57. if (ret != SQLITE_OK) {
  58. db_d_append_error("%s\n%s\n%s",
  59. _("Unable to create index:"),
  60. db_get_string(&sql),
  61. (char *)sqlite3_errmsg(sqlite));
  62. db_d_report_error();
  63. sqlite3_finalize(statement);
  64. db_free_string(&sql);
  65. return DB_FAILED;
  66. }
  67. ret = sqlite3_step(statement);
  68. /* get real result code */
  69. ret = sqlite3_reset(statement);
  70. if (ret == SQLITE_SCHEMA) {
  71. sqlite3_finalize(statement);
  72. /* try again */
  73. }
  74. else if (ret != SQLITE_OK) {
  75. db_d_append_error("%s\n%s",
  76. _("Error in sqlite3_step():"),
  77. (char *)sqlite3_errmsg(sqlite));
  78. db_d_report_error();
  79. sqlite3_finalize(statement);
  80. db_free_string(&sql);
  81. return DB_FAILED;
  82. }
  83. else
  84. break;
  85. }
  86. sqlite3_finalize(statement);
  87. db_free_string(&sql);
  88. return DB_OK;
  89. }