Now also parse new diffs
[handlerosm.git] / osmsucker.c
blob1cf6e1dee9f22d7b4e161984ce3b404923c7cf89
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/mman.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <string.h>
8 #include <errno.h>
9 #include <math.h>
10 #include <unistd.h>
13 * <osm>
14 * <node>
15 * <tag k=".." v=".." />
16 * </node>
17 * <way>
18 * <nd>
19 * <tag>
20 * </way>
21 * <relation>
22 * <member>
23 * <tag>
24 * </relation>
27 /* TODO:
28 * Do something usefull with changesets and version;
31 #ifdef MMAP
32 # define stopcondition (start = ++end) < (range + max)
33 # define nextline start = end + 1
34 #else
35 # define nextline free(start); start = NULL; tmp = getline(&start, &tmplen, stdin); if (tmp == -1) { goto exit; }
36 # define stopcondition 1
37 #endif
39 #define file_delete_nodes "delete_nodes.csv"
40 #define file_delete_ways "delete_ways.csv"
41 #define file_delete_relations "delete_relations.csv"
43 #define file_modify_nodes "modify_nodes.csv"
44 #define file_modify_ways "modify_ways.csv"
45 #define file_modify_relations "modify_relations.csv"
47 #define file_nodes "nodes.csv"
49 #ifdef BENCHMARK
50 #define file_nodes_uint "nodes_uint.csv"
51 #define file_nodes_gis "nodes_gis.csv"
52 #endif
54 #define file_node_tags "node_tags.csv"
55 #define file_ways "ways.csv"
56 #define file_way_tags "way_tags.csv"
57 #define file_way_nds "way_nds.csv"
58 #define file_relations "relations.csv"
59 #define file_relation_tags "relation_tags.csv"
60 #define file_relation_member_node "relation_member_node.csv"
61 #define file_relation_member_relation "relation_member_relation.csv"
62 #define file_relation_member_way "relation_member_way.csv"
64 /* http://www.cs.utk.edu/~vose/c-stuff/bithacks.html */
65 static unsigned int reverse(unsigned int v) {
66 unsigned int t = v << 1; // t will have the reversed bits of v
67 int i;
69 v >>= 1;
70 for (i = sizeof(v) * 8 - 2; i; i--)
72 t |= v & 1;
73 t <<= 1;
74 v >>= 1;
76 t |= v;
78 return t;
81 static unsigned long zcurve(char *lon, char *lat) {
82 unsigned int array[2];
83 unsigned int i,j;
84 unsigned long out;
85 double temp = strtod(lon, (char **) NULL) + 180.0; /* Longitude */
86 if (temp < 0.0 || temp >= 360.0) temp = 0.0;
87 array[0] = reverse( 5965232.0 * temp);
89 temp = strtod(lat, (char **) NULL) + 90.0; /* Latitude */
90 if (temp < 0.0 || temp >= 180.0) temp = 0.0;
91 array[1] = reverse( 11930464.0 * temp);
93 for (j = 0; j < sizeof(unsigned int)*8; j++) {
94 for (i = 0; i < 2; i++) {
95 out <<= 1;
96 out |= array[i] & 1;
97 array[i] >>= 1;
101 return out;
105 static unsigned int coordtouint(char *input) {
106 double maxbit = (double) 4294967296.0 / (double) 360.0;
107 double proper = strtod(input, NULL) * maxbit;
108 return (unsigned int) proper;
111 static char * escape_string(char *instr)
113 unsigned int i, j=0, need = 0;
114 unsigned int len = strlen(instr);
115 char *outstr;
117 for (i=0;i<len;i++)
118 if (instr[i]=='\\' || instr[i]=='\'') need++;
120 len += need;
121 outstr = malloc(len + 1);
123 for (i=0;i<=strlen(instr);i++) {
124 if (instr[i]=='\\' || instr[i]=='\'')
125 outstr[j++]='\\';
126 outstr[j++]=instr[i];
128 return outstr;
131 #ifdef MMAP
132 static void parser(char *range, unsigned long int max) {
133 #else
134 static void parser() {
135 #endif
136 typedef enum { NONE = 0, CREATE = 1, MODIFY = 2, DELETE = 3 } ywk_state_t;
137 typedef enum { OSM = 0, NODE = 1, WAY = 2, RELATION = 3, TAG = 4, ND = 5, MEMBER = 6 } osm_state_t;
138 typedef enum { UNKNOWN = 0, ID, LAT, LON, USER, UID, TIMESTAMP, KEY, VALUE, TYPE, REF, ROLE, VERSION, CHANGESET} key_state_t;
139 char *attr_id = NULL, *attr_lat = NULL, *attr_lon = NULL, *attr_user = NULL, *attr_uid = NULL, *attr_timestamp = NULL, *attr_changeset = NULL, *attr_key = NULL, *attr_value = NULL,
140 *attr_type = NULL, *attr_ref = NULL, *attr_role = NULL, *attr_version = NULL;
142 unsigned int attr_lat_uint = 0;
143 unsigned int attr_lon_uint = 0;
146 unsigned long int count_nodes = 0, count_node_tags = 0,
147 count_ways = 0, count_way_tags = 0, count_way_nds = 0,
148 count_relations = 0, count_relation_tags = 0, count_members_node = 0, count_members_relation = 0, count_members_way = 0,
149 count_delete_nodes = 0, count_delete_ways = 0, count_delete_relations = 0,
150 count_modify_nodes = 0, count_modify_ways = 0, count_modify_relations = 0;
152 unsigned long int sequence = 0;
154 ywk_state_t ywk = NONE;
155 osm_state_t current_tag = OSM;
156 osm_state_t parent_tag = OSM;
158 char *start = NULL, *end, *nodename, *nodename_end;
159 ssize_t tmp;
160 size_t tmplen = 0;
162 #ifdef MMAP
163 start = range;
164 #else
165 nextline;
166 #endif
167 end = strchrnul((const char*) start, '\n');
169 if (strncmp(start, "<?xml", 5) != 0)
170 return;
172 nextline;
173 end = strchrnul((const char*) start, '\n');
175 if (strncmp(start, "<osm", 4) != 0)
176 return;
178 if (strncmp(&start[4], "Change", 6) == 0)
179 ywk = CREATE;
181 FILE *fd_nodes,
182 #ifdef BENCHMARK
183 *fd_nodes_uint,
184 *fd_nodes_gis,
185 #endif
186 *fd_node_tags,
187 *fd_ways,
188 *fd_way_tags,
189 *fd_way_nds,
190 *fd_relations,
191 *fd_relation_tags,
192 *fd_members_node,
193 *fd_members_relation,
194 *fd_members_way,
195 *fd_delete_nodes,
196 *fd_delete_ways,
197 *fd_delete_relations,
198 *fd_modify_nodes,
199 *fd_modify_ways,
200 *fd_modify_relations
203 fd_nodes = fopen(file_nodes, "w");
204 if (fd_nodes == NULL) { perror("Open:"); exit(-1); }
205 #ifdef BENCHMARK
206 fd_nodes_uint = fopen(file_nodes_uint, "w");
207 if (fd_nodes_uint == NULL) { perror("Open:"); exit(-1); }
208 fd_nodes_gis = fopen(file_nodes_gis, "w");
209 if (fd_nodes_gis == NULL) { perror("Open:"); exit(-1); }
210 #endif
211 fd_node_tags = fopen(file_node_tags, "w");
212 if (fd_node_tags == NULL) { perror("Open:"); exit(-1); }
213 fd_ways = fopen(file_ways, "w");
214 if (fd_ways == NULL) { perror("Open:"); exit(-1); }
215 fd_way_tags = fopen(file_way_tags, "w");
216 if (fd_way_tags == NULL) { perror("Open:"); exit(-1); }
217 fd_way_nds = fopen(file_way_nds, "w");
218 if (fd_way_nds == NULL) { perror("Open:"); exit(-1); }
219 fd_relations = fopen(file_relations, "w");
220 if (fd_relations == NULL) { perror("Open:"); exit(-1); }
221 fd_relation_tags = fopen(file_relation_tags, "w");
222 if (fd_relation_tags == NULL) { perror("Open:"); exit(-1); }
223 fd_members_node = fopen(file_relation_member_node, "w");
224 if (fd_members_node == NULL) { perror("Open:"); exit(-1); }
225 fd_members_relation = fopen(file_relation_member_relation, "w");
226 if (fd_members_relation == NULL) { perror("Open:"); exit(-1); }
227 fd_members_way = fopen(file_relation_member_way, "w");
228 if (fd_members_way == NULL) { perror("Open:"); exit(-1); }
231 fd_delete_nodes = fopen(file_delete_nodes, "w");
232 if (fd_delete_nodes == NULL) { perror("Open:"); exit(-1); }
233 fd_delete_ways = fopen(file_delete_ways, "w");
234 if (fd_delete_ways == NULL) { perror("Open:"); exit(-1); }
235 fd_delete_relations = fopen(file_delete_relations, "w");
236 if (fd_delete_relations == NULL) { perror("Open:"); exit(-1); }
238 fd_modify_nodes = fopen(file_modify_nodes, "w");
239 if (fd_modify_nodes == NULL) { perror("Open:"); exit(-1); }
240 fd_modify_ways = fopen(file_modify_ways, "w");
241 if (fd_modify_ways == NULL) { perror("Open:"); exit(-1); }
242 fd_modify_relations = fopen(file_modify_relations, "w");
243 if (fd_modify_relations == NULL) { perror("Open:"); exit(-1); }
246 nextline;
248 do {
249 end = strchrnul((const char*) start, '\n');
251 nodename = strchrnul(start, '<') + 1;
252 nodename_end = strchrnul(nodename, ' ');
254 if (nodename[0] == '/') {
255 free(attr_id);
256 free(attr_lat);
257 free(attr_lon);
258 free(attr_timestamp);
259 free(attr_changeset);
260 free(attr_user);
261 free(attr_uid);
262 free(attr_version);
264 attr_id = attr_lat = attr_lon = attr_user = attr_uid = attr_timestamp = attr_changeset = attr_version = NULL;
266 sequence = 0;
268 nextline;
269 continue;
272 switch (nodename_end - nodename) {
273 case 2:
274 current_tag = ND;
275 break;
276 case 3: {
277 switch (nodename[0]) {
278 case 'o':
279 current_tag = OSM;
280 break;
281 case 'w':
282 current_tag = WAY;
283 break;
284 case 't':
285 current_tag = TAG;
286 break;
287 default:
288 fprintf(stderr, "--> %c%c", nodename[0], nodename[1]);
290 break;
292 case 4:
293 current_tag = NODE;
294 break;
295 case 5:
296 /* BOUND */
297 nextline;
298 continue;
299 case 6:
300 switch (nodename[2]) {
301 case 'e':
302 ywk = CREATE;
303 nextline;
304 continue;
305 break;
306 case 'd':
307 ywk = MODIFY;
308 nextline;
309 continue;
310 break;
311 case 'l':
312 ywk = DELETE;
313 nextline;
314 continue;
315 break;
316 case 'm':
317 current_tag = MEMBER;
318 break;
319 default:
320 fprintf(stderr, "--> %c%c", nodename[0], nodename[1]);
323 break;
324 case 8:
325 current_tag = RELATION;
326 break;
327 default:
328 fprintf(stderr, "--> %c%c", nodename[0], nodename[1]);
332 char *key, *key_end, *value_end;
333 key = nodename_end + 1;
335 do {
336 char *value;
337 key_state_t current_key = UNKNOWN;
338 key_end = strchrnul(key, '=');
340 if (key_end == NULL || key_end >= end)
341 break;
343 switch (key_end - key) {
344 case 1: {
345 switch (key[0]) {
346 case 'k':
347 current_key = KEY;
348 break;
349 case 'v':
350 current_key = VALUE;
351 break;
352 default:
353 current_key = UNKNOWN;
355 break;
357 case 2:
358 current_key = ID;
359 break;
360 case 3: {
361 switch (key[1]) {
362 case 'a':
363 current_key = LAT;
364 break;
365 case 'o':
366 current_key = LON;
367 break;
368 case 'e':
369 current_key = REF;
370 break;
371 case 'i':
372 current_key = UID;
373 break;
374 default:
375 current_key = UNKNOWN;
376 fprintf(stderr, "--> %c%c\n", key[0], key[1]);
378 break;
380 case 4: {
381 switch (key[0]) {
382 case 'u':
383 current_key = USER;
384 break;
385 case 'r':
386 current_key = ROLE;
387 break;
388 case 't':
389 current_key = TYPE;
390 break;
391 default:
392 current_key = UNKNOWN;
393 fprintf(stderr, "--> %c%c\n", key[0], key[1]);
395 break;
397 case 7: {
398 current_key = VERSION;
399 break;
401 case 9: {
402 switch (key[0]) {
403 case 't':
404 current_key = TIMESTAMP;
405 break;
406 case 'c':
407 current_key = CHANGESET;
408 break;
409 default:
410 current_key = UNKNOWN;
411 fprintf(stderr, "--> %c%c\n", key[0], key[1]);
413 break;
415 default: {
416 char *thingie = strndup(key, (key_end - key));
417 current_key = UNKNOWN;
419 fprintf(stderr, "UNKNOWN ATTR %s-> %c%c\n", thingie, key[0], key[1]);
420 free(thingie);
424 value = key_end + 2;
425 value_end = value;
426 value_end = strchr(value_end, '"');
428 if (value_end > end)
429 break;
431 switch (current_key) {
432 case ID:
433 if (attr_id) free(attr_id);
434 attr_id = strndup(value, (value_end - value));
435 break;
437 case LAT:
438 if (attr_lat) free(attr_lat);
439 attr_lat = strndup(value, (value_end - value));
440 attr_lat_uint = coordtouint(attr_lat);
441 break;
443 case LON:
444 if (attr_lon) free(attr_lon);
445 attr_lon = strndup(value, (value_end - value));
446 attr_lon_uint = coordtouint(attr_lon);
447 break;
449 case TIMESTAMP:
450 if (attr_timestamp) free(attr_timestamp);
451 // attr_timestamp = strndup(value, (value_end - value));
452 attr_timestamp = strndup(value, (value_end - (value + 1))); /* another stupid fix */
453 // attr_timestamp[10] = ' '; /* Stupid timestamp fix */
454 break;
456 case CHANGESET:
457 if (attr_changeset) free(attr_changeset);
458 attr_changeset = strndup(value, (value_end - value));
459 break;
461 case USER: {
462 char *tmp;
463 if (attr_user) free(attr_user);
464 attr_user = strndup(value, (value_end - value));
465 tmp = escape_string(attr_user);
466 free(attr_user);
467 attr_user = tmp;
468 break;
471 case UID: {
472 if (attr_uid) free(attr_uid);
473 attr_uid = strndup(value, (value_end - value));
474 break;
477 case VERSION: {
478 if (attr_version) free(attr_version);
479 attr_version = strndup(value, (value_end - value));
480 break;
483 case KEY: {
484 char *tmp;
485 if (attr_key) free(attr_key);
486 attr_key = strndup(value, (value_end - value));
487 tmp = escape_string(attr_key);
488 free(attr_key);
489 attr_key = tmp;
490 break;
493 case VALUE: {
494 char *tmp;
495 if (attr_value) free(attr_value);
496 attr_value = strndup(value, (value_end - value));
497 tmp = escape_string(attr_value);
498 free(attr_value);
499 attr_value = tmp;
500 break;
503 case TYPE:
504 if (attr_type) free(attr_type);
505 attr_type = strndup(value, (value_end - value));
506 break;
508 case REF:
509 if (attr_ref) free(attr_ref);
510 attr_ref = strndup(value, (value_end - value));
511 break;
513 case ROLE: {
514 char *tmp;
515 if (attr_role) free(attr_role);
516 attr_role = strndup(value, (value_end - value));
517 tmp = escape_string(attr_role);
518 free(attr_role);
519 attr_role = tmp;
520 break;
523 default:
524 fprintf(stderr, "--> %c%c\n", value[0], value[1]);
527 key = value_end + 2;
528 } while (key < end);
530 if (ywk == DELETE || ywk == MODIFY) {
531 FILE *this = NULL;
532 switch (current_tag) {
533 case NODE:
534 if (ywk == DELETE) { this = fd_delete_nodes; count_delete_nodes++; } else { this = fd_modify_nodes; count_modify_nodes++; }
535 break;
536 case WAY:
537 if (ywk == DELETE) { this = fd_delete_ways; count_delete_ways++; } else { this = fd_modify_ways; count_modify_ways++; }
538 break;
539 case RELATION:
540 if (ywk == DELETE) { this = fd_delete_relations; count_delete_relations++; } else { this = fd_modify_relations; count_modify_relations++; }
541 break;
543 if (this) {
544 fputs(attr_id, this);
545 fputs("\n", this);
549 if (ywk != DELETE) {
550 switch (current_tag) {
551 case NODE:
552 fprintf(fd_nodes, "%s, %s, %s, %s, '%s', %lu\n", attr_id, attr_lon, attr_lat, (attr_uid != NULL ? attr_uid : "0"), attr_timestamp, zcurve(attr_lon, attr_lat));
553 #ifdef BENCHMARK
554 fprintf(fd_nodes_uint, "%s, %d, %d, %s, '%s'\n", attr_id, attr_lon_uint, attr_lat_uint, (attr_uid != NULL ? attr_uid : "0"), attr_timestamp);
555 fprintf(fd_nodes_gis, "%s, 'POINT( %s %s )', '%s', '%s'\n", attr_id, attr_lat, attr_lon, (attr_uid != NULL ? attr_uid : "0"), attr_timestamp);
556 #endif
557 count_nodes++;
558 break;
559 case TAG: {
560 switch (parent_tag) {
561 case NODE:
562 fprintf(fd_node_tags, "%s, '%s', '%s'\n", attr_id, attr_key, attr_value);
563 count_node_tags++;
564 break;
565 case WAY:
566 fprintf(fd_way_tags, "%s, '%s', '%s'\n", attr_id, attr_key, attr_value);
567 count_way_tags++;
568 break;
569 case RELATION:
570 fprintf(fd_relation_tags, "%s, '%s', '%s'\n", attr_id, attr_key, attr_value);
571 count_relation_tags++;
572 break;
573 default:
574 break;
576 break;
578 case WAY:
579 fprintf(fd_ways, "%s, %s, '%s'\n", attr_id, (attr_uid != NULL ? attr_uid : "0"), attr_timestamp);
580 count_ways++;
581 // fprintf(fd_way_tags, "%s, '%s', '%s'\n", attr_id, "type", "way");
582 // count_way_tags++;
583 break;
584 case RELATION:
585 fprintf(fd_relations, "%s, %s, '%s'\n", attr_id, (attr_uid != NULL ? attr_uid : "0"), attr_timestamp);
586 count_relations++;
587 break;
588 case MEMBER:
589 if (strcmp(attr_type, "node") == 0) {
590 fprintf(fd_members_node, "%s, %lu, %s, '%s'\n", attr_id, sequence, attr_ref, attr_role);
591 count_members_node++;
592 } else if (strcmp(attr_type, "way") == 0) {
593 fprintf(fd_members_way, "%s, %lu, %s, '%s'\n", attr_id, sequence, attr_ref, attr_role);
594 count_members_way++;
595 } else if (strcmp(attr_type, "relation") == 0) {
596 fprintf(fd_members_relation, "%s, %lu, %s, '%s'\n", attr_id, sequence, attr_ref, attr_role);
597 count_members_relation++;
599 sequence++;
600 break;
601 case ND:
602 fprintf(fd_way_nds, "%s, %lu, %s\n", attr_id, sequence, attr_ref);
603 sequence++;
604 count_way_nds++;
605 break;
606 default:
607 break;
611 if (end[-2] == '/') {
612 switch (current_tag) {
613 case NODE:
614 free(attr_lat);
615 free(attr_lon);
616 attr_lat = NULL;
617 attr_lon = NULL;
618 attr_lat_uint = 0;
619 attr_lon_uint = 0;
620 /* no break! */
622 case WAY:
623 case RELATION:
624 free(attr_id);
625 free(attr_timestamp);
626 free(attr_changeset);
627 free(attr_user);
628 free(attr_uid);
629 free(attr_version);
631 attr_id = attr_user = attr_uid = attr_timestamp = attr_changeset = attr_version = NULL;
633 sequence = 0;
634 break;
636 case TAG:
637 free(attr_key);
638 free(attr_value);
640 attr_key = NULL;
641 attr_value = NULL;
642 break;
644 case ND:
645 case MEMBER:
646 free(attr_type);
647 free(attr_ref);
648 free(attr_role);
650 attr_type = NULL;
651 attr_ref = NULL;
652 attr_role = NULL;
653 default:
654 break;
656 } else if (current_tag == NODE || current_tag == WAY || current_tag == RELATION) {
657 parent_tag = current_tag;
661 nextline;
662 } while (stopcondition);
663 exit:
665 free(attr_id);
666 free(attr_lat);
667 free(attr_lon);
668 free(attr_timestamp);
669 free(attr_changeset);
670 free(attr_user);
671 free(attr_uid);
672 free(attr_version);
674 free(attr_key);
675 free(attr_value);
677 fclose(fd_nodes);
678 #ifdef BENCHMARK
679 fclose(fd_nodes_uint);
680 fclose(fd_nodes_gis);
681 #endif
682 fclose(fd_node_tags);
683 fclose(fd_ways);
684 fclose(fd_way_tags);
685 fclose(fd_way_nds);
686 fclose(fd_relations);
687 fclose(fd_relation_tags);
688 fclose(fd_members_node);
689 fclose(fd_members_relation);
690 fclose(fd_members_way);
692 fclose(fd_delete_nodes);
693 fclose(fd_delete_ways);
694 fclose(fd_delete_relations);
695 fclose(fd_modify_nodes);
696 fclose(fd_modify_ways);
697 fclose(fd_modify_relations);
701 char *current = get_current_dir_name();
703 puts("START TRANSACTION;");
705 if (ywk == NONE) {
706 puts("CREATE TABLE nodes_legacy (id integer, long double, lat double, uid integer, timestamp timestamptz, zcurve bigint);");
707 #ifdef BENCHMARK
708 puts("CREATE TABLE nodes_legacy_uint (id integer, long integer, lat integer, uid integer, timestamp timestamptz);");
709 puts("CREATE TABLE nodes_legacy_gis (id integer, poi point, uid integer, timestamp timestamptz);");
710 #endif
711 puts("CREATE TABLE node_tags (node integer, k varchar(255), v varchar(1024));");
712 puts("CREATE TABLE ways (id integer,uid integer, timestamp timestamptz);");
713 puts("CREATE TABLE way_tags (way integer, k varchar(255), v varchar(1024));");
714 puts("CREATE TABLE way_nds (way integer, idx integer, to_node integer);");
715 puts("CREATE TABLE relations(id integer, uid integer, timestamp timestamptz);");
716 puts("CREATE TABLE relation_members_node (relation integer, idx integer, to_node integer, role varchar(255));");
717 puts("CREATE TABLE relation_members_relation (relation integer, idx integer, to_relation integer, role varchar(255));");
718 puts("CREATE TABLE relation_members_way (relation integer, idx integer, to_way integer, role varchar(255));");
719 puts("CREATE TABLE relation_tags (relation integer, k varchar(255), v varchar(1024));");
720 } else {
721 if (count_delete_nodes > 0 || count_delete_ways > 0 || count_delete_relations > 0 ||
722 count_modify_nodes > 0 || count_modify_ways > 0 || count_modify_relations > 0) {
723 if (count_delete_relations > 0 || count_modify_relations > 0) {
724 puts("CREATE TEMPORARY TABLE delete_relations (id integer);");
726 if (count_delete_ways > 0 || count_modify_ways > 0) {
727 puts("CREATE TEMPORARY TABLE delete_ways (id integer);");
729 if (count_delete_nodes > 0 || count_modify_nodes > 0) {
730 puts("CREATE TEMPORARY TABLE delete_nodes (id integer);");
733 if (count_delete_nodes > 0 || count_delete_ways > 0 || count_delete_relations > 0) {
734 if (count_delete_relations > 0) {
735 printf("COPY %lu RECORDS INTO delete_relations FROM '%s/" file_delete_relations "' USING DELIMITERS ',', '\\n', '''';\n", count_delete_relations, current);
738 if (count_delete_ways > 0) {
739 printf("COPY %lu RECORDS INTO delete_ways FROM '%s/" file_delete_ways "' USING DELIMITERS ',', '\\n', '''';\n", count_delete_ways, current);
742 if (count_delete_nodes > 0) {
743 printf("COPY %lu RECORDS INTO delete_nodes FROM '%s/" file_delete_nodes "' USING DELIMITERS ',', '\\n', '''';\n", count_delete_nodes, current);
746 if (count_delete_relations > 0) {
747 puts("DELETE FROM relation_members_relation WHERE to_relation IN (SELECT id FROM delete_relations);");
750 if (count_delete_ways > 0) {
751 puts("DELETE FROM relation_members_way WHERE to_way IN (SELECT id FROM delete_ways);");
754 if (count_delete_nodes > 0) {
755 puts("DELETE FROM relation_members_node WHERE to_node IN (SELECT id FROM delete_nodes);\n"
756 "DELETE FROM way_nds WHERE to_node IN (SELECT id FROM delete_nodes);");
760 if (count_modify_relations > 0) {
761 printf("COPY %lu RECORDS INTO delete_relations FROM '%s/" file_modify_relations "' USING DELIMITERS ',', '\\n', '''';\n", count_modify_relations, current);
764 if (count_modify_ways > 0) {
765 printf("COPY %lu RECORDS INTO delete_ways FROM '%s/" file_modify_ways "' USING DELIMITERS ',', '\\n', '''';\n", count_modify_ways, current);
768 if (count_modify_nodes > 0) {
769 printf("COPY %lu RECORDS INTO delete_nodes FROM '%s/" file_modify_nodes "' USING DELIMITERS ',', '\\n', '''';\n", count_modify_nodes, current);
772 if (count_delete_relations > 0 || count_modify_relations > 0) {
773 puts("DELETE FROM relation_members_relation WHERE relation IN (SELECT id FROM delete_relations);\n"
774 "DELETE FROM relation_members_way WHERE relation IN (SELECT id FROM delete_relations);\n"
775 "DELETE FROM relation_members_node WHERE relation IN (SELECT id FROM delete_relations);\n"
776 "DELETE FROM relation_tags WHERE relation IN (SELECT id FROM delete_relations);\n"
777 "DELETE FROM relations WHERE id IN (SELECT id FROM delete_relations);\n"
778 "DROP TABLE delete_relations;\n");
781 if (count_delete_ways > 0 || count_modify_ways > 0) {
782 puts("DELETE FROM way_nds WHERE way IN (SELECT id FROM delete_ways);\n"
783 "DELETE FROM way_tags WHERE way IN (SELECT id FROM delete_ways);\n"
784 "DELETE FROM ways WHERE id IN (SELECT id FROM delete_ways);\n"
785 "DROP TABLE delete_ways;\n");
788 if (count_delete_nodes > 0 || count_modify_nodes > 0) {
789 puts("DELETE FROM node_tags WHERE node IN (SELECT id FROM delete_nodes);\n"
790 "DELETE FROM nodes_legacy WHERE id IN (SELECT id FROM delete_nodes);\n"
791 "DROP TABLE delete_nodes;\n");
796 printf("COPY %lu RECORDS INTO nodes_legacy from '%s/" file_nodes "' USING DELIMITERS ',', '\\n', '''';\n", count_nodes, current);
797 #ifdef BENCHMARK
798 printf("COPY %lu RECORDS INTO nodes_legacy_uint from '%s/" file_nodes_uint "' USING DELIMITERS ',', '\\n', '''';\n", count_nodes, current);
799 printf("COPY %lu RECORDS INTO nodes_legacy_gis from '%s/" file_nodes_gis "' USING DELIMITERS ',', '\\n', '''';\n", count_nodes, current);
800 #endif
801 printf("COPY %lu RECORDS INTO node_tags from '%s/" file_node_tags "' USING DELIMITERS ',', '\\n', '''';\n", count_node_tags, current);
802 printf("COPY %lu RECORDS INTO ways from '%s/" file_ways "' USING DELIMITERS ',', '\\n', '''';\n", count_ways, current);
803 printf("COPY %lu RECORDS INTO way_tags from '%s/" file_way_tags "' USING DELIMITERS ',', '\\n', '''';\n", count_way_tags, current);
804 printf("COPY %lu RECORDS INTO way_nds from '%s/" file_way_nds "' USING DELIMITERS ',', '\\n', '''';\n", count_way_nds, current);
805 printf("COPY %lu RECORDS INTO relations from '%s/" file_relations "' USING DELIMITERS ',', '\\n', '''';\n", count_relations, current);
806 printf("COPY %lu RECORDS INTO relation_tags from '%s/" file_relation_tags "' USING DELIMITERS ',', '\\n', '''';\n", count_relation_tags, current);
807 printf("COPY %lu RECORDS INTO relation_members_node from '%s/" file_relation_member_node "' USING DELIMITERS ',', '\\n', '''';\n", count_members_node, current);
808 printf("COPY %lu RECORDS INTO relation_members_relation from '%s/" file_relation_member_relation "' USING DELIMITERS ',', '\\n', '''';\n", count_members_relation, current);
809 printf("COPY %lu RECORDS INTO relation_members_way from '%s/" file_relation_member_way "' USING DELIMITERS ',', '\\n', '''';\n", count_members_way, current);
811 free(current);
813 puts("COMMIT;");
815 if (ywk == NONE) {
816 puts("START TRANSACTION;");
818 puts("CREATE SEQUENCE s_nodes AS INTEGER;");
819 puts("ALTER SEQUENCE s_nodes RESTART WITH (SELECT MAX(id) FROM nodes_legacy);");
820 puts("ALTER TABLE nodes_legacy ALTER COLUMN id SET NOT NULL;");
821 puts("ALTER TABLE nodes_legacy ALTER COLUMN id SET DEFAULT NEXT VALUE FOR \"sys\".\"s_nodes\";");
822 puts("ALTER TABLE nodes_legacy ADD CONSTRAINT pk_nodes_id PRIMARY KEY (id);");
824 puts("CREATE SEQUENCE s_ways AS INTEGER;");
825 puts("ALTER SEQUENCE s_ways RESTART WITH (SELECT MAX(id) FROM ways);");
826 puts("ALTER TABLE ways ALTER COLUMN id SET NOT NULL;");
827 puts("ALTER TABLE ways ALTER COLUMN id SET DEFAULT NEXT VALUE FOR \"sys\".\"s_ways\";");
828 puts("ALTER TABLE ways ADD CONSTRAINT pk_ways_id PRIMARY KEY (id);");
830 puts("CREATE SEQUENCE s_relations AS INTEGER;");
831 puts("ALTER SEQUENCE s_relations RESTART WITH (SELECT MAX(id) FROM relations);");
832 puts("ALTER TABLE relations ALTER COLUMN id SET NOT NULL;");
833 puts("ALTER TABLE relations ALTER COLUMN id SET DEFAULT NEXT VALUE FOR \"sys\".\"s_relations\";");
834 puts("ALTER TABLE relations ADD CONSTRAINT pk_relations_id PRIMARY KEY (id);");
836 puts("ALTER TABLE relation_members_node ADD CONSTRAINT pk_relation_members_node PRIMARY KEY (relation, idx);");
837 puts("ALTER TABLE relation_members_way ADD CONSTRAINT pk_relation_members_way PRIMARY KEY (relation,idx);");
838 puts("ALTER TABLE relation_members_relation ADD CONSTRAINT pk_relation_members_relation PRIMARY KEY (relation,idx);");
840 puts("COMMIT;");
843 puts("START TRANSACTION;");
845 puts("ALTER TABLE node_tags ADD CONSTRAINT fk_node_tags_node FOREIGN KEY (node) REFERENCES nodes_legacy (id);");
846 puts("ALTER TABLE node_tags ADD CONSTRAINT pk_node_tags UNIQUE (node, k, v);");
848 puts("ALTER TABLE way_tags ADD CONSTRAINT fk_way_tags_way FOREIGN KEY (way) REFERENCES ways (id);");
849 puts("ALTER TABLE way_tags ADD CONSTRAINT pk_way_tags UNIQUE (way, k, v);");
851 puts("ALTER TABLE way_nds ADD CONSTRAINT pk_way_nds PRIMARY KEY (way, idx);");
852 puts("ALTER TABLE way_nds ADD CONSTRAINT fk_way_nds_way FOREIGN KEY (way) REFERENCES ways (id);");
853 puts("ALTER TABLE way_nds ADD CONSTRAINT fk_way_nds_node FOREIGN KEY (to_node) REFERENCES nodes_legacy (id);");
855 puts("ALTER TABLE relation_tags ADD CONSTRAINT fk_relation_tags FOREIGN KEY (relation) REFERENCES relations (id);");
856 puts("ALTER TABLE relation_tags ADD CONSTRAINT pk_relation_tags UNIQUE (relation, k, v);");
858 puts("ALTER TABLE relation_members_node ADD CONSTRAINT fk_relation_members_node FOREIGN KEY (relation) REFERENCES relations (id);");
859 puts("ALTER TABLE relation_members_node ADD CONSTRAINT fk_relation_members_tonode FOREIGN KEY (to_node) REFERENCES nodes_legacy (id);");
861 puts("ALTER TABLE relation_members_way ADD CONSTRAINT fk_relation_members_way FOREIGN KEY (relation) REFERENCES relations (id);");
862 puts("ALTER TABLE relation_members_way ADD CONSTRAINT fk_relation_members_toway FOREIGN KEY (to_way) REFERENCES ways (id);");
864 puts("ALTER TABLE relation_members_relation ADD CONSTRAINT fk_relation_members_relation FOREIGN KEY (relation) REFERENCES relations (id);");
865 puts("ALTER TABLE relation_members_relation ADD CONSTRAINT fk_relation_members_torelation FOREIGN KEY (to_relation) REFERENCES relations (id);");
867 puts("COMMIT;");
872 int main(int argc, char *argv[]) {
873 #ifdef MMAP
874 int fd;
875 struct stat statbuf;
877 if (argc != 2)
878 exit(-1);
880 fprintf(stderr, "Analysing %s...\n", argv[1]);
882 fd = open(argv[1], O_RDONLY);
884 if (fd < 0)
885 exit(-1);
887 if (fstat (fd, &statbuf) == -1) { perror("fstat:"); exit(-1); }
889 if (statbuf.st_size > 0) {
890 char *range = NULL;
891 range = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, (off_t) 0);
892 if (range == MAP_FAILED) { perror("Mmap:"); puts("(did you compile PAE in the kernel?)"); exit(-1); }
893 parser(range, statbuf.st_size / sizeof(char));
894 munmap(range, statbuf.st_size);
897 close(fd);
898 #else
899 parser();
900 #endif
901 exit(0);