7 static void exit_mysql_err(MYSQL *mysql) {
8 const char *err = mysql_error(mysql);
10 fprintf(stderr, "019_populate_node_tags_and_remove_helper: MySQL error: %s\n", err);
12 fprintf(stderr, "019_populate_node_tags_and_remove_helper: MySQL error\n");
18 static void write_csv_col(FILE *f, const char *str, char end) {
19 char *out = (char *) malloc(2 * strlen(str) + 4);
27 } else if (*str == '\"') {
39 if (fwrite(out, len, 1, f) != 1) {
47 static void unescape(char *str) {
48 char *i = str, *o = str, tmp;
54 case 's': *o++ = ';'; break;
55 case 'e': *o++ = '='; break;
56 case '\\': *o++ = '\\'; break;
57 default: *o++ = tmp; break;
65 static int read_node_tags(char **tags, char **k, char **v) {
66 if (!**tags) return 0;
67 char *i = strchr(*tags, ';');
68 if (!i) i = *tags + strlen(*tags);
69 char *j = strchr(*tags, '=');
76 *tags = *i ? i + 1 : i;
92 static void proc_nodes(struct data *d, const char *tbl, FILE *out, FILE *out_tags, int hist) {
97 snprintf(query, sizeof(query), "SELECT id, latitude, longitude, "
98 "user_id, visible, tags, timestamp, tile FROM %s", tbl);
99 if (mysql_query(d->mysql, query))
100 exit_mysql_err(d->mysql);
102 res = mysql_use_result(d->mysql);
103 if (!res) exit_mysql_err(d->mysql);
105 while ((row = mysql_fetch_row(res))) {
106 unsigned long id = strtoul(row[0], NULL, 10);
109 if (id >= d->version_size) {
110 fprintf(stderr, "preallocated nodes size exceeded");
115 version = ++(d->version[id]);
117 fprintf(out, "\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%u\"\n",
118 row[0], row[1], row[2], row[3], row[4], row[6], row[7], version);
120 /*fprintf(out, "\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n",
121 row[0], row[1], row[2], row[3], row[4], row[6], row[7]);*/
124 char *tags_it = row[5], *k, *v;
125 while (read_node_tags(&tags_it, &k, &v)) {
127 fprintf(out_tags, "\"%s\",\"%u\",", row[0], version);
129 fprintf(out_tags, "\"%s\",", row[0]);
132 write_csv_col(out_tags, k, ',');
133 write_csv_col(out_tags, v, '\n');
136 if (mysql_errno(d->mysql)) exit_mysql_err(d->mysql);
138 mysql_free_result(res);
141 static size_t select_size(MYSQL *mysql, const char *q) {
146 if (mysql_query(mysql, q))
147 exit_mysql_err(mysql);
149 res = mysql_store_result(mysql);
150 if (!res) exit_mysql_err(mysql);
152 row = mysql_fetch_row(res);
153 if (!row) exit_mysql_err(mysql);
156 ret = strtoul(row[0], NULL, 10);
161 mysql_free_result(res);
166 static MYSQL *connect_to_mysql(char **argv) {
167 MYSQL *mysql = mysql_init(NULL);
168 if (!mysql) exit_mysql_err(mysql);
170 if (!mysql_real_connect(mysql, argv[1], argv[2], argv[3], argv[4],
171 argv[5][0] ? atoi(argv[5]) : 0, argv[6][0] ? argv[6] : NULL, 0))
172 exit_mysql_err(mysql);
174 if (mysql_set_character_set(mysql, "utf8"))
175 exit_mysql_err(mysql);
180 static void open_file(FILE **f, char *fn) {
181 *f = fopen(fn, "w+");
188 int main(int argc, char **argv) {
190 FILE *current_nodes, *current_node_tags, *nodes, *node_tags;
192 struct data data, *d = &data;
195 printf("Usage: 019_populate_node_tags_and_remove_helper host user passwd database port socket prefix\n");
199 d->mysql = connect_to_mysql(argv);
201 d->version_size = 1 + select_size(d->mysql, "SELECT max(id) FROM current_nodes");
202 d->version = (uint16_t *) malloc(sizeof(uint16_t) * d->version_size);
208 memset(d->version, 0, sizeof(uint16_t) * d->version_size);
210 prefix_len = strlen(argv[7]);
211 tempfn = (char *) malloc(prefix_len + 32);
212 strcpy(tempfn, argv[7]);
214 strcpy(tempfn + prefix_len, "current_nodes");
215 open_file(¤t_nodes, tempfn);
217 strcpy(tempfn + prefix_len, "current_node_tags");
218 open_file(¤t_node_tags, tempfn);
220 strcpy(tempfn + prefix_len, "nodes");
221 open_file(&nodes, tempfn);
223 strcpy(tempfn + prefix_len, "node_tags");
224 open_file(&node_tags, tempfn);
228 proc_nodes(d, "nodes", nodes, node_tags, 1);
229 proc_nodes(d, "current_nodes", current_nodes, current_node_tags, 0);
233 mysql_close(d->mysql);
235 fclose(current_nodes);
236 fclose(current_node_tags);