db.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <grass/dbmi.h>
  4. #include <grass/gis.h>
  5. #include "globals.h"
  6. #include "proto.h"
  7. int db__driver_open_database(dbHandle * handle)
  8. {
  9. char buf[500];
  10. const char *name, *schema, *user, *password;
  11. dbConnection connection;
  12. PGCONN pgconn;
  13. PGresult *res;
  14. int row;
  15. init_error();
  16. db_get_connection(&connection);
  17. name = db_get_handle_dbname(handle);
  18. /* if name is empty use connection.databaseName */
  19. if (strlen(name) == 0)
  20. name = connection.databaseName;
  21. G_debug(3,
  22. "db_driver_open_database() driver=pg database definition = '%s'",
  23. name);
  24. if (parse_conn(name, &pgconn) == DB_FAILED) {
  25. report_error();
  26. return DB_FAILED;
  27. }
  28. G_debug(3,
  29. "host = %s, port = %s, options = %s, tty = %s, dbname = %s, user = %s, password = %s, "
  30. "schema = %s", pgconn.host, pgconn.port, pgconn.options,
  31. pgconn.tty, pgconn.dbname, pgconn.user, pgconn.password,
  32. pgconn.schema);
  33. db_get_login("pg", name, &user, &password);
  34. pg_conn =
  35. PQsetdbLogin(pgconn.host, pgconn.port, pgconn.options, pgconn.tty,
  36. pgconn.dbname, user, password);
  37. if (PQstatus(pg_conn) == CONNECTION_BAD) {
  38. append_error("Cannot connect to Postgres: ");
  39. append_error(PQerrorMessage(pg_conn));
  40. report_error();
  41. PQfinish(pg_conn);
  42. return DB_FAILED;
  43. }
  44. /* Set schema */
  45. schema = db_get_handle_dbschema(handle);
  46. /* Cannot use default schema because link to table can point to different database */
  47. /*
  48. if ( schema )
  49. schema = connection.schemaName;
  50. */
  51. if (pgconn.schema) {
  52. schema = pgconn.schema;
  53. }
  54. if (schema && strlen(schema) > 0) {
  55. sprintf(buf, "set search_path to %s", schema);
  56. res = PQexec(pg_conn, buf);
  57. if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) {
  58. append_error("Cannot set schema: ");
  59. append_error(schema);
  60. report_error();
  61. PQclear(res);
  62. return DB_FAILED;
  63. }
  64. }
  65. /* Read internal codes */
  66. res =
  67. PQexec(pg_conn,
  68. "select oid, typname from pg_type where typname in ( "
  69. "'bit', 'int2', 'int4', 'int8', 'serial', 'oid', "
  70. "'float4', 'float8', 'numeric', "
  71. "'char', 'bpchar', 'varchar', 'text', "
  72. "'time', 'date', 'timestamp', "
  73. "'bool', 'geometry' ) order by oid");
  74. if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) {
  75. append_error("Cannot select data types");
  76. report_error();
  77. PQclear(res);
  78. return DB_FAILED;
  79. }
  80. pg_ntypes = PQntuples(res);
  81. pg_types = G_realloc(pg_types, 2 * pg_ntypes * sizeof(int));
  82. for (row = 0; row < pg_ntypes; row++) {
  83. int pgtype, type;
  84. pgtype = atoi(PQgetvalue(res, row, 0));
  85. pg_types[row][0] = pgtype;
  86. if (strcmp(PQgetvalue(res, row, 1), "bit") == 0)
  87. type = PG_TYPE_BIT;
  88. else if (strcmp(PQgetvalue(res, row, 1), "int2") == 0)
  89. type = PG_TYPE_INT2;
  90. else if (strcmp(PQgetvalue(res, row, 1), "int4") == 0)
  91. type = PG_TYPE_INT4;
  92. else if (strcmp(PQgetvalue(res, row, 1), "int8") == 0)
  93. type = PG_TYPE_INT8;
  94. else if (strcmp(PQgetvalue(res, row, 1), "serial") == 0)
  95. type = PG_TYPE_SERIAL;
  96. else if (strcmp(PQgetvalue(res, row, 1), "oid") == 0)
  97. type = PG_TYPE_OID;
  98. else if (strcmp(PQgetvalue(res, row, 1), "float4") == 0)
  99. type = PG_TYPE_FLOAT4;
  100. else if (strcmp(PQgetvalue(res, row, 1), "float8") == 0)
  101. type = PG_TYPE_FLOAT8;
  102. else if (strcmp(PQgetvalue(res, row, 1), "numeric") == 0)
  103. type = PG_TYPE_NUMERIC;
  104. else if (strcmp(PQgetvalue(res, row, 1), "char") == 0)
  105. type = PG_TYPE_CHAR;
  106. else if (strcmp(PQgetvalue(res, row, 1), "bpchar") == 0)
  107. type = PG_TYPE_BPCHAR;
  108. else if (strcmp(PQgetvalue(res, row, 1), "varchar") == 0)
  109. type = PG_TYPE_VARCHAR;
  110. else if (strcmp(PQgetvalue(res, row, 1), "text") == 0)
  111. type = PG_TYPE_TEXT;
  112. else if (strcmp(PQgetvalue(res, row, 1), "date") == 0)
  113. type = PG_TYPE_DATE;
  114. else if (strcmp(PQgetvalue(res, row, 1), "time") == 0)
  115. type = PG_TYPE_TIME;
  116. else if (strcmp(PQgetvalue(res, row, 1), "timestamp") == 0)
  117. type = PG_TYPE_TIMESTAMP;
  118. else if (strcmp(PQgetvalue(res, row, 1), "bool") == 0)
  119. type = PG_TYPE_BOOL;
  120. else if (strcmp(PQgetvalue(res, row, 1), "geometry") == 0)
  121. type = PG_TYPE_POSTGIS_GEOM;
  122. else
  123. type = PG_TYPE_UNKNOWN;
  124. G_debug(3, "pgtype = %d, \tname = %s -> \ttype = %d", pgtype,
  125. PQgetvalue(res, row, 1), type);
  126. pg_types[row][1] = type;
  127. }
  128. PQclear(res);
  129. return DB_OK;
  130. }
  131. int db__driver_close_database()
  132. {
  133. init_error();
  134. PQfinish(pg_conn);
  135. return DB_OK;
  136. }