int main (int argc, char **argv) { SHPLOADERCONFIG *config; SHPLOADERSTATE *state; char *header, *footer, *record; int c; int ret, i; #ifdef ENABLE_NLS setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, PGSQL_LOCALEDIR); textdomain (PACKAGE); #endif /* If no options are specified, display usage */ if (argc == 1) { usage(); exit(0); } /* Parse command line options and set configuration */ config = malloc(sizeof(SHPLOADERCONFIG)); set_loader_config_defaults(config); /* Keep the flag list alphabetic so it's easy to see what's left. */ while ((c = pgis_getopt(argc, argv, "acdeg:iknps:t:wDGIN:ST:W:X:")) != EOF) { switch (c) { case 'c': case 'd': case 'a': case 'p': config->opt = c; break; case 'D': config->dump_format = 1; break; case 'G': config->geography = 1; break; case 'S': config->simple_geometries = 1; break; case 's': if (pgis_optarg) { char *ptr = strchr(pgis_optarg, ':'); if (ptr) { *ptr++ = '\0'; sscanf(pgis_optarg, "%d", &config->shp_sr_id); sscanf(ptr, "%d", &config->sr_id); } else { /* Only TO_SRID specified */ sscanf(pgis_optarg, "%d", &config->sr_id); } } else { /* With -s, user must specify TO_SRID or FROM_SRID:TO_SRID */ fprintf(stderr, "The -s parameter must be specified in the form [FROM_SRID:]TO_SRID\n"); exit(1); } break; case 'g': config->geo_col = pgis_optarg; break; case 'k': config->quoteidentifiers = 1; break; case 'i': config->forceint4 = 1; break; case 'I': config->createindex = 1; break; case 'w': config->use_wkt = 1; break; case 'n': config->readshape = 0; break; case 'W': config->encoding = pgis_optarg; break; case 'N': switch (pgis_optarg[0]) { case 'a': config->null_policy = POLICY_NULL_ABORT; break; case 'i': config->null_policy = POLICY_NULL_INSERT; break; case 's': config->null_policy = POLICY_NULL_SKIP; break; default: fprintf(stderr, "Unsupported NULL geometry handling policy.\nValid policies: insert, skip, abort\n"); exit(1); } break; case 't': if (strcasecmp(pgis_optarg, "2D") == 0) { config->force_output = FORCE_OUTPUT_2D; } else if (strcasecmp(pgis_optarg, "3DZ") == 0 ) { config->force_output = FORCE_OUTPUT_3DZ; } else if (strcasecmp(pgis_optarg, "3DM") == 0 ) { config->force_output = FORCE_OUTPUT_3DM; } else if (strcasecmp(pgis_optarg, "4D") == 0 ) { config->force_output = FORCE_OUTPUT_4D; } else { fprintf(stderr, "Unsupported output type: %s\nValid output types are 2D, 3DZ, 3DM and 4D\n", pgis_optarg); exit(1); } break; case 'T': config->tablespace = pgis_optarg; break; case 'X': config->idxtablespace = pgis_optarg; break; case 'e': config->usetransaction = 0; break; case '?': usage(); exit(0); default: usage(); exit(0); } } /* Once we have parsed the arguments, make sure certain combinations are valid */ if (config->dump_format && !config->usetransaction) { fprintf(stderr, "Invalid argument combination - cannot use both -D and -e\n"); exit(1); } if (config->dump_format && config->shp_sr_id != SRID_UNKNOWN) { fprintf(stderr, "Invalid argument combination - cannot use -D with -s FROM_SRID:TO_SRID\n"); exit(1); } /* Determine the shapefile name from the next argument, if no shape file, exit. */ if (pgis_optind < argc) { config->shp_file = argv[pgis_optind]; pgis_optind++; } else { usage(); exit(0); } /* Determine the table and schema names from the next argument */ if (pgis_optind < argc) { char *strptr = argv[pgis_optind]; char *chrptr = strchr(strptr, '.'); /* OK, this is a schema-qualified table name... */ if (chrptr) { if ( chrptr == strptr ) { /* ".something" ??? */ usage(); exit(0); } /* Null terminate at the '.' */ *chrptr = '\0'; /* Copy in the parts */ config->schema = strdup(strptr); config->table = strdup(chrptr+1); } else { config->table = strdup(strptr); } } /* If the table parameter is not provided, use the shape file name as a proxy value. Strip out the .shp and the leading path information first. */ if ( config->shp_file && config->table == NULL) { char *shp_file = strdup(config->shp_file); char *ptr; for ( ptr = shp_file + strlen(shp_file); ptr > shp_file; ptr-- ) { if ( *ptr == '.' ) { *ptr = '\0'; } if ( *ptr == '/' || *ptr == '\\' ) { ptr++; break; } } config->table = strdup(ptr); free(shp_file); } /* Transform table name to lower case if no quoting specified */ if (!config->quoteidentifiers) { if ( config->table ) strtolower(config->table); if ( config->schema ) strtolower(config->schema); } /* Create the shapefile state object */ state = ShpLoaderCreate(config); /* Open the shapefile */ ret = ShpLoaderOpenShape(state); if (ret != SHPLOADEROK) { fprintf(stderr, "%s\n", state->message); if (ret == SHPLOADERERR) exit(1); } /* If reading the whole shapefile, display its type */ if (state->config->readshape) { fprintf(stderr, "Shapefile type: %s\n", SHPTypeName(state->shpfiletype)); fprintf(stderr, "Postgis type: %s[%d]\n", state->pgtype, state->pgdims); } /* Print the header to stdout */ ret = ShpLoaderGetSQLHeader(state, &header); if (ret != SHPLOADEROK) { fprintf(stderr, "%s\n", state->message); if (ret == SHPLOADERERR) exit(1); } printf("%s", header); free(header); /* If we are not in "prepare" mode, go ahead and write out the data. */ if ( state->config->opt != 'p' ) { /* If in COPY mode, output the COPY statement */ if (state->config->dump_format) { ret = ShpLoaderGetSQLCopyStatement(state, &header); if (ret != SHPLOADEROK) { fprintf(stderr, "%s\n", state->message); if (ret == SHPLOADERERR) exit(1); } printf("%s", header); free(header); } /* Main loop: iterate through all of the records and send them to stdout */ for (i = 0; i < ShpLoaderGetRecordCount(state); i++) { ret = ShpLoaderGenerateSQLRowStatement(state, i, &record); switch (ret) { case SHPLOADEROK: /* Simply display the geometry */ printf("%s\n", record); free(record); break; case SHPLOADERERR: /* Display the error message then stop */ fprintf(stderr, "%s\n", state->message); exit(1); break; case SHPLOADERWARN: /* Display the warning, but continue */ fprintf(stderr, "%s\n", state->message); printf("%s\n", record); free(record); break; case SHPLOADERRECDELETED: /* Record is marked as deleted - ignore */ break; case SHPLOADERRECISNULL: /* Record is NULL and should be ignored according to NULL policy */ break; } } /* If in COPY mode, terminate the COPY statement */ if (state->config->dump_format) printf("\\.\n"); } /* Print the footer to stdout */ ret = ShpLoaderGetSQLFooter(state, &footer); if (ret != SHPLOADEROK) { fprintf(stderr, "%s\n", state->message); if (ret == SHPLOADERERR) exit(1); } printf("%s", footer); free(footer); /* Free the state object */ ShpLoaderDestroy(state); /* Free configuration variables */ if (config->schema) free(config->schema); if (config->table) free(config->table); free(config); return 0; }
int main(int argc, char **argv) { SHPDUMPERCONFIG *config; SHPDUMPERSTATE *state; int ret, c, i; /* If no options are specified, display usage */ if (argc == 1) { usage(0); /* TODO: should this exit with error ? */ } /* Parse command line options and set configuration */ config = malloc(sizeof(SHPDUMPERCONFIG)); set_dumper_config_defaults(config); while ((c = pgis_getopt(argc, argv, "bf:h:du:p:P:g:rkm:")) != EOF) { switch (c) { case 'b': config->binary = 1; break; case 'f': config->shp_file = pgis_optarg; break; case 'h': config->conn->host = pgis_optarg; break; case 'd': config->dswitchprovided = 1; break; case 'r': config->includegid = 1; config->unescapedattrs = 1; break; case 'u': config->conn->username = pgis_optarg; break; case 'p': config->conn->port = pgis_optarg; break; case 'P': config->conn->password = pgis_optarg; break; case 'g': config->geo_col_name = pgis_optarg; break; case 'm': config->column_map_filename = pgis_optarg; break; case 'k': config->keep_fieldname_case = 1; break; default: usage(pgis_optopt == '?' ? 0 : 1); } } /* Determine the database name from the next argument, if no database, exit. */ if (pgis_optind < argc) { config->conn->database = argv[pgis_optind]; pgis_optind++; } else { usage(1); } /* Determine the table and schema names from the next argument if supplied, otherwise if it's a user-defined query then set that instead */ if (pgis_optind < argc) { /* User-defined queries begin with SELECT */ if (!strncmp(argv[pgis_optind], "SELECT ", 7) || !strncmp(argv[pgis_optind], "select ", 7)) { config->usrquery = argv[pgis_optind]; } else { /* Schema qualified table name */ char *strptr = argv[pgis_optind]; char *chrptr = strchr(strptr, '.'); /* OK, this is a schema-qualified table name... */ if (chrptr) { if ( chrptr == strptr ) { /* table is ".something" display help */ usage(0); exit(0); } /* Null terminate at the '.' */ *chrptr = '\0'; /* Copy in the parts */ config->schema = strdup(strptr); config->table = strdup(chrptr+1); } else { config->table = strdup(strptr); } } } else { usage(1); } state = ShpDumperCreate(config); ret = ShpDumperConnectDatabase(state); if (ret != SHPDUMPEROK) { fprintf(stderr, "%s\n", state->message); fflush(stderr); exit(1); } /* Display a warning if the -d switch is used with PostGIS >= 1.0 */ if (state->pgis_major_version > 0 && state->config->dswitchprovided) { fprintf(stderr, _("WARNING: -d switch is useless when dumping from postgis-1.0.0+\n")); fflush(stderr); } /* Open the table ready to return rows */ fprintf(stdout, _("Initializing... \n")); fflush(stdout); ret = ShpDumperOpenTable(state); if (ret != SHPDUMPEROK) { fprintf(stderr, "%s\n", state->message); fflush(stderr); if (ret == SHPDUMPERERR) exit(1); } fprintf(stdout, _("Done (postgis major version: %d).\n"), state->pgis_major_version); fprintf(stdout, _("Output shape: %s\n"), shapetypename(state->outshptype)); fprintf(stdout, _("Dumping: ")); fflush(stdout); for (i = 0; i < ShpDumperGetRecordCount(state); i++) { /* Mimic existing behaviour */ if (!(state->currow % state->config->fetchsize)) { fprintf(stdout, "X"); fflush(stdout); } ret = ShpLoaderGenerateShapeRow(state); if (ret != SHPDUMPEROK) { fprintf(stderr, "%s\n", state->message); fflush(stderr); if (ret == SHPDUMPERERR) exit(1); } } fprintf(stdout, _(" [%d rows].\n"), ShpDumperGetRecordCount(state)); fflush(stdout); ret = ShpDumperCloseTable(state); if (ret != SHPDUMPEROK) { fprintf(stderr, "%s\n", state->message); fflush(stderr); if (ret == SHPDUMPERERR) exit(1); } ShpDumperDestroy(state); return 0; }