db.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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', 'topogeometry') 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. G_debug(3, "row = %d value = %s", row, PQgetvalue(res, row, 1));
  96. if (strcmp(PQgetvalue(res, row, 1), "bit") == 0)
  97. type = PG_TYPE_BIT;
  98. else if (strcmp(PQgetvalue(res, row, 1), "int2") == 0)
  99. type = PG_TYPE_INT2;
  100. else if (strcmp(PQgetvalue(res, row, 1), "int4") == 0)
  101. type = PG_TYPE_INT4;
  102. else if (strcmp(PQgetvalue(res, row, 1), "int8") == 0)
  103. type = PG_TYPE_INT8;
  104. else if (strcmp(PQgetvalue(res, row, 1), "serial") == 0)
  105. type = PG_TYPE_SERIAL;
  106. else if (strcmp(PQgetvalue(res, row, 1), "oid") == 0)
  107. type = PG_TYPE_OID;
  108. else if (strcmp(PQgetvalue(res, row, 1), "float4") == 0)
  109. type = PG_TYPE_FLOAT4;
  110. else if (strcmp(PQgetvalue(res, row, 1), "float8") == 0)
  111. type = PG_TYPE_FLOAT8;
  112. else if (strcmp(PQgetvalue(res, row, 1), "numeric") == 0)
  113. type = PG_TYPE_NUMERIC;
  114. else if (strcmp(PQgetvalue(res, row, 1), "char") == 0)
  115. type = PG_TYPE_CHAR;
  116. else if (strcmp(PQgetvalue(res, row, 1), "bpchar") == 0)
  117. type = PG_TYPE_BPCHAR;
  118. else if (strcmp(PQgetvalue(res, row, 1), "varchar") == 0)
  119. type = PG_TYPE_VARCHAR;
  120. else if (strcmp(PQgetvalue(res, row, 1), "text") == 0)
  121. type = PG_TYPE_TEXT;
  122. else if (strcmp(PQgetvalue(res, row, 1), "date") == 0)
  123. type = PG_TYPE_DATE;
  124. else if (strcmp(PQgetvalue(res, row, 1), "time") == 0)
  125. type = PG_TYPE_TIME;
  126. else if (strcmp(PQgetvalue(res, row, 1), "timestamp") == 0)
  127. type = PG_TYPE_TIMESTAMP;
  128. else if (strcmp(PQgetvalue(res, row, 1), "bool") == 0)
  129. type = PG_TYPE_BOOL;
  130. else if (strcmp(PQgetvalue(res, row, 1), "geometry") == 0)
  131. type = PG_TYPE_POSTGIS_GEOM;
  132. else if (strcmp(PQgetvalue(res, row, 1), "topogeometry") == 0)
  133. type = PG_TYPE_POSTGIS_TOPOGEOM;
  134. else
  135. type = PG_TYPE_UNKNOWN;
  136. G_debug(3, "db_driver_open_database(): pgtype = %d, name = %s -> type = %d", pgtype,
  137. PQgetvalue(res, row, 1), type);
  138. pg_types[row][1] = type;
  139. }
  140. PQclear(res);
  141. return DB_OK;
  142. }
  143. int db__driver_close_database()
  144. {
  145. PQfinish(pg_conn);
  146. return DB_OK;
  147. }