00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <stdlib.h>
00018 #include <stdio.h>
00019 #include <dirent.h>
00020 #include <string.h>
00021 #include <unistd.h>
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024 #include <fcntl.h>
00025 #include <grass/glocale.h>
00026 #include <grass/gis.h>
00027 #include <grass/Vect.h>
00028 #include <grass/dbmi.h>
00029
00036 int
00037 Vect_copy_map_lines ( struct Map_info *In, struct Map_info *Out )
00038 {
00039 int i, type, nlines, ret;
00040 struct line_pnts *Points;
00041 struct line_cats *Cats;
00042
00043 Points = Vect_new_line_struct ();
00044 Cats = Vect_new_cats_struct ();
00045
00046 if ( Vect_level ( In ) < 1 )
00047 G_fatal_error ("Vect_copy_map_lines(): input vector is not open");
00048
00049 ret = 0;
00050
00051
00052 if ( Vect_level ( In ) >= 2 ) {
00053 nlines = Vect_get_num_lines ( In );
00054 for ( i = 1; i <= nlines; i++ ) {
00055 type = Vect_read_line (In, Points, Cats, i);
00056 if ( type == -1 ) {
00057 G_warning ("Cannot read vector file\n" );
00058 ret = 1;
00059 break;
00060 }
00061 if ( type == 0 ) continue;
00062
00063 Vect_write_line ( Out, type, Points, Cats );
00064 }
00065 } else {
00066 Vect_rewind ( In );
00067 while ( 1 ) {
00068 type = Vect_read_next_line (In, Points, Cats);
00069 if ( type == -1 ) {
00070 G_warning ("Cannot read vector file\n" );
00071 ret = 1;
00072 break;
00073 } else if ( type == -2 ) {
00074 break;
00075 } else if ( type == 0 ) {
00076 continue;
00077 }
00078 Vect_write_line ( Out, type, Points, Cats );
00079 }
00080 }
00081 Vect_destroy_line_struct (Points);
00082 Vect_destroy_cats_struct (Cats);
00083
00084 return ret;
00085 }
00086
00087
00088
00089
00090
00091 int
00092 copy_file(const char *src, const char *dst)
00093 {
00094 char buf[1024];
00095 int fd, fd2;
00096 FILE *f2;
00097 unsigned int len, len2;
00098
00099 if((fd = open(src, O_RDONLY)) < 0) return 1;
00100
00101
00102 if((f2 = fopen(dst, "w")) == NULL)
00103 {
00104 close(fd);
00105 return 1;
00106 }
00107
00108 fd2 = fileno(f2);
00109
00110 while((len = read(fd, buf, 1024)) > 0)
00111 {
00112 while(len && (len2 = write(fd2, buf, len)) >= 0)
00113 len -= len2;
00114 }
00115
00116 close(fd);
00117
00118 fclose(f2);
00119
00120 if ( len == -1 || len2 == -1 ) return 1;
00121
00122 return 0;
00123 }
00124
00134 int
00135 Vect_copy ( char *in, char *mapset, char *out, FILE *msgout )
00136 {
00137 int i, n, ret, type;
00138 struct Map_info In, Out;
00139 struct field_info *Fi, *Fin;
00140 char old_path[1000], new_path[1000], buf[1000];
00141 struct stat info;
00142 char *files[] = { GRASS_VECT_FRMT_ELEMENT, GRASS_VECT_COOR_ELEMENT,
00143 GRASS_VECT_HEAD_ELEMENT, GRASS_VECT_HIST_ELEMENT,
00144 GV_TOPO_ELEMENT, GV_SIDX_ELEMENT, GV_CIDX_ELEMENT,
00145 NULL };
00146
00147 dbDriver *driver;
00148
00149 G_debug (2, "Copy vector '%s' in '%s' to '%s'", in, mapset, out );
00150
00151 if (Vect_legal_filename(out) < 0 )
00152 G_fatal_error ( _("Map name is not SQL compliant.") );
00153
00154
00155 if ( G_find_vector2(out, G_mapset()) ) {
00156 G_warning (_("The vector '%s' already exists and will be overwritten."), out);
00157 ret = Vect_delete ( out );
00158 if ( ret != 0 ) {
00159 G_warning ( "Cannot copy vector" );
00160 return -1;
00161 }
00162 }
00163
00164
00165 G__make_mapset_element ( GRASS_VECT_DIRECTORY );
00166 sprintf ( buf, "%s/%s", GRASS_VECT_DIRECTORY, out );
00167 G__make_mapset_element ( buf );
00168
00169 i = 0;
00170 while ( files[i] )
00171 {
00172 sprintf ( buf, "%s/%s", in, files[i] );
00173 G__file_name (old_path, GRASS_VECT_DIRECTORY, buf, mapset );
00174 sprintf ( buf, "%s/%s", out, files[i] );
00175 G__file_name (new_path, GRASS_VECT_DIRECTORY, buf, G_mapset() );
00176
00177 if ( stat (old_path, &info) == 0)
00178 {
00179 G_debug (2, "copy %s to %s", old_path, new_path );
00180 if ( copy_file ( old_path, new_path ) )
00181 {
00182 G_warning ( "Cannot copy vector file '%s' to '%s'", old_path, new_path );
00183 }
00184 }
00185 i++;
00186 }
00187
00188 G__file_name (old_path, GRASS_VECT_DIRECTORY, in, mapset );
00189 G__file_name (new_path, GRASS_VECT_DIRECTORY, out, G_mapset() );
00190
00191
00192 Vect_set_open_level (1);
00193 Vect_open_old_head (&In, in, mapset);
00194
00195 if ( In.format != GV_FORMAT_NATIVE ) {
00196 Vect_close ( &In );
00197 return 0;
00198 }
00199
00200
00201 Vect_open_update_head ( &Out, out, G_mapset() );
00202
00203
00204 n = Vect_get_num_dblinks ( &In );
00205 type = GV_1TABLE;
00206 if ( n > 1 ) type = GV_MTABLE;
00207 for ( i = 0; i < n; i++ ) {
00208 Fi = Vect_get_dblink ( &In, i );
00209 if ( Fi == NULL ) {
00210 G_warning ( "Cannot get db link info" );
00211 Vect_close ( &In );
00212 Vect_close ( &Out );
00213 return -1;
00214 }
00215 Fin = Vect_default_field_info ( &Out, Fi->number, Fi->name, type );
00216 G_debug (3, "Copy drv:db:table '%s:%s:%s' to '%s:%s:%s'",
00217 Fi->driver, Fi->database, Fi->table, Fin->driver, Fin->database, Fin->table );
00218 Vect_map_add_dblink ( &Out, Fi->number, Fi->name, Fin->table, Fi->key, Fin->database, Fin->driver);
00219
00220 ret = db_copy_table ( Fi->driver, Fi->database, Fi->table,
00221 Fin->driver, Vect_subst_var(Fin->database,&Out), Fin->table );
00222 if ( ret == DB_FAILED ) {
00223 G_warning ( "Cannot copy table" );
00224 Vect_close ( &In );
00225 Vect_close ( &Out );
00226 return -1;
00227 }
00228
00229 driver = db_start_driver_open_database ( Fin->driver, Vect_subst_var(Fin->database,&Out) );
00230 if ( driver == NULL ) {
00231 G_warning ( "Cannot open database -> create index" );
00232 } else {
00233 if ( db_create_index2(driver, Fin->table, Fi->key ) != DB_OK )
00234 G_warning ( "Cannot create index" );
00235
00236 db_close_database_shutdown_driver ( driver );
00237 }
00238 }
00239
00240 Vect_close ( &In );
00241 Vect_close ( &Out );
00242
00243 return 0;
00244 }
00245
00256 int
00257 Vect_rename ( char *in, char *out, FILE *msgout )
00258 {
00259 int i, n, ret, type;
00260 struct Map_info Map;
00261 struct field_info *Fin, *Fout;
00262 int *fields;
00263 dbDriver *driver;
00264
00265 G_debug (2, "Rename vector '%s' to '%s'", in, out );
00266
00267 if (Vect_legal_filename(out) < 0 )
00268 G_fatal_error ( _("Map name is not SQL compliant.") );
00269
00270
00271 if ( G_find_vector2(out, G_mapset()) ) {
00272 G_warning (_("The vector '%s' already exists and will be overwritten."), out);
00273 Vect_delete ( out );
00274 }
00275
00276
00277 ret = G_rename ( GRASS_VECT_DIRECTORY, in, out );
00278
00279 if ( ret == 0 ) {
00280 G_warning (_("Input vector '%s' not found"), in );
00281 return -1;
00282 } else if ( ret == -1 ) {
00283 G_warning (_("Cannot copy vector '%s' to '%s'"), in, out );
00284 return -1;
00285 }
00286
00287
00288 Vect_set_open_level (1);
00289 Vect_open_update_head ( &Map, out, G_mapset() );
00290
00291 if ( Map.format != GV_FORMAT_NATIVE ) {
00292 Vect_close ( &Map );
00293 return 0;
00294 }
00295
00296
00297 n = Vect_get_num_dblinks ( &Map );
00298 type = GV_1TABLE;
00299 if ( n > 1 ) type = GV_MTABLE;
00300
00301
00302 fields = (int *) G_malloc ( n * sizeof(int) );
00303
00304 for ( i = 0; i < n; i++ ) {
00305 Fin = Vect_get_dblink ( &Map, i );
00306
00307 fields[i] = Fin->number;
00308 }
00309
00310 for ( i = 0; i < n; i++ ) {
00311 G_debug (3, "field[%d] = %d", i, fields[i] );
00312
00313 Fin = Vect_get_field ( &Map, fields[i] );
00314 if ( Fin == NULL ) {
00315 G_warning ( "Cannot get db link info" );
00316 Vect_close ( &Map );
00317 return -1;
00318 }
00319
00320 Fout = Vect_default_field_info ( &Map, Fin->number, Fin->name, type );
00321 G_debug (3, "Copy drv:db:table '%s:%s:%s' to '%s:%s:%s'",
00322 Fin->driver, Fin->database, Fin->table, Fout->driver, Fout->database, Fout->table );
00323
00324
00325 ret = db_copy_table ( Fin->driver, Fin->database, Fin->table,
00326 Fout->driver, Vect_subst_var(Fout->database,&Map), Fout->table );
00327
00328 if ( ret == DB_FAILED ) {
00329 G_warning ( "Cannot copy table" );
00330 Vect_close ( &Map );
00331 return -1;
00332 }
00333
00334
00335 Vect_map_del_dblink ( &Map, Fin->number );
00336
00337 Vect_map_add_dblink ( &Map, Fout->number, Fout->name, Fout->table, Fin->key,
00338 Fout->database, Fout->driver);
00339
00340
00341 ret = db_delete_table ( Fin->driver, Fin->database, Fin->table );
00342 if ( ret == DB_FAILED ) {
00343 G_warning ( "Cannot delete table" );
00344 Vect_close ( &Map );
00345 return -1;
00346 }
00347
00348 driver = db_start_driver_open_database ( Fout->driver, Vect_subst_var(Fout->database, &Map) );
00349 if ( driver == NULL ) {
00350 G_warning ( "Cannot open database -> create index" );
00351 } else {
00352 if ( db_create_index2(driver, Fout->table, Fin->key ) != DB_OK )
00353 G_warning ( "Cannot create index" );
00354
00355 db_close_database_shutdown_driver ( driver );
00356 }
00357 }
00358
00359 Vect_close ( &Map );
00360 free ( fields );
00361
00362 return 0;
00363 }
00364
00371 int
00372 Vect_delete ( char *map )
00373 {
00374 int i, n, ret;
00375 struct Map_info Map;
00376 struct field_info *Fi;
00377 char buf[5000];
00378 DIR *dir;
00379 struct dirent *ent;
00380 char *tmp;
00381
00382 G_debug (3, "Delete vector '%s'", map );
00383
00384 G_chop ( map );
00385
00386 if ( map == NULL || strlen ( map ) == 0 ) {
00387 G_warning ( "Wrong map name '%s'", map );
00388 return -1;
00389 }
00390
00391 sprintf ( buf, "%s/%s/%s/%s/%s/%s", G_gisdbase(), G_location(),
00392 G_mapset(), GRASS_VECT_DIRECTORY, map,
00393 GRASS_VECT_DBLN_ELEMENT );
00394
00395 G_debug (1, "dbln file: %s", buf);
00396
00397 if ( access(buf,F_OK) == 0 )
00398 {
00399
00400 Vect_set_open_level (1);
00401 ret = Vect_open_old_head (&Map, map, G_mapset());
00402 if ( ret < 1 ) {
00403 G_warning ( "Cannot open vector %s", map );
00404 return -1;
00405 }
00406
00407
00408 if ( Map.format == GV_FORMAT_NATIVE ) {
00409
00410 n = Vect_get_num_dblinks ( &Map );
00411 for ( i = 0; i < n; i++ ) {
00412 Fi = Vect_get_dblink ( &Map, i );
00413 if ( Fi == NULL ) {
00414 G_warning ( "Cannot get db link info" );
00415 Vect_close ( &Map );
00416 return -1;
00417 }
00418 G_debug (3, "Delete drv:db:table '%s:%s:%s'", Fi->driver, Fi->database, Fi->table);
00419
00420 ret = db_table_exists ( Fi->driver, Fi->database, Fi->table );
00421 if ( ret == -1 ) {
00422 G_warning ( "Cannot get info if table '%s' linked to vector exists.", Fi->table );
00423 Vect_close ( &Map );
00424 return -1;
00425 }
00426
00427 if ( ret == 1 ) {
00428 ret = db_delete_table ( Fi->driver, Fi->database, Fi->table );
00429 if ( ret == DB_FAILED ) {
00430 G_warning ( "Cannot delete table" );
00431 Vect_close ( &Map );
00432 return -1;
00433 }
00434 } else {
00435 G_warning ( "Table '%s' linked to vector did not exist.", Fi->table );
00436 }
00437 }
00438 }
00439
00440 Vect_close ( &Map );
00441 }
00442
00443
00444 sprintf ( buf, "%s/%s/vector/%s", G_location_path(), G_mapset(), map );
00445 G_debug (3, "opendir '%s'", buf );
00446 dir = opendir( buf );
00447 if (dir == NULL) {
00448 G_warning ( "Cannot open directory '%s'", buf );
00449 return -1;
00450 }
00451
00452 while ( (ent = readdir (dir)) ) {
00453 G_debug (3, "file = '%s'", ent->d_name );
00454 if ( (strcmp (ent->d_name, ".") == 0) || (strcmp (ent->d_name, "..") == 0) ) continue;
00455 sprintf ( buf, "%s/%s/vector/%s/%s", G_location_path(), G_mapset(), map, ent->d_name );
00456 G_debug (3, "delete file '%s'", buf );
00457 ret = unlink ( buf );
00458 if ( ret == -1 ) {
00459 G_warning ( "Cannot delete file '%s'", buf );
00460 closedir (dir);
00461 return -1;
00462 }
00463 }
00464 closedir (dir);
00465
00466
00467
00468 sprintf ( buf, "%s/%s/vector/%s", G_location_path(), G_mapset(), map );
00469
00470 tmp = G_tempfile();
00471
00472 G_debug (3, "rename '%s' to '%s'", buf, tmp );
00473 ret = rename ( buf, tmp );
00474
00475 if ( ret == -1 ) {
00476 G_warning ( "Cannot rename directory '%s' to '%s'", buf, tmp );
00477 return -1;
00478 }
00479
00480 G_debug (3, "remove directory '%s'", tmp );
00481
00482 ret = rmdir ( tmp );
00483 if ( ret == -1 ) {
00484 G_warning ( "Cannot remove directory '%s'", tmp );
00485 return -1;
00486 }
00487
00488 return 0;
00489 }
00490
00497 int
00498 Vect_copy_tables ( struct Map_info *In, struct Map_info *Out, int field )
00499 {
00500 int i, n, ret, type;
00501 struct field_info *Fi, *Fin;
00502 dbDriver *driver;
00503
00504 G_debug (2, "Vect_copy_tables()");
00505
00506 n = Vect_get_num_dblinks ( In );
00507 type = GV_1TABLE;
00508 if ( n > 1 ) type = GV_MTABLE;
00509
00510 for ( i = 0; i < n; i++ ) {
00511 Fi = Vect_get_dblink ( In, i );
00512 if ( Fi == NULL ) {
00513 G_warning ( "Cannot get db link info" );
00514 return -1;
00515 }
00516 if ( field > 0 && Fi->number != field ) continue;
00517
00518 Fin = Vect_default_field_info ( Out, Fi->number, Fi->name, type );
00519 G_debug (2, "Copy drv:db:table '%s:%s:%s' to '%s:%s:%s'",
00520 Fi->driver, Fi->database, Fi->table, Fin->driver, Fin->database, Fin->table );
00521
00522 ret = Vect_map_add_dblink ( Out, Fi->number, Fi->name, Fin->table, Fi->key, Fin->database, Fin->driver);
00523 if ( ret == -1 ) {
00524 G_warning ( "Cannot add database link" );
00525 return -1;
00526 }
00527
00528 ret = db_copy_table ( Fi->driver, Fi->database, Fi->table,
00529 Fin->driver, Vect_subst_var(Fin->database,Out), Fin->table );
00530 if ( ret == DB_FAILED ) {
00531 G_warning ( "Cannot copy table" );
00532 return -1;
00533 }
00534
00535 driver = db_start_driver_open_database ( Fin->driver, Vect_subst_var(Fin->database,Out) );
00536 if ( driver == NULL ) {
00537 G_warning ( "Cannot open database -> create index" );
00538 } else {
00539 if ( db_create_index2(driver, Fin->table, Fi->key ) != DB_OK )
00540 G_warning ( "Cannot create index" );
00541
00542 db_close_database_shutdown_driver ( driver );
00543 }
00544 }
00545
00546 return 0;
00547 }
00548
00561 int
00562 Vect_copy_table ( struct Map_info *In, struct Map_info *Out, int field_in,
00563 int field_out, char *field_name, int type )
00564 {
00565 return Vect_copy_table_by_cats ( In, Out, field_in, field_out, field_name, type, NULL, 0);
00566 }
00567
00582 int
00583 Vect_copy_table_by_cats ( struct Map_info *In, struct Map_info *Out, int field_in,
00584 int field_out, char *field_name, int type, int *cats, int ncats )
00585 {
00586 int ret;
00587 struct field_info *Fi, *Fin;
00588 char *name, *key;
00589
00590 G_debug (2, "Vect_copy_table(): field_in = %d field_out = %d", field_in, field_out);
00591
00592 Fi = Vect_get_field ( In, field_in );
00593 if ( Fi == NULL ) {
00594 G_warning ( "Cannot get db link info" );
00595 return -1;
00596 }
00597
00598 if ( field_name != NULL ) name = field_name;
00599 else name = Fi->name;
00600
00601 Fin = Vect_default_field_info ( Out, field_out, name, type );
00602 G_debug (3, "Copy drv:db:table '%s:%s:%s' to '%s:%s:%s'",
00603 Fi->driver, Fi->database, Fi->table, Fin->driver, Fin->database, Fin->table );
00604
00605 ret = Vect_map_add_dblink ( Out, Fin->number, Fin->name, Fin->table, Fi->key, Fin->database, Fin->driver);
00606 if ( ret == -1 ) {
00607 G_warning ( "Cannot add database link" );
00608 return -1;
00609 }
00610
00611 if ( cats )
00612 key = Fi->key;
00613 else
00614 key = NULL;
00615
00616 ret = db_copy_table_by_ints ( Fi->driver, Fi->database, Fi->table,
00617 Fin->driver, Vect_subst_var(Fin->database,Out), Fin->table, key, cats, ncats );
00618 if ( ret == DB_FAILED ) {
00619 G_warning ( "Cannot copy table" );
00620 return -1;
00621 }
00622
00623 return 0;
00624 }
00625
00631 void
00632 Vect_set_release_support ( struct Map_info * Map )
00633 {
00634 Map->plus.release_support = 1;
00635 }
00636
00644 void
00645 Vect_set_category_index_update ( struct Map_info * Map )
00646 {
00647 Map->plus.update_cidx = 1;
00648 }
00649