File: create.c

package info (click to toggle)
grass 8.4.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 277,040 kB
  • sloc: ansic: 460,798; python: 227,732; cpp: 42,026; sh: 11,262; makefile: 7,007; xml: 3,637; sql: 968; lex: 520; javascript: 484; yacc: 450; asm: 387; perl: 157; sed: 25; objc: 6; ruby: 4
file content (123 lines) | stat: -rw-r--r-- 3,448 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <unistd.h>

#include <grass/gis.h>
#include <grass/glocale.h>

#include "local_proto.h"

static void file_handler(void *);

char *create_pgfile(const char *dsn, const char *schema, const char *olink,
                    char **options, int topo, char **fid_column,
                    char **geom_column)
{
    int i;
    const char *epsg;
    char *filename, *conninfo;
    char buf[GPATH_MAX];
    FILE *fp;

    struct Key_Value *key_val;

    filename = NULL;
    G_asprintf(&filename, "PG_%d", (int)getpid());
    G_debug(1, "PG file: %s", filename);

    fp = G_fopen_new("", filename);
    if (!fp)
        G_fatal_error(_("Unable to create <%s> file"), filename);
    sprintf(buf, "GRASS_VECTOR_PGFILE=%s", filename);
    putenv(G_store(buf));
    G_add_error_handler(file_handler, filename);

    key_val = G_create_key_value();

    /* be friendly, ignored 'PG:' prefix for GRASS-PostGIS data driver */
    if (G_strncasecmp(dsn, "PG:", 3) == 0) {
        int length;

        length = strlen(dsn);
        conninfo = (char *)G_malloc(length - 2);
        for (i = 3; i < length; i++)
            conninfo[i - 3] = dsn[i];
        conninfo[length - 3] = '\0';
    }
    else {
        conninfo = G_store(dsn);
    }

    /* required options */
    G_set_key_value("conninfo", conninfo, key_val);
    if (schema)
        G_set_key_value("schema", schema, key_val);
    if (topo)
        G_set_key_value("topology", "yes", key_val);

    /* is EPSG defined */
    epsg = G_database_epsg_code();

    /* extra options */
    if (options) {
        char **tokens;

        for (i = 0; options[i]; i++) {
            tokens = G_tokenize(options[i], "=");
            if (G_number_of_tokens(tokens) != 2) {
                G_warning(_("Invalid option skipped: %s"), options[i]);
                continue;
            }
            G_debug(1, "option: %s=%s", tokens[0], tokens[1]);
            /* force lower case */
            G_str_to_lower(tokens[0]);
            /* strip whitespace for key/value */
            G_strip(tokens[0]);
            G_strip(tokens[1]);

            if (strcmp(tokens[0], "srid") == 0 &&
                (epsg && strcmp(tokens[1], epsg) != 0))
                G_warning(_("EPSG code defined for current project (%s) is "
                            "overridden by %s"),
                          epsg, tokens[1]);

            G_set_key_value(tokens[0], tokens[1], key_val);

            if (strcmp(tokens[0], "fid") == 0)
                G_asprintf(fid_column, "%s", tokens[1]);
            if (strcmp(tokens[0], "geometry_name") == 0)
                G_asprintf(geom_column, "%s", tokens[1]);

            G_free_tokens(tokens);
        }
    }

    /* check EPSG code if defined as an option */
    if (epsg && !G_find_key_value("srid", key_val))
        G_set_key_value("srid", epsg, key_val);

    if (olink) {
        /* create a link for output feature table */
        G_set_key_value("link", "yes", key_val);
        G_set_key_value("link_name", olink, key_val);
    }
    else {
        G_set_key_value("link", "no", key_val);
    }

    if (G_fwrite_key_value(fp, key_val) < 0)
        G_fatal_error(_("Error writing <%s> file"), filename);

    fclose(fp);

    G_free(conninfo);

    return filename;
}

void file_handler(void *p)
{
    const char *filename = (const char *)p;

    G_debug(1, "file_handler: %s", filename);
    G_remove("", filename);
    putenv("GRASS_VECTOR_PGFILE=");
}