later than last version
[handlerosm.git] / osmsucker-ywk.c
blob0590c4f3322c37ee6ff43782f7cdeeee0cf7c7ae
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 #ifdef MMAP
28 # define stopcondition (start = ++end) < (range + max)
29 # define nextline start = end + 1
30 #else
31 # define nextline free(start); start = NULL; tmp = getline(&start, &tmplen, stdin); if (tmp == -1) { goto exit; }
32 # define stopcondition 1
33 #endif
35 #define file_delete_nodes "delete_nodes.csv"
36 #define file_delete_ways "delete_ways.csv"
37 #define file_delete_relations "delete_relations.csv"
39 #define file_modify_nodes "modify_nodes.csv"
40 #define file_modify_ways "modify_ways.csv"
41 #define file_modify_relations "modify_relations.csv"
43 #define file_nodes "nodes.csv"
45 #ifdef BENCHMARK
46 #define file_nodes_uint "nodes_uint.csv"
47 #define file_nodes_gis "nodes_gis.csv"
48 #endif
50 #define file_node_tags "node_tags.csv"
51 #define file_ways "ways.csv"
52 #define file_way_tags "way_tags.csv"
53 #define file_way_nds "way_nds.csv"
54 #define file_relations "relations.csv"
55 #define file_relation_tags "relation_tags.csv"
56 #define file_relation_member_node "relation_member_node.csv"
57 #define file_relation_member_relation "relation_member_relation.csv"
58 #define file_relation_member_way "relation_member_way.csv"
60 unsigned int coordtouint(char *input) {
61 double maxbit = (double) 4294967296.0 / (double) 360.0;
62 double proper = strtod(input, NULL) * maxbit;
63 return (unsigned int) proper;
66 char * escape_string(char *instr)
68 unsigned int i, j=0, need = 0;
69 unsigned int len = strlen(instr);
70 char *outstr;
72 for (i=0;i<len;i++)
73 if (instr[i]=='\\' || instr[i]=='\'') need++;
75 len += need;
76 outstr = malloc(len + 1);
78 for (i=0;i<=strlen(instr);i++) {
79 if (instr[i]=='\\' || instr[i]=='\'')
80 outstr[j++]='\\';
81 outstr[j++]=instr[i];
83 return outstr;
86 #ifdef MMAP
87 static void parser(char *range, unsigned long int max) {
88 #else
89 static void parser() {
90 #endif
91 typedef enum { NONE = 0, CREATE = 1, MODIFY = 2, DELETE = 3 } ywk_state_t;
92 typedef enum { OSM = 0, NODE = 1, WAY = 2, RELATION = 3, TAG = 4, ND = 5, MEMBER = 6 } osm_state_t;
93 typedef enum { UNKNOWN = 0, ID, LAT, LON, USER, UID, TIMESTAMP, KEY, VALUE, TYPE, REF, ROLE} key_state_t;
94 char *attr_id = NULL, *attr_lat = NULL, *attr_lon = NULL, *attr_user = NULL, *attr_uid = NULL, *attr_timestamp = NULL, *attr_key = NULL, *attr_value = NULL,
95 *attr_type = NULL, *attr_ref = NULL, *attr_role = NULL;
97 unsigned int attr_lat_uint = 0;
98 unsigned int attr_lon_uint = 0;
101 unsigned long int count_nodes = 0, count_node_tags = 0,
102 count_ways = 0, count_way_tags = 0, count_way_nds = 0,
103 count_relations = 0, count_relation_tags = 0, count_members_node = 0, count_members_relation = 0, count_members_way = 0;
105 unsigned long int sequence = 0;
107 ywk_state_t ywk = CREATE;
108 osm_state_t current_tag = OSM;
109 osm_state_t parent_tag = OSM;
111 char *start = NULL, *end, *nodename, *nodename_end;
112 ssize_t tmp;
113 size_t tmplen = 0;
115 #ifdef MMAP
116 start = range;
117 #else
118 nextline;
119 #endif
120 end = strchrnul((const char*) start, '\n');
122 if (strncmp(start, "<?xml", 5) != 0)
123 return;
125 nextline;
126 end = strchrnul((const char*) start, '\n');
128 if (strncmp(start, "<osm", 4) != 0)
129 return;
131 if (strncmp(&start[4], "Change", 6) == 0)
132 ywk = CREATE;
134 FILE *fd_nodes,
135 #ifdef BENCHMARK
136 *fd_nodes_uint,
137 *fd_nodes_gis,
138 #endif
139 *fd_node_tags,
140 *fd_ways,
141 *fd_way_tags,
142 *fd_way_nds,
143 *fd_relations,
144 *fd_relation_tags,
145 *fd_members_node,
146 *fd_members_relation,
147 *fd_members_way;
149 if (ywk = NONE) {
150 fd_nodes = fopen(file_nodes, "w");
151 if (fd_nodes == NULL) { perror("Open:"); exit(-1); }
152 #ifdef BENCHMARK
153 fd_nodes_uint = fopen(file_nodes_uint, "w");
154 if (fd_nodes_uint == NULL) { perror("Open:"); exit(-1); }
155 fd_nodes_gis = fopen(file_nodes_gis, "w");
156 if (fd_nodes_gis == NULL) { perror("Open:"); exit(-1); }
157 #endif
158 fd_node_tags = fopen(file_node_tags, "w");
159 if (fd_node_tags == NULL) { perror("Open:"); exit(-1); }
160 fd_ways = fopen(file_ways, "w");
161 if (fd_ways == NULL) { perror("Open:"); exit(-1); }
162 fd_way_tags = fopen(file_way_tags, "w");
163 if (fd_way_tags == NULL) { perror("Open:"); exit(-1); }
164 fd_way_nds = fopen(file_way_nds, "w");
165 if (fd_way_nds == NULL) { perror("Open:"); exit(-1); }
166 fd_relations = fopen(file_relations, "w");
167 if (fd_relations == NULL) { perror("Open:"); exit(-1); }
168 fd_relation_tags = fopen(file_relation_tags, "w");
169 if (fd_relation_tags == NULL) { perror("Open:"); exit(-1); }
170 fd_members_node = fopen(file_relation_member_node, "w");
171 if (fd_members_node == NULL) { perror("Open:"); exit(-1); }
172 fd_members_relation = fopen(file_relation_member_relation, "w");
173 if (fd_members_relation == NULL) { perror("Open:"); exit(-1); }
174 fd_members_way = fopen(file_relation_member_way, "w");
175 if (fd_members_way == NULL) { perror("Open:"); exit(-1); }
176 } else {
177 fd_node_tags = fd_ways = fd_way_tags = fd_way_nds = fd_relations = fd_relation_tags = fd_members_node = fd_members_relation = fd_members_way = fd_nodes = stdout;
178 fputs("START TRANSACTION;\n", fd_nodes);
181 nextline;
183 do {
184 end = strchrnul((const char*) start, '\n');
186 nodename = strchrnul(start, '<') + 1;
187 nodename_end = strchrnul(nodename, ' ');
189 if (nodename[0] == '/') {
190 free(attr_id);
191 free(attr_lat);
192 free(attr_lon);
193 free(attr_timestamp);
194 free(attr_user);
195 free(attr_uid);
197 attr_id = attr_lat = attr_lon = attr_user = attr_uid = attr_timestamp = NULL;
199 sequence = 0;
201 nextline;
202 continue;
205 switch (nodename_end - nodename) {
206 case 2:
207 current_tag = ND;
208 break;
209 case 3: {
210 switch (nodename[0]) {
211 case 'o':
212 current_tag = OSM;
213 break;
214 case 'w':
215 current_tag = WAY;
216 break;
217 case 't':
218 current_tag = TAG;
219 break;
220 default:
221 fprintf(stderr, "--> %c%c", nodename[0], nodename[1]);
223 break;
225 case 4:
226 current_tag = NODE;
227 break;
228 case 5:
229 /* BOUND */
230 nextline;
231 continue;
232 case 6:
233 switch (nodename[2]) {
234 case 'e':
235 ywk = CREATE;
236 nextline;
237 continue;
238 break;
239 case 'd':
240 ywk = MODIFY;
241 nextline;
242 continue;
243 break;
244 case 'l':
245 ywk = DELETE;
246 nextline;
247 continue;
248 break;
249 case 'm':
250 current_tag = MEMBER;
251 break;
252 default:
253 fprintf(stderr, "--> %c%c", nodename[0], nodename[1]);
256 break;
257 case 8:
258 current_tag = RELATION;
259 break;
260 default:
261 fprintf(stderr, "--> %c%c", nodename[0], nodename[1]);
265 char *key, *key_end, *value_end;
266 key = nodename_end + 1;
268 do {
269 char *value;
270 key_state_t current_key = UNKNOWN;
271 key_end = strchrnul(key, '=');
273 if (key_end == NULL || key_end >= end)
274 break;
276 switch (key_end - key) {
277 case 1: {
278 switch (key[0]) {
279 case 'k':
280 current_key = KEY;
281 break;
282 case 'v':
283 current_key = VALUE;
284 break;
285 default:
286 current_key = UNKNOWN;
288 break;
290 case 2:
291 current_key = ID;
292 break;
293 case 3: {
294 switch (key[1]) {
295 case 'a':
296 current_key = LAT;
297 break;
298 case 'o':
299 current_key = LON;
300 break;
301 case 'e':
302 current_key = REF;
303 break;
304 case 'i':
305 current_key = UID;
306 break;
307 default:
308 current_key = UNKNOWN;
309 fprintf(stderr, "--> %c%c\n", key[0], key[1]);
311 break;
313 case 4: {
314 switch (key[0]) {
315 case 'u':
316 current_key = USER;
317 break;
318 case 'r':
319 current_key = ROLE;
320 break;
321 case 't':
322 current_key = TYPE;
323 break;
324 default:
325 current_key = UNKNOWN;
326 fprintf(stderr, "--> %c%c\n", key[0], key[1]);
328 break;
330 case 9:
331 current_key = TIMESTAMP;
332 break;
333 default: {
334 char *thingie = strndup(key, (key_end - key));
335 current_key = UNKNOWN;
337 fprintf(stderr, "UNKNOWN ATTR %s-> %c%c\n", thingie, key[0], key[1]);
338 free(thingie);
342 value = key_end + 2;
343 value_end = value;
344 value_end = strchr(value_end, '"');
346 if (value_end > end)
347 break;
349 switch (current_key) {
350 case ID:
351 if (attr_id) free(attr_id);
352 attr_id = strndup(value, (value_end - value));
353 break;
355 case LAT:
356 if (attr_lat) free(attr_lat);
357 attr_lat = strndup(value, (value_end - value));
358 attr_lat_uint = coordtouint(attr_lat);
359 break;
361 case LON:
362 if (attr_lon) free(attr_lon);
363 attr_lon = strndup(value, (value_end - value));
364 attr_lon_uint = coordtouint(attr_lon);
365 break;
367 case TIMESTAMP:
368 if (attr_timestamp) free(attr_timestamp);
369 // attr_timestamp = strndup(value, (value_end - value));
370 attr_timestamp = strndup(value, (value_end - (value + 1))); /* another stupid fix */
371 // attr_timestamp[10] = ' '; /* Stupid timestamp fix */
372 break;
374 case USER: {
375 char *tmp;
376 if (attr_user) free(attr_user);
377 attr_user = strndup(value, (value_end - value));
378 tmp = escape_string(attr_user);
379 free(attr_user);
380 attr_user = tmp;
381 break;
384 case UID: {
385 if (attr_uid) free(attr_uid);
386 attr_uid = strndup(value, (value_end - value));
387 break;
390 case KEY: {
391 char *tmp;
392 if (attr_key) free(attr_key);
393 attr_key = strndup(value, (value_end - value));
394 tmp = escape_string(attr_key);
395 free(attr_key);
396 attr_key = tmp;
397 break;
400 case VALUE: {
401 char *tmp;
402 if (attr_value) free(attr_value);
403 attr_value = strndup(value, (value_end - value));
404 tmp = escape_string(attr_value);
405 free(attr_value);
406 attr_value = tmp;
407 break;
410 case TYPE:
411 if (attr_type) free(attr_type);
412 attr_type = strndup(value, (value_end - value));
413 break;
415 case REF:
416 if (attr_ref) free(attr_ref);
417 attr_ref = strndup(value, (value_end - value));
418 break;
420 case ROLE: {
421 char *tmp;
422 if (attr_role) free(attr_role);
423 attr_role = strndup(value, (value_end - value));
424 tmp = escape_string(attr_role);
425 free(attr_role);
426 attr_role = tmp;
427 break;
430 default:
431 fprintf(stderr, "--> %c%c\n", value[0], value[1]);
434 key = value_end + 2;
435 } while (key < end);
437 if (ywk == DELETE || ywk == MODIFY) {
438 switch (current_tag) {
439 case NODE:
440 fprintf(fd_nodes, "DELETE FROM node_tags WHERE node = %s;\n", attr_id);
441 fprintf(fd_nodes, "DELETE FROM nodes_legacy WHERE id = %s;\n", attr_id);
442 break;
443 case WAY:
444 fprintf(fd_nodes, "DELETE FROM way_tags WHERE way = %s;\n", attr_id);
445 fprintf(fd_nodes, "DELETE FROM way_nds WHERE way = %s;\n", attr_id);
446 fprintf(fd_nodes, "DELETE FROM ways WHERE id = %s;\n", attr_id);
447 break;
448 case RELATION:
449 fprintf(fd_nodes, "DELETE FROM relation_tags WHERE relation = %s;\n", attr_id);
450 fprintf(fd_nodes, "DELETE FROM relation_members_node WHERE relation = %s;\n", attr_id);
451 fprintf(fd_nodes, "DELETE FROM relation_members_way WHERE relation = %s;\n", attr_id);
452 fprintf(fd_nodes, "DELETE FROM relation_members_relation WHERE relation = %s;\n", attr_id);
453 fprintf(fd_nodes, "DELETE FROM relations WHERE id = %s;\n", attr_id);
454 break;
458 if (ywk != DELETE) {
459 if (ywk > NONE) {
460 fputs("INSERT INTO ", fd_nodes);
461 switch (current_tag) {
462 case NODE:
463 fputs("nodes_legacy", fd_nodes);
464 break;
465 case WAY:
466 fputs("ways", fd_nodes);
467 break;
468 case RELATION:
469 fputs("relations", fd_nodes);
470 break;
471 case ND:
472 fputs("way_nds", fd_nodes);
473 break;
474 case MEMBER:
475 fputs("members_", fd_nodes);
476 fputs(attr_type, fd_nodes);
477 break;
478 case TAG:
479 switch (parent_tag) {
480 case NODE:
481 fputs("node_tags", fd_nodes);
482 break;
483 case WAY:
484 fputs("way_tags", fd_nodes);
485 break;
486 case RELATION:
487 fputs("relation_tags", fd_nodes);
488 break;
490 break;
492 fputs(" VALUES (", fd_nodes);
495 switch (current_tag) {
496 case NODE:
497 fprintf(fd_nodes, "%s, %s, %s, %s, '%s'%s\n", attr_id, attr_lat, attr_lon, (attr_uid != NULL ? attr_uid : "0"), attr_timestamp, (ywk==NONE?"":");"));
498 #ifdef BENCHMARK
499 fprintf(fd_nodes_uint, "%s, %d, %d, %s, '%s'%s\n", attr_id, attr_lat_uint, attr_lon_uint, (attr_uid != NULL ? attr_uid : "0"), attr_timestamp, (ywk==NONE?"":");"));
500 fprintf(fd_nodes_gis, "%s, 'POINT( %s %s )', '%s', '%s'%s\n", attr_id, attr_lon, attr_lat, (attr_uid != NULL ? attr_uid : "0"), attr_timestamp, (ywk==NONE?"":");"));
501 #endif
502 count_nodes++;
503 break;
504 case TAG: {
505 switch (parent_tag) {
506 case NODE:
507 fprintf(fd_node_tags, "%s, '%s', '%s'%s\n", attr_id, attr_key, attr_value, (ywk==NONE?"":");"));
508 count_node_tags++;
509 break;
510 case WAY:
511 fprintf(fd_way_tags, "%s, '%s', '%s'%s\n", attr_id, attr_key, attr_value, (ywk==NONE?"":");"));
512 count_way_tags++;
513 break;
514 case RELATION:
515 fprintf(fd_relation_tags, "%s, '%s', '%s'%s\n", attr_id, attr_key, attr_value, (ywk==NONE?"":");"));
516 count_relation_tags++;
517 break;
518 default:
519 break;
521 break;
523 case WAY:
524 fprintf(fd_ways, "%s, %s, '%s'%s\n", attr_id, (attr_uid != NULL ? attr_uid : "0"), attr_timestamp, (ywk==NONE?"":");"));
525 count_ways++;
526 // fprintf(fd_way_tags, "%s, '%s', '%s'%s\n", attr_id, "type", "way", (ywk==NONE?"":");"));
527 // count_way_tags++;
528 break;
529 case RELATION:
530 fprintf(fd_relations, "%s, %s, '%s'%s\n", attr_id, (attr_uid != NULL ? attr_uid : "0"), attr_timestamp, (ywk==NONE?"":");"));
531 count_relations++;
532 break;
533 case MEMBER:
534 if (strcmp(attr_type, "node") == 0) {
535 fprintf(fd_members_node, "%s, %lu, %s, '%s'%s\n", attr_id, sequence, attr_ref, attr_role, (ywk==NONE?"":");"));
536 count_members_node++;
537 } else if (strcmp(attr_type, "way") == 0) {
538 fprintf(fd_members_way, "%s, %lu, %s, '%s'%s\n", attr_id, sequence, attr_ref, attr_role, (ywk==NONE?"":");"));
539 count_members_way++;
540 } else if (strcmp(attr_type, "relation") == 0) {
541 fprintf(fd_members_relation, "%s, %lu, %s, '%s'%s\n", attr_id, sequence, attr_ref, attr_role, (ywk==NONE?"":");"));
542 count_members_relation++;
544 sequence++;
545 break;
546 case ND:
547 fprintf(fd_way_nds, "%s, %lu, %s%s\n", attr_id, sequence, attr_ref, (ywk==NONE?"":");"));
548 sequence++;
549 count_way_nds++;
550 break;
551 default:
552 break;
558 if (end[-2] == '/') {
559 switch (current_tag) {
560 case NODE:
561 free(attr_lat);
562 free(attr_lon);
563 attr_lat = NULL;
564 attr_lon = NULL;
565 attr_lat_uint = 0;
566 attr_lon_uint = 0;
567 /* no break! */
569 case WAY:
570 case RELATION:
571 free(attr_id);
572 free(attr_timestamp);
573 free(attr_user);
574 free(attr_uid);
576 attr_id = attr_user = attr_uid = attr_timestamp = NULL;
578 sequence = 0;
579 break;
581 case TAG:
582 free(attr_key);
583 free(attr_value);
585 attr_key = NULL;
586 attr_value = NULL;
587 break;
589 case ND:
590 case MEMBER:
591 free(attr_type);
592 free(attr_ref);
593 free(attr_role);
595 attr_type = NULL;
596 attr_ref = NULL;
597 attr_role = NULL;
598 default:
599 break;
601 } else if (current_tag == NODE || current_tag == WAY || current_tag == RELATION) {
602 parent_tag = current_tag;
606 nextline;
607 } while (stopcondition);
608 exit:
610 free(attr_id);
611 free(attr_lat);
612 free(attr_lon);
613 free(attr_timestamp);
614 free(attr_user);
615 free(attr_uid);
617 free(attr_key);
618 free(attr_value);
620 fclose(fd_nodes);
621 #ifdef BENCHMARK
622 fclose(fd_nodes_uint);
623 fclose(fd_nodes_gis);
624 #endif
625 fclose(fd_node_tags);
626 fclose(fd_ways);
627 fclose(fd_way_tags);
628 fclose(fd_way_nds);
629 fclose(fd_relations);
630 fclose(fd_relation_tags);
631 fclose(fd_members_node);
632 fclose(fd_members_relation);
633 fclose(fd_members_way);
635 if (ywk == NONE) {
637 char *current = get_current_dir_name();
639 puts("START TRANSACTION;");
641 puts("CREATE TABLE nodes_legacy (id integer, long double, lat double, uid integer, timestamp timestamptz);");
642 #ifdef BENCHMARK
643 puts("CREATE TABLE nodes_legacy_uint (id integer, long integer, lat integer, uid integer, timestamp timestamptz);");
644 puts("CREATE TABLE nodes_legacy_gis (id integer, poi point, uid integer, timestamp timestamptz);");
645 #endif
646 puts("CREATE TABLE node_tags (node integer, k varchar(255), v varchar(1024));");
647 puts("CREATE TABLE ways (id integer,uid integer, timestamp timestamptz);");
648 puts("CREATE TABLE way_tags (way integer, k varchar(255), v varchar(1024));");
649 puts("CREATE TABLE way_nds (way integer, idx integer, to_node integer);");
650 puts("CREATE TABLE relations(id integer, uid integer, timestamp timestamptz);");
651 puts("CREATE TABLE relation_members_node (relation integer, idx integer, to_node integer, role varchar(255));");
652 puts("CREATE TABLE relation_members_relation (relation integer, idx integer, to_relation integer, role varchar(255));");
653 puts("CREATE TABLE relation_members_way (relation integer, idx integer, to_way integer, role varchar(255));");
654 puts("CREATE TABLE relation_tags (relation integer, k varchar(255), v varchar(1024));");
656 printf("COPY %lu RECORDS INTO nodes_legacy from '%s/" file_nodes "' USING DELIMITERS ',', '\\n', '''';\n", count_nodes, current);
657 #ifdef BENCHMARK
658 printf("COPY %lu RECORDS INTO nodes_legacy_uint from '%s/" file_nodes_uint "' USING DELIMITERS ',', '\\n', '''';\n", count_nodes, current);
659 printf("COPY %lu RECORDS INTO nodes_legacy_gis from '%s/" file_nodes_gis "' USING DELIMITERS ',', '\\n', '''';\n", count_nodes, current);
660 #endif
661 printf("COPY %lu RECORDS INTO node_tags from '%s/" file_node_tags "' USING DELIMITERS ',', '\\n', '''';\n", count_node_tags, current);
662 printf("COPY %lu RECORDS INTO ways from '%s/" file_ways "' USING DELIMITERS ',', '\\n', '''';\n", count_ways, current);
663 printf("COPY %lu RECORDS INTO way_tags from '%s/" file_way_tags "' USING DELIMITERS ',', '\\n', '''';\n", count_way_tags, current);
664 printf("COPY %lu RECORDS INTO way_nds from '%s/" file_way_nds "' USING DELIMITERS ',', '\\n', '''';\n", count_way_nds, current);
665 printf("COPY %lu RECORDS INTO relations from '%s/" file_relations "' USING DELIMITERS ',', '\\n', '''';\n", count_relations, current);
666 printf("COPY %lu RECORDS INTO relation_tags from '%s/" file_relation_tags "' USING DELIMITERS ',', '\\n', '''';\n", count_relation_tags, current);
667 printf("COPY %lu RECORDS INTO relation_members_node from '%s/" file_relation_member_node "' USING DELIMITERS ',', '\\n', '''';\n", count_members_node, current);
668 printf("COPY %lu RECORDS INTO relation_members_relation from '%s/" file_relation_member_relation "' USING DELIMITERS ',', '\\n', '''';\n", count_members_relation, current);
669 printf("COPY %lu RECORDS INTO relation_members_way from '%s/" file_relation_member_way "' USING DELIMITERS ',', '\\n', '''';\n", count_members_way, current);
671 free(current);
673 puts("COMMIT;");
675 puts("START TRANSACTION;");
677 puts("CREATE SEQUENCE s_nodes AS INTEGER;");
678 puts("ALTER SEQUENCE s_nodes RESTART WITH (SELECT MAX(id) FROM nodes_legacy);");
679 puts("ALTER TABLE nodes_legacy ALTER COLUMN id SET NOT NULL;");
680 puts("ALTER TABLE nodes_legacy ALTER COLUMN id SET DEFAULT NEXT VALUE FOR \"sys\".\"s_nodes\";");
681 puts("ALTER TABLE nodes_legacy ADD CONSTRAINT pk_nodes_id PRIMARY KEY (id);");
683 puts("CREATE SEQUENCE s_ways AS INTEGER;");
684 puts("ALTER SEQUENCE s_ways RESTART WITH (SELECT MAX(id) FROM ways);");
685 puts("ALTER TABLE ways ALTER COLUMN id SET NOT NULL;");
686 puts("ALTER TABLE ways ALTER COLUMN id SET DEFAULT NEXT VALUE FOR \"sys\".\"s_ways\";");
687 puts("ALTER TABLE ways ADD CONSTRAINT pk_ways_id PRIMARY KEY (id);");
689 puts("CREATE SEQUENCE s_relations AS INTEGER;");
690 puts("ALTER SEQUENCE s_relations RESTART WITH (SELECT MAX(id) FROM relations);");
691 puts("ALTER TABLE relations ALTER COLUMN id SET NOT NULL;");
692 puts("ALTER TABLE relations ALTER COLUMN id SET DEFAULT NEXT VALUE FOR \"sys\".\"s_relations\";");
693 puts("ALTER TABLE relations ADD CONSTRAINT pk_relations_id PRIMARY KEY (id);");
695 puts("ALTER TABLE relation_members_node ADD CONSTRAINT pk_relation_members_node PRIMARY KEY (relation, idx);");
696 puts("ALTER TABLE relation_members_way ADD CONSTRAINT pk_relation_members_way PRIMARY KEY (relation,idx);");
697 puts("ALTER TABLE relation_members_relation ADD CONSTRAINT pk_relation_members_relation PRIMARY KEY (relation,idx);");
699 puts("COMMIT;");
702 puts("START TRANSACTION;");
704 puts("ALTER TABLE node_tags ADD CONSTRAINT fk_node_tags_node FOREIGN KEY (node) REFERENCES nodes_legacy (id);");
705 puts("ALTER TABLE node_tags ADD CONSTRAINT pk_node_tags UNIQUE (node, k, v);");
707 puts("ALTER TABLE way_tags ADD CONSTRAINT fk_way_tags_way FOREIGN KEY (way) REFERENCES ways (id);");
708 puts("ALTER TABLE way_tags ADD CONSTRAINT pk_way_tags UNIQUE (way, k, v);");
710 puts("ALTER TABLE way_nds ADD CONSTRAINT pk_way_nds PRIMARY KEY (way, idx);");
711 puts("ALTER TABLE way_nds ADD CONSTRAINT fk_way_nds_way FOREIGN KEY (way) REFERENCES ways (id);");
712 puts("ALTER TABLE way_nds ADD CONSTRAINT fk_way_nds_node FOREIGN KEY (to_node) REFERENCES nodes_legacy (id);");
714 puts("ALTER TABLE relation_tags ADD CONSTRAINT fk_relation_tags FOREIGN KEY (relation) REFERENCES relations (id);");
715 puts("ALTER TABLE relation_tags ADD CONSTRAINT pk_relation_tags UNIQUE (relation, k, v);");
717 puts("ALTER TABLE relation_members_node ADD CONSTRAINT fk_relation_members_node FOREIGN KEY (relation) REFERENCES relations (id);");
718 puts("ALTER TABLE relation_members_node ADD CONSTRAINT fk_relation_members_tonode FOREIGN KEY (to_node) REFERENCES nodes_legacy (id);");
720 puts("ALTER TABLE relation_members_way ADD CONSTRAINT fk_relation_members_way FOREIGN KEY (relation) REFERENCES relations (id);");
721 puts("ALTER TABLE relation_members_way ADD CONSTRAINT fk_relation_members_toway FOREIGN KEY (to_way) REFERENCES ways (id);");
723 puts("ALTER TABLE relation_members_relation ADD CONSTRAINT fk_relation_members_relation FOREIGN KEY (relation) REFERENCES relations (id);");
724 puts("ALTER TABLE relation_members_relation ADD CONSTRAINT fk_relation_members_torelation FOREIGN KEY (to_relation) REFERENCES relations (id);");
727 puts("COMMIT;");
732 int main(int argc, char *argv[]) {
733 #ifdef MMAP
734 int fd;
735 struct stat statbuf;
737 if (argc != 2)
738 exit(-1);
740 fprintf(stderr, "Analysing %s...\n", argv[1]);
742 fd = open(argv[1], O_RDONLY);
744 if (fd < 0)
745 exit(-1);
747 if (fstat (fd, &statbuf) == -1) { perror("fstat:"); exit(-1); }
749 if (statbuf.st_size > 0) {
750 char *range = NULL;
751 range = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, (off_t) 0);
752 if (range == MAP_FAILED) { perror("Mmap:"); puts("(did you compile PAE in the kernel?)"); exit(-1); }
753 parser(range, statbuf.st_size / sizeof(char));
754 munmap(range, statbuf.st_size);
757 close(fd);
758 #else
759 parser();
760 #endif
761 exit(0);