Пример #1
0
int main(int argc, char **argv)
{
    struct GModule *module;
    struct Option *map_opt, *field_opt, *fs_opt, *vs_opt, *nv_opt, *col_opt,
	*where_opt, *file_opt;
    struct Flag *c_flag, *v_flag, *r_flag;
    dbDriver *driver;
    dbString sql, value_string;
    dbCursor cursor;
    dbTable *table;
    dbColumn *column;
    dbValue *value;
    struct field_info *Fi;
    int ncols, col, more;
    struct Map_info Map;
    char query[1024];
    struct ilist *list_lines;

    struct bound_box *min_box, *line_box;
    int i, line, area, init_box, cat;

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("database"));
    G_add_keyword(_("attribute table"));
    module->description = _("Prints vector map attributes.");

    map_opt = G_define_standard_option(G_OPT_V_MAP);
    field_opt = G_define_standard_option(G_OPT_V_FIELD);

    col_opt = G_define_standard_option(G_OPT_DB_COLUMNS);

    where_opt = G_define_standard_option(G_OPT_DB_WHERE);

    fs_opt = G_define_standard_option(G_OPT_F_SEP);
    fs_opt->description = _("Output field separator");
    fs_opt->guisection = _("Format");

    vs_opt = G_define_standard_option(G_OPT_F_SEP);
    vs_opt->key = "vs";
    vs_opt->description = _("Output vertical record separator");
    vs_opt->answer = NULL;
    vs_opt->guisection = _("Format");

    nv_opt = G_define_option();
    nv_opt->key = "nv";
    nv_opt->type = TYPE_STRING;
    nv_opt->required = NO;
    nv_opt->description = _("Null value indicator");
    nv_opt->guisection = _("Format");

    file_opt = G_define_standard_option(G_OPT_F_OUTPUT); 
    file_opt->key = "file";
    file_opt->required = NO; 
    file_opt->description = 
	_("Name for output file (if omitted or \"-\" output to stdout)"); 
    
    r_flag = G_define_flag();
    r_flag->key = 'r';
    r_flag->description =
	_("Print minimal region extent of selected vector features instead of attributes");

    c_flag = G_define_flag();
    c_flag->key = 'c';
    c_flag->description = _("Do not include column names in output");
    c_flag->guisection = _("Format");

    v_flag = G_define_flag();
    v_flag->key = 'v';
    v_flag->description = _("Vertical output (instead of horizontal)");
    v_flag->guisection = _("Format");

    G_gisinit(argv[0]);

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    /* set input vector map name and mapset */
    if (file_opt->answer && strcmp(file_opt->answer, "-") != 0) { 
	if (NULL == freopen(file_opt->answer, "w", stdout)) { 
	    G_fatal_error(_("Unable to open file <%s> for writing"), file_opt->answer); 
	} 
    } 
    
    if (r_flag->answer) {
	min_box = (struct bound_box *) G_malloc(sizeof(struct bound_box));
	G_zero((void *)min_box, sizeof(struct bound_box));

	line_box = (struct bound_box *) G_malloc(sizeof(struct bound_box));
	list_lines = Vect_new_list();
    }
    else {
      min_box = line_box = NULL;
      list_lines = NULL;
    }

    db_init_string(&sql);
    db_init_string(&value_string);

    /* open input vector */
    if (!r_flag->answer)
	Vect_open_old_head2(&Map, map_opt->answer, "", field_opt->answer);
    else {
	if (2 > Vect_open_old2(&Map, map_opt->answer, "", field_opt->answer)) {
	    Vect_close(&Map);
	    G_fatal_error(_("Unable to open vector map <%s> at topology level. "
			   "Flag '%c' requires topology level."),
			  map_opt->answer, r_flag->key);
	}
    }

    if ((Fi = Vect_get_field2(&Map, field_opt->answer)) == NULL)
	G_fatal_error(_("Database connection not defined for layer <%s>"),
		      field_opt->answer);

    driver = db_start_driver_open_database(Fi->driver, Fi->database);

    if (!driver)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);

    if (col_opt->answer)
	sprintf(query, "SELECT %s FROM ", col_opt->answer);
    else
	sprintf(query, "SELECT * FROM ");

    db_set_string(&sql, query);
    db_append_string(&sql, Fi->table);

    if (where_opt->answer) {
	char *buf = NULL;

	buf = G_malloc((strlen(where_opt->answer) + 8));
	sprintf(buf, " WHERE %s", where_opt->answer);
	db_append_string(&sql, buf);
	G_free(buf);
    }

    if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK)
	G_fatal_error(_("Unable to open select cursor"));

    table = db_get_cursor_table(&cursor);
    ncols = db_get_table_number_of_columns(table);

    /* column names if horizontal output (ignore for -r) */
    if (!v_flag->answer && !c_flag->answer && !r_flag->answer) {
	for (col = 0; col < ncols; col++) {
	    column = db_get_table_column(table, col);
	    if (col)
		fprintf(stdout, "%s", fs_opt->answer);
	    fprintf(stdout, "%s", db_get_column_name(column));
	}
	fprintf(stdout, "\n");
    }

    init_box = 1;

    /* fetch the data */
    while (1) {
	if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
	    G_fatal_error(_("Unable to fetch data from table <%s>"),
			  Fi->table);

	if (!more)
	    break;

	cat = -1;
	for (col = 0; col < ncols; col++) {
	    column = db_get_table_column(table, col);
	    value = db_get_column_value(column);

	    if (cat < 0 && strcmp(Fi->key, db_get_column_name(column)) == 0) {
		cat = db_get_value_int(value);
		if (r_flag->answer)
		    break;
	    }

	    if (r_flag->answer)
		continue;

	    db_convert_column_value_to_string(column, &value_string);

	    if (!c_flag->answer && v_flag->answer)
		fprintf(stdout, "%s%s", db_get_column_name(column),
			fs_opt->answer);

	    if (col && !v_flag->answer)
		fprintf(stdout, "%s", fs_opt->answer);

	    if (nv_opt->answer && db_test_value_isnull(value))
		fprintf(stdout, "%s", nv_opt->answer);
	    else
		fprintf(stdout, "%s", db_get_string(&value_string));

	    if (v_flag->answer)
		fprintf(stdout, "\n");
	}

	if (r_flag->answer) {
	    /* get minimal region extent */
	    Vect_cidx_find_all(&Map, Vect_get_field_number(&Map, field_opt->answer), -1, cat, list_lines);
	    for (i = 0; i < list_lines->n_values; i++) {
		line = list_lines->value[i];
		area = Vect_get_centroid_area(&Map, line);
		if (area > 0) {
		    if (!Vect_get_area_box(&Map, area, line_box))
			G_fatal_error(_("Unable to get bounding box of area %d"),
				      area);
		}
		else {
		    if (!Vect_get_line_box(&Map, line, line_box))
			G_fatal_error(_("Unable to get bounding box of line %d"),
				      line);
		}
		if (init_box) {
		    Vect_box_copy(min_box, line_box);
		    init_box = 0;
		}
		else {
		    Vect_box_extend(min_box, line_box);
		}
	    }
	}
	else {
	    if (!v_flag->answer)
		fprintf(stdout, "\n");
	    else if (vs_opt->answer)
		fprintf(stdout, "%s\n", vs_opt->answer);
	}
    }

    if (r_flag->answer) {
	fprintf(stdout, "n=%f\n", min_box->N);
	fprintf(stdout, "s=%f\n", min_box->S);
	fprintf(stdout, "w=%f\n", min_box->W);
	fprintf(stdout, "e=%f\n", min_box->E);
	if (Vect_is_3d(&Map)) {
	    fprintf(stdout, "t=%f\n", min_box->T);
	    fprintf(stdout, "b=%f\n", min_box->B);
	}
	fflush(stdout);

	G_free((void *)min_box);
	G_free((void *)line_box);

	Vect_destroy_list(list_lines);
    }

    db_close_cursor(&cursor);
    db_close_database_shutdown_driver(driver);
    Vect_close(&Map);

    exit(EXIT_SUCCESS);
}
Пример #2
0
/*!
  \brief Write data to GRASS ASCII vector format

  Prints message if some features without category are skipped.

  \param[out] ascii  pointer to the output ASCII file
  \param[out] att    att file (< version 5 only)
  \param Map    pointer to Map_info structure
  \param ver    version number 4 or 5
  \param format format GV_ASCII_FORMAT_POINT or GV_ASCII_FORMAT_STD
  \param dp     number of significant digits
  \param fs     field separator
  \param region_flag check region
  \param type   feature type filter
  \param field  field number
  \param Clist  list of categories to filter features or NULL
  \param where  SQL select where statement to filter features or NULL
  \param column_names array of columns to be included to the output or NULL
                 "*" as the first item in the array indicates all columns
  \param header TRUE to print also header

  \return number of written features
  \return -1 on error
*/
int Vect_write_ascii(FILE *ascii,
		     FILE *att, struct Map_info *Map, int ver,
		     int format, int dp, char *fs, int region_flag, int type,
		     int field, const struct cat_list *Clist, const char* where,
		     const char **column_names, int header)
{
    int ltype, ctype, i, cat, line, left, right, found;
    double *xptr, *yptr, *zptr, x, y;
    static struct line_pnts *Points;
    struct line_cats *Cats, *ACats;
    char *xstring, *ystring, *zstring;
    size_t xsize, ysize, zsize;
    struct Cell_head window;
    struct ilist *fcats;
    int count, n_skipped;

    /* where || columns */
    struct field_info *Fi;
    dbDriver *driver;
    dbValue value;
    dbHandle handle;
    int *cats, ncats, more;
    dbTable *Table;
    dbString dbstring;
    dbColumn *Column;
    dbValue *Value;
    char *buf;
    size_t bufsize;
    dbCursor cursor;
    /* columns */
    char **columns;
    int *coltypes;
    char *all_columns;
    
    Fi = NULL;
    driver = NULL;
    columns = NULL;
    coltypes = NULL;
    all_columns = NULL;
    
    G_zero(&value, sizeof(dbValue));
    db_init_string(&dbstring);

    xstring = NULL;
    ystring = NULL;
    zstring = NULL;
    xsize = 0;
    ysize = 0;
    zsize = 0;
    buf = NULL;
    bufsize = 0;

    /* get the region */
    G_get_window(&window);

    count = ncats = 0;
    xstring = ystring = zstring = NULL;
    cats = NULL;
    
    if (field > 0 && (where || column_names)) {
	Fi = Vect_get_field(Map, field);
	if (!Fi) {
	    G_fatal_error(_("Database connection not defined for layer %d"),
			  field);
	}

	driver = db_start_driver(Fi->driver);
	if (!driver)
	    G_fatal_error(_("Unable to start driver <%s>"), Fi->driver);
	
	db_init_handle(&handle);
	db_set_handle(&handle, Fi->database, NULL);
	
	if (db_open_database(driver, &handle) != DB_OK)
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  Fi->database, Fi->driver);
	
	/* select cats (sorted array) */
	ncats = db_select_int(driver, Fi->table, Fi->key, where, &cats);
	G_debug(3, "%d categories selected from table <%s>", ncats, Fi->table);

	if (!column_names) {
	    db_close_database(driver);
	    db_shutdown_driver(driver);
	}
	else {
	    int icol, ncols;
	    const char *col_name;
            int len_all = 0;
            
	    db_set_string(&dbstring, Fi->table);
	    if (db_describe_table(driver, &dbstring, &Table) != DB_OK) {
		G_warning(_("Unable to describe table <%s>"), Fi->table);
		return -1;
	    }
	    
	    ncols = db_get_table_number_of_columns(Table);
	    columns = (char **) G_malloc((ncols + 1) * sizeof(char *));

            if (column_names[0] && strcmp(column_names[0], "*") == 0) {
                
                /* all columns */
                icol = 0;
                for (i = 0; i < ncols; i++) {
                    col_name = db_get_column_name(db_get_table_column(Table, i));
		    /* key column skipped */
                    if (strcmp(Fi->key, col_name) != 0)
			columns[icol++] = G_store(col_name);
                }
                columns[icol] = NULL;
            }
            else {
		int j;

		icol = 0;
		i = 0;
		while (column_names[i]) {
		    /* key column skipped */
                    if (strcmp(Fi->key, column_names[i]) != 0) {
			found = 0;
			for (j = 0; j < ncols; j++) {
			    col_name = db_get_column_name(db_get_table_column(Table, j));
			    if (strcmp(col_name, column_names[i]) == 0) {
				columns[icol++] = G_store(col_name);
				found = 1;
				break;
			    }
			}
			if (!found) {
			    G_warning(_("Column <%s> does not exist"),
				      column_names[i]);
			    G_important_message(_("Available columns:"));
			    for (j = 0; j < ncols; j++) {
				col_name = db_get_column_name(db_get_table_column(Table, j));
				G_important_message("%s", col_name);
			    }
			    G_warning(_("Export cancelled"));
			    db_close_database(driver);
			    db_shutdown_driver(driver);
			    return -1;
			}
		    }
		    i++;
                }
                columns[icol] = NULL;
            }

	    db_zero_string(&dbstring);
	    db_free_table(Table);
	    Table = NULL;
            
	    if (columns[0]) {
		/* selected columns only */
		i = 0;
		while (columns[i])
		    len_all += strlen(columns[i++]);
		
		coltypes = G_malloc(i * sizeof(int));
		
		all_columns = G_malloc(len_all + i + 2);

		i = 0;
		strcpy(all_columns, columns[0]);
		while (columns[i]) {
		    /* get column types */
		    coltypes[i] = db_column_Ctype(driver, Fi->table, columns[i]);
		    if (coltypes[i] < 0) {
			db_close_database(driver);
			db_shutdown_driver(driver);
			G_warning(_("Unknown type of column <%s>, export cancelled"),
				  columns[i]);
			return -1;
		    }
		    if (i > 0) {
			strcat(all_columns, ",");
			strcat(all_columns, columns[i]);
		    }
		    i++;
		}
	    }
	    else {
		/* no column or only key column selected */
		G_free(columns);
		columns = NULL;

		db_close_database(driver);
		db_shutdown_driver(driver);
	    }
	}
    }

    if (format == GV_ASCII_FORMAT_POINT && header) {

	/* print header */
	if (Map->head.with_z)
	    fprintf(ascii, "east%snorth%sheight%scat", fs, fs, fs);
	else
	    fprintf(ascii, "east%snorth%scat", fs, fs);
	if (columns) {
	    for (i = 0; columns[i]; i++) {
		if (db_select_value
		    (driver, Fi->table, Fi->key, cat,
		     columns[i], &value) < 0)
		    G_fatal_error(_("Unable to select record from table <%s> (key %s, column %s)"),
				  Fi->table, Fi->key, columns[i]);
		if (columns[i])
		    fprintf(ascii, "%s%s", fs, columns[i]);
		else
		    fprintf(ascii, "%s", columns[i]); /* can not happen */
	    }
	}
	fprintf(ascii, "%s", HOST_NEWLINE);
    }

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    ACats = Vect_new_cats_struct();
    fcats = Vect_new_list();

    /* by default, read_next_line will NOT read Dead lines */
    /* but we can override that (in Level I only) by specifying */
    /* the type  -1, which means match all line types */

    Vect_rewind(Map);

    count = n_skipped = line = 0;
    while (TRUE) {
	ltype = Vect_read_next_line(Map, Points, Cats);
	if (ltype == -1 ) {      /* failure */
	    if (columns) {
		db_close_database(driver);
		db_shutdown_driver(driver);

                free_col_arrays(coltypes, all_columns,
                                column_names && strcmp(column_names[0], "*") == 0 ? columns : NULL);
	    }
	    
	    return -1;
	}

	if (ltype == -2)	{	/* EOF */
	    if (columns) {
		db_close_database(driver);
		db_shutdown_driver(driver);
                
                free_col_arrays(coltypes, all_columns,
                                column_names && strcmp(column_names[0], "*") == 0 ? columns : NULL);
	    }
	    break;
	}

	line++;

	if (!(ltype & type))
	    continue;

	if (format == GV_ASCII_FORMAT_POINT && !(ltype & GV_POINTS))
	    continue;

	found = get_cat(Cats, Clist, cats, ncats, field, &cat);

	if (!found && field > 0 && ltype == GV_BOUNDARY &&
	    type & GV_AREA && Vect_level(Map) > 1) {
	    Vect_get_line_areas(Map, line, &left, &right);
	    if (left < 0)
		left = Vect_get_isle_area(Map, abs(left));
	    if (left > 0) {
		Vect_get_area_cats(Map, left, ACats);
		found = get_cat(ACats, Clist, cats, ncats, field, &cat);
	    }
	    if (right < 0)
		right = Vect_get_isle_area(Map, abs(right));
	    if (!found && right > 0) {
		Vect_get_area_cats(Map, right, ACats);
		found = get_cat(ACats, Clist, cats, ncats, field, &cat);
	    }
	}
	
	if (!found) {
            if (Cats->n_cats < 1)
                n_skipped++;
            
	    continue;
	}

	if (ver < 5) {
	    Vect_cat_get(Cats, 1, &cat);
	}

	switch (ltype) {
	case GV_BOUNDARY:
	    if (ver == 5)
		ctype = 'B';
	    else
		ctype = 'A';
	    break;
	case GV_CENTROID:
	    if (ver < 5) {
		if (att != NULL) {
		    if (cat > 0) {
			G_rasprintf(&xstring, &xsize, "%.*f", dp, Points->x[0]);
			G_trim_decimal(xstring);
			G_rasprintf(&ystring, &ysize, "%.*f", dp, Points->y[0]);
			G_trim_decimal(ystring);
			fprintf(att, "A %s %s %d%s", xstring, ystring, cat, HOST_NEWLINE);
		    }
		}
		continue;
	    }
	    ctype = 'C';
	    break;
	case GV_LINE:
	    ctype = 'L';
	    break;
	case GV_POINT:
	    ctype = 'P';
	    break;
	case GV_FACE:
	    ctype = 'F';
	    break;
	case GV_KERNEL:
	    ctype = 'K';
	    break;
	default:
	    ctype = 'X';
	    G_warning(_("Unknown feature type %d"), (int)ltype);
	    break;
	}

	if (format == GV_ASCII_FORMAT_POINT) {
	    if (region_flag) {
		if ((window.east < Points->x[0]) ||
		    (window.west > Points->x[0]))
		    continue;
	    }
	    G_rasprintf(&xstring, &xsize, "%.*f", dp, Points->x[0]);
	    G_trim_decimal(xstring);

	    if (region_flag) {
		if ((window.north < Points->y[0]) ||
		    (window.south > Points->y[0]))
		    continue;
	    }
	    G_rasprintf(&ystring, &ysize, "%.*f", dp, Points->y[0]);
	    G_trim_decimal(ystring);

	    Vect_field_cat_get(Cats, field, fcats);

	    if (Map->head.with_z && ver == 5) {
		if (region_flag) {
		    if ((window.top < Points->z[0]) ||
			(window.bottom > Points->z[0]))
			continue;
		}
		G_rasprintf(&zstring, &zsize, "%.*f", dp, Points->z[0]);
		G_trim_decimal(zstring);
		fprintf(ascii, "%s%s%s%s%s", xstring, fs, ystring, fs,
			zstring);
	    }
	    else {
		fprintf(ascii, "%s%s%s", xstring, fs, ystring);
	    }

	    if (fcats->n_values > 0 && cat > -1) {
		if (fcats->n_values > 1) {
		    G_warning(_("Feature has more categories. Only one category (%d) "
				"is exported."), cat);
		}
		fprintf(ascii, "%s%d", fs, cat);
		
		/* print attributes */
		if (columns) {

		    G_rasprintf(&buf, &bufsize, "SELECT %s FROM %s WHERE %s = %d",
			    all_columns, Fi->table, Fi->key, cat);
		    G_debug(2, "SQL: %s", buf);
		    db_set_string(&dbstring, buf);

		    if (db_open_select_cursor
				    (driver, &dbstring, &cursor, DB_SEQUENTIAL) != DB_OK) {
			db_close_database(driver);
			db_shutdown_driver(driver);
			G_fatal_error(_("Cannot select attributes for cat = %d"),
			  cat);
		    }
		    if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
			db_close_database(driver);
			db_shutdown_driver(driver);
			G_fatal_error(_("Unable to fetch data from table"));
		    }

		    Table = db_get_cursor_table(&cursor);


		    for (i = 0; columns[i]; i++) {
			Column = db_get_table_column(Table, i);
			Value = db_get_column_value(Column);

			if (db_test_value_isnull(Value)) {
			    fprintf(ascii, "%s", fs);
			}
			else {
			    switch(coltypes[i])
			    {
			    case DB_C_TYPE_INT: {
				fprintf(ascii, "%s%d", fs, db_get_value_int(Value));
				break;
			    }
			    case DB_C_TYPE_DOUBLE: {
				fprintf(ascii, "%s%.*f", fs, dp, db_get_value_double(Value));
				break;
			    }
			    case DB_C_TYPE_STRING: {
				fprintf(ascii, "%s%s", fs, db_get_value_string(Value));
				break;
			    }
			    case DB_C_TYPE_DATETIME: {
				break;
			    }
			    case -1:
				G_fatal_error(_("Column <%s> not found in table <%s>"),
					      columns[i], Fi->table);
			    default: G_fatal_error(_("Column <%s>: unsupported data type"),
						   columns[i]);
			    }
			}
		    }
		    db_close_cursor(&cursor);
		}
	    }

	    fprintf(ascii, "%s", HOST_NEWLINE);
	}
	else if (format == GV_ASCII_FORMAT_STD) {
	    /* FORMAT_STANDARD */
	    if (ver == 5 && Cats->n_cats > 0)
		fprintf(ascii, "%c  %d %d%s", ctype, Points->n_points,
			Cats->n_cats, HOST_NEWLINE);
	    else
              fprintf(ascii, "%c  %d%s", ctype, Points->n_points, HOST_NEWLINE);

	    xptr = Points->x;
	    yptr = Points->y;
	    zptr = Points->z;

	    while (Points->n_points--) {

		G_rasprintf(&xstring, &xsize, "%.*f", dp, *xptr++);
		G_trim_decimal(xstring);
		G_rasprintf(&ystring, &ysize, "%.*f", dp, *yptr++);
		G_trim_decimal(ystring);

		if (ver == 5) {
		    if (Map->head.with_z) {
			G_rasprintf(&zstring, &zsize, "%.*f", dp, *zptr++);
			G_trim_decimal(zstring);
			fprintf(ascii, " %-12s %-12s %-12s%s", xstring,
				ystring, zstring, HOST_NEWLINE);
		    }
		    else {
                      fprintf(ascii, " %-12s %-12s%s", xstring, ystring, HOST_NEWLINE);
		    }
		}		/*Version 4 */
		else {
                    fprintf(ascii, " %-12s %-12s%s", ystring, xstring, HOST_NEWLINE);
		}
	    }

	    if (ver == 5) {
		for (i = 0; i < Cats->n_cats; i++) {
		    fprintf(ascii, " %-5d %-10d%s", Cats->field[i],
			    Cats->cat[i], HOST_NEWLINE);
		}
	    }
	    else {
		if (cat > -1) {
		    if (ltype == GV_POINT) {
			G_rasprintf(&xstring, &xsize, "%.*f", dp, Points->x[0]);
			G_trim_decimal(xstring);
			G_rasprintf(&ystring, &ysize, "%.*f", dp, Points->y[0]);
			G_trim_decimal(ystring);
			fprintf(att, "P %s %s %d%s", xstring, ystring, cat, HOST_NEWLINE);
		    }
		    else {
			x = (Points->x[1] + Points->x[0]) / 2;
			y = (Points->y[1] + Points->y[0]) / 2;

			G_rasprintf(&xstring, &xsize, "%.*f", dp, x);
			G_trim_decimal(xstring);
			G_rasprintf(&ystring, &ysize, "%.*f", dp, y);
			G_trim_decimal(ystring);
			fprintf(att, "L %s %s %d%s", xstring, ystring, cat, HOST_NEWLINE);
		    }
		}
	    }
	}
	else if (format == GV_ASCII_FORMAT_WKT) {
	    if (ltype & (GV_BOUNDARY | GV_CENTROID | GV_FACE | GV_KERNEL))
		continue;
	    /* Well-Known Text */
	    Vect_sfa_line_astext(Points, ltype, Vect_is_3d(Map), dp, ascii);
	    count++;
	}
	else {
	    G_fatal_error(_("Unknown format"));
	}
	count++;
    }

    if (format == GV_ASCII_FORMAT_WKT) {
	/* process areas - topology required */
	int i, area, nareas, isle, nisles;

	if (Vect_level(Map) < 2) {
	    G_warning(_("Topology not available, unable to process areas"));
	    nareas = 0;
	}
	else {
	    nareas = Vect_get_num_areas(Map);
	}
	for (area = 1; area <= nareas; area++) {
	    if (!Vect_area_alive(Map, area)) /* skip dead areas */
		continue;
	    if (Vect_get_area_cat(Map, area, field) < 0)
		continue;
	    /* get boundary -> linearring */
	    if (Vect_get_area_points(Map, area, Points) < 0) {
		G_warning(_("Unable to get boundary of area id %d"), area);
		continue;
	    }
	    fprintf(ascii, "POLYGON(");
	    /* write outter ring */
	    Vect_sfa_line_astext(Points, GV_BOUNDARY, 0, dp, ascii); /* boundary is always 2D */
	    /* get isles (holes) -> inner rings */
	    nisles = Vect_get_area_num_isles(Map, area);
	    for (i = 0; i < nisles; i++) {
		/* get isle boundary -> linearring */
		isle = Vect_get_area_isle(Map, area, i);
		if (Vect_get_isle_points(Map, isle, Points) < 0) {
		    G_warning(_("Unable to get boundary of isle id %d (area id %d)"), isle, area);
		    continue;
		}
		fprintf(ascii, ", ");
		/* write inner ring */
		Vect_sfa_line_astext(Points, GV_BOUNDARY, 0, dp, ascii); /* boundary is always 2D */
	    }
	    fprintf(ascii, ")%s", HOST_NEWLINE);
	    
	    count++;
	}
    }

    if (n_skipped > 0)
        G_important_message(_("%d features without category skipped. To export also "
                              "features without category use '%s=-1'."), n_skipped, "layer");
    
    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);
    Vect_destroy_cats_struct(ACats);
    
    return count;
}
Пример #3
0
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;
}
Пример #4
0
/* Returns 0 - ok , 1 - error */
int
plot(int ctype, struct Map_info *Map, int type, int field,
     char *columns, int ncols, char *sizecol, int size, double scale,
     COLOR * ocolor, COLOR * colors, int y_center, double *max_reference,
     int do3d)
{
    int ltype, nlines, line, col, more, coltype, nselcols;
    double x, y, csize, len;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int cat;
    double *val;
    char buf[2000];
    struct field_info *Fi;
    dbDriver *driver;
    dbValue *value;
    dbString sql;
    dbCursor cursor;
    dbTable *table;
    dbColumn *column;

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    db_init_string(&sql);

    Fi = Vect_get_field(Map, field);
    if (Fi == NULL)
	G_fatal_error(_("Database connection not defined for layer %d"),
		      field);

    /* Open driver */
    driver = db_start_driver_open_database(Fi->driver, Fi->database);
    if (driver == NULL) {
	G_warning(_("Unable to open database <%s> by driver <%s>"),
		  Fi->database,
		  Fi->driver);
	return 1;
    }
    db_set_error_handler_driver(driver);

    val = (double *)G_malloc((ncols + 1) * sizeof(double));	/* + 1 for sizecol */

    Vect_rewind(Map);

    nlines = Vect_get_num_lines(Map);

    /* loop through each vector feature */
    for (line = 1; line <= nlines; line++) {
	G_debug(3, "line = %d", line);
	ltype = Vect_read_line(Map, Points, Cats, line);

	if (!(ltype & type))
	    continue;

	Vect_cat_get(Cats, field, &cat);
	if (cat < 0)
	    continue;

	/* Select values from DB */
	if (ctype == CTYPE_PIE && sizecol != NULL) {
	    sprintf(buf, "select %s, %s from %s where %s = %d", columns,
		    sizecol, Fi->table, Fi->key, cat);
	    nselcols = ncols + 1;
	}
	else {
	    sprintf(buf, "select %s from %s where %s = %d", columns,
		    Fi->table, Fi->key, cat);
	    nselcols = ncols;
	}

	db_set_string(&sql, buf);
	G_debug(3, "SQL: %s", buf);

	if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) !=
	    DB_OK) {
	    G_warning(_("Unable to open select cursor: '%s'"),
		      buf);
	    return 1;
	}

	table = db_get_cursor_table(&cursor);
	if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK || !more)
	    continue;

	for (col = 0; col < nselcols; col++) {
	    column = db_get_table_column(table, col);
	    value = db_get_column_value(column);
	    coltype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
	    switch (coltype) {
	    case DB_C_TYPE_INT:
		val[col] = (double)db_get_value_int(value);
		break;
	    case DB_C_TYPE_DOUBLE:
		val[col] = db_get_value_double(value);
		break;
	    default:
		G_warning("Column type not supported (must be INT or FLOAT)");
		return 1;
	    }
	    G_debug(4, "  val[%d]: %f", col, val[col]);
	}

	db_close_cursor(&cursor);

	/* Center of chart */
	if (ltype & GV_LINES) {	/* find center */
	    len = Vect_line_length(Points) / 2;
	    Vect_point_on_line(Points, len, &x, &y, NULL, NULL, NULL);
	}
	else {
	    x = Points->x[0];
	    y = Points->y[0];
	}

	if (ctype == CTYPE_PIE) {
	    if (sizecol != NULL) {
		csize = val[ncols];
		size = scale * csize;
	    }
	    pie(x, y, size, val, ncols, ocolor, colors, do3d);
	}
	else {
	    bar(x, y, size, scale, val, ncols, ocolor, colors, y_center,
		max_reference, do3d);
	}
    }

    db_close_database_shutdown_driver(driver);
    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);

    return 0;
}
Пример #5
0
void QgsGrassVectorMapLayer::load()
{
  clear();

  if ( !mMap )
  {
    return;
  }

  // Attributes are not loaded for topo layers in which case field == 0
  if ( mField == 0 )
  {
    return;
  }

  QgsDebugMsg( QString( "cidxFieldIndex() = %1 cidxFieldNumCats() = %2" ).arg( cidxFieldIndex() ).arg( cidxFieldNumCats() ) );

  mFieldInfo = Vect_get_field( mMap->map(), mField ); // should work also with field = 0

  if ( !mFieldInfo )
  {
    QgsDebugMsg( "No field info -> no attribute table" );
  }
  else
  {
    QgsDebugMsg( "Field info found -> open database" );

    QFileInfo di( mMap->grassObject().mapsetPath() + "/vector/" + mMap->grassObject().name() + "/dbln" );
    mLastLoaded = di.lastModified();

    QString error;
    dbDriver *databaseDriver = openDriver( error );

    if ( !databaseDriver || !error.isEmpty() )
    {
      QgsDebugMsg( error );
    }
    else
    {
      QgsDebugMsg( "Database opened -> open select cursor" );
      QgsGrass::lock(); // not sure if lock is necessary
      dbString dbstr;
      db_init_string( &dbstr );
      db_set_string( &dbstr, ( char * )"select * from " );
      db_append_string( &dbstr, mFieldInfo->table );

      QgsDebugMsg( QString( "SQL: %1" ).arg( db_get_string( &dbstr ) ) );
      dbCursor databaseCursor;
      if ( db_open_select_cursor( databaseDriver, &dbstr, &databaseCursor, DB_SCROLL ) != DB_OK )
      {
        db_close_database_shutdown_driver( databaseDriver );
        QgsGrass::warning( "Cannot select attributes from table '" + QString( mFieldInfo->table ) + "'" );
      }
      else
      {
#ifdef QGISDEBUG
        int nRecords = db_get_num_rows( &databaseCursor );
        QgsDebugMsg( QString( "Number of records: %1" ).arg( nRecords ) );
#endif

        dbTable  *databaseTable = db_get_cursor_table( &databaseCursor );
        int nColumns = db_get_table_number_of_columns( databaseTable );

        // Read columns' description
        for ( int i = 0; i < nColumns; i++ )
        {
          QPair<double, double> minMax( DBL_MAX, -DBL_MAX );

          dbColumn *column = db_get_table_column( databaseTable, i );

          int ctype = db_sqltype_to_Ctype( db_get_column_sqltype( column ) );
          QVariant::Type qtype = QVariant::String; //default to string
          QgsDebugMsg( QString( "column = %1 ctype = %2" ).arg( db_get_column_name( column ) ).arg( ctype ) );

          QString ctypeStr;
          switch ( ctype )
          {
            case DB_C_TYPE_INT:
              ctypeStr = QStringLiteral( "integer" );
              qtype = QVariant::Int;
              break;
            case DB_C_TYPE_DOUBLE:
              ctypeStr = QStringLiteral( "double" );
              qtype = QVariant::Double;
              break;
            case DB_C_TYPE_STRING:
              ctypeStr = QStringLiteral( "string" );
              qtype = QVariant::String;
              break;
            case DB_C_TYPE_DATETIME:
              ctypeStr = QStringLiteral( "datetime" );
              qtype = QVariant::String;
              break;
          }
          mTableFields.append( QgsField( db_get_column_name( column ), qtype, ctypeStr,
                                         db_get_column_length( column ), db_get_column_precision( column ) ) );
          mMinMax << minMax;
          if ( G_strcasecmp( db_get_column_name( column ), mFieldInfo->key ) == 0 )
          {
            mKeyColumn = i;
          }
        }

        if ( mKeyColumn < 0 )
        {
          mTableFields.clear();
          QgsGrass::warning( QObject::tr( "Key column '%1' not found in the table '%2'" ).arg( mFieldInfo->key, mFieldInfo->table ) );
        }
        else
        {
          mHasTable = true;
          // Read attributes to the memory
          for ( ;; )
          {
            int more;

            if ( db_fetch( &databaseCursor, DB_NEXT, &more ) != DB_OK )
            {
              QgsDebugMsg( "Cannot fetch DB record" );
              break;
            }
            if ( !more )
            {
              break; // no more records
            }

            // Check cat value
            dbColumn *column = db_get_table_column( databaseTable, mKeyColumn );
            dbValue *value = db_get_column_value( column );

            if ( db_test_value_isnull( value ) )
            {
              continue;
            }
            int cat = db_get_value_int( value );
            if ( cat < 0 )
            {
              continue;
            }

            QList<QVariant> values;
            for ( int i = 0; i < nColumns; i++ )
            {
              column = db_get_table_column( databaseTable, i );
              int sqltype = db_get_column_sqltype( column );
              int ctype = db_sqltype_to_Ctype( sqltype );
              value = db_get_column_value( column );
              db_convert_value_to_string( value, sqltype, &dbstr );

              QgsDebugMsgLevel( QString( "column = %1 value = %2" ).arg( db_get_column_name( column ), db_get_string( &dbstr ) ), 3 );

              QVariant variant;
              if ( !db_test_value_isnull( value ) )
              {
                int iv;
                double dv;
                //layer.mAttributes[layer.nAttributes].values[i] = strdup( db_get_string( &dbstr ) );
                switch ( ctype )
                {
                  case DB_C_TYPE_INT:
                    iv = db_get_value_int( value );
                    variant = QVariant( iv );
                    mMinMax[i].first = std::min( mMinMax[i].first, ( double )iv );
                    mMinMax[i].second = std::min( mMinMax[i].second, ( double )iv );
                    break;
                  case DB_C_TYPE_DOUBLE:
                    dv = db_get_value_double( value );
                    variant = QVariant( dv );
                    mMinMax[i].first = std::min( mMinMax[i].first, dv );
                    mMinMax[i].second = std::min( mMinMax[i].second, dv );
                    break;
                  case DB_C_TYPE_STRING:
                    // Store as byte array so that codec may be used later
                    variant = QVariant( QByteArray( db_get_value_string( value ) ) );
                    break;
                  case DB_C_TYPE_DATETIME:
                    variant = QVariant( QByteArray( db_get_string( &dbstr ) ) );
                    break;
                  default:
                    variant = QVariant( QByteArray( db_get_string( &dbstr ) ) );
                }
              }
              QgsDebugMsgLevel( QString( "column = %1 variant = %2" ).arg( db_get_column_name( column ), variant.toString() ), 3 );
              values << variant;
            }
            mAttributes.insert( cat, values );
          }
        }
        mValid = true;
        db_close_cursor( &databaseCursor );
        db_close_database_shutdown_driver( databaseDriver );
        db_free_string( &dbstr );

        QgsDebugMsg( QString( "mTableFields.size = %1" ).arg( mTableFields.size() ) );
        QgsDebugMsg( QString( "number of attributes = %1" ).arg( mAttributes.size() ) );
      }
      QgsGrass::unlock();
    }
  }

  // Add cat if no attribute fields exist (otherwise qgis crashes)
  if ( mTableFields.size() == 0 )
  {
    mKeyColumn = 0;
    mTableFields.append( QgsField( QStringLiteral( "cat" ), QVariant::Int, QStringLiteral( "integer" ) ) );
    QPair<double, double> minMax( 0, 0 );

    if ( cidxFieldIndex() >= 0 )
    {
      int ncats, cat, type, id;

      ncats = Vect_cidx_get_num_cats_by_index( mMap->map(), cidxFieldIndex() );

      if ( ncats > 0 )
      {
        Vect_cidx_get_cat_by_index( mMap->map(), cidxFieldIndex(), 0, &cat, &type, &id );
        minMax.first = cat;

        Vect_cidx_get_cat_by_index( mMap->map(), cidxFieldIndex(), ncats - 1, &cat, &type, &id );
        minMax.second = cat;
      }
    }
    mMinMax << minMax;
  }
  mFields = mTableFields;
  mAttributeFields = mTableFields;

  QgsDebugMsg( QString( "layer loaded mTableFields.size() = %1 mAttributes.size() = %2" ).arg( mTableFields.size() ).arg( mAttributes.size() ) );
  mValid = true;
}
Пример #6
0
bool aggregator_parse_feed( string data, map <string, string> &feed )
{
	channel.clear();
	image.clear();
	items.clear();
	item = 0;

	XML_Parser xml_parser = my_xml_parser_create( data );

	XML_SetUserData(xml_parser, &xml_parser);
	XML_SetElementHandler(xml_parser, aggregator_element_start, aggregator_element_end);
	XML_SetCharacterDataHandler(xml_parser, aggregator_element_data);
	
	if( !XML_Parse(xml_parser, data.c_str(), (int) data.length(), 1) )
	{
		string error = "The feed from "+feed["title"]+" seems to be broken, because of error " +
			XML_ErrorString( XML_GetErrorCode( xml_parser ) ) + " on line " +
			str( XML_GetCurrentLineNumber( xml_parser ) ) + ".";
		set_page_message( error, "error");
		return false;
	}

	XML_ParserFree(xml_parser);

	for( int i = item; i>=0; i-- )
	{
		string	title, link, guid, date;

		for( map <string, string>::iterator curr = items[i].begin(), end = items[i].end();  curr != end;  curr++ )
		{
			trim( curr->second );
			items[i][curr->first] = curr->second;
		}
		
		// Resolve the item's title. If no title is found, we use up to 40
		// characters of the description ending at a word boundary but not
		// splitting potential entities.
		if (isset(items[i]["TITLE"]))
		{
			title = items[i]["TITLE"];
		}
		else if (isset(items[i]["DESCRIPTION"]))
		{
			title = items[i]["DESCRIPTION"].substr(0, 40);
		}
		else
		{
			title = "";
		}

		// Resolve the items link.
		if (isset(items[i]["LINK"])) 
		{
			link = items[i]["LINK"];
		}
		else 
		{
			link = feed["link"];
		}
		guid = isset(items[i]["GUID"]) ? items[i]["GUID"] : "";

		// Atom feeds have a CONTENT and/or SUMMARY tag instead of a DESCRIPTION tag.
		if (isset(items[i]["CONTENT:ENCODED"])) {
			items[i]["DESCRIPTION"] = items[i]["CONTENT:ENCODED"];
		}
		else if (isset(items[i]["SUMMARY"])) {
			items[i]["DESCRIPTION"] = items[i]["SUMMARY"];
		}
		else if (isset(items[i]["CONTENT"])) {
			items[i]["DESCRIPTION"] = items[i]["CONTENT"];
		}

		if (isset(items[i]["DC:CREATOR"])) {
			items[i]["AUTHOR"] = items[i]["DC:CREATOR"];
		}

		// Try to resolve and parse the item's publication date. If no date is
		// found, we use the current date instead.
		date = "now";
		if (isset(items[i]["PUBDATE"])) { date = items[i]["PUBDATE"]; }
		if (isset(items[i]["DC:DATE"])) { date = items[i]["DC:DATE"]; }
		if (isset(items[i]["DCTERMS:ISSUED"])) { date = items[i]["DCTERMS:ISSUED"]; }
		if (isset(items[i]["DCTERMS:CREATED"])) { date = items[i]["DCTERMS:CREATED"]; }
		if (isset(items[i]["DCTERMS:MODIFIED"])) { date = items[i]["DCTERMS:MODIFIED"]; }
		if (isset(items[i]["ISSUED"])) { date = items[i]["ISSUED"]; }
		if (isset(items[i]["CREATED"])) { date = items[i]["CREATED"]; }
		if (isset(items[i]["MODIFIED"])) { date = items[i]["MODIFIED"]; }
		if (isset(items[i]["PUBLISHED"])) { date = items[i]["PUBLISHED"]; }
		if (isset(items[i]["UPDATED"])) { date = items[i]["UPDATED"]; }

		string timestamp = strtotime( date );
		if( timestamp == "") timestamp = str( time() );

		map <string, string> entry;

		if(DB_TYPE==1)
		{
			if( isset( guid ) )
			{
				map <string, string> item;
				REDIS_RES *result = redis_query_fields( redis_arg("SORT aggregator_item:fid:%d BY nosort", intval(feed["fid"])), "GET aggregator_item:*->", "#iid,guid");
				while( redis_fetch_fields( result, item ) ) {
					if( item["guid"] == guid) {
						redis_free(result); 
						entry["iid"] = item["iid"];
						break;
					}
				}
			}
			else if (isset(link) && link != feed["link"] && link != feed["url"])
			{
				map <string, string> item;
				REDIS_RES *result = redis_query_fields( redis_arg("SORT aggregator_item:fid:%d BY nosort", intval(feed["fid"])), "GET aggregator_item:*->", "#iid,link");
				while( redis_fetch_fields( result, item ) ) {
					if( entry["link"] == link) {
						redis_free(result); 
						entry["iid"] = item["iid"];
						break;
					}
				}
			}
			else
			{
				map <string, string> item;
				REDIS_RES *result = redis_query_fields( redis_arg("SORT aggregator_item:fid:%d BY nosort", intval(feed["fid"])), "GET aggregator_item:*->", "#iid,title");
				while( redis_fetch_fields( result, item ) ) {
					if( entry["title"] == title) {
						redis_free(result); 
						entry["iid"] = item["iid"];
						break;
					}
				}
			}
		}
		if(DB_TYPE==2)
		{
			if( isset( guid ) )
			{
				db_fetch(db_querya("SELECT iid FROM aggregator_item WHERE fid = %d AND guid = '%s'", feed["fid"].c_str(), guid.c_str()), entry );
			}
			else if (isset(link) && link != feed["link"] && link != feed["url"])
			{
				db_fetch(db_querya("SELECT iid FROM aggregator_item WHERE fid = %d AND link = '%s'", feed["fid"].c_str(), link.c_str()), entry );
			}
			else {
				db_fetch(db_querya("SELECT iid FROM aggregator_item WHERE fid = %d AND title = '%s'", feed["fid"].c_str(), title.c_str()), entry );
			}
		}

		entry["fid"] = feed["fid"];
		entry["livetime"] = feed["livetime"];
		entry["timestamp"] = timestamp;
		entry["title"] = title;
		entry["link"] = link;
		entry["author"] = items[i]["AUTHOR"];
		entry["description"] = items[i]["DESCRIPTION"];
		entry["guid"] = guid;

		aggregator_save_item( entry );
	}

	// Remove all items that are older than flush item timer.
	if(DB_TYPE==1)
	{
	}
	if(DB_TYPE==2)
	{
		db_querya("DELETE FROM aggregator_item WHERE fid = %d AND livetime>0 AND timestamp < unix_timestamp()-livetime", feed["fid"].c_str() );
	}
	
	return true;
}
Пример #7
0
/*!
  \brief Select array of ordered integers from table/column

  \param driver DB driver
  \param tab table name
  \param col column name
  \param where where statement
  \param[out] pval array of ordered integer values

  \return number of selected values
  \return -1 on error
*/
int db_select_int(dbDriver * driver, const char *tab, const char *col,
		  const char *where, int **pval)
{
    int type, more, alloc, count;
    int *val;
    char buf[1024];
    const char *sval;
    dbString stmt;
    dbCursor cursor;
    dbColumn *column;
    dbValue *value;
    dbTable *table;

    G_debug(3, "db_select_int()");

    if (col == NULL || strlen(col) == 0) {
	G_warning(_("Missing column name"));
	return -1;
    }

    /* allocate */
    alloc = 1000;
    val = (int *)G_malloc(alloc * sizeof(int));

    if (where == NULL || strlen(where) == 0)
	G_snprintf(buf, 1023, "SELECT %s FROM %s", col, tab);
    else
	G_snprintf(buf, 1023, "SELECT %s FROM %s WHERE %s", col, tab, where);

    G_debug(3, "  SQL: %s", buf);

    db_init_string(&stmt);
    db_append_string(&stmt, buf);

    if (db_open_select_cursor(driver, &stmt, &cursor, DB_SEQUENTIAL) != DB_OK)
	return (-1);

    table = db_get_cursor_table(&cursor);
    column = db_get_table_column(table, 0);	/* first column */
    if (column == NULL) {
	return -1;
    }
    value = db_get_column_value(column);
    type = db_get_column_sqltype(column);
    type = db_sqltype_to_Ctype(type);

    /* fetch the data */
    count = 0;
    while (1) {
	if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
	    return (-1);

	if (!more)
	    break;

	if (count == alloc) {
	    alloc += 1000;
	    val = (int *)G_realloc(val, alloc * sizeof(int));
	}

	switch (type) {
	case (DB_C_TYPE_INT):
	    val[count] = db_get_value_int(value);
	    break;
	case (DB_C_TYPE_STRING):
	    sval = db_get_value_string(value);
	    val[count] = atoi(sval);
	    break;
	case (DB_C_TYPE_DOUBLE):
	    val[count] = (int)db_get_value_double(value);
	    break;
	default:
	    return (-1);
	}
	count++;
    }

    db_close_cursor(&cursor);
    db_free_string(&stmt);

    qsort((void *)val, count, sizeof(int), cmp);

    *pval = val;

    return (count);
}
Пример #8
0
bool OGRGRASSLayer::SetQueryMatch()
{
    CPLDebug ( "GRASS", "SetQueryMatch" );

    // NOTE: we don't have to call ResetSequentialCursor() first because
    // this method is called immediately after OpenSequentialCursor()
    
    if ( !bCursorOpened ) {
	CPLError( CE_Failure, CPLE_AppDefined, "Cursor is not opened.");
	return false;
    }

    int more;
    int cidx = 0; // index to category index
    int fidx = 0; // index to feature index (paFeatureIndex)
    // number of categories in category index
    int ncats = Vect_cidx_get_num_cats_by_index ( poMap, iLayerIndex );
    dbTable *table = db_get_cursor_table ( poCursor );
    while ( true ) {
	if( db_fetch ( poCursor, DB_NEXT, &more) != DB_OK ) 
	{
	    CPLError( CE_Failure, CPLE_AppDefined, "Cannot fetch attributes.");
	    return false;
	}
	if ( !more ) break;

	dbColumn *column = db_get_table_column ( table, iCatField );
	dbValue *value = db_get_column_value ( column );
	int cat = db_get_value_int ( value );

	// NOTE: because of bug in GRASS library it is impossible to use
	//       Vect_cidx_find_next
	
	// Go through category index until first record of current category 
	// is found or a category > current is found
	int cidxcat, type, id;
	while ( cidx < ncats ) {
	    Vect_cidx_get_cat_by_index ( poMap, iLayerIndex, cidx, 
		                         &cidxcat, &type, &id );

	    if ( cidxcat < cat ) {
	    	cidx++;
		continue;
	    }
	    if ( cidxcat > cat ) break; // Not found
	    
	    // We have the category we want, check type
	    if ( !(type & (GV_POINT|GV_LINES|GV_AREA)) )
	    {
	    	cidx++;
		continue;
	    }

	    // Both category and type match -> find feature and set it on
	    while ( true ) {
		if ( fidx > nTotalCount || paFeatureIndex[fidx] > cidx ) { 
		    // should not happen
		    break;
		}
		    
		if ( paFeatureIndex[fidx] == cidx ) {
		    paQueryMatch[fidx] = 1;
		    fidx++;
		    break;
		}
		fidx++;
	    }
	    cidx++;
	}

	if ( id < 0 ) continue; // not found
    }

    return true;
}
Пример #9
0
OGRFeature *OGRGRASSLayer::GetNextFeature()
{
    CPLDebug ( "GRASS", "OGRGRASSLayer::GetNextFeature" );
    OGRFeature  *poFeature = NULL;

    int cat;

    // Get next iNextId
    while ( true ) {
	if( iNextId >= nTotalCount ) // No more features
	{ 
	    // Close cursor / driver if opened 
	    if ( bCursorOpened ) 
	    {
	    	db_close_cursor ( poCursor);
	    	bCursorOpened = false;
	    }
	    if ( poDriver ) 
	    {
    	    	db_close_database_shutdown_driver ( poDriver );
		poDriver = NULL;
	    }

	    return NULL;
	}

	// Attributes
	if( pszQuery != NULL && !paQueryMatch[iNextId] ) {
	    iNextId++;
	    continue;
	}

	// Spatial
	if( m_poFilterGeom && !paSpatialMatch[iNextId] ) {
	    iNextId++;
	    continue;
	}
	
	break; // Attributes & spatial filter match
    }

    OGRGeometry *poOGR = GetFeatureGeometry ( iNextId, &cat );

    poFeature = new OGRFeature( poFeatureDefn );
    poFeature->SetGeometryDirectly( poOGR );
    poFeature->SetFID ( iNextId );
    iNextId++;
    
    // Get attributes
    CPLDebug ( "GRASS", "bHaveAttributes = %d", bHaveAttributes );
    if ( bHaveAttributes ) 
    {
	if ( !poDriver ) 
	{
	    StartDbDriver();
	}
	if ( poDriver ) {
	    if ( !bCursorOpened ) 
	    {
		OpenSequentialCursor();
	    }
	    if ( bCursorOpened ) 
	    {
		dbTable  *table = db_get_cursor_table ( poCursor );
		if ( iCurrentCat < cat ) 
		{
		    while ( true ) {
			int more;
			if( db_fetch ( poCursor, DB_NEXT, &more) != DB_OK ) 
			{
			    CPLError( CE_Failure, CPLE_AppDefined, 
				      "Cannot fetch attributes.");
			    break;
			}
			if ( !more ) break;

			dbColumn *column = db_get_table_column ( table, iCatField );
			dbValue *value = db_get_column_value ( column );
			iCurrentCat = db_get_value_int ( value );

			if ( iCurrentCat >= cat ) break;
		    }
		}
		if ( cat == iCurrentCat )
		{
		    SetAttributes ( poFeature, table );
		} 
		else 
		{
		    CPLError( CE_Failure, CPLE_AppDefined, "Attributes not found.");
		}
	    }
	}
    } 
    else if ( iLayer > 0 ) // Add category
    {
	poFeature->SetField( 0, cat );
    }	
    
    m_nFeaturesRead++;
    return poFeature;
}
Пример #10
0
static int setup_create_user(const char *host, const char *user,
   const char *pass, const char *name)
{
   int ret, major, minor, patch;
   char root[256], user_buf[512], pass_buf[512], name_buf[512];
   char *p1, *p2, *p3;
   DB_RESULT result;
   DB_ROW row;

   printf("Setup will attempt to add this user to your database.\n\n");
   printf("This will only work if your bot resides on the same\n");
   printf("machines as your MySQL server.\n\n");
   printf("This involves connecting to your MySQL as root.\n\n");
   printf("Hit Ctrl-C if you wish to abort, or enter to confirm.\n");

   getchar();

   setup_err = 0;

   /* try to connect as root */
   ret = db_connect(0, host, "root", NULL, "mysql", setup_error);

   if(ret != 0)
   {
      printf("Your MySQL server has a root password set.\n");
      printf("Setup will use this to add a user to your database.\n\n");
      printf("Leave blank to abort.\n\n");

      system("stty -echo");
      text_input("Enter your MySQL root password", root, 256, NULL);
      system("stty echo");

      if(root[0] == 0)
         return -1;

      if(db_connect(0, host, "root", root, "mysql", setup_error) != 0)
      {
         printf("Setup could not connect to your database.\n\n");
         printf("Check in your config file that your database\n");
         printf("settings are correct.  Also try manually\n");
         printf("adding a MySQL user.\n");
         return -1;
      }
   }

   result = db_query(0, "SELECT VERSION()");
   row = db_fetch(result);

   p1 = strtok(row[0], ".-");
   p2 = strtok(NULL, ".-");
   p3 = strtok(NULL, ".-");

   if((p1 == NULL) || (p2 == NULL) || (p3 == NULL))
   {
      printf("Could not determine MySQL version.\n");
      return -1;
   }

   major = p1 ? atoi(p1) : 0;
   minor = p2 ? atoi(p2) : 0;
   patch = p3 ? atoi(p3) : 0;

   db_escape(user_buf, user, 256);
   db_escape(pass_buf, pass, 256);
   db_escape(name_buf, name, 256);

   if(((major >= 3) && (minor >= 23)) || (major > 3))
   {
      db_query(0, "GRANT ALL PRIVILEGES ON %s.* TO %s@localhost "
         "IDENTIFIED BY '%s' WITH GRANT OPTION", name_buf, user_buf,
         pass_buf);
   }
   else if((major >= 3) && (minor == 22) && (patch >= 11))
   {
      db_query(0, "INSERT INTO user (host, user, password) VALUES("
         "'localhost', '%s', PASSWORD('%s'))", user_buf, pass_buf);
      db_query(0, "INSERT INTO db VALUES('%%', '%s', '%s', 'Y', 'Y', "
         "'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y')", name_buf, user_buf);
      db_query(0, "FLUSH PRIVILEGES");
   }
   else
   {
      printf("Setup doesn't know how to deal with MySQL %d.%d.%d.\n\n",
         major, minor, patch);
      printf("You're on your own.\n");
      return -1;
   }

   db_disconnect(0);

   if(setup_err)
   {
      printf("Could not create a user.  You'll have to do it manually\n");
      return -1;
   }

   printf("Created user `%s' on `%s'.\n", user, host);

   return 0;
}
Пример #11
0
/*
 * setup_database() : Creates empty SQL tables.
 *
 * Returns negative if something was canceled by user or error, otherwise
 * zero.
 *
 */
int sql_setup_database(const char *dir, const char *dbhost,
   const char *dbuser, const char *dbpass, const char *dbname)
{
   int ret;
   DB_RESULT result;
   DB_ROW row;

   setup_err = 0;

   /* try connecting to server */
   ret = db_connect(0, dbhost, dbuser, dbpass, NULL, setup_error);

   if(ret == DB_ERR_INIT)
   {
      printf("Could not initialize database client library.\n");
      return -1;
   }

   if(ret == DB_ERR_CONNECT)
   {
      if(setup_create_user(dbhost, dbuser, dbpass, dbname) != 0)
         return -1;

      ret = db_connect(0, dbhost, dbuser, dbpass, NULL, setup_error);

      if(ret != 0)
      {
         printf("Could not connect to database server.\n\n");
         printf("Please manually add `%s' to the user table.\n", dbuser);
         return -1;
      }
   }

   /* try selecting database */
   ret = db_select(0, dbname);

   if(ret != 0)
   {
      if(setup_create_db(dbhost, dbuser, dbpass, dbname) != 0)
         return -1;
   }

   /* check for tables */
   result = db_query(0, "SELECT COUNT(*) FROM bot_user");

   if(setup_err)
   {
      if(setup_create_tables() != 0)
         return -1;
   }
   else
   {
      row = db_fetch(result);

      if(db_int(row[0]) > 0)
      {
         printf("It seems your bot is already setup!\n");
         printf("If you need to add an owner, use ");
         printf("mx3bot --setup-owner\n\n");
         return -1;
      }
   }

   return 0;
}
Пример #12
0
int main(int argc, char **argv) {
	DBHANDLE db;
	int rc,c, flags, len;
	char *ptr_command, *ptr_key, *find;
	char *command, *key, *value;
	command = key = value = NULL;
	char *help_cmd = "command list:\n [add | update] key value \n [del | find] key \n [open | close] dbname\n [help count iterate exit]";

	flags = O_RDWR;
	while ((c = getopt(argc, argv, "nt?")) != -1) {
		switch (c) {
		case 'n':
			flags |= O_CREAT;
			break;
		case 't':
			flags |= O_TRUNC;
			break;
		case '?':
			err_quit("usage: [-n] create new file [-t] truncate db <filename>");
			break;
		}
	}
	if (optind != argc - 1) {
		err_quit("usage: [-n] create new file [-t] truncate db <filename>");
	}

	if ((db = db_open(argv[optind], flags, FILE_MODE)) == NULL) {
		err_sys("db_open %s error", argv[optind]);
	}

	for (;;) {
		char buf[MAX_LEN];
		printf("APUEDB> ");
		if (fgets(buf, MAX_LEN, stdin) == NULL) {
			printf("Bye~\n");
			exit(1);
		}
		to_lowercase(buf);
		len = strlen(buf);
		if ((ptr_command = strchr(buf,COMMAND_SEP)) == NULL) {
			buf[len-1] = '\0';
			if (strcmp(buf,"help") == 0) {
				printf("%s\n", help_cmd);
				continue;
			} else if (strcmp(buf, "count") == 0) {
				printf("%d\n", db_count(db));
			} else if (strcmp(buf, "iterate") == 0) {
				char *ptr;
				db_rewind(db);
				while ((ptr = db_nextrec(db, NULL)) != NULL) {
					printf("%s\n", ptr);
				}
				continue;
			} else if (strcmp(buf, "exit") == 0) {
				printf("Bye~\n");
				exit(1);
			} else {
				printf("invalid command, use command help for help\n");
				continue;
			}
		}
		command = strndup(buf, ptr_command - buf);

		if (strcmp(command, "add") == 0) {
			if ((ptr_key = strchr(ptr_command+1, COMMAND_SEP)) == NULL) {
				printf("invalid add command, usage: add key value\n");
			} else {
				key = strndup(ptr_command+1, ptr_key - ptr_command - 1);
				value = strndup(ptr_key+1, buf + len - 1 - ptr_key - 1);
				rc = db_store(db, key, value, DB_INSERT);
				if (rc == 0) {
					printf("add +OK\n");
				} else {
					printf("key %s already exist\n", key);
				}
			}
		} else if (strcmp(command, "update") == 0) {
			if ((ptr_key = strchr(ptr_command+1, COMMAND_SEP)) == NULL) {
				printf("invalid add command, usage: add key value\n");
			} else {
				key = strndup(ptr_command+1, ptr_key - ptr_command - 1);
				value = strndup(ptr_key+1, buf + len - 1 - ptr_key - 1);
				rc = db_store(db, key, value, DB_REPLACE);
				if (rc == 0) {
					printf("update +OK\n");
				} else {
					printf("key %s not found\n", key);
				}
			}
		} else if (strcmp(command, "del") == 0) {
			if ((ptr_key = strchr(ptr_command+1, COMMAND_SEP)) != NULL) {
				printf("invalid del command, usage: del key\n");
				continue;
			}
			key = strndup(ptr_command+1, buf + len - 1 - ptr_command -1);
			rc = db_delete(db, key);
			if (rc == 0) {
				printf("del +OK\n");
			} else {
				printf("key %s not found\n", key);
			}
		} else if (strcmp(command, "find") == 0) {
			if ((ptr_key = strchr(ptr_command+1, COMMAND_SEP)) != NULL) {
				printf("invalid find command, usage: find key\n");
				continue;
			}
			key = strndup(ptr_command+1, buf + len - 1 - ptr_command -1);
			find = db_fetch(db, key);
			if (find != NULL) {
				printf("%d,%s\n", strlen(find), find);
			} else {
				printf("key %s not found\n", key);
			}
		}
		if (key != NULL) {
			free(key);
			key = NULL;
		}
		if (command != NULL) {
			free(command);
			command = NULL;
		}
		if (value != NULL) {
			free(value);
			value = NULL;
		}
	}
}
Пример #13
0
Файл: main.c Проект: caomw/grass
int sel(dbDriver * driver, dbString * stmt)
{
    dbCursor cursor;
    dbTable *table;
    dbColumn *column;
    dbValue *value;
    dbString value_string;
    int col, ncols;
    int more;

    if (db_open_select_cursor(driver, stmt, &cursor, DB_SEQUENTIAL) != DB_OK)
	return DB_FAILED;
    if (parms.test_only)
	return DB_OK;

    table = db_get_cursor_table(&cursor);
    ncols = db_get_table_number_of_columns(table);
    if (parms.d) {
	for (col = 0; col < ncols; col++) {
	    column = db_get_table_column(table, col);
	    print_column_definition(column);
	}

	return DB_OK;
    }

    if (parms.output && strcmp(parms.output, "-") != 0) { 
	if (NULL == freopen(parms.output, "w", stdout)) { 
	    G_fatal_error(_("Unable to open file <%s> for writing"), parms.output); 
	} 
    } 
    
    db_init_string(&value_string);

    /* column names if horizontal output */
    if (parms.h && parms.c) {
	for (col = 0; col < ncols; col++) {
	    column = db_get_table_column(table, col);
	    if (col)
		fprintf(stdout, "%s", parms.fs);
	    fprintf(stdout, "%s", db_get_column_name(column));
	}
	fprintf(stdout, "\n");
    }

    /* fetch the data */
    while (TRUE) {
	if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
	    return DB_FAILED;
	if (!more)
	    break;

	for (col = 0; col < ncols; col++) {
	    column = db_get_table_column(table, col);
	    value = db_get_column_value(column);
	    db_convert_column_value_to_string(column, &value_string);
	    if (parms.c && !parms.h)
		fprintf(stdout, "%s%s", db_get_column_name(column), parms.fs);
	    if (col && parms.h)
		fprintf(stdout, "%s", parms.fs);
	    if (parms.nv && db_test_value_isnull(value))
		fprintf(stdout, "%s", parms.nv);
	    else
		fprintf(stdout, "%s", db_get_string(&value_string));
	    if (!parms.h)
		fprintf(stdout, "\n");
	}
	if (parms.h)
	    fprintf(stdout, "\n");
	else if (parms.vs)
	    fprintf(stdout, "%s\n", parms.vs);
    }

    return DB_OK;
}
Пример #14
0
struct Map_info *G_sites_open_old(const char *name, const char *mapset)
{
    struct Map_info *Map;
    struct field_info *fi;
    int more, nrows, row, ncols, col, ndbl, nstr, adbl, astr, ctype;
    SITE_ATT *sa;

    dbDriver *driver;
    dbString stmt;
    dbCursor cursor;
    dbTable *table;
    dbColumn *column;
    dbValue *value;

    G_message(
	_("Dev note: Adapted sites library used for vector points. "
	  "(module should be updated to GRASS 6 vector library)"));

    Map = (struct Map_info *)G_malloc(sizeof(struct Map_info));

    Vect_set_open_level(1);
    Vect_open_old(Map, name, mapset);

    G_debug(1, "Vector map opened");

    /* Load attributes */
    Map->site_att = NULL;
    Map->n_site_att = 0;
    Map->n_site_dbl = 0;
    Map->n_site_str = 0;

    fi = Vect_get_field(Map, 1);
    if (fi == NULL) {		/* not attribute table */
	G_debug(1, "No attribute table");
	return Map;
    }

    driver = db_start_driver_open_database(fi->driver, fi->database);
    if (driver == NULL)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      fi->database,
		      fi->driver);

    db_init_string(&stmt);
    db_set_string(&stmt, "select * from ");
    db_append_string(&stmt, fi->table);

    if (db_open_select_cursor(driver, &stmt, &cursor, DB_SEQUENTIAL) != DB_OK)
	G_fatal_error(_("Unable to open select cursor: '%s'"),
		      db_get_string(&stmt));

    nrows = db_get_num_rows(&cursor);
    G_debug(1, "%d rows selected from vector attribute table", nrows);

    Map->site_att = (SITE_ATT *) malloc(nrows * sizeof(SITE_ATT));
    Map->n_site_att = nrows;

    table = db_get_cursor_table(&cursor);
    ncols = db_get_table_number_of_columns(table);

    row = 0;
    adbl = astr = 0;
    while (1) {
	if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
	    G_fatal_error(_("Cannot fetch row"));

	if (!more)
	    break;

	/* Get number of each type */
	if (row == 0) {
	    for (col = 0; col < ncols; col++) {
		column = db_get_table_column(table, col);
		ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));

		if (strcmp(db_get_column_name(column), fi->key) == 0)
		    continue;

		switch (ctype) {
		case DB_C_TYPE_INT:
		case DB_C_TYPE_DOUBLE:
		    adbl++;
		    break;
		case DB_C_TYPE_STRING:
		case DB_C_TYPE_DATETIME:
		    astr++;
		    break;
		}
	    }
	    Map->n_site_dbl = adbl;
	    Map->n_site_str = astr;
	    G_debug(1, "adbl = %d astr = %d", adbl, astr);
	}

	sa = &(Map->site_att[row]);
	sa->dbl = (double *)malloc(adbl * sizeof(double));
	sa->str = (char **)malloc(astr * sizeof(char *));

	ndbl = nstr = 0;
	for (col = 0; col < ncols; col++) {
	    column = db_get_table_column(table, col);
	    ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
	    value = db_get_column_value(column);

	    if (strcmp(db_get_column_name(column), fi->key) == 0) {
		sa->cat = db_get_value_int(value);
	    }
	    else {
		switch (ctype) {
		case DB_C_TYPE_INT:
		    sa->dbl[ndbl] = db_get_value_int(value);
		    ndbl++;
		    break;
		case DB_C_TYPE_DOUBLE:
		    sa->dbl[ndbl] = db_get_value_double(value);
		    ndbl++;
		    break;
		case DB_C_TYPE_STRING:
		    sa->str[nstr] = G_store(db_get_value_string(value));
		    nstr++;
		    break;
		case DB_C_TYPE_DATETIME:
		    sa->str[nstr] = "";	/* TODO */
		    nstr++;
		    break;
		}
	    }
	}
	row++;
    }
    db_close_database_shutdown_driver(driver);

    /* sort attributes */
    qsort((void *)Map->site_att, Map->n_site_att, sizeof(SITE_ATT),
	  site_att_cmp);

    return Map;
}
Пример #15
0
int check_data( db_t hdb, const trans_stat_t * stat )
{
    int rc = EXIT_FAILURE;
    db_result_t db_rc = DB_OK;

    db_row_t row;

    storage_t row_data;
    db_cursor_t c;  // Cursor to scan table to check
    // Cursor parameters
    db_table_cursor_t p = {
        PKEY_INDEX_NAME,   //< Index by which to sort the table
        DB_SCAN_FORWARD | DB_LOCK_DEFAULT
    };

    // Open cursor
    c = db_open_table_cursor(hdb, STORAGE_TABLE, &p);
    row = db_alloc_row( binds_def, DB_ARRAY_DIM( binds_def ) );

    db_rc = db_seek_first(c);

    // Scan table and check that pkey values are monotonically increase
    {
        int counter = 0;
        trans_stat_t s = { 0, 0 };
        for(; !db_eof(c) && DB_OK == db_rc; db_rc = db_seek_next(c) )
        {
            db_rc = db_fetch(c, row, &row_data);
            if( row_data.f1 != ++counter ) {
                break;
            }
            s.lazy_tx += row_data.f2 == 50 ? 1 : 0;
            s.forced_tx += row_data.f2 == 16 ? 1 : 0;
        }

        if( DB_OK != db_rc ) {
            print_error_message( "Error to scan table of backup db\n", c );
        }
        else if( row_data.f1 != counter ) {
            fprintf( stderr, "Pkey field values sequence violation detected in backup db: (%" PRId64 ", %d)\n",
                     row_data.f1, counter
                     );
        }
        else if( s.lazy_tx != stat->lazy_tx ) {
            fprintf( stderr, "Unexpected count of records which was commited in lazy-commit mode: %d, but expected %d.\n",
                     s.lazy_tx, stat->lazy_tx );
        }
        else if( s.forced_tx != stat->forced_tx ) {
            fprintf( stderr, "Unexpected count of records which was commited in force-commit mode: %d, but expected %d.\n",
                     s.forced_tx, stat->forced_tx );
        }
        else {
            fprintf( stdout, "%d records is inside\n", counter );
            rc = EXIT_SUCCESS;
        }
    }

    db_close_cursor( c );
    db_free_row( row );
    db_shutdown(hdb, DB_SOFT_SHUTDOWN, NULL);

    return rc;
}
Пример #16
0
OGRFeature *OGRGRASSLayer::GetFeature( long nFeatureId )

{
    CPLDebug ( "GRASS", "OGRGRASSLayer::GetFeature nFeatureId = %d", nFeatureId );

    int cat;
    OGRFeature *poFeature = NULL;

    OGRGeometry *poOGR = GetFeatureGeometry ( nFeatureId, &cat );

    poFeature = new OGRFeature( poFeatureDefn );
    poFeature->SetGeometryDirectly( poOGR );
    poFeature->SetFID ( nFeatureId );

    // Get attributes
    if ( bHaveAttributes && !poDriver ) 
    {
	StartDbDriver();
    }
    if ( poDriver ) 
    {
	if ( bCursorOpened ) 
	{
	    db_close_cursor ( poCursor);
	    bCursorOpened = false;
	}
	CPLDebug ( "GRASS", "Open cursor for key = %d", cat );
	char buf[2000];
	sprintf ( buf, "SELECT * FROM %s WHERE %s = %d", 
		       poLink->table, poLink->key, cat );
	db_set_string ( poDbString, buf);
	if ( db_open_select_cursor ( poDriver, poDbString, 
		    poCursor, DB_SEQUENTIAL) == DB_OK ) 
	{
	    iCurrentCat = cat; // Not important
	    bCursorOpened = true;
	} 
	else 
	{
	    CPLError( CE_Failure, CPLE_AppDefined, "Cannot open cursor.");
	}

	if ( bCursorOpened ) 
	{
	    int more;
	    if( db_fetch ( poCursor, DB_NEXT, &more) != DB_OK ) 
	    {
		CPLError( CE_Failure, CPLE_AppDefined, "Cannot fetch attributes.");
	    } 
	    else 
	    {
		if ( !more ) 
		{
		    CPLError( CE_Failure, CPLE_AppDefined, "Attributes not found.");
		} 
		else 
		{
	    	    dbTable *table = db_get_cursor_table ( poCursor );
		    SetAttributes ( poFeature, table );
		}
	    }
	    db_close_cursor ( poCursor);
	    bCursorOpened = false;
	}
    } 
    else if ( iLayer > 0 ) // Add category
    {
	poFeature->SetField( 0, cat );
    }	
    
    m_nFeaturesRead++;
    return poFeature;
}
Пример #17
0
string aggregator_admin_overview()
{
	map <string, map <string, string> > form;
	vector < map <string, string> > feeds;
	map <string, string> feed;	

	set_page_title( "Feed aggregator" );
	
	form["feeds"]["#type"] = "table";
	form["feeds"]["#header"] = "Title,Items,Last update,Next update,Operations, , ";
	form["feeds"]["#weight"] = "1";
	form["feeds"]["#prefix"] = "<h3>Feed overview</h3>";

	if(DB_TYPE==1)
	{
		REDIS_RES *result = redis_query_fields("SORT aggregator_feed BY aggregator_feed:*->title ALPHA", "GET aggregator_feed:*->", "#fid,title,url,refresh,checked,link,description,etag,modified,image,block");
		while( redis_fetch_fields( result, feed ) ) {
			feed["items"] = redis_str("SCARD aggregator_item:fid:%d", intval(feed["fid"]) );
			feeds.push_back( feed );
		}
	}
	if(DB_TYPE==2)
	{
		MYSQL_RES * result = db_querya("SELECT f.*, COUNT(i.iid) AS items FROM aggregator_feed f LEFT JOIN aggregator_item i ON f.fid = i.fid GROUP BY f.fid, f.title, f.url, f.refresh, f.checked, f.link, f.description, f.etag, f.modified, f.image, f.block ORDER BY f.title");
		while ( db_fetch( result, feed ) ) {	
			feeds.push_back( feed );
		}
	}

	for(size_t n=0; n< feeds.size(); n++)
	{
		form["tit_"+str(n)]["#type"] = "markup";
		form["tit_"+str(n)]["#value"] = "<a href=\""+url("aggregator/sources/"+feeds[n]["fid"])+"\">"+feeds[n]["title"]+"</a>";
		form["tit_"+str(n)]["#table"] = "feeds";

		form["ite_"+str(n)]["#type"] = "markup";
		form["ite_"+str(n)]["#value"] = format_plural( intval(feeds[n]["items"]), "%i item", "%i items" );
		form["ite_"+str(n)]["#table"] = "feeds";

		form["ago_"+str(n)]["#type"] = "markup";
		form["ago_"+str(n)]["#value"] = intval( feeds[n]["checked"] ) ? format_interval(time() - intval(feeds[n]["checked"]) )+" ago" : "never";
		form["ago_"+str(n)]["#table"] = "feeds";

		form["lef_"+str(n)]["#type"] = "markup";
		form["lef_"+str(n)]["#value"] = intval( feeds[n]["checked"] ) ? format_interval( intval(feeds[n]["checked"]) + intval(feeds[n]["refresh"]) - time()) + " left" : "never";
		form["lef_"+str(n)]["#table"] = "feeds";

		form["edi_"+str(n)]["#type"] = "markup";
		form["edi_"+str(n)]["#value"] = "<a href=\""+url("admin/aggregator/edit/feed/"+feeds[n]["fid"])+"\">edit</a>";
		form["edi_"+str(n)]["#table"] = "feeds";

		form["rem_"+str(n)]["#type"] = "markup";
		form["rem_"+str(n)]["#value"] = "<a href=\""+url("admin/aggregator/remove/feed/"+feeds[n]["fid"])+"\">remove items</a>";
		form["rem_"+str(n)]["#table"] = "feeds";

		form["upd_"+str(n)]["#type"] = "markup";
		form["upd_"+str(n)]["#value"] = "<a href=\""+url("admin/aggregator/update/feed/"+feeds[n]["fid"])+"\">update items</a>";
		form["upd_"+str(n)]["#table"] = "feeds";
		
		form["feeds"]["#row"+str(n)] = "tit_"+str(n)+",ite_"+str(n)+",ago_"+str(n)+",lef_"+str(n)+",edi_"+str(n)+",rem_"+str(n)+",upd_"+str(n);
	}

	return get_form("aggregator_admin_overview", form);
}
Пример #18
0
int query(struct Map_info *Map)
{
    int i, j, idx, cat_no, nlines, type;
    register int line_num;
    struct line_pnts *Points;
    struct line_cats *Cats;
    struct field_info *Fi;
    dbString stmt, value_string;
    dbDriver *driver;

    /* Initialize the Point struct */
    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    G_message(_("Reading features..."));

    /* Cycle through all lines and make a list of categories of 'qfield' for each category given by 'field' */
    nlines = Vect_get_num_lines(Map);
    for (line_num = 1; line_num <= nlines; line_num++) {
	type = Vect_read_line(Map, Points, Cats, line_num);
	if (!(type & options.type))
	    continue;

	for (i = 0; i < Cats->n_cats; i++) {
	    if (Cats->field[i] == options.field) {

		cat_no = Cats->cat[i];

		idx = find_cat(cat_no, 1);

		for (j = 0; j < Cats->n_cats; j++) {
		    if (Cats->field[j] == options.qfield) {	/* Add to list */
			if (Values[idx].nqcats == Values[idx].aqcats) {	/* Alloc space */
			    Values[idx].aqcats += 2;
			    Values[idx].qcat =
				(int *)G_realloc(Values[idx].qcat,
						 Values[idx].aqcats *
						 sizeof(int));
			}
			Values[idx].qcat[Values[idx].nqcats] = Cats->cat[j];
			Values[idx].nqcats++;
		    }
		}
	    }
	}

	/* If there is no field cat add cat -1, values for cat -1 are reported at the end  */
	Vect_cat_get(Cats, options.field, &cat_no);

	if (cat_no == -1) {
	    idx = find_cat(cat_no, 1);

	    for (j = 0; j < Cats->n_cats; j++) {
		if (Cats->field[j] == options.qfield) {	/* Add to list */
		    if (Values[idx].nqcats == Values[idx].aqcats) {	/* Alloc space */
			Values[idx].aqcats += 2;
			Values[idx].qcat =
			    (int *)G_realloc(Values[idx].qcat,
					     Values[idx].aqcats *
					     sizeof(int));
		    }
		    Values[idx].qcat[Values[idx].nqcats] = Cats->cat[j];
		    Values[idx].nqcats++;
		}
	    }
	}

	G_percent(line_num, nlines, 2);
    }

    db_init_string(&stmt);
    db_init_string(&value_string);

    if ((Fi = Vect_get_field(Map, options.qfield)) == NULL)
	G_fatal_error(_("Database connection not defined for layer %d. Use v.db.connect first."),
		      options.qfield);

    /* Open driver */
    driver = db_start_driver_open_database(Fi->driver, Fi->database);
    if (driver == NULL)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);

    /* Query the database for each category */
    G_message(_("Querying database... "));
    for (i = 0; i < vstat.rcat; i++) {
	int j, ctype, nrows, more;
	char buf[2000];
	dbCursor cursor;
	dbTable *table;
	dbColumn *column;
	dbValue *value;

	G_debug(3, "cat %d", Values[i].cat);
	G_percent(i + 1, vstat.rcat, 1);

	/* Skip if cat is zero and large number of query categories (many features without category).
	 * It would cause problems on server side and take long time. Postgres limit is 10000 */
	/* TODO: verify because no category is encoded as cat = -1, not cat = zero */
	if (Values[i].cat == 0 && Values[i].nqcats > 1000) {
	    G_warning(_("Query for category '0' (no category) was not executed because of too many "
		       "(%d) query categories. All later reported values for cat 0 are not valid."),
		      Values[i].nqcats);
	    continue;
	}

	if (Values[i].nqcats > 0) {
	    sprintf(buf, "SELECT %s FROM %s WHERE", options.qcol, Fi->table);
	    db_set_string(&stmt, buf);

	    for (j = 0; j < Values[i].nqcats; j++) {
		G_debug(4, "  qcat %d", Values[i].qcat[j]);

		if (j > 0)
		    db_append_string(&stmt, " OR");

		sprintf(buf, " %s = %d", Fi->key, Values[i].qcat[j]);
		db_append_string(&stmt, buf);
	    }
	    G_debug(4, "  SQL: '%s'", db_get_string(&stmt));

	    if (db_open_select_cursor(driver, &stmt, &cursor, DB_SEQUENTIAL)
		!= DB_OK)
		G_fatal_error("Cannot open cursor: '%s'",
			      db_get_string(&stmt));

	    table = db_get_cursor_table(&cursor);
	    column = db_get_table_column(table, 0);	/* first column */
	    value = db_get_column_value(column);
	    ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
	    vstat.qtype = ctype;
	    nrows = db_get_num_rows(&cursor);

	    G_debug(4, "  nrows = %d, columnt type = %d", nrows, ctype);

	    if (nrows != 1) {
		if (nrows > 1) {
		    G_warning(_("Multiple query results, output value set to NULL (category [%d])"),
			      Values[i].cat);
		}
		Values[i].null = 1;
	    }
	    else {
		if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
		    G_fatal_error(_("Unable to fetch record"));

		db_convert_column_value_to_string(column, &stmt);
		G_debug(4, "  value = %s", db_get_string(&stmt));

		if (db_test_value_isnull(value)) {
		    Values[i].null = 1;
		}
		else {
		    switch (ctype) {
		    case (DB_C_TYPE_INT):
			Values[i].i1 = db_get_value_int(value);
			break;
		    case (DB_C_TYPE_DOUBLE):
			Values[i].d1 = db_get_value_double(value);
			break;
		    case (DB_C_TYPE_STRING):
			Values[i].str1 = G_store(db_get_value_string(value));
			break;
		    case (DB_C_TYPE_DATETIME):
			db_convert_column_value_to_string(column,
							  &value_string);
			Values[i].str1 =
			    G_store(db_get_string(&value_string));
		    }
		    Values[i].null = 0;
		}
	    }
	    db_close_cursor(&cursor);
	}
	else {			/* no qcats -> upload NULL */
	    Values[i].null = 1;
	}
    }

    db_close_database_shutdown_driver(driver);

    return 0;
}
Пример #19
0
string profile_admin()
{
	string out;
	map <string, string> item;
	map <string, map<string,string> > form;

	form["profiles"]["#type"] = "table";
	form["profiles"]["#header"] = "Title,Name,Type,Operations";
	form["profiles"]["#weight"] = "1";
	
	size_t i = 0;

	if(DB_TYPE==1)
	{
		REDIS_RES *result = redis_query_fields("SORT profile_fields BY profile_fields:*->title ALPHA", "GET profile_fields:*->", "#fid,title,name,explanation");
		while( redis_fetch_fields( result, item ) )
		{
			form["A"+str(i)]["#type"] = "markup";
			form["A"+str(i)]["#value"] = item["title"];
			form["A"+str(i)]["#table"] = "profiles";

			form["B"+str(i)]["#type"] = "markup";
			form["B"+str(i)]["#value"] = item["name"];
			form["B"+str(i)]["#table"] = "profiles";

			form["C"+str(i)]["#type"] = "markup";
			form["C"+str(i)]["#value"] = item["type"];
			form["C"+str(i)]["#table"] = "profiles";

			form["D"+str(i)]["#type"] = "markup";
			form["D"+str(i)]["#value"] = "<a href=\""+url("admin/profile/edit/"+item["fid"])+"\">Edit</a> <a href=\""+url("admin/profile/delete/"+item["fid"])+"\">Delete</a>";
			form["D"+str(i)]["#table"] = "profiles";

			form["profiles"]["#row"+str(i)] = "A"+str(i)+",B"+str(i)+",C"+str(i)+",D"+str(i);

			i++;
		}	
	}

	if(DB_TYPE==2)
	{	
		MYSQL_RES *result;	
		result = db_querya("SELECT * FROM profile_fields");
		while( db_fetch( result, item ) )
		{
			form["A"+str(i)]["#type"] = "markup";
			form["A"+str(i)]["#value"] = item["title"];
			form["A"+str(i)]["#table"] = "profiles";

			form["B"+str(i)]["#type"] = "markup";
			form["B"+str(i)]["#value"] = item["name"];
			form["B"+str(i)]["#table"] = "profiles";

			form["C"+str(i)]["#type"] = "markup";
			form["C"+str(i)]["#value"] = item["type"];
			form["C"+str(i)]["#table"] = "profiles";

			form["D"+str(i)]["#type"] = "markup";
			form["D"+str(i)]["#value"] = "<a href=\""+url("admin/profile/edit/"+item["fid"])+"\">Edit</a> <a href=\""+url("admin/profile/delete/"+item["fid"])+"\">Delete</a>";
			form["D"+str(i)]["#table"] = "profiles";

			form["profiles"]["#row"+str(i)] = "A"+str(i)+",B"+str(i)+",C"+str(i)+",D"+str(i);

			i++;
		}
	}

	out+= get_form("profiles_admin", form) + "<a href=\""+url("admin/profile/add")+"\">Add field</a>";

	return out;
}
Пример #20
0
static db_result_t
upgrade_to_schema_v2( db_t hdb )
{
    db_result_t rc = DB_OK;
    /* 1. Convert string type v1's 'sex_title' column to int-type 'sex' column, as v2 schema declares */
    /* 1.1. Append a new uint8 type 'sex' column */
    db_fielddef_t sex = { CONTACT_NFIELDS, "sex", DB_COLTYPE_UINT8, 0, 0, DB_NULLABLE, 0 };

    /* 1.2. Fill 'sex' column with data according to schema: Mr->0, Mrs->1,Other->2 */
    // Use absolute bound fields ( see ittiadb/manuals/users-guide/api-c-database-access.html#absolute-bound-fields )
    db_ansi_t sex_old[ MAX_SEX_TITLE + 1 ];
    db_len_t sex_ind = DB_FIELD_NULL, sex_ind_new = DB_FIELD_NULL;
    uint8_t sex_new = 0;
    db_bind_t binds_def[] = {
        {CONTACT_SEX, DB_VARTYPE_ANSISTR, DB_BIND_ADDRESS(sex_old), sizeof(sex_old), DB_BIND_ADDRESS(&sex_ind), DB_BIND_ABSOLUTE},
        {CONTACT_NFIELDS, DB_VARTYPE_UINT8, DB_BIND_ADDRESS(&sex_new), sizeof(sex_new), DB_BIND_ADDRESS(&sex_ind_new),   DB_BIND_ABSOLUTE},
    };
    db_row_t row = db_alloc_row( binds_def, 2 );

    db_table_cursor_t p = {
        NULL,   //< No index
        DB_CAN_MODIFY | DB_LOCK_EXCLUSIVE
    };
    db_cursor_t c;

    rc = db_add_field( hdb, CONTACT_TABLE, &sex );
    if( DB_OK != rc ) {
        print_error_message( "Couldn't append 'sex' column on v1->v2 upgrade", 0 );
        return DB_FAIL;
    }

    c = db_open_table_cursor(hdb, CONTACT_TABLE, &p);

    db_begin_tx( hdb, DB_DEFAULT_ISOLATION | DB_LOCK_DEFAULT );
    for ( rc = db_seek_first( c ); DB_OK == rc && !db_eof( c ); db_seek_next( c ) ) {
        rc = db_fetch( c, row, 0 );
        if( 0 == strcmp( "Mr", sex_old ) ) {
            sex_new = 0;
        }
        else if( 0 == strcmp( "Mrs", sex_old ) ) {
            sex_new = 1;
        }
        else {
            sex_new = 2;
        }
        sex_ind_new = 0;
        rc = db_update( c, row, 0 );
    }
    db_commit_tx( hdb, DB_DEFAULT_COMPLETION );

    if( DB_OK != rc ) {
        print_error_message( "Couldn't fill appended 'sex' column with data", c );
    }

    db_free_row( row );
    db_close_cursor( c );


    /* 1.3 Drop v1 sex_title column. */
    /* Note: Dropping columns isn't available in ITTIA evaluation version. */
    rc = db_drop_field( hdb, CONTACT_TABLE, "sex_title" );
    if( DB_OK != rc ) {
        if( DB_EEVALUATION == get_db_error() ) {
            rc = DB_OK;
            fprintf( stdout, "No db_drop_field() feature supported in ITTIA Evaluation version\n" );
        }
        else {
            print_error_message( "Couldn't drop 'sex_title' v1 schema column", c );
        }
    }

    /* 2. Indexes modifications */
    // 2.1. drop old pkey
    rc = db_drop_index( hdb, CONTACT_TABLE, CONTACT_BY_ID );
    if ( DB_OK != rc ) {
        print_error_message( "Couldn't drop v1 pkey index", c );
    }

    // 2.2. create a new one
    // 2.2.1. Set NOT NULL property on ring_id field
    // Note: this feature isn't supported in evaluation version of ittiadb.
    {
        extern db_fielddef_t contact_fields[];   //< Defined in schema_upgrade_schema_v2.c
        rc = db_update_field( hdb, CONTACT_TABLE, "ring_id", &contact_fields[ CONTACT_RING_ID ] );

        if ( DB_OK != rc ) {
            print_error_message( "Couldn't set not null on ring_id column", c );
        }
    }

    // 2.2.2. Create PKey index
    {
        extern db_indexdef_t contact_indexes[];  //< Defined in schema_upgrade_schema_v2.c
        rc = db_create_index( hdb, CONTACT_TABLE, CONTACT_BY_ID_RING_ID, &contact_indexes[0] );

        if ( DB_OK != rc ) {
            print_error_message( "Couldn't create v2 pkey index", c );
        }
    }
}
Пример #21
0
/*!
  \brief Select pairs key/value to array, values are sorted by key (must be integer)

  \param driver DB driver
  \param tab table name
  \param key key column name
  \param col value column name
  \param[out] cvarr dbCatValArray to store within

  \return number of selected values
  \return -1 on error
 */
int db_select_CatValArray(dbDriver * driver, const char *tab, const char *key,
			  const char *col, const char *where,
			  dbCatValArray * cvarr)
{
    int i, type, more, nrows;
    char buf[1024];
    dbString stmt;
    dbCursor cursor;
    dbColumn *column;
    dbValue *value;
    dbTable *table;

    G_debug(3, "db_select_CatValArray ()");

    if (key == NULL || strlen(key) == 0) {
	G_warning(_("Missing key column name"));
	return -1;
    }

    if (col == NULL || strlen(col) == 0) {
	G_warning(_("Missing column name"));
	return -1;
    }
    db_init_string(&stmt);

    sprintf(buf, "SELECT %s, %s FROM %s", key, col, tab);
    db_set_string(&stmt, buf);

    if (where != NULL && strlen(where) > 0) {
	db_append_string(&stmt, " WHERE ");
	db_append_string(&stmt, where);
    }

    G_debug(3, "  SQL: %s", db_get_string(&stmt));

    if (db_open_select_cursor(driver, &stmt, &cursor, DB_SEQUENTIAL) != DB_OK)
	return (-1);

    nrows = db_get_num_rows(&cursor);
    G_debug(3, "  %d rows selected", nrows);
    if (nrows < 0) {
	G_warning(_("Unable select records from table <%s>"), tab);
	db_close_cursor(&cursor);
	db_free_string(&stmt);
	return -1;
    }

    db_CatValArray_alloc(cvarr, nrows);

    table = db_get_cursor_table(&cursor);

    /* Check if key column is integer */
    column = db_get_table_column(table, 0);
    type = db_sqltype_to_Ctype(db_get_column_sqltype(column));
    G_debug(3, "  key type = %d", type);

    if (type != DB_C_TYPE_INT) {
	G_warning(_("Key column type is not integer"));
	db_close_cursor(&cursor);
	db_free_string(&stmt);
	return -1;
    }

    column = db_get_table_column(table, 1);
    type = db_sqltype_to_Ctype(db_get_column_sqltype(column));
    G_debug(3, "  col type = %d", type);

    /*
       if ( type != DB_C_TYPE_INT && type != DB_C_TYPE_DOUBLE ) {
       G_fatal_error ( "Column type not supported by db_select_to_array()" );
       }
     */

    cvarr->ctype = type;

    /* fetch the data */
    for (i = 0; i < nrows; i++) {
	if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
	    return (-1);

	column = db_get_table_column(table, 0);	/* first column */
	value = db_get_column_value(column);
	cvarr->value[i].cat = db_get_value_int(value);

	column = db_get_table_column(table, 1);
	value = db_get_column_value(column);
	cvarr->value[i].isNull = value->isNull;
	switch (type) {
	case (DB_C_TYPE_INT):
	    if (value->isNull)
		cvarr->value[i].val.i = 0;
	    else
		cvarr->value[i].val.i = db_get_value_int(value);
	    break;

	case (DB_C_TYPE_DOUBLE):
	    if (value->isNull)
		cvarr->value[i].val.d = 0.0;
	    else
		cvarr->value[i].val.d = db_get_value_double(value);
	    break;

	case (DB_C_TYPE_STRING):
	    cvarr->value[i].val.s = (dbString *) malloc(sizeof(dbString));
	    db_init_string(cvarr->value[i].val.s);

	    if (!(value->isNull))
		db_set_string(cvarr->value[i].val.s,
			      db_get_value_string(value));
	    break;

	case (DB_C_TYPE_DATETIME):
	    cvarr->value[i].val.t =
		(dbDateTime *) calloc(1, sizeof(dbDateTime));

	    if (!(value->isNull))
		memcpy(cvarr->value[i].val.t, &(value->t),
		       sizeof(dbDateTime));
	    break;

	default:
	    return (-1);
	}
    }
    cvarr->n_values = nrows;

    db_close_cursor(&cursor);
    db_free_string(&stmt);

    db_CatValArray_sort(cvarr);

    return (nrows);
}
Пример #22
0
int db__copy_table(const char *from_drvname, const char *from_dbname,
		   const char *from_tblname, const char *to_drvname,
		   const char *to_dbname, const char *to_tblname,
		   const char *where, const char *select, const char *selcol,
		   int *ivals, int nvals)
{
    int col, ncols, sqltype, ctype, more, selcol_found;
    char buf[1000];
    int *ivalues;
    dbHandle from_handle, to_handle;
    dbString tblname, sql;
    dbString value_string;
    dbString *tblnames;
    dbTable *table, *out_table;
    dbCursor cursor;
    dbColumn *column;
    dbValue *value;
    const char *colname;
    dbDriver *from_driver, *to_driver;
    int count, i;

    G_debug(3, "db_copy_table():\n  from driver = %s, db = %s, table = %s\n"
	    "  to driver = %s, db = %s, table = %s, where = %s, select = %s",
	    from_drvname, from_dbname, from_tblname, to_drvname, to_dbname,
	    to_tblname, where, select);

    db_init_handle(&from_handle);
    db_init_handle(&to_handle);
    db_init_string(&tblname);
    db_init_string(&sql);
    db_init_string(&value_string);

    /* Make a copy of input values and sort it */
    if (ivals) {
	ivalues = (int *)G_malloc(nvals * sizeof(int));
	memcpy(ivalues, ivals, nvals * sizeof(int));
	qsort((void *)ivalues, nvals, sizeof(int), cmp);
    }

    /* Open input driver and database */
    from_driver = db_start_driver(from_drvname);
    if (from_driver == NULL) {
	G_warning(_("Unable to start driver <%s>"), from_drvname);
	return DB_FAILED;
    }
    db_set_handle(&from_handle, from_dbname, NULL);
    if (db_open_database(from_driver, &from_handle) != DB_OK) {
	G_warning(_("Unable to open database <%s> by driver <%s>"),
		  from_dbname, from_drvname);
	db_close_database_shutdown_driver(from_driver);
	return DB_FAILED;
    }

    /* Open output driver and database */
    if (strcmp(from_drvname, to_drvname) == 0
	&& strcmp(from_dbname, to_dbname) == 0) {
	G_debug(3, "Use the same driver");
	to_driver = from_driver;
    }
    else {
	to_driver = db_start_driver(to_drvname);
	if (to_driver == NULL) {
	    G_warning(_("Unable to start driver <%s>"), to_drvname);
	    db_close_database_shutdown_driver(from_driver);
	    return DB_FAILED;
	}
	db_set_handle(&to_handle, to_dbname, NULL);
	if (db_open_database(to_driver, &to_handle) != DB_OK) {
	    G_warning(_("Unable to open database <%s> by driver <%s>"),
		      to_dbname, to_drvname);
	    db_close_database_shutdown_driver(to_driver);
	    if (from_driver != to_driver) {
		db_close_database_shutdown_driver(from_driver);
	    }
	    return DB_FAILED;
	}
    }

    db_begin_transaction(to_driver);

    /* Because in SQLite3 an opened cursor is no more valid
       if 'schema' is modified (create table), we have to open
       cursor twice */

    /* test if the table exists */
    if (db_list_tables(to_driver, &tblnames, &count, 0) != DB_OK) {
	G_warning(_("Unable to get list tables in database <%s>"),
		  to_dbname);
	db_close_database_shutdown_driver(to_driver);
	if (from_driver != to_driver)
	    db_close_database_shutdown_driver(from_driver);

	return DB_FAILED;
    }

    for (i = 0; i < count; i++) {
	const char *tblname = db_get_string(&tblnames[i]);

	if (strcmp(to_tblname, tblname) == 0) {
	    G_warning(_("Table <%s> already exists in database <%s>"),
		      to_tblname, to_dbname);
	    db_close_database_shutdown_driver(to_driver);
	    if (from_driver != to_driver)
		db_close_database_shutdown_driver(from_driver);

	    return DB_FAILED;
	}
    }

    /* Create new table */
    /* Open cursor for data structure */
    if (select) {
	db_set_string(&sql, select);

	/* TODO!: cannot use this because it will not work if a query 
	 *         ends with 'group by' for example */
	/*
	   tmp = strdup ( select );
	   G_tolcase ( tmp );

	   if ( !strstr( tmp,"where") )
	   {
	   db_append_string ( &sql, " where 0 = 1");
	   }
	   else
	   {
	   db_append_string ( &sql, " and 0 = 1");
	   }

	   free (tmp);
	 */
    }
    else {
	db_set_string(&sql, "select * from ");
	db_append_string(&sql, from_tblname);
	db_append_string(&sql, " where 0 = 1");	/* to get no data */
    }

    G_debug(3, db_get_string(&sql));
    if (db_open_select_cursor(from_driver, &sql, &cursor, DB_SEQUENTIAL) !=
	DB_OK) {
	G_warning(_("Unable to open select cursor: '%s'"),
		  db_get_string(&sql));
	db_close_database_shutdown_driver(to_driver);
	if (from_driver != to_driver) {
	    db_close_database_shutdown_driver(from_driver);
	}
	return DB_FAILED;
    }
    G_debug(3, "Select cursor opened");

    table = db_get_cursor_table(&cursor);
    ncols = db_get_table_number_of_columns(table);
    G_debug(3, "ncols = %d", ncols);

    out_table = db_alloc_table(ncols);
    db_set_table_name(out_table, to_tblname);

    selcol_found = 0;
    for (col = 0; col < ncols; col++) {
	dbColumn *out_column;

	column = db_get_table_column(table, col);
	colname = db_get_column_name(column);
	sqltype = db_get_column_sqltype(column);
	ctype = db_sqltype_to_Ctype(sqltype);

	G_debug(3, "%s (%s)", colname, db_sqltype_name(sqltype));

	out_column = db_get_table_column(out_table, col);

	if (selcol && G_strcasecmp(colname, selcol) == 0) {
	    if (ctype != DB_C_TYPE_INT)
		G_fatal_error(_("Column <%s> is not integer"),
			      colname);
	    selcol_found = 1;
	}

	db_set_column_name(out_column, db_get_column_name(column));
	db_set_column_description(out_column,
				  db_get_column_description(column));
	db_set_column_sqltype(out_column, db_get_column_sqltype(column));
	db_set_column_length(out_column, db_get_column_length(column));
	db_set_column_precision(out_column, db_get_column_precision(column));
	db_set_column_scale(out_column, db_get_column_scale(column));
    }

    db_close_cursor(&cursor);

    if (selcol && !selcol_found)
	G_fatal_error(_("Column <%s> not found"), selcol);

    if (db_create_table(to_driver, out_table) != DB_OK) {
	G_warning(_("Unable to create table <%s>"),
		  to_tblname);
	db_close_database_shutdown_driver(to_driver);
	if (from_driver != to_driver) {
	    db_close_database_shutdown_driver(from_driver);
	}
	return DB_FAILED;
    }

    /* Open cursor with data */
    if (select) {
	db_set_string(&sql, select);
    }
    else {
	db_set_string(&sql, "select * from ");
	db_append_string(&sql, from_tblname);
	if (where) {
	    db_append_string(&sql, " where ");
	    db_append_string(&sql, where);
	}
    }

    G_debug(3, db_get_string(&sql));
    if (db_open_select_cursor(from_driver, &sql, &cursor, DB_SEQUENTIAL) !=
	DB_OK) {
	G_warning(_("Unable to open select cursor: '%s'"),
		  db_get_string(&sql));
	db_close_database_shutdown_driver(to_driver);
	if (from_driver != to_driver) {
	    db_close_database_shutdown_driver(from_driver);
	}
	return DB_FAILED;
    }
    G_debug(3, "Select cursor opened");

    table = db_get_cursor_table(&cursor);
    ncols = db_get_table_number_of_columns(table);
    G_debug(3, "ncols = %d", ncols);

    /* Copy all rows */
    while (1) {
	int select;

	if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
	    G_warning(_("Unable to fetch data from table <%s>"),
		      from_tblname);
	    db_close_cursor(&cursor);
	    db_close_database_shutdown_driver(to_driver);
	    if (from_driver != to_driver) {
		db_close_database_shutdown_driver(from_driver);
	    }
	    return DB_FAILED;
	}
	if (!more)
	    break;

	sprintf(buf, "insert into %s values ( ", to_tblname);
	db_set_string(&sql, buf);
	select = 1;
	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);
	    ctype = db_sqltype_to_Ctype(sqltype);
	    value = db_get_column_value(column);

	    if (selcol && G_strcasecmp(colname, selcol) == 0) {
		if (db_test_value_isnull(value))
		    continue;
		if (!bsearch(&(value->i), ivalues, nvals, sizeof(int), cmp)) {
		    select = 0;
		    break;
		}
	    }
	    if (col > 0)
		db_append_string(&sql, ", ");
	    db_convert_value_to_string(value, sqltype, &value_string);
	    switch (ctype) {
	    case DB_C_TYPE_STRING:
	    case DB_C_TYPE_DATETIME:
		if (db_test_value_isnull(value)) {
		    db_append_string(&sql, "null");
		}
		else {
		    db_double_quote_string(&value_string);
		    db_append_string(&sql, "'");
		    db_append_string(&sql, db_get_string(&value_string));
		    db_append_string(&sql, "'");
		}
		break;
	    case DB_C_TYPE_INT:
	    case DB_C_TYPE_DOUBLE:
		if (db_test_value_isnull(value)) {
		    db_append_string(&sql, "null");
		}
		else {
		    db_append_string(&sql, db_get_string(&value_string));
		}
		break;
	    default:
		G_warning(_("Unknown column type (column <%s>)"),
			  colname);
		db_close_cursor(&cursor);
		db_close_database_shutdown_driver(to_driver);
		if (from_driver != to_driver) {
		    db_close_database_shutdown_driver(from_driver);
		}
		return DB_FAILED;
	    }
	}
	if (!select)
	    continue;
	db_append_string(&sql, ")");
	G_debug(3, db_get_string(&sql));
	if (db_execute_immediate(to_driver, &sql) != DB_OK) {
	    G_warning("Unable to insert new record: '%s'",
		      db_get_string(&sql));
	    db_close_cursor(&cursor);
	    db_close_database_shutdown_driver(to_driver);
	    if (from_driver != to_driver) {
		db_close_database_shutdown_driver(from_driver);
	    }
	    return DB_FAILED;
	}
    }
    if (selcol)
	G_free(ivalues);
    G_debug(3, "Table copy OK");

    db_close_cursor(&cursor);
    db_commit_transaction(to_driver);
    db_close_database_shutdown_driver(to_driver);
    if (from_driver != to_driver) {
	db_close_database_shutdown_driver(from_driver);
    }

    return DB_OK;
}
Пример #23
0
int display_attr(struct Map_info *Map, int type, char *attrcol,
		 struct cat_list *Clist, LATTR *lattr, int chcat)
{
    int i, ltype, more;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int cat;
    char buf[2000];
    struct field_info *fi;
    dbDriver *driver;
    dbString stmt, valstr, text;
    dbCursor cursor;
    dbTable *table;
    dbColumn *column;

    G_debug(2, "attr()");

    if (attrcol == NULL || *attrcol == '\0') {
	G_fatal_error(_("attrcol not specified, cannot display attributes"));
    }

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    db_init_string(&stmt);
    db_init_string(&valstr);
    db_init_string(&text);

    fi = Vect_get_field(Map, lattr->field);
    if (fi == NULL)
	return 1;

    driver = db_start_driver_open_database(fi->driver, fi->database);
    if (driver == NULL)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      fi->database,
		      fi->driver);

    Vect_rewind(Map);
    while (1) {
	ltype = Vect_read_next_line(Map, Points, Cats);
	if (ltype == -1)
	    G_fatal_error(_("Unable to read vector map"));
	else if (ltype == -2)		/* EOF */
	    break;

	if (!(type & ltype) && !((type & GV_AREA) && (ltype & GV_CENTROID)))
	    continue;		/* used for both lines and labels */

	D_RGB_color(lattr->color.R, lattr->color.G, lattr->color.B);
	D_text_size(lattr->size, lattr->size);
	if (lattr->font)
	    D_font(lattr->font);
	if (lattr->enc)
	    D_encoding(lattr->enc);

	if (chcat) {
	    int found = 0;

	    for (i = 0; i < Cats->n_cats; i++) {
		if (Cats->field[i] == Clist->field &&
		    Vect_cat_in_cat_list(Cats->cat[i], Clist)) {
		    found = 1;
		    break;
		}
	    }
	    if (!found)
		continue;
	}
	else if (Clist->field > 0) {
	    int found = 0;

	    for (i = 0; i < Cats->n_cats; i++) {
		if (Cats->field[i] == Clist->field) {
		    found = 1;
		    break;
		}
	    }
	    /* lines with no category will be displayed */
	    if (Cats->n_cats > 0 && !found)
		continue;
	}

	if (Vect_cat_get(Cats, lattr->field, &cat)) {
	    int ncats = 0;

	    /* Read attribute from db */
	    db_free_string(&text);
	    for (i = 0; i < Cats->n_cats; i++) {
		int nrows;

		if (Cats->field[i] != lattr->field)
		    continue;
		db_init_string(&stmt);
		sprintf(buf, "select %s from %s where %s = %d", attrcol,
			fi->table, fi->key, Cats->cat[i]);
		G_debug(2, "SQL: %s", buf);
		db_append_string(&stmt, buf);

		if (db_open_select_cursor
		    (driver, &stmt, &cursor, DB_SEQUENTIAL) != DB_OK)
		    G_fatal_error(_("Unable to open select cursor: '%s'"),
				  db_get_string(&stmt));

		nrows = db_get_num_rows(&cursor);

		if (ncats > 0)
		    db_append_string(&text, "/");

		if (nrows > 0) {
		    table = db_get_cursor_table(&cursor);
		    column = db_get_table_column(table, 0);	/* first column */

		    if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
			continue;
		    db_convert_column_value_to_string(column, &valstr);

		    db_append_string(&text, db_get_string(&valstr));
		}
		else {
		    G_warning(_("No attribute found for cat %d: %s"), cat,
			      db_get_string(&stmt));
		}

		db_close_cursor(&cursor);
		ncats++;
	    }

	    show_label_line(Points, ltype, lattr, db_get_string(&text));
	}
    }

    db_close_database_shutdown_driver(driver);
    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);

    return 0;
}
Пример #24
0
/*------------------------------------------------------------------------------------------------*/
void
P_Aux_to_Vector(struct Map_info *Map, struct Map_info *Out, dbDriver * driver,
		char *tab_name)
{

    int more, line_num, type, count = 0;
    double coordX, coordY, coordZ;

    struct line_pnts *point;
    struct line_cats *cat;
    dbTable *table;
    dbColumn *column;
    dbValue *value;
    dbCursor cursor;
    dbString sql;

    char buf[1024];

    point = Vect_new_line_struct();
    cat = Vect_new_cats_struct();

    db_init_string(&sql);
    db_zero_string(&sql);

    sprintf(buf, "select ID, X, Y, sum(Interp) from %s group by ID, X, Y",
	    tab_name);

    db_append_string(&sql, buf);
    db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL);

    while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
	count++;
	table = db_get_cursor_table(&cursor);

	column = db_get_table_column(table, 0);
	type = db_sqltype_to_Ctype(db_get_column_sqltype(column));
	if (type == DB_C_TYPE_INT)
	    value = db_get_column_value(column);
	else
	    continue;
	line_num = db_get_value_int(value);

	column = db_get_table_column(table, 1);
	type = db_sqltype_to_Ctype(db_get_column_sqltype(column));
	if (type == DB_C_TYPE_DOUBLE)
	    value = db_get_column_value(column);
	else
	    continue;
	coordZ = db_get_value_double(value);

	column = db_get_table_column(table, 2);
	type = db_sqltype_to_Ctype(db_get_column_sqltype(column));
	if (type == DB_C_TYPE_DOUBLE)
	    value = db_get_column_value(column);
	else
	    continue;
	coordX = db_get_value_double(value);

	column = db_get_table_column(table, 3);
	type = db_sqltype_to_Ctype(db_get_column_sqltype(column));
	if (type == DB_C_TYPE_DOUBLE)
	    value = db_get_column_value(column);
	else
	    continue;
	coordY = db_get_value_double(value);

	Vect_copy_xyz_to_pnts(point, &coordX, &coordY, &coordZ, 1);
	Vect_reset_cats(cat);
	Vect_cat_set(cat, 1, 1);
	Vect_write_line(Out, GV_POINT, point, cat);
    }
    return;
}
Пример #25
0
Файл: main.c Проект: caomw/grass
int main(int argc, char *argv[])
{
    int i, cat, with_z, more, ctype, nrows;
    char buf[DB_SQL_MAX];
    int count;
    double coor[3];
    int ncoor;
    struct Option *driver_opt, *database_opt, *table_opt;
    struct Option *xcol_opt, *ycol_opt, *zcol_opt, *keycol_opt, *where_opt,
	*outvect;
    struct Flag *same_table_flag;
    struct GModule *module;
    struct Map_info Map;
    struct line_pnts *Points;
    struct line_cats *Cats;
    dbString sql;
    dbDriver *driver;
    dbCursor cursor;
    dbTable *table;
    dbColumn *column;
    dbValue *value;
    struct field_info *fi;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("import"));
    G_add_keyword(_("database"));
    G_add_keyword(_("points"));
    module->description =
	_("Creates new vector (points) map from database table containing coordinates.");

    table_opt = G_define_standard_option(G_OPT_DB_TABLE);
    table_opt->required = YES;
    table_opt->description = _("Input table name");

    driver_opt = G_define_standard_option(G_OPT_DB_DRIVER);
    driver_opt->options = db_list_drivers();
    driver_opt->answer = (char *)db_get_default_driver_name();
    driver_opt->guisection = _("Input DB");

    database_opt = G_define_standard_option(G_OPT_DB_DATABASE);
    database_opt->answer = (char *)db_get_default_database_name();
    database_opt->guisection = _("Input DB");

    xcol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    xcol_opt->key = "x";
    xcol_opt->required = YES;
    xcol_opt->description = _("Name of column containing x coordinate");

    ycol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    ycol_opt->key = "y";
    ycol_opt->required = YES;
    ycol_opt->description = _("Name of column containing y coordinate");

    zcol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    zcol_opt->key = "z";
    zcol_opt->description = _("Name of column containing z coordinate");
    zcol_opt->guisection = _("3D output");

    keycol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    keycol_opt->key = "key";
    keycol_opt->required = NO;
    keycol_opt->label = _("Name of column containing category number");
    keycol_opt->description = _("Must refer to an integer column");

    where_opt = G_define_standard_option(G_OPT_DB_WHERE);
    where_opt->guisection = _("Selection");

    outvect = G_define_standard_option(G_OPT_V_OUTPUT);

    same_table_flag = G_define_flag();
    same_table_flag->key = 't';
    same_table_flag->description =
	_("Use imported table as attribute table for new map");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    if (zcol_opt->answer) {
	with_z = WITH_Z;
	ncoor = 3;
    }
    else {
	with_z = WITHOUT_Z;
	ncoor = 2;
    }

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    db_init_string(&sql);

    if (G_get_overwrite()) {
	/* We don't want to delete the input table when overwriting the output
	 * vector. */
	char name[GNAME_MAX], mapset[GMAPSET_MAX];

	if (!G_name_is_fully_qualified(outvect->answer, name, mapset)) {
	    strcpy(name, outvect->answer);
	    strcpy(mapset, G_mapset());
	}

	Vect_set_open_level(1); /* no topo needed */

	if (strcmp(mapset, G_mapset()) == 0 && G_find_vector2(name, mapset) &&
	    Vect_open_old(&Map, name, mapset) >= 0) {
	    int num_dblinks;

	    num_dblinks = Vect_get_num_dblinks(&Map);
	    for (i = 0; i < num_dblinks; i++) {
		if ((fi = Vect_get_dblink(&Map, i)) != NULL &&
		    strcmp(fi->driver, driver_opt->answer) == 0 &&
		    strcmp(fi->database, database_opt->answer) == 0 &&
		    strcmp(fi->table, table_opt->answer) == 0)
		    G_fatal_error(_("Vector map <%s> cannot be overwritten "
				    "because input table <%s> is linked to "
				    "this map."),
				    outvect->answer, table_opt->answer);
	    }
	    Vect_close(&Map);
	}
    }

    if (Vect_open_new(&Map, outvect->answer, with_z) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"),
			outvect->answer);

    Vect_set_error_handler_io(NULL, &Map);
    
    Vect_hist_command(&Map);

    fi = Vect_default_field_info(&Map, 1, NULL, GV_1TABLE);

    /* Open driver */
    driver = db_start_driver_open_database(driver_opt->answer,
					   database_opt->answer);
    if (driver == NULL) {
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      fi->database, fi->driver);
    }
    db_set_error_handler_driver(driver);
    
    /* check if target table already exists */
    G_debug(3, "Output vector table <%s>, driver: <%s>, database: <%s>",
	    outvect->answer, db_get_default_driver_name(),
	    db_get_default_database_name());

    if (!same_table_flag->answer &&
	db_table_exists(db_get_default_driver_name(),
			db_get_default_database_name(), outvect->answer) == 1)
	G_fatal_error(_("Output vector map, table <%s> (driver: <%s>, database: <%s>) "
		       "already exists"), outvect->answer,
		      db_get_default_driver_name(),
		      db_get_default_database_name());

    if (keycol_opt->answer) {
        int coltype;
        coltype = db_column_Ctype(driver, table_opt->answer, keycol_opt->answer);

        if (coltype == -1)
            G_fatal_error(_("Column <%s> not found in table <%s>"),
                          keycol_opt->answer, table_opt->answer);
        if (coltype != DB_C_TYPE_INT)
            G_fatal_error(_("Data type of key column must be integer"));
    }
    else {
        if (same_table_flag->answer) {
            G_fatal_error(_("Option <%s> must be specified when -%c flag is given"),
                          keycol_opt->key, same_table_flag->key);
        }

        if (strcmp(db_get_default_driver_name(), "sqlite") != 0)
            G_fatal_error(_("Unable to define key column. This operation is not supported "
                            "by <%s> driver. You need to define <%s> option."),
                          fi->driver, keycol_opt->key);
    }

    /* Open select cursor */
    sprintf(buf, "SELECT %s, %s", xcol_opt->answer, ycol_opt->answer);
    db_set_string(&sql, buf);
    if (with_z) {
	sprintf(buf, ", %s", zcol_opt->answer);
	db_append_string(&sql, buf);
    }
    if (keycol_opt->answer) {
	sprintf(buf, ", %s", keycol_opt->answer);
	db_append_string(&sql, buf);
    }
    sprintf(buf, " FROM %s", table_opt->answer);
    db_append_string(&sql, buf);
    
    if (where_opt->answer) {
	sprintf(buf, " WHERE %s", where_opt->answer);
	db_append_string(&sql, buf);
    }
    G_debug(2, "SQL: %s", db_get_string(&sql));

    if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) {
	G_fatal_error(_("Unable to open select cursor: '%s'"),
		      db_get_string(&sql));
    }

    table = db_get_cursor_table(&cursor);
    nrows = db_get_num_rows(&cursor);

    G_debug(2, "%d points selected", nrows);

    count = cat = 0;
    G_message(_("Writing features..."));
    while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
	G_percent(count, nrows, 2);
	/* key column */
        if (keycol_opt->answer) {
            column = db_get_table_column(table, with_z ? 3 : 2);
            ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
            if (ctype != DB_C_TYPE_INT)
                G_fatal_error(_("Key column must be integer"));
            value = db_get_column_value(column);
            cat = db_get_value_int(value);
        }
        else {
            cat++;
        }

        /* coordinates */
	for (i = 0; i < ncoor; i++) {
	    column = db_get_table_column(table, i);
	    ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
	    if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
		G_fatal_error(_("x/y/z column must be integer or double"));
	    value = db_get_column_value(column);
	    if (ctype == DB_C_TYPE_INT)
		coor[i] = (double)db_get_value_int(value);
	    else
		coor[i] = db_get_value_double(value);
	}

	Vect_reset_line(Points);
	Vect_reset_cats(Cats);

	Vect_append_point(Points, coor[0], coor[1], coor[2]);

	Vect_cat_set(Cats, 1, cat);

	Vect_write_line(&Map, GV_POINT, Points, Cats);

	count++;
    }
    G_percent(1, 1, 1);

    /* close connection to input DB before copying attributes */
    db_close_database_shutdown_driver(driver);

    /* Copy table */
    if (!same_table_flag->answer) {
        G_message(_("Copying attributes..."));
        
        if (DB_FAILED == db_copy_table_where(driver_opt->answer, database_opt->answer,
                                             table_opt->answer,
                                             fi->driver, fi->database, fi->table,
                                             where_opt->answer)) { /* where can be NULL */
            G_warning(_("Unable to copy table"));
	}
	else {
	    Vect_map_add_dblink(&Map, 1, NULL, fi->table,
                                keycol_opt->answer ? keycol_opt->answer : GV_KEY_COLUMN,
				fi->database, fi->driver);
	}

        if (!keycol_opt->answer) {
            /* TODO: implement for all DB drivers in generic way if
             * possible */
            
            driver = db_start_driver_open_database(fi->driver, fi->database);
            if (driver == NULL) {
                G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
                              fi->database, fi->driver);
            }
            db_set_error_handler_driver(driver);

            /* add key column */
            sprintf(buf, "ALTER TABLE %s ADD COLUMN %s INTEGER",
                    fi->table, GV_KEY_COLUMN);
            db_set_string(&sql, buf);
            
            if (db_execute_immediate(driver, &sql) != DB_OK) {
                G_fatal_error(_("Unable to add key column <%s>: "
                                "SERIAL type is not supported by <%s>"), 
                              GV_KEY_COLUMN, fi->driver);
            }

            /* update key column */
            sprintf(buf, "UPDATE %s SET %s = _ROWID_",
                    fi->table, GV_KEY_COLUMN);
            db_set_string(&sql, buf);
            
            if (db_execute_immediate(driver, &sql) != DB_OK) {
                G_fatal_error(_("Failed to update key column <%s>"),
                              GV_KEY_COLUMN);
            }

        }
    }
    else {
        /* do not copy attributes, link original table */
	Vect_map_add_dblink(&Map, 1, NULL, table_opt->answer,
                            keycol_opt->answer ? keycol_opt->answer : GV_KEY_COLUMN,
                            database_opt->answer, driver_opt->answer);
    }

    Vect_build(&Map);
    Vect_close(&Map);

    G_done_msg(_n("%d point written to vector map.",
                  "%d points written to vector map.",
                  count), count);

    return (EXIT_SUCCESS);
}
Пример #26
0
/*--------------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{

    /* Variables' declarations */
    int row, nrows, col, ncols, MaxPoints;
    int nsubregion_col, nsubregion_row;
    int subregion = 0, nsubregions = 0;
    int last_row, last_column;
    int nlines, nlines_first, line_num;
    int more;
    int clas, region = TRUE;
    double Z_interp;
    double Thres_j, Thres_d, ew_resol, ns_resol;
    double minNS, minEW, maxNS, maxEW;
    const char *mapset;
    char buf[1024], table_name[GNAME_MAX];
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];

    int colorBordo, ripieno, conta, lungPunti, lungHull, xi, c1, c2;
    double altPiano;
    extern double **P, **cvxHull, **punti_bordo;

    /* Struct declarations */
    struct Cell_head elaboration_reg, original_reg;
    struct element_grow **raster_matrix;

    struct Map_info In, Out, First;
    struct Option *in_opt, *out_opt, *first_opt, *Thres_j_opt, *Thres_d_opt;
    struct GModule *module;

    struct line_pnts *points, *points_first;
    struct line_cats *Cats, *Cats_first;

    struct field_info *field;
    dbDriver *driver;
    dbString sql;
    dbTable *table;
    dbCursor cursor;

/*------------------------------------------------------------------------------------------*/
    /* Options' declaration */ ;
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("LIDAR"));
    module->description =
	_("Building contour determination and Region Growing "
	  "algorithm for determining the building inside");

    in_opt = G_define_standard_option(G_OPT_V_INPUT);
    in_opt->description =
	_("Input vector (v.lidar.edgedetection output");

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);

    first_opt = G_define_option();
    first_opt->key = "first";
    first_opt->type = TYPE_STRING;
    first_opt->key_desc = "name";
    first_opt->required = YES;
    first_opt->gisprompt = "old,vector,vector";
    first_opt->description = _("Name of the first pulse vector map");

    Thres_j_opt = G_define_option();
    Thres_j_opt->key = "tj";
    Thres_j_opt->type = TYPE_DOUBLE;
    Thres_j_opt->required = NO;
    Thres_j_opt->description =
	_("Threshold for cell object frequency in region growing");
    Thres_j_opt->answer = "0.2";

    Thres_d_opt = G_define_option();
    Thres_d_opt->key = "td";
    Thres_d_opt->type = TYPE_DOUBLE;
    Thres_d_opt->required = NO;
    Thres_d_opt->description =
	_("Threshold for double pulse in region growing");
    Thres_d_opt->answer = "0.6";

    /* Parsing */
    G_gisinit(argv[0]);
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    Thres_j = atof(Thres_j_opt->answer);
    Thres_d = atof(Thres_d_opt->answer);

    Thres_j += 1;

    /* Open input vector */
    Vect_check_input_output_name(in_opt->answer, out_opt->answer,
				 GV_FATAL_EXIT);

    if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL) {
	G_fatal_error(_("Vector map <%s> not found"), in_opt->answer);
    }

    /* Setting auxiliar table's name */
    if (G_name_is_fully_qualified(in_opt->answer, xname, xmapset)) {
	sprintf(table_name, "%s_edge_Interpolation", xname);
    }
    else
	sprintf(table_name, "%s_edge_Interpolation", in_opt->answer);

    Vect_set_open_level(1);	/* WITHOUT TOPOLOGY */
    if (Vect_open_old(&In, in_opt->answer, mapset) < 1)
	G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer);

    Vect_set_open_level(1);	/* WITHOUT TOPOLOGY */
    if (Vect_open_old(&First, first_opt->answer, mapset) < 1)
	G_fatal_error(_("Unable to open vector map <%s>"), first_opt->answer);

    /* Open output vector */
    if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z)) {
	Vect_close(&In);
	Vect_close(&First);
	exit(EXIT_FAILURE);
    }

    /* Copy vector Head File */
    Vect_copy_head_data(&In, &Out);
    Vect_hist_copy(&In, &Out);
    Vect_hist_command(&Out);

    /* Starting driver and open db for edgedetection interpolation table */
    field = Vect_get_field(&In, F_INTERPOLATION);
    /*if (field == NULL)
       G_fatal_error (_("Cannot read field info")); */

    driver = db_start_driver_open_database(field->driver, field->database);
    if (driver == NULL)
	G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
		      field->driver);

    /* is this the right place to open the cursor ??? */
    
    db_init_string(&sql);
    db_zero_string(&sql);

    sprintf(buf, "SELECT Interp,ID FROM %s", table_name);
    G_debug(1, "buf: %s", buf);
    db_append_string(&sql, buf);

    if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK)
	G_fatal_error(_("Unable to open table <%s>"), table_name);

    count_obj = 1;

    /* no topology, get number of lines in input vector */
    nlines = 0;
    points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    Vect_rewind(&In);
    while (Vect_read_next_line(&In, points, Cats) > 0) {
	nlines++;
    }
    Vect_rewind(&In);

    /* no topology, get number of lines in first pulse input vector */
    nlines_first = 0;
    points_first = Vect_new_line_struct();
    Cats_first = Vect_new_cats_struct();
    Vect_rewind(&First);
    while (Vect_read_next_line(&First, points_first, Cats_first) > 0) {
	nlines_first++;
    }
    Vect_rewind(&First);

    /* Setting regions and boxes */
    G_debug(1, _("Setting regions and boxes"));
    G_get_set_window(&original_reg);
    G_get_set_window(&elaboration_reg);

    /*  Fixing parameters of the elaboration region */
    /*! The original_region will be divided into subregions */
    ew_resol = original_reg.ew_res;
    ns_resol = original_reg.ns_res;

    /* calculate number of subregions */
    nsubregion_col = ceil((original_reg.east - original_reg.west) / (LATO * ew_resol)) + 0.5;
    nsubregion_row = ceil((original_reg.north - original_reg.south) / (LATO * ns_resol)) + 0.5;

    if (nsubregion_col < 0)
	nsubregion_col = 0;
    if (nsubregion_row < 0)
	nsubregion_row = 0;

    nsubregions = nsubregion_row * nsubregion_col;

    /* Subdividing and working with tiles */
    elaboration_reg.south = original_reg.north;
    last_row = FALSE;

    while (last_row == FALSE) {	/* For each strip of LATO rows */

	elaboration_reg.north = elaboration_reg.south;

	if (elaboration_reg.north > original_reg.north)	/* First row */
	    elaboration_reg.north = original_reg.north;

	elaboration_reg.south = elaboration_reg.north - LATO * ns_resol;
	if (elaboration_reg.south <= original_reg.south) {	/* Last row */
	    elaboration_reg.south = original_reg.south;
	    last_row = TRUE;
	}

	elaboration_reg.east = original_reg.west;
	last_column = FALSE;

	while (last_column == FALSE) {	/* For each strip of LATO columns */
	    struct bound_box elaboration_box;

	    subregion++;
	    if (nsubregions > 1)
		G_message(_("subregion %d of %d"), subregion, nsubregions);

	    elaboration_reg.west = elaboration_reg.east;
	    if (elaboration_reg.west < original_reg.west)	/* First column */
		elaboration_reg.west = original_reg.west;

	    elaboration_reg.east = elaboration_reg.west + LATO * ew_resol;

	    if (elaboration_reg.east >= original_reg.east) {	/* Last column */
		elaboration_reg.east = original_reg.east;
		last_column = TRUE;
	    }

	    /* Setting the active region */
	    elaboration_reg.ns_res = ns_resol;
	    elaboration_reg.ew_res = ew_resol;
	    nrows = (elaboration_reg.north - elaboration_reg.south) / ns_resol + 0.1;
	    ncols = (elaboration_reg.east - elaboration_reg.west) / ew_resol + 0.1;
	    elaboration_reg.rows = nrows;
	    elaboration_reg.cols = ncols;

	    G_debug(1, _("Rows = %d"), nrows);
	    G_debug(1, _("Columns = %d"), ncols);

	    raster_matrix = structMatrix(0, nrows, 0, ncols);
	    MaxPoints = nrows * ncols;

	    /* Initializing matrix */
	    for (row = 0; row <= nrows; row++) {
		for (col = 0; col <= ncols; col++) {
		    raster_matrix[row][col].interp = 0;
		    raster_matrix[row][col].fi = 0;
		    raster_matrix[row][col].bordo = 0;
		    raster_matrix[row][col].dueImp = SINGLE_PULSE;
		    raster_matrix[row][col].orig = 0;
		    raster_matrix[row][col].fo = 0;
		    raster_matrix[row][col].clas = PRE_TERRAIN;
		    raster_matrix[row][col].fc = 0;
		    raster_matrix[row][col].obj = 0;
		}
	    }

	    G_verbose_message(_("read points in input vector"));
	    Vect_region_box(&elaboration_reg, &elaboration_box);
	    line_num = 0;
	    Vect_rewind(&In);
	    while (Vect_read_next_line(&In, points, Cats) > 0) {
		line_num++;

		if ((Vect_point_in_box
		     (points->x[0], points->y[0], points->z[0],
		      &elaboration_box)) &&
		    ((points->x[0] != elaboration_reg.west) ||
		     (points->x[0] == original_reg.west)) &&
		    ((points->y[0] != elaboration_reg.north) ||
		     (points->y[0] == original_reg.north))) {

		    row =
			(int)(Rast_northing_to_row
			      (points->y[0], &elaboration_reg));
		    col =
			(int)(Rast_easting_to_col
			      (points->x[0], &elaboration_reg));

		    Z_interp = 0;
		    /* TODO: make sure the current db_fetch() usage works */
		    /* why not: */
		    /*
		    db_init_string(&sql);
		    sprintf(buf, "SELECT Interp,ID FROM %s WHERE ID=%d", table_name, line_num);
		    db_append_string(&sql, buf);

		    if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK)
			G_fatal_error(_("Unable to open table <%s>"), table_name);

		    while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
			dbColumn *Z_Interp_col;
			dbValue *Z_Interp_value;
			table = db_get_cursor_table(&cursor);

			Z_Interp_col = db_get_table_column(table, 1);

			if (db_sqltype_to_Ctype(db_get_column_sqltype(Z_Interp_col)) ==
			    DB_C_TYPE_DOUBLE)
			    Z_Interp_value = db_get_column_value(Z_Interp_col);
			else
			    continue;

			Z_interp = db_get_value_double(Z_Interp_value);
			break;
		    }
		    db_close_cursor(&cursor);
		    db_free_string(&sql);
		    */
		    /* instead of */
		    while (1) {
			if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK ||
			    !more)
			    break;
			dbColumn *Z_Interp_col, *ID_col;
			dbValue *Z_Interp_value, *ID_value;

			table = db_get_cursor_table(&cursor);

			ID_col = db_get_table_column(table, 1);
			if (db_sqltype_to_Ctype(db_get_column_sqltype(ID_col))
			    == DB_C_TYPE_INT)
			    ID_value = db_get_column_value(ID_col);
			else
			    continue;

			if (db_get_value_int(ID_value) == line_num) {
			    Z_Interp_col = db_get_table_column(table, 0);
			    if (db_sqltype_to_Ctype
				(db_get_column_sqltype(Z_Interp_col)) ==
				DB_C_TYPE_DOUBLE)
				Z_Interp_value =
				    db_get_column_value(Z_Interp_col);
			    else
				continue;
			    Z_interp = db_get_value_double(Z_Interp_value);
			    break;
			}
		    }

		    raster_matrix[row][col].interp += Z_interp;
		    raster_matrix[row][col].fi++;

		    /*if (( clas = Vect_get_line_cat (&In, line_num, F_EDGE_DETECTION_CLASS) ) != UNKNOWN_EDGE) { */
		    if (Vect_cat_get(Cats, F_EDGE_DETECTION_CLASS, &clas)) {
			raster_matrix[row][col].clas += clas;
			raster_matrix[row][col].fc++;
		    }

		    raster_matrix[row][col].orig += points->z[0];
		    raster_matrix[row][col].fo++;
		}

		Vect_reset_cats(Cats);
		Vect_reset_line(points);
	    }

	    for (row = 0; row <= nrows; row++) {
		for (col = 0; col <= ncols; col++) {

		    if (raster_matrix[row][col].fc != 0) {
			raster_matrix[row][col].clas--;
			raster_matrix[row][col].
			    clas /= raster_matrix[row][col].fc;
		    }

		    if (raster_matrix[row][col].fi != 0)
			raster_matrix[row][col].
			    interp /= raster_matrix[row][col].fi;

		    if (raster_matrix[row][col].fo != 0)
			raster_matrix[row][col].
			    orig /= raster_matrix[row][col].fo;
		}
	    }

	    /* DOUBLE IMPULSE */
	    Vect_rewind(&First);
	    while (Vect_read_next_line(&First, points_first, Cats_first) > 0) {

		if ((Vect_point_in_box
		     (points_first->x[0], points_first->y[0],
		      points_first->z[0], &elaboration_box)) &&
		    ((points->x[0] != elaboration_reg.west) ||
		     (points->x[0] == original_reg.west)) &&
		    ((points->y[0] != elaboration_reg.north) ||
		     (points->y[0] == original_reg.north))) {

		    row =
			(int)(Rast_northing_to_row
			      (points_first->y[0], &elaboration_reg));
		    col =
			(int)(Rast_easting_to_col
			      (points_first->x[0], &elaboration_reg));

		    if (fabs
			(points_first->z[0] - raster_matrix[row][col].orig) >=
			Thres_d)
			raster_matrix[row][col].dueImp = DOUBLE_PULSE;
		}
		Vect_reset_cats(Cats_first);
		Vect_reset_line(points_first);
	    }

	    /* REGION GROWING */
	    if (region == TRUE) {
		G_verbose_message(_("Region Growing"));

		punti_bordo = G_alloc_matrix(MaxPoints, 3);
		P = Pvector(0, MaxPoints);

		colorBordo = 5;
		ripieno = 6;

		for (row = 0; row <= nrows; row++) {
		    G_percent(row, nrows, 2);
		    for (col = 0; col <= ncols; col++) {

			if ((raster_matrix[row][col].clas >= Thres_j) &&
			    (raster_matrix[row][col].clas < colorBordo)
			    && (raster_matrix[row][col].fi != 0) &&
			    (raster_matrix[row][col].dueImp ==
			     SINGLE_PULSE)) {

			    /* Selecting a connected Object zone */
			    ripieno++;
			    if (ripieno > 10)
				ripieno = 6;

			    /* Selecting points on a connected edge */
			    for (conta = 0; conta < MaxPoints; conta++) {
				punti_bordo[conta][0] = 0;
				punti_bordo[conta][1] = 0;
				punti_bordo[conta][2] = 0;
				P[conta] = punti_bordo[conta];	/* It only makes indexes to be equal, not coord values!! */
			    }

			    lungPunti = 0;
			    lungHull = 0;

			    regGrow8(elaboration_reg, raster_matrix,
				     punti_bordo, &lungPunti, row, col,
				     colorBordo, Thres_j, MaxPoints);

			    /* CONVEX-HULL COMPUTATION */
			    lungHull = ch2d(P, lungPunti);
			    cvxHull = G_alloc_matrix(lungHull, 3);


			    for (xi = 0; xi < lungHull; xi++) {
				cvxHull[xi][0] = P[xi][0];
				cvxHull[xi][1] = P[xi][1];
				cvxHull[xi][2] = P[xi][2];
			    }

			    /* Computes the interpoling plane based only on Object points */
			    altPiano =
				pianOriz(punti_bordo, lungPunti, &minNS,
					 &minEW, &maxNS, &maxEW,
					 raster_matrix, colorBordo);

			    for (c1 = minNS; c1 <= maxNS; c1++) {
				for (c2 = minEW; c2 <= maxEW; c2++) {
				    if (checkHull(c1, c2, cvxHull, lungHull)
					== 1) {
					raster_matrix[c1][c2].obj = count_obj;

					if ((raster_matrix[c1][c2].clas ==
					     PRE_TERRAIN)
					    && (raster_matrix[c1][c2].orig >=
						altPiano) && (lungHull > 3))
					    raster_matrix[c1][c2].clas =
						ripieno;
				    }
				}
			    }
			    G_free_matrix(cvxHull);
			    count_obj++;
			}
		    }
		}
		G_free_matrix(punti_bordo);
		free_Pvector(P, 0, MaxPoints);
	    }

	    /* WRITING THE OUTPUT VECTOR CATEGORIES */
	    Vect_rewind(&In);
	    while (Vect_read_next_line(&In, points, Cats) > 0) {	/* Read every line for buffering points */

		if ((Vect_point_in_box
		     (points->x[0], points->y[0], points->z[0],
		      &elaboration_box)) &&
		    ((points->x[0] != elaboration_reg.west) ||
		     (points->x[0] == original_reg.west)) &&
		    ((points->y[0] != elaboration_reg.north) ||
		     (points->y[0] == original_reg.north))) {

		    row =
			(int)(Rast_northing_to_row
			      (points->y[0], &elaboration_reg));
		    col =
			(int)(Rast_easting_to_col
			      (points->x[0], &elaboration_reg));

		    if (raster_matrix[row][col].clas == PRE_TERRAIN) {
			if (raster_matrix[row][col].dueImp == SINGLE_PULSE)
			    Vect_cat_set(Cats, F_CLASSIFICATION,
					 TERRAIN_SINGLE);
			else
			    Vect_cat_set(Cats, F_CLASSIFICATION,
					 TERRAIN_DOUBLE);
		    }
		    else {
			if (raster_matrix[row][col].dueImp == SINGLE_PULSE)
			    Vect_cat_set(Cats, F_CLASSIFICATION,
					 OBJECT_SINGLE);
			else
			    Vect_cat_set(Cats, F_CLASSIFICATION,
					 OBJECT_DOUBLE);
		    }

		    Vect_cat_set(Cats, F_COUNTER_OBJ,
				 raster_matrix[row][col].obj);
		    Vect_write_line(&Out, GV_POINT, points, Cats);
		}
		Vect_reset_cats(Cats);
		Vect_reset_line(points);
	    }
	    free_structmatrix(raster_matrix, 0, nrows - 1, 0, ncols - 1);
	}			/*! END WHILE; last_column = TRUE */
    }				/*! END WHILE; last_row = TRUE */

    Vect_close(&In);
    Vect_close(&First);
    Vect_close(&Out);

    db_close_database_shutdown_driver(driver);

    G_done_msg(" ");
    exit(EXIT_SUCCESS);
}