link.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <grass/gis.h>
  4. #include <grass/glocale.h>
  5. static char *get_option_pg(char **, const char *);
  6. static void check_option_on_off(const char *, char **);
  7. void make_link(const char *dsn_opt,
  8. const char *format,
  9. char *option_str, char **options)
  10. {
  11. int use_ogr;
  12. char *filename, *pg_schema, *pg_fid, *pg_geom_name, *dsn;
  13. char *pg_spatial_index, *pg_primary_key, *pg_topo;
  14. FILE *fp;
  15. struct Key_Value *key_val;
  16. key_val = G_create_key_value();
  17. /* use OGR ? */
  18. if (strcmp(format, "PostgreSQL") == 0) {
  19. #if defined HAVE_OGR && defined HAVE_POSTGRES
  20. if (getenv("GRASS_VECTOR_OGR")) {
  21. use_ogr = TRUE;
  22. filename = "OGR";
  23. G_remove("", "PG");
  24. }
  25. else {
  26. use_ogr = FALSE;
  27. filename = "PG";
  28. G_remove("", "OGR");
  29. }
  30. #else
  31. #ifdef HAVE_POSTGRES
  32. if (getenv("GRASS_VECTOR_OGR"))
  33. G_warning(_("Environment variable GRASS_VECTOR_OGR defined, "
  34. "but GRASS is compiled with OGR support. "
  35. "Using GRASS-PostGIS data driver instead."));
  36. use_ogr = FALSE;
  37. filename = "PG";
  38. G_remove("", "OGR");
  39. #else /* -> force using OGR */
  40. G_warning(_("GRASS is not compiled with PostgreSQL support. "
  41. "Using OGR-PostgreSQL driver instead of native "
  42. "GRASS-PostGIS data driver."));
  43. use_ogr = TRUE;
  44. filename = "OGR";
  45. G_remove("", "PG");
  46. #endif /* HAVE_POSTRES */
  47. #endif /* HAVE_OGR && HAVE_POSTGRES */
  48. } /* format=PostgreSQL */
  49. else {
  50. use_ogr = TRUE;
  51. filename = "OGR";
  52. G_remove("", "PG");
  53. }
  54. /* be friendly, ignored 'PG:' prefix for GRASS-PostGIS data driver */
  55. if (!use_ogr && strcmp(format, "PostgreSQL") == 0 &&
  56. G_strncasecmp(dsn_opt, "PG:", 3) == 0) {
  57. int i, length;
  58. length = strlen(dsn_opt);
  59. dsn = (char *) G_malloc(length - 3);
  60. for (i = 3; i < length; i++)
  61. dsn[i-3] = dsn_opt[i];
  62. dsn[length-3] = '\0';
  63. }
  64. else {
  65. dsn = G_store(dsn_opt);
  66. }
  67. /* parse options for PG data format */
  68. pg_schema = pg_fid = pg_geom_name = NULL;
  69. pg_spatial_index = pg_primary_key = pg_topo = NULL;
  70. if (options && *options && !use_ogr) {
  71. pg_schema = get_option_pg(options, "schema");
  72. pg_fid = get_option_pg(options, "fid");
  73. pg_geom_name = get_option_pg(options, "geometry_name");
  74. pg_spatial_index = get_option_pg(options, "spatial_index");
  75. if (pg_spatial_index) {
  76. check_option_on_off("spatial_index", &pg_spatial_index);
  77. }
  78. pg_primary_key = get_option_pg(options, "primary_key");
  79. if (pg_primary_key) {
  80. check_option_on_off("primary_key", &pg_primary_key);
  81. }
  82. pg_topo = get_option_pg(options, "topology");
  83. if (pg_topo) {
  84. check_option_on_off("topology", &pg_topo);
  85. }
  86. }
  87. /* add key/value items */
  88. if (dsn) {
  89. if (use_ogr)
  90. G_set_key_value("dsn", dsn, key_val);
  91. else
  92. G_set_key_value("conninfo", dsn, key_val);
  93. }
  94. if (format && use_ogr)
  95. G_set_key_value("format", format, key_val);
  96. if (use_ogr && option_str)
  97. G_set_key_value("options", option_str, key_val);
  98. if (!use_ogr) {
  99. if (pg_schema)
  100. G_set_key_value("schema", pg_schema, key_val);
  101. if (pg_fid)
  102. G_set_key_value("fid", pg_fid, key_val);
  103. if (pg_geom_name)
  104. G_set_key_value("geometry_name", pg_geom_name, key_val);
  105. if (pg_spatial_index)
  106. G_set_key_value("spatial_index", pg_spatial_index, key_val);
  107. if (pg_primary_key)
  108. G_set_key_value("primary_key", pg_primary_key, key_val);
  109. if (pg_topo)
  110. G_set_key_value("topology", pg_topo, key_val);
  111. }
  112. /* save file - OGR or PG */
  113. fp = G_fopen_new("", filename);
  114. if (!fp)
  115. G_fatal_error(_("Unable to create <%s> file"), filename);
  116. if (G_fwrite_key_value(fp, key_val) < 0)
  117. G_fatal_error(_("Error writing <%s> file"), filename);
  118. fclose(fp);
  119. }
  120. char *get_option_pg(char **options, const char *key)
  121. {
  122. int i, opt_len, key_len;
  123. char *opt, *value;
  124. key_len = strlen(key);
  125. /* parse options for PG data provider*/
  126. opt = value = NULL;
  127. for (i = 0; options[i] && !opt; i++) {
  128. if (G_strncasecmp(key, options[i], key_len) == 0)
  129. opt = options[i];
  130. }
  131. if (!opt)
  132. return NULL;
  133. opt_len = strlen(opt);
  134. value = G_malloc(opt_len - key_len);
  135. key_len++;
  136. for (i = key_len; i < opt_len; i++) {
  137. value[i - key_len] = opt[i];
  138. }
  139. value[opt_len - key_len] = '\0';
  140. return value;
  141. }
  142. void check_option_on_off(const char *key, char **value)
  143. {
  144. if(G_strcasecmp(*value, "on") != 0 &&
  145. G_strcasecmp(*value, "off") != 0) {
  146. G_warning(_("Invalid option '%s=%s' ignored (allowed values: '%s', '%s')"),
  147. key, *value, "ON", "OFF");
  148. G_free(*value);
  149. *value = NULL;
  150. }
  151. }