db.c 4.5 KB

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