/*! \brief Open database (OGR datasource) \param handle pointer to dbHandle (db name and schema) \return DB_OK on success \return DB_FAILED on failure */ int db__driver_open_database(dbHandle * handle) { const char *name; dbConnection connection; init_error(); db_get_connection(&connection); name = db_get_handle_dbname(handle); /* if name is empty use connection.databaseName */ if (strlen(name) == 0) name = connection.databaseName; G_debug(3, "db_driver_open_database() name = '%s'", name); OGRRegisterAll(); hDs = OGROpen(name, TRUE, NULL); if (hDs == NULL) { append_error(_("Unable to open OGR data source")); report_error(); return DB_FAILED; } G_debug(3, "Datasource opened"); return DB_OK; }
/*! \brief Sets up database connection settings using GRASS default from dbmi.h \todo DB_OK on success, DB_* error code on fail \return returns DB_OK */ int db_set_default_connection(void) { dbConnection connection; char buf[GPATH_MAX]; G_debug(1, "Creating new default DB params with db_set_default_connection()"); /* is this really needed ? */ db_get_connection(&connection); if (strcmp(DB_DEFAULT_DRIVER, "dbf") == 0) { /* Set default values and create dbf db dir */ connection.driverName = "dbf"; connection.databaseName = "$GISDBASE/$LOCATION_NAME/$MAPSET/dbf/"; db_set_connection(&connection); sprintf(buf, "%s/%s/dbf", G_location_path(), G_mapset()); G__make_mapset_element("dbf"); } else if (strcmp(DB_DEFAULT_DRIVER, "sqlite") == 0) { /* Set default values and create dbf db dir */ connection.driverName = "sqlite"; /* * TODO: Use one DB for entire mapset (LFS problems?) * or per-map DBs in $MASPET/vector/mapname/sqlite.db (how to set that here?) * or $MAPSET/sqlite/mapname.sql as with dbf? */ connection.databaseName = "$GISDBASE/$LOCATION_NAME/$MAPSET/sqlite.db"; db_set_connection(&connection); } else G_fatal_error(_("Programmer error")); return DB_OK; }
int db__driver_open_database(dbHandle * handle) { char buf[500]; const char *name, *schema, *user, *password; dbConnection connection; PGCONN pgconn; PGresult *res; int row; db_get_connection(&connection); name = db_get_handle_dbname(handle); /* if name is empty use connection.databaseName */ if (strlen(name) == 0) name = connection.databaseName; G_debug(3, "db_driver_open_database(): driver=pg database definition = '%s'", name); if (parse_conn(name, &pgconn) == DB_FAILED) { db_d_report_error(); return DB_FAILED; } G_debug(3, "db_driver_open_database(): host = %s, port = %s, options = %s, tty = %s, " "dbname = %s, user = %s, password = %s, " "schema = %s", pgconn.host, pgconn.port, pgconn.options, pgconn.tty, pgconn.dbname, pgconn.user, pgconn.password, pgconn.schema); db_get_login("pg", name, &user, &password); pg_conn = PQsetdbLogin(pgconn.host, pgconn.port, pgconn.options, pgconn.tty, pgconn.dbname, user, password); if (PQstatus(pg_conn) == CONNECTION_BAD) { db_d_append_error("%s\n%s", _("Connection failed."), PQerrorMessage(pg_conn)); db_d_report_error(); PQfinish(pg_conn); return DB_FAILED; } /* set schema */ schema = db_get_handle_dbschema(handle); /* Cannot use default schema because link to table can point to different database */ /* if ( schema ) schema = connection.schemaName; */ if (pgconn.schema) { schema = pgconn.schema; } /* set path to the schema */ if (schema && strlen(schema) > 0) { sprintf(buf, "set search_path to %s", schema); res = PQexec(pg_conn, buf); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { db_d_append_error("%s %s", _("Unable to set schema:"), schema); db_d_report_error(); PQclear(res); return DB_FAILED; } } /* read internal codes */ res = PQexec(pg_conn, "select oid, typname from pg_type where typname in ( " "'bit', 'int2', 'int4', 'int8', 'serial', 'oid', " "'float4', 'float8', 'numeric', " "'char', 'bpchar', 'varchar', 'text', " "'time', 'date', 'timestamp', " "'bool', 'geometry', 'topogeometry') order by oid"); if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) { db_d_append_error(_("Unable to select data types")); db_d_report_error(); PQclear(res); return DB_FAILED; } pg_ntypes = PQntuples(res); pg_types = G_realloc(pg_types, 2 * pg_ntypes * sizeof(int)); for (row = 0; row < pg_ntypes; row++) { int pgtype, type; pgtype = atoi(PQgetvalue(res, row, 0)); pg_types[row][0] = pgtype; G_debug(3, "row = %d value = %s", row, PQgetvalue(res, row, 1)); if (strcmp(PQgetvalue(res, row, 1), "bit") == 0) type = PG_TYPE_BIT; else if (strcmp(PQgetvalue(res, row, 1), "int2") == 0) type = PG_TYPE_INT2; else if (strcmp(PQgetvalue(res, row, 1), "int4") == 0) type = PG_TYPE_INT4; else if (strcmp(PQgetvalue(res, row, 1), "int8") == 0) type = PG_TYPE_INT8; else if (strcmp(PQgetvalue(res, row, 1), "serial") == 0) type = PG_TYPE_SERIAL; else if (strcmp(PQgetvalue(res, row, 1), "oid") == 0) type = PG_TYPE_OID; else if (strcmp(PQgetvalue(res, row, 1), "float4") == 0) type = PG_TYPE_FLOAT4; else if (strcmp(PQgetvalue(res, row, 1), "float8") == 0) type = PG_TYPE_FLOAT8; else if (strcmp(PQgetvalue(res, row, 1), "numeric") == 0) type = PG_TYPE_NUMERIC; else if (strcmp(PQgetvalue(res, row, 1), "char") == 0) type = PG_TYPE_CHAR; else if (strcmp(PQgetvalue(res, row, 1), "bpchar") == 0) type = PG_TYPE_BPCHAR; else if (strcmp(PQgetvalue(res, row, 1), "varchar") == 0) type = PG_TYPE_VARCHAR; else if (strcmp(PQgetvalue(res, row, 1), "text") == 0) type = PG_TYPE_TEXT; else if (strcmp(PQgetvalue(res, row, 1), "date") == 0) type = PG_TYPE_DATE; else if (strcmp(PQgetvalue(res, row, 1), "time") == 0) type = PG_TYPE_TIME; else if (strcmp(PQgetvalue(res, row, 1), "timestamp") == 0) type = PG_TYPE_TIMESTAMP; else if (strcmp(PQgetvalue(res, row, 1), "bool") == 0) type = PG_TYPE_BOOL; else if (strcmp(PQgetvalue(res, row, 1), "geometry") == 0) type = PG_TYPE_POSTGIS_GEOM; else if (strcmp(PQgetvalue(res, row, 1), "topogeometry") == 0) type = PG_TYPE_POSTGIS_TOPOGEOM; else type = PG_TYPE_UNKNOWN; G_debug(3, "db_driver_open_database(): pgtype = %d, name = %s -> type = %d", pgtype, PQgetvalue(res, row, 1), type); pg_types[row][1] = type; } /* print notice messages only on verbose level */ PQsetNoticeProcessor(pg_conn, notice_processor, NULL); PQclear(res); return DB_OK; }
int db__driver_open_database(dbHandle * handle) { const char *name; int len; dbConnection connection; char buf[1024]; DIR *dir; struct dirent *ent; char **tokens; int no_tokens, n; G_debug(2, "DBF: db__driver_open_database() name = '%s'", db_get_handle_dbname(handle)); db.name[0] = '\0'; db.tables = NULL; db.atables = 0; db.ntables = 0; db_get_connection(&connection); name = db_get_handle_dbname(handle); /* if name is empty use connection.databaseName */ if (strlen(name) == 0) { name = connection.databaseName; } strcpy(db.name, name); /* open database dir and read table ( *.dbf files ) names * to structure */ /* parse variables in db.name if present */ if (db.name[0] == '$') { tokens = G_tokenize(db.name, "/"); no_tokens = G_number_of_tokens(tokens); db.name[0] = '\0'; /* re-init */ for (n = 0; n < no_tokens; n++) { G_debug(3, "tokens[%d] = %s", n, tokens[n]); if (tokens[n][0] == '$') { G_strchg(tokens[n], '$', ' '); G_chop(tokens[n]); strcat(db.name, G__getenv(tokens[n])); G_debug(3, " -> %s", G__getenv(tokens[n])); } else strcat(db.name, tokens[n]); strcat(db.name, "/"); } G_free_tokens(tokens); } G_debug(2, "db.name = %s", db.name); errno = 0; dir = opendir(db.name); if (dir == NULL) { if (errno == ENOENT) { int status; status = G_mkdir(db.name); if (status != 0) { /* mkdir failed */ append_error("Cannot create dbf database: %s\n", name); report_error(); return DB_FAILED; } } else { /* some other problem */ append_error("Cannot open dbf database: %s\n", name); report_error(); return DB_FAILED; } } while ((ent = readdir(dir))) { len = strlen(ent->d_name) - 4; if ((len > 0) && (G_strcasecmp(ent->d_name + len, ".dbf") == 0)) { strcpy(buf, ent->d_name); buf[len] = '\0'; add_table(buf, ent->d_name); } } closedir(dir); return DB_OK; }
int db__driver_open_database(dbHandle * handle) { char *name; dbConnection default_connection; MYSQL *res; db_get_connection(&default_connection); name = G_store(db_get_handle_dbname(handle)); /* if name is empty use default_connection.databaseName */ if (strlen(name) == 0) name = default_connection.databaseName; G_debug(3, "db_driver_open_database() mysql: database definition = '%s'", name); /* Embedded version */ { char *datadir, *database; char *server_args[4]; char *buf; if (!replace_variables(name, &datadir, &database)) { db_d_append_error(_("Unable parse MySQL embedded database name")); db_d_append_error(mysql_error(connection)); db_d_report_error(); return DB_FAILED; } server_args[0] = "mesql"; /* this string is not used */ G_asprintf(&buf, "--datadir=%s", datadir); server_args[1] = buf; /* With InnoDB it is very slow to close the database */ server_args[2] = "--skip-innodb"; /* OK? */ /* Without --bootstrap it complains about missing * mysql.time_zone_leap_second table */ server_args[3] = "--bootstrap"; /* OK? */ if (mysql_server_init(4, server_args, NULL)) { db_d_append_error(_("Cannot initialize MySQL embedded server")); db_d_append_error(mysql_error(connection)); db_d_report_error(); free(datadir); free(database); return DB_FAILED; } connection = mysql_init(NULL); mysql_options(connection, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL); res = mysql_real_connect(connection, NULL, NULL, NULL, database, 0, NULL, 0); free(datadir); free(database); if (res == NULL) { db_d_append_error(_("Unable to connect to MySQL embedded server: ")); db_d_append_error(mysql_error(connection)); db_d_report_error(); return DB_FAILED; } } return DB_OK; }
/*! \brief Get default information about link to database for new dblink \param Map pointer to Map_info structure \param field layer number \param field_name layer name \param type how many tables are linked to map: GV_1TABLE / GV_MTABLE \return pointer to allocated field_info structure */ struct field_info *Vect_default_field_info(struct Map_info *Map, int field, const char *field_name, int type) { struct field_info *fi; char buf[GNAME_MAX], buf2[GNAME_MAX]; const char *schema; dbConnection connection; G_debug(1, "Vect_default_field_info(): map = %s field = %d", Map->name, field); if (Map->format == GV_FORMAT_OGR_DIRECT) { G_zero(&connection, sizeof(dbConnection)); connection.driverName = G_store("ogr"); connection.databaseName = G_store(Map->fInfo.ogr.dsn); } else { db_get_connection(&connection); } G_debug(2, "drv = %s db = %s", connection.driverName, connection.databaseName); if (!connection.driverName && !connection.databaseName) { /* Set default values */ db_set_default_connection(); db_get_connection(&connection); G_important_message(_("Default driver / database set to:\n" "driver: %s\ndatabase: %s"), connection.driverName, connection.databaseName); } /* they must be a matched pair, so if one is set but not the other then give up and let the user figure it out */ else if (!connection.driverName) { G_fatal_error(_("Default driver is not set")); } else if (!connection.databaseName) { G_fatal_error(_("Default database is not set")); } fi = (struct field_info *)G_malloc(sizeof(struct field_info)); fi->number = field; /* Table name */ if (type == GV_1TABLE) { sprintf(buf, "%s", Map->name); } else { if (field_name != NULL && strlen(field_name) > 0) sprintf(buf, "%s_%s", Map->name, field_name); else sprintf(buf, "%s_%d", Map->name, field); } schema = connection.schemaName; if (schema && strlen(schema) > 0) { sprintf(buf2, "%s.%s", schema, buf); fi->table = G_store(buf2); } else { fi->table = G_store(buf); } /* Field name */ if (field_name) fi->name = G_store(field_name); else fi->name = G_store(buf); fi->key = G_store(GV_KEY_COLUMN); /* Should be: id/fid/gfid/... ? */ fi->database = G_store(connection.databaseName); fi->driver = G_store(connection.driverName); return fi; }
int db__driver_create_table(dbTable * table) { int col, ncols; dbColumn *column; const char *colname; int sqltype; char buf[500]; PGresult *res; dbString sql; dbConnection connection; G_debug(3, "db__driver_create_table()"); init_error(); db_init_string(&sql); /* db_table_to_sql ( table, &sql ); */ db_set_string(&sql, "create table "); db_append_string(&sql, db_get_table_name(table)); db_append_string(&sql, " ( "); ncols = db_get_table_number_of_columns(table); for (col = 0; col < ncols; col++) { column = db_get_table_column(table, col); colname = db_get_column_name(column); sqltype = db_get_column_sqltype(column); G_debug(3, "%s (%s)", colname, db_sqltype_name(sqltype)); if (col > 0) db_append_string(&sql, ", "); db_append_string(&sql, colname); db_append_string(&sql, " "); switch (sqltype) { case DB_SQL_TYPE_CHARACTER: sprintf(buf, "varchar(%d)", db_get_column_length(column)); db_append_string(&sql, buf); break; case DB_SQL_TYPE_TEXT: db_append_string(&sql, "text"); break; case DB_SQL_TYPE_SMALLINT: db_append_string(&sql, "smallint"); break; case DB_SQL_TYPE_INTEGER: db_append_string(&sql, "integer"); break; case DB_SQL_TYPE_REAL: db_append_string(&sql, "real"); break; /* TODO: better numeric types */ case DB_SQL_TYPE_DOUBLE_PRECISION: case DB_SQL_TYPE_DECIMAL: case DB_SQL_TYPE_NUMERIC: case DB_SQL_TYPE_INTERVAL: db_append_string(&sql, "double precision"); break; case DB_SQL_TYPE_DATE: db_append_string(&sql, "date"); break; case DB_SQL_TYPE_TIME: db_append_string(&sql, "time"); break; case DB_SQL_TYPE_TIMESTAMP: db_append_string(&sql, "timestamp"); break; default: G_warning("Unknown column type (%s)", colname); return DB_FAILED; } } db_append_string(&sql, " )"); G_debug(3, " SQL: %s", db_get_string(&sql)); res = PQexec(pg_conn, db_get_string(&sql)); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { append_error("Cannot create table:\n"); append_error(db_get_string(&sql)); append_error("\n"); append_error(PQerrorMessage(pg_conn)); report_error(); PQclear(res); db_free_string(&sql); return DB_FAILED; } PQclear(res); /* Grant privileges */ db_get_connection(&connection); db_set_string(&sql, "grant select on "); db_append_string(&sql, db_get_table_name(table)); db_append_string(&sql, " to public"); if (connection.group) { db_append_string(&sql, ", group "); db_append_string(&sql, connection.group); } G_debug(3, " SQL: %s", db_get_string(&sql)); res = PQexec(pg_conn, db_get_string(&sql)); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { append_error("Cannot grant select on table:\n"); append_error(db_get_string(&sql)); append_error("\n"); append_error(PQerrorMessage(pg_conn)); report_error(); PQclear(res); db_free_string(&sql); return DB_FAILED; } PQclear(res); db_free_string(&sql); return DB_OK; }
/*! \brief Initialize a new dbDriver for db transaction. If <i>name</i> is NULL, the db name will be assigned connection.driverName. \param name driver name \return pointer to dbDriver structure \return NULL on error */ dbDriver *db_start_driver(const char *name) { dbDriver *driver; dbDbmscap *list, *cur; const char *startup; int p1[2], p2[2]; int pid; int stat; dbConnection connection; char ebuf[5]; /* Set some environment variables which are later read by driver. * This is necessary when application is running without GISRC file and all * gis variables are set by application. * Even if GISRC is set, application may change some variables during runtime, * if for example reads data from different gdatabase, location or mapset*/ /* setenv() is not portable, putenv() is POSIX, putenv() in glibc 2.0-2.1.1 doesn't conform to SUSv2, * G_putenv() as well, but that is what we want, makes a copy of string */ if (G_get_gisrc_mode() == G_GISRC_MODE_MEMORY) { G_debug(3, "G_GISRC_MODE_MEMORY\n"); sprintf(ebuf, "%d", G_GISRC_MODE_MEMORY); G_putenv("GRASS_DB_DRIVER_GISRC_MODE", ebuf); /* to tell driver that it must read variables */ if (G_getenv_nofatal("DEBUG")) { G_putenv("DEBUG", G_getenv_nofatal("DEBUG")); } else { G_putenv("DEBUG", "0"); } G_putenv("GISDBASE", G_getenv_nofatal("GISDBASE")); G_putenv("LOCATION_NAME", G_getenv_nofatal("LOCATION_NAME")); G_putenv("MAPSET", G_getenv_nofatal("MAPSET")); } else { /* Warning: GISRC_MODE_MEMORY _must_ be set to G_GISRC_MODE_FILE, because the module can be * run from an application which previously set environment variable to G_GISRC_MODE_MEMORY */ sprintf(ebuf, "%d", G_GISRC_MODE_FILE); G_putenv("GRASS_DB_DRIVER_GISRC_MODE", ebuf); } /* read the dbmscap file */ if (NULL == (list = db_read_dbmscap())) return (dbDriver *) NULL; /* if name is empty use connection.driverName, added by RB 4/2000 */ if (name == '\0') { db_get_connection(&connection); if (NULL == (name = connection.driverName)) return (dbDriver *) NULL; } /* find this system name */ for (cur = list; cur; cur = cur->next) if (strcmp(cur->driverName, name) == 0) break; if (cur == NULL) { char msg[256]; db_free_dbmscap(list); sprintf(msg, "%s: no such driver available", name); db_error(msg); return (dbDriver *) NULL; } /* allocate a driver structure */ driver = (dbDriver *) db_malloc(sizeof(dbDriver)); if (driver == NULL) { db_free_dbmscap(list); return (dbDriver *) NULL; } /* copy the relevant info from the dbmscap entry into the driver structure */ db_copy_dbmscap_entry(&driver->dbmscap, cur); startup = driver->dbmscap.startup; /* free the dbmscap list */ db_free_dbmscap(list); /* run the driver as a child process and create pipes to its stdin, stdout */ #ifdef __MINGW32__ #define pipe(fds) _pipe(fds, 250000, _O_BINARY | _O_NOINHERIT) #endif /* open the pipes */ if ((pipe(p1) < 0) || (pipe(p2) < 0)) { db_syserror("can't open any pipes"); return (dbDriver *) NULL; } close_on_exec(p1[READ]); close_on_exec(p1[WRITE]); close_on_exec(p2[READ]); close_on_exec(p2[WRITE]); pid = G_spawn_ex(startup, SF_BACKGROUND, SF_REDIRECT_DESCRIPTOR, 0, p1[READ], SF_CLOSE_DESCRIPTOR, p1[WRITE], SF_REDIRECT_DESCRIPTOR, 1, p2[WRITE], SF_CLOSE_DESCRIPTOR, p2[READ], startup, NULL); /* create a child */ if (pid < 0) { db_syserror("can't create fork"); return (dbDriver *) NULL; } close(p1[READ]); close(p2[WRITE]); /* record driver process id in driver struct */ driver->pid = pid; /* convert pipes to FILE* */ driver->send = fdopen(p1[WRITE], "wb"); driver->recv = fdopen(p2[READ], "rb"); /* most systems will have to use unbuffered io to get the send/recv to work */ #ifndef USE_BUFFERED_IO setbuf(driver->send, NULL); setbuf(driver->recv, NULL); #endif db__set_protocol_fds(driver->send, driver->recv); if (db__recv_return_code(&stat) != DB_OK || stat != DB_OK) driver = NULL; return driver; }
int main(int argc, char *argv[]) { dbConnection conn; struct Flag *print, *check_set_default, *def; /* struct Option *driver, *database, *user, *password, *keycol; */ struct Option *driver, *database, *schema, *group; struct GModule *module; /* Initialize the GIS calls */ G_gisinit(argv[0]); /* Set description */ module = G_define_module(); G_add_keyword(_("database")); G_add_keyword(_("attribute table")); G_add_keyword(_("connection settings")); module->description = _("Prints/sets general DB connection for current mapset."); print = G_define_flag(); print->key = 'p'; print->description = _("Print current connection parameters and exit"); print->guisection = _("Print"); check_set_default = G_define_flag(); check_set_default->key = 'c'; check_set_default->description = _("Check connection parameters, set if uninitialized, and exit"); check_set_default->guisection = _("Set"); def = G_define_flag(); def->key = 'd'; def->label = _("Set from default settings and exit"); def->description = _("Overwrite current settings if initialized"); def->guisection = _("Set"); driver = G_define_standard_option(G_OPT_DB_DRIVER); driver->options = db_list_drivers(); driver->answer = (char *) db_get_default_driver_name(); driver->guisection = _("Set"); database = G_define_standard_option(G_OPT_DB_DATABASE); database->answer = (char *) db_get_default_database_name(); database->guisection = _("Set"); schema = G_define_standard_option(G_OPT_DB_SCHEMA); schema->answer = (char *) db_get_default_schema_name(); schema->guisection = _("Set"); group = G_define_option(); group->key = "group"; group->type = TYPE_STRING; group->required = NO; group->multiple = NO; group->answer = (char*) db_get_default_group_name(); group->description = _("Default group of database users to which " "select privilege is granted"); group->guisection = _("Set"); /* commented due to new mechanism: user = G_define_option() ; user->key = "user" ; user->type = TYPE_STRING ; user->required = NO ; user->multiple = NO ; user->description= "User:"******"password" ; password->type = TYPE_STRING ; password->required = NO ; password->multiple = NO ; password->description= "Password:"******"driver:%s\n", conn.driverName ? conn.driverName : ""); fprintf(stdout, "database:%s\n", conn.databaseName ? conn.databaseName : ""); fprintf(stdout, "schema:%s\n", conn.schemaName ? conn.schemaName : ""); fprintf(stdout, "group:%s\n", conn.group ? conn.group : ""); } else G_fatal_error(_("Database connection not defined. " "Run db.connect.")); exit(EXIT_SUCCESS); } if (check_set_default->answer) { /* check connection and set to system-wide default in required */ /* * TODO: improve db_{get,set}_connection() to not return DB_OK on error * (thus currently there is no point in checking for that here) */ db_get_connection(&conn); if (!conn.driverName && !conn.databaseName) { db_set_default_connection(); db_get_connection(&conn); G_important_message(_("Default driver / database set to:\n" "driver: %s\ndatabase: %s"), conn.driverName, conn.databaseName); } /* they must be a matched pair, so if one is set but not the other then give up and let the user figure it out */ else if (!conn.driverName) { G_fatal_error(_("Default driver is not set")); } else if (!conn.databaseName) { G_fatal_error(_("Default database is not set")); } /* connection either already existed or now exists */ exit(EXIT_SUCCESS); } if (def->answer) { db_set_default_connection(); db_get_connection(&conn); G_important_message(_("Default driver / database set to:\n" "driver: %s\ndatabase: %s"), conn.driverName, conn.databaseName); exit(EXIT_SUCCESS); } /* set connection */ db_get_connection(&conn); /* read current */ if (driver->answer) conn.driverName = driver->answer; if (database->answer) conn.databaseName = database->answer; if (schema->answer) conn.schemaName = schema->answer; if (group->answer) conn.group = group->answer; db_set_connection(&conn); exit(EXIT_SUCCESS); }