db.c 4.8 KB

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