int write_attributes(dbDriver *driver, int cat, const struct field_info *Fi, OGRLayerH Ogr_layer, OGRFeatureH Ogr_feature) { int j, ogrfieldnum; char buf[2000]; int ncol, sqltype, ctype, ogrtype, more; const char *fidcol, *colname; dbTable *table; dbString dbstring; dbColumn *column; dbCursor cursor; dbValue *value; OGRFieldDefnH hFieldDefn; G_debug(3, "write_attributes(): cat = %d", cat); if (cat < 0) { G_warning(_("Feature without category of layer %d"), Fi->number); return 0; } db_init_string(&dbstring); /* read & set attributes */ sprintf(buf, "SELECT * FROM %s WHERE %s = %d", Fi->table, Fi->key, cat); G_debug(4, "SQL: %s", buf); db_set_string(&dbstring, buf); /* select data */ if (db_open_select_cursor(driver, &dbstring, &cursor, DB_SEQUENTIAL) != DB_OK) { G_fatal_error(_("Unable to select attributes for category %d"), cat); } if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) { G_fatal_error(_("Unable to fetch data from table <%s>"), Fi->table); } if (!more) { G_warning(_("No database record for category %d, " "no attributes will be written"), cat); return -1; } fidcol = OGR_L_GetFIDColumn(Ogr_layer); table = db_get_cursor_table(&cursor); ncol = db_get_table_number_of_columns(table); for (j = 0; j < ncol; j++) { column = db_get_table_column(table, j); colname = db_get_column_name(column); if (fidcol && *fidcol && strcmp(colname, fidcol) == 0) { /* skip fid column */ continue; } value = db_get_column_value(column); /* for debug only */ db_convert_column_value_to_string(column, &dbstring); G_debug(2, "col %d : val = %s", j, db_get_string(&dbstring)); sqltype = db_get_column_sqltype(column); ctype = db_sqltype_to_Ctype(sqltype); ogrtype = sqltype_to_ogrtype(sqltype); G_debug(2, " colctype = %d", ctype); ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, colname); if (ogrfieldnum < 0) { /* create field if not exists */ hFieldDefn = OGR_Fld_Create(colname, ogrtype); if (OGR_L_CreateField(Ogr_layer, hFieldDefn, TRUE) != OGRERR_NONE) G_warning(_("Unable to create field <%s>"), colname); ogrfieldnum = OGR_F_GetFieldIndex(Ogr_feature, colname); } /* Reset */ OGR_F_UnsetField(Ogr_feature, ogrfieldnum); /* prevent writing NULL values */ if (!db_test_value_isnull(value)) { switch (ctype) { case DB_C_TYPE_INT: OGR_F_SetFieldInteger(Ogr_feature, ogrfieldnum, db_get_value_int(value)); break; case DB_C_TYPE_DOUBLE: OGR_F_SetFieldDouble(Ogr_feature, ogrfieldnum, db_get_value_double(value)); break; case DB_C_TYPE_STRING: OGR_F_SetFieldString(Ogr_feature, ogrfieldnum, db_get_value_string(value)); break; case DB_C_TYPE_DATETIME: db_convert_column_value_to_string(column, &dbstring); OGR_F_SetFieldString(Ogr_feature, ogrfieldnum, db_get_string(&dbstring)); break; } } } db_close_cursor (&cursor); db_free_string(&dbstring); return 1; }
/* return -1 on error */ static int read_dblinks_ogr(struct Map_info *Map) { struct dblinks *dbl; dbl = Map->dblnk; G_debug(3, "Searching for FID column in OGR DB"); #ifndef HAVE_OGR G_warning(_("GRASS is not compiled with OGR support")); #else #if GDAL_VERSION_NUM > 1320 && HAVE_OGR /* seems to be fixed after 1320 release */ int nLayers; char *ogr_fid_col; G_debug(3, "GDAL_VERSION_NUM: %d", GDAL_VERSION_NUM); if (Map->fInfo.ogr.ds == NULL) { /* open the connection to fetch the FID column name */ OGRRegisterAll(); /* data source handle */ Map->fInfo.ogr.ds = OGROpen(Map->fInfo.ogr.dsn, FALSE, NULL); if (Map->fInfo.ogr.ds == NULL) { G_warning(_("Unable to open OGR data source '%s'"), Map->fInfo.ogr.dsn); return -1; } } if (Map->fInfo.ogr.layer == NULL) { /* get layer number */ nLayers = OGR_DS_GetLayerCount(Map->fInfo.ogr.ds); /* Layers = Maps in OGR DB */ G_debug(3, "%d layers (maps) found in data source", nLayers); G_debug(3, "Trying to open OGR layer: %s", Map->fInfo.ogr.layer_name); if (Map->fInfo.ogr.layer_name) { Map->fInfo.ogr.layer = OGR_DS_GetLayerByName(Map->fInfo.ogr.ds, Map->fInfo.ogr.layer_name); if (Map->fInfo.ogr.layer == NULL) { OGR_DS_Destroy(Map->fInfo.ogr.ds); Map->fInfo.ogr.ds = NULL; G_warning(_("Unable to open OGR layer <%s>"), Map->fInfo.ogr.layer_name); return -1; } } } /* get fid column */ ogr_fid_col = G_store(OGR_L_GetFIDColumn(Map->fInfo.ogr.layer)); G_debug(3, "Using FID column <%s> in OGR DB", ogr_fid_col); Vect_add_dblink(dbl, 1, Map->fInfo.ogr.layer_name, Map->fInfo.ogr.layer_name, ogr_fid_col, Map->fInfo.ogr.dsn, "ogr"); #else dbDriver *driver; dbCursor cursor; dbString sql; int FID = 0, OGC_FID = 0, OGR_FID = 0, GID = 0; G_debug(3, "GDAL_VERSION_NUM: %d", GDAL_VERSION_NUM); /* FID is not available for all OGR drivers */ db_init_string(&sql); driver = db_start_driver_open_database("ogr", Map->fInfo.ogr.dsn); if (driver == NULL) { G_warning(_("Unable to open OGR DBMI driver")); return -1; } /* this is a bit stupid, but above FID auto-detection doesn't work yet...: */ db_auto_print_errors(0); sprintf(buf, "select FID from %s where FID > 0", Map->fInfo.ogr.layer_name); db_set_string(&sql, buf); if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) { /* FID not available, so we try ogc_fid */ G_debug(3, "Failed. Now searching for ogc_fid column in OGR DB"); sprintf(buf, "select ogc_fid from %s where ogc_fid > 0", Map->fInfo.ogr.layer_name); db_set_string(&sql, buf); if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) { /* Neither FID nor ogc_fid available, so we try ogr_fid */ G_debug(3, "Failed. Now searching for ogr_fid column in OGR DB"); sprintf(buf, "select ogr_fid from %s where ogr_fid > 0", Map->fInfo.ogr.layer_name); db_set_string(&sql, buf); if (db_open_select_cursor (driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) { /* Neither FID nor ogc_fid available, so we try gid */ G_debug(3, "Failed. Now searching for gid column in OGR DB"); sprintf(buf, "select gid from %s where gid > 0", Map->fInfo.ogr.layer_name); db_set_string(&sql, buf); if (db_open_select_cursor (driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) { /* neither FID nor ogc_fid nor ogr_fid nor gid available */ G_warning(_("All FID tests failed. Neither 'FID' nor 'ogc_fid' " "nor 'ogr_fid' nor 'gid' available in OGR DB table")); db_close_database_shutdown_driver(driver); return 0; } else GID = 1; } else OGR_FID = 1; } else OGC_FID = 1; } else FID = 1; G_debug(3, "FID: %d, OGC_FID: %d, OGR_FID: %d, GID: %d", FID, OGC_FID, OGR_FID, GID); db_close_cursor(&cursor); db_close_database_shutdown_driver(driver); db_auto_print_errors(1); if (FID) { G_debug(3, "Using FID column in OGR DB"); Vect_add_dblink(dbl, 1, Map->fInfo.ogr.layer_name, Map->fInfo.ogr.layer_name, "FID", Map->fInfo.ogr.dsn, "ogr"); } else { if (OGC_FID) { G_debug(3, "Using ogc_fid column in OGR DB"); Vect_add_dblink(dbl, 1, Map->fInfo.ogr.layer_name, Map->fInfo.ogr.layer_name, "ogc_fid", Map->fInfo.ogr.dsn, "ogr"); } else { if (OGR_FID) { G_debug(3, "Using ogr_fid column in OGR DB"); Vect_add_dblink(dbl, 1, Map->fInfo.ogr.layer_name, Map->fInfo.ogr.layer_name, "ogr_fid", Map->fInfo.ogr.dsn, "ogr"); } else { if (GID) { G_debug(3, "Using gid column in OGR DB"); Vect_add_dblink(dbl, 1, Map->fInfo.ogr.layer_name, Map->fInfo.ogr.layer_name, "gid", Map->fInfo.ogr.dsn, "ogr"); } } } } #endif /* GDAL_VERSION_NUM > 1320 && HAVE_OGR */ return 1; #endif /* HAVE_GDAL */ }
dbDriver *create_table(OGRLayerH hLayer, const struct field_info *Fi) { int col, ncols; int sqltype, ogrtype, length; const char *colname; dbDriver *driver; dbHandle handle; dbCursor cursor; dbTable *table; dbColumn *column; dbString sql; OGRFieldDefnH hFieldDefn; OGRFeatureDefnH hFeatureDefn; db_init_string(&sql); db_init_handle(&handle); driver = db_start_driver(Fi->driver); if (!driver) { G_warning(_("Unable to start driver <%s>"), Fi->driver); return NULL; } db_set_handle(&handle, Fi->database, NULL); if (db_open_database(driver, &handle) != DB_OK) { G_warning(_("Unable to open database <%s> by driver <%s>"), Fi->database, Fi->driver); db_close_database_shutdown_driver(driver); return NULL; } /* to get no data */ db_set_string(&sql, "select * from "); db_append_string(&sql, Fi->table); db_append_string(&sql, " where 0 = 1"); if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) { G_warning(_("Unable to open select cursor: '%s'"), db_get_string(&sql)); db_close_database_shutdown_driver(driver); return NULL; } table = db_get_cursor_table(&cursor); ncols = db_get_table_number_of_columns(table); hFeatureDefn = OGR_L_GetLayerDefn(hLayer); 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); ogrtype = sqltype_to_ogrtype(sqltype); length = db_get_column_length(column); if (strcmp(OGR_L_GetFIDColumn(hLayer), colname) == 0 || OGR_FD_GetFieldIndex(hFeatureDefn, colname) > -1) { /* field already exists */ continue; } hFieldDefn = OGR_Fld_Create(colname, ogrtype); /* GDAL 1.9.0 (r22968) uses VARCHAR instead of CHAR */ if (ogrtype == OFTString && length > 0) OGR_Fld_SetWidth(hFieldDefn, length); if (OGR_L_CreateField(hLayer, hFieldDefn, TRUE) != OGRERR_NONE) { G_warning(_("Creating field <%s> failed"), colname); db_close_database_shutdown_driver(driver); return NULL; } OGR_Fld_Destroy(hFieldDefn); } return driver; }
/*! \brief Fetch record \param cn pointer to dbCursor \param position position indicator (DB_NEXT, DB_FIRST, DB_LAST, etc) \param[out] more 0 for no record fetched otherwise 1 \return DB_OK on success \return DB_FAILED on error */ int db__driver_fetch(dbCursor * cn, int position, int *more) { int i, col; int ogrType, sqlType; dbToken token; dbTable *table; dbColumn *column; dbValue *value; cursor *c; G_debug(3, "db_driver_fetch()"); /* get cursor token */ token = db_get_cursor_token(cn); /* get the cursor by its token */ if (!(c = (cursor *) db_find_token(token))) { append_error(_("Cursor not found")); report_error(); return DB_FAILED; } /* fetch on position */ switch (position) { case DB_NEXT: G_debug(4, "DB_NEXT:"); if (c->hFeature) OGR_F_Destroy(c->hFeature); c->hFeature = OGR_L_GetNextFeature(c->hLayer); break; case DB_CURRENT: break; case DB_PREVIOUS: append_error(_("DB_PREVIOUS not supported")); report_error(); return DB_FAILED; break; case DB_FIRST: OGR_L_ResetReading(c->hLayer); if (c->hFeature) OGR_F_Destroy(c->hFeature); c->hFeature = OGR_L_GetNextFeature(c->hLayer); break; case DB_LAST: append_error(_("DB_LAST not supported")); report_error(); return DB_FAILED; break; }; if (c->hFeature == NULL) { *more = 0; return DB_OK; } *more = 1; /* get the data out of the descriptor into the table */ table = db_get_cursor_table(cn); /* check fid column */ if (strlen(OGR_L_GetFIDColumn(c->hLayer)) > 0) { column = db_get_table_column(table, 0); ogrType = db_get_column_host_type(column); sqlType = db_get_column_sqltype(column); value = db_get_column_value(column); value->i = OGR_F_GetFID(c->hFeature); G_debug(3, "fidcol '%s': ogrType %d, sqlType %d: val = %d", db_get_column_name(column), ogrType, sqlType, value->i); col = 0; } else { col = -1; } /* loop attributes */ for (i = 0; i < c->ncols; i++) { if (!(c->cols[i])) { continue; } /* unknown type */ col++; column = db_get_table_column(table, col); ogrType = db_get_column_host_type(column); sqlType = db_get_column_sqltype(column); value = db_get_column_value(column); db_zero_string(&value->s); /* Is null? */ if (OGR_F_IsFieldSet(c->hFeature, i)) { value->isNull = 0; } else { value->isNull = 1; continue; } G_debug(3, "col %d, ogrType %d, sqlType %d: val = '%s'", col, ogrType, sqlType, OGR_F_GetFieldAsString(c->hFeature, i)); switch (ogrType) { case OFTInteger: value->i = OGR_F_GetFieldAsInteger(c->hFeature, i); break; case OFTReal: value->d = OGR_F_GetFieldAsDouble(c->hFeature, i); break; case OFTString: case OFTDate: case OFTTime: case OFTDateTime: db_set_string(&(value->s), (char *)OGR_F_GetFieldAsString(c->hFeature, i)); break; default: G_warning(_("Unknown type")); break; } } G_debug(4, "Row fetched"); return DB_OK; }