Bläddra i källkod

vlib/pg: add field_info to Format_info_pg struct
`make distclean` required...


git-svn-id: https://svn.osgeo.org/grass/grass/trunk@60561 15284696-431f-4ddb-bdfa-cd5b030d7da7

Martin Landa 11 år sedan
förälder
incheckning
417c1f3e2f
3 ändrade filer med 53 tillägg och 55 borttagningar
  1. 1 0
      include/vect/dig_structs.h
  2. 3 0
      lib/vector/Vlib/close_pg.c
  3. 49 55
      lib/vector/Vlib/write_pg.c

+ 1 - 0
include/vect/dig_structs.h

@@ -642,6 +642,7 @@ struct Format_info_pg
       V1_close_pg().
     */
     dbDriver *dbdriver;
+    struct field_info *fi;
 
     /*!
       \brief Start/Finish transaction

+ 3 - 0
lib/vector/Vlib/close_pg.c

@@ -85,6 +85,9 @@ int V1_close_pg(struct Map_info *Map)
     G_free(pg_info->geom_column);
     G_free(pg_info->fid_column);
 
+    if (pg_info->fi)
+        G_free(pg_info->fi);
+    
     if (pg_info->toposchema_name)
         G_free(pg_info->toposchema_name);
 

+ 49 - 55
lib/vector/Vlib/write_pg.c

@@ -11,7 +11,7 @@
    \todo function to delete corresponding entry in fidx
    \todo PostGIS version of V2__add_area_cats_to_cidx_nat
 
-   (C) 2012-2013 by Martin Landa, and the GRASS Development Team
+   (C) 2012-2014 by Martin Landa, and the GRASS Development Team
 
    This program is free software under the GNU General Public License
    (>=v2). Read the file COPYING that comes with GRASS for details.
@@ -38,7 +38,7 @@
 */
 #define USE_TOPO_STMT 0
 
-static int create_table(struct Format_info_pg *, const struct field_info *);
+static int create_table(struct Format_info_pg *);
 static int check_schema(const struct Format_info_pg *);
 static int create_topo_schema(struct Format_info_pg *, int);
 static int create_pg_layer(struct Map_info *, int);
@@ -58,9 +58,8 @@ static unsigned char *polygon_to_wkb(int, const struct line_pnts **, int,
 static char *line_to_wkb(struct Format_info_pg *, const struct line_pnts **,
                          int, int, int);
 static int write_feature(struct Map_info *, int, int,
-                         const struct line_pnts **, int, int, const struct field_info *);
-static char *build_insert_stmt(const struct Format_info_pg *, const char *, int, 
-                               int, const struct field_info *);
+                         const struct line_pnts **, int, int);
+static char *build_insert_stmt(const struct Format_info_pg *, const char *, int, int);
 static int insert_topo_element(struct Map_info *, int, int, const char *);
 static int update_next_edge(struct Map_info*, int, int);
 static int delete_face(const struct Map_info *, int);
@@ -70,7 +69,7 @@ static int add_line_to_topo_pg(struct Map_info *, off_t, int, const struct line_
 static int delete_line_from_topo_pg(struct Map_info *, int, int, const struct line_pnts *);
 static int set_constraint_to_deferrable(struct Format_info_pg *, const char *, const char *,
                                         const char *, const char *, const char *);
-static dbDriver *open_db(struct Format_info_pg *, const struct field_info *);
+static dbDriver *open_db(struct Format_info_pg *);
 #endif
 
 static struct line_pnts *Points;
@@ -574,17 +573,18 @@ int V2__update_area_pg(struct Map_info *Map,
   \brief Create new feature table
 
   \param pg_info pointer to Format_info_pg
-  \param Fi pointer to field_info
 
   \return -1 on error
   \return 0 on success
 */
-int create_table(struct Format_info_pg *pg_info, const struct field_info *Fi)
+int create_table(struct Format_info_pg *pg_info)
 {
     int spatial_index, primary_key;
     char stmt[DB_SQL_MAX];
     char *geom_type, *def_file;
     
+    struct field_info *Fi;
+    
     PGresult *result;
 
     def_file = getenv("GRASS_VECTOR_PGFILE");
@@ -630,6 +630,8 @@ int create_table(struct Format_info_pg *pg_info, const struct field_info *Fi)
             pg_info->schema_name, pg_info->table_name, pg_info->fid_column,
             primary_key ? " PRIMARY KEY" : "", GV_KEY_COLUMN);
     
+    Fi = pg_info->fi;
+    
     if (Fi) {
         /* append attributes */
         int col, ncols, sqltype, length;
@@ -644,7 +646,7 @@ int create_table(struct Format_info_pg *pg_info, const struct field_info *Fi)
 
         db_init_string(&dbtable_name);
 
-        driver = open_db(pg_info, Fi);
+        driver = open_db(pg_info);
         if (driver == NULL)
             return -1;
 
@@ -795,6 +797,11 @@ int check_schema(const struct Format_info_pg *pg_info)
 
     PGresult *result;
 
+    if (!pg_info->conn || !pg_info->table_name) {
+        G_warning(_("No connection defined"));
+        return -1;
+    }
+
     /* add geometry column */
     sprintf(stmt, "SELECT nspname FROM pg_namespace");
     G_debug(2, "SQL: %s", stmt);
@@ -1049,9 +1056,6 @@ int create_pg_layer(struct Map_info *Map, int type)
     int ndblinks;
 
     struct Format_info_pg *pg_info;
-    struct field_info *Fi;
-
-    Fi = NULL;
 
     pg_info = &(Map->fInfo.pg);
     if (!pg_info->conninfo) {
@@ -1096,11 +1100,12 @@ int create_pg_layer(struct Map_info *Map, int type)
     /* create new PostGIS table */
     ndblinks = Vect_get_num_dblinks(Map);
     if (ndblinks > 0) {
-        Fi = Vect_get_dblink(Map, 0);
-        if (Fi) {
+        pg_info->fi = Vect_get_dblink(Map, 0); /* TODO: support more layers */
+        if (pg_info->fi) {
             if (ndblinks > 1)
                 G_warning(_("More layers defined, using driver <%s> and "
-                            "database <%s>"), Fi->driver, Fi->database);
+                            "database <%s>"),
+                          pg_info->fi->driver, pg_info->fi->database);
         }
         else {
             G_warning(_("Database connection not defined. "
@@ -1109,7 +1114,7 @@ int create_pg_layer(struct Map_info *Map, int type)
     }
 
     /* create new feature table */
-    if (create_table(pg_info, Fi) == -1) {
+    if (create_table(pg_info) == -1) {
         G_warning(_("Unable to create new PostGIS feature table"));
         return -1;
     }
@@ -1129,9 +1134,6 @@ int create_pg_layer(struct Map_info *Map, int type)
         }
     }
     
-    if (Fi)
-        G_free(Fi);
-
     return 0;
 }
 
@@ -1185,7 +1187,6 @@ off_t write_line_sf(struct Map_info *Map, int type,
 
     SF_FeatureType sf_type;
 
-    struct field_info *Fi;
     struct Format_info_pg *pg_info;
     struct Format_info_offset *offset_info;
 
@@ -1212,16 +1213,9 @@ off_t write_line_sf(struct Map_info *Map, int type,
     }
     
     /* get category & check for attributes */
-    Fi = NULL; 
     cat = -1;
     if (cats->n_cats > 0) {
-        int field;
-        
-        field = cats->field[0]; /* we assume only one layer defined */
-        if (Vect_get_num_dblinks(Map) > 0) {
-            /* check for attributes */
-            Fi = Vect_get_field(Map, field);
-        }
+        int field = pg_info->fi->number;
         
         if (!Vect_cat_get(cats, field, &cat))
             G_warning(_("No category defined for layer %d"), field);
@@ -1288,7 +1282,7 @@ off_t write_line_sf(struct Map_info *Map, int type,
     }
 
     /* write feature's geometry and fid */
-    if (-1 == write_feature(Map, -1, type, points, nparts, cat, Fi)) {
+    if (-1 == write_feature(Map, -1, type, points, nparts, cat)) {
         Vect__execute_pg(pg_info->conn, "ROLLBACK");
         return -1;
     }
@@ -1332,9 +1326,9 @@ off_t write_line_tp(struct Map_info *Map, int type, int is_node,
 {
     int line, cat, line_id;
 
-    struct field_info *Fi;
     struct Format_info_pg *pg_info;
     struct Plus_head *plus;
+    struct field_info *Fi;
     
     pg_info = &(Map->fInfo.pg);
     plus = &(Map->plus);
@@ -1371,22 +1365,19 @@ off_t write_line_tp(struct Map_info *Map, int type, int is_node,
     G_debug(3, "write_line_pg(): type = %d n_points = %d",
             type, points->n_points);
 
-    Fi = NULL; /* no attributes to be written */
+    Fi = pg_info->fi;
+    
     cat = -1;
     if (cats && cats->n_cats > 0) {
-        if (Vect_get_num_dblinks(Map) > 0) {
-            /* check for attributes */
-            Fi = Vect_get_dblink(Map, 0);
-            if (Fi) {
-                if (!pg_info->dbdriver)
-                    open_db(pg_info, Fi);
-                if (!Vect_cat_get(cats, Fi->number, &cat))
-                    G_warning(_("No category defined for layer %d"), Fi->number);
-                if (cats->n_cats > 1) {
-                    G_warning(_("Feature has more categories, using "
-                                "category %d (from layer %d)"),
-                              cat, cats->field[0]);
-                }
+        if (Fi) {
+            if (!pg_info->dbdriver)
+                open_db(pg_info);
+            if (!Vect_cat_get(cats, Fi->number, &cat))
+                G_warning(_("No category defined for layer %d"), Fi->number);
+            if (cats->n_cats > 1) {
+                G_warning(_("Feature has more categories, using "
+                            "category %d (from layer %d)"),
+                          cat, cats->field[0]);
             }
         }
         /* assume layer=1 */
@@ -1420,7 +1411,7 @@ off_t write_line_tp(struct Map_info *Map, int type, int is_node,
        - feature table for simple features
        - feature table and topo schema for topological access
     */
-    line_id = write_feature(Map, line, type, &points, 1, cat, Fi);
+    line_id = write_feature(Map, line, type, &points, 1, cat);
     if (line_id < 0) {
         Vect__execute_pg(pg_info->conn, "ROLLBACK");
         return -1;
@@ -1841,15 +1832,13 @@ char *line_to_wkb(struct Format_info_pg *pg_info,
    \param points pointer to line_pnts struct
    \param nparts number of parts (rings for polygon)
    \param cat category number (-1 for no category)
-   \param Fi pointer to field_info (attributes to copy, NULL for no attributes)
 
    \return topo_id for PostGIS Topology 
    \return 0 for simple features access
    \return -1 on error
  */
 int write_feature(struct Map_info *Map, int line, int type,
-                  const struct line_pnts **points, int nparts,
-                  int cat, const struct field_info *Fi)
+                  const struct line_pnts **points, int nparts, int cat)
 {
     int with_z, topo_id;
     char *stmt, *geom_data;
@@ -1900,7 +1889,7 @@ int write_feature(struct Map_info *Map, int line, int type,
     /* build INSERT statement
        simple feature geometry + attributes
     */
-    stmt = build_insert_stmt(pg_info, geom_data, topo_id, cat, Fi);
+    stmt = build_insert_stmt(pg_info, geom_data, topo_id, cat);
 
     /* stmt can NULL when writing PostGIS topology with no attributes
      * attached */
@@ -1934,13 +1923,14 @@ int write_feature(struct Map_info *Map, int line, int type,
    \return allocated string with INSERT statement
  */
 char *build_insert_stmt(const struct Format_info_pg *pg_info,
-                        const char *geom_data, int topo_id,
-                        int cat, const struct field_info *Fi)
+                        const char *geom_data, int topo_id, int cat)
 {
     int topogeom_type;
     
     char *stmt, buf[DB_SQL_MAX];
 
+    struct field_info *Fi;
+    
     topogeom_type = -1;
     if (pg_info->toposchema_name) {
         switch (pg_info->feature_type) {
@@ -1959,6 +1949,8 @@ char *build_insert_stmt(const struct Format_info_pg *pg_info,
         }
     }
 
+    Fi = pg_info->fi;
+    
     stmt = NULL;
     if (Fi && cat > -1) {
         /* write attributes (simple features and topology elements) */
@@ -2775,8 +2767,7 @@ int add_line_to_topo_pg(struct Map_info *Map, off_t offset, int type,
             Vect_reset_line(Points);
             Vect_append_point(Points, x, y, z);
             
-            write_feature(Map, node, GV_POINT, (const struct line_pnts **) &Points, 1,
-                          -1, NULL);
+            write_feature(Map, node, GV_POINT, (const struct line_pnts **) &Points, 1, -1);
         }
     }
 
@@ -2872,17 +2863,20 @@ int set_constraint_to_deferrable(struct Format_info_pg *pg_info,
   \brief Open database connection with attribute table
 
   \param pg_info pointer to Format_info_pg struct
-  \param Fi pointer to field_info struct 
 
   \return pointer to dbDriver on succes
   \return NULL on failure
 */
-dbDriver *open_db(struct Format_info_pg *pg_info, const struct field_info *Fi) {
+dbDriver *open_db(struct Format_info_pg *pg_info) {
     dbDriver *driver;
     dbHandle handle;
     
+    struct field_info *Fi;
+    
     db_init_handle(&handle);
     
+    Fi = pg_info->fi;
+    
     pg_info->dbdriver = driver = db_start_driver(Fi->driver);
     if (!driver) {
         G_warning(_("Unable to start driver <%s>"), Fi->driver);