1 /*
2
3 shapefiles.c -- implements shapefile support [import - export]
4
5 version 5.0, 2020 August 1
6
7 Author: Sandro Furieri a.furieri@lqt.it
8
9 -----------------------------------------------------------------------------
10
11 Version: MPL 1.1/GPL 2.0/LGPL 2.1
12
13 The contents of this file are subject to the Mozilla Public License Version
14 1.1 (the "License"); you may not use this file except in compliance with
15 the License. You may obtain a copy of the License at
16 http://www.mozilla.org/MPL/
17
18 Software distributed under the License is distributed on an "AS IS" basis,
19 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
20 for the specific language governing rights and limitations under the
21 License.
22
23 The Original Code is the SpatiaLite library
24
25 The Initial Developer of the Original Code is Alessandro Furieri
26
27 Portions created by the Initial Developer are Copyright (C) 2008-2021
28 the Initial Developer. All Rights Reserved.
29
30 Contributor(s): Brad Hards <bradh@frogmouth.net>
31
32 Alternatively, the contents of this file may be used under the terms of
33 either the GNU General Public License Version 2 or later (the "GPL"), or
34 the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
35 in which case the provisions of the GPL or the LGPL are applicable instead
36 of those above. If you wish to allow use of your version of this file only
37 under the terms of either the GPL or the LGPL, and not to allow others to
38 use your version of this file under the terms of the MPL, indicate your
39 decision by deleting the provisions above and replace them with the notice
40 and other provisions required by the GPL or the LGPL. If you do not delete
41 the provisions above, a recipient may use your version of this file under
42 the terms of any one of the MPL, the GPL or the LGPL.
43
44 */
45
46 #if defined(_WIN32) && !defined(__MINGW32__)
47 /* MSVC strictly requires this include [off_t] */
48 #include <sys/types.h>
49 #endif
50
51 #include <stdlib.h>
52 #include <stdio.h>
53 #include <string.h>
54 #include <math.h>
55 #include <float.h>
56
57 #if defined(_WIN32) && !defined(__MINGW32__)
58 #include "config-msvc.h"
59 #else
60 #include "config.h"
61 #endif
62
63 #include <spatialite/sqlite.h>
64 #include <spatialite/debug.h>
65
66 #include <spatialite/gaiaaux.h>
67 #include <spatialite/gaiageo.h>
68 #include <spatialite.h>
69 #include <spatialite_private.h>
70 #include <spatialite/geojson.h>
71
72 #ifndef OMIT_FREEXL
73 #include <freexl.h>
74 #endif
75
76 #ifndef OMIT_PROJ /* including PROJ */
77 #ifdef PROJ_NEW /* supporting PROJ.6 */
78 #include <proj.h>
79 #endif
80 #endif
81
82 #ifdef ENABLE_MINIZIP /* MINIZIP is enabled */
83 #include <minizip/unzip.h>
84 #endif
85
86 #if defined(_WIN32) && !defined(__MINGW32__)
87 #define strcasecmp _stricmp
88 #define strncasecmp _strnicmp
89 #endif
90
91 /* 64 bit integer: portable format for printf() */
92 #if defined(_WIN32) && !defined(__MINGW32__)
93 #define FRMT64 "%I64d"
94 #else
95 #define FRMT64 "%lld"
96 #endif
97
98 #define GAIA_ZIPFILE_SHP 1
99 #define GAIA_ZIPFILE_SHX 2
100 #define GAIA_ZIPFILE_DBF 3
101 #define GAIA_ZIPFILE_PRJ 4
102
103 struct auxdbf_fld
104 {
105 /* auxiliary DBF field struct */
106 char already_used;
107 gaiaDbfFieldPtr dbf_field;
108 struct auxdbf_fld *next;
109 };
110
111 struct auxdbf_list
112 {
113 /* auxiliary DBF struct */
114 struct auxdbf_fld *first;
115 struct auxdbf_fld *last;
116 };
117
118 struct resultset_values
119 {
120 /* a struct wrapping values from a resultset */
121 int type;
122 sqlite3_int64 int_value;
123 double dbl_value;
124 unsigned char *txt_blob_value;
125 int txt_blob_size;
126 };
127
128 struct resultset_comparator
129 {
130 /* object for comparing two rows of the same resultset */
131 struct resultset_values *previous;
132 struct resultset_values *current;
133 int num_columns;
134 sqlite3_int64 previous_rowid;
135 sqlite3_int64 current_rowid;
136 };
137
138 struct aux_elemgeom_ignore
139 {
140 /* an Elementary Geometries Ignore option */
141 char *column;
142 struct aux_elemgeom_ignore *next;
143 };
144
145 struct aux_elemgeom_options
146 {
147 /* Elementary Geometries Options */
148 struct aux_elemgeom_ignore *first;
149 struct aux_elemgeom_ignore *last;
150 int cast2multi;
151 };
152
153 struct zip_mem_shapefile
154 {
155 /* a struct wrapping a Memory Shapefile from Zipfile */
156 gaiaMemFile shp;
157 gaiaMemFile shx;
158 gaiaMemFile dbf;
159 gaiaMemFile prj;
160 };
161
162 struct zip_mem_shp_item
163 {
164 /* a Shapefile within a Zipfile */
165 char *basename;
166 int shp;
167 int shx;
168 int dbf;
169 int prj;
170 struct zip_mem_shp_item *next;
171 };
172
173 struct zip_mem_shp_list
174 {
175 /* a list of Shapefiles within a Zipfile */
176 struct zip_mem_shp_item *first;
177 struct zip_mem_shp_item *last;
178 };
179
180 SPATIALITE_PRIVATE const void *
gaiaElemGeomOptionsCreate()181 gaiaElemGeomOptionsCreate ()
182 {
183 /* creating an Elementary Geometries Options object */
184 struct aux_elemgeom_options *options =
185 malloc (sizeof (struct aux_elemgeom_options));
186 options->first = NULL;
187 options->last = NULL;
188 options->cast2multi = 0;
189 return options;
190 }
191
192 SPATIALITE_PRIVATE void
gaiaElemGeomOptionsDestroy(const void * opts)193 gaiaElemGeomOptionsDestroy (const void *opts)
194 {
195 /* destroying an Elementary Geometries Options object */
196 struct aux_elemgeom_ignore *ign;
197 struct aux_elemgeom_ignore *ign2;
198 struct aux_elemgeom_options *options = (struct aux_elemgeom_options *) opts;
199 if (options == NULL)
200 return;
201
202 ign = options->first;
203 while (ign != NULL)
204 {
205 ign2 = ign->next;
206 if (ign->column != NULL)
207 free (ign->column);
208 free (ign);
209 ign = ign2;
210 }
211 free (options);
212 }
213
214 static void
ignore_column(struct aux_elemgeom_options * options,const char * column)215 ignore_column (struct aux_elemgeom_options *options, const char *column)
216 {
217 /* marking a Column to be ignored */
218 int len;
219 struct aux_elemgeom_ignore *ign;
220 if (options == NULL)
221 return;
222
223 ign = malloc (sizeof (struct aux_elemgeom_ignore));
224 len = strlen (column);
225 ign->column = malloc (len + 1);
226 strcpy (ign->column, column);
227 ign->next = NULL;
228
229 if (options->first == NULL)
230 options->first = ign;
231 if (options->last != NULL)
232 options->last->next = ign;
233 options->last = ign;
234 }
235
236 SPATIALITE_PRIVATE void
gaiaElemGeomOptionsAdd(const void * opts,const char * option)237 gaiaElemGeomOptionsAdd (const void *opts, const char *option)
238 {
239 /* adding an Elementary Geometries Option */
240 struct aux_elemgeom_options *options = (struct aux_elemgeom_options *) opts;
241 if (options == NULL)
242 return;
243
244 if (strncasecmp (option, "::cast2multi::", 14) == 0)
245 options->cast2multi = 1;
246 if (strncasecmp (option, "::ignore::", 10) == 0)
247 ignore_column (options, option + 10);
248 }
249
250 static struct resultset_comparator *
create_resultset_comparator(int columns)251 create_resultset_comparator (int columns)
252 {
253 /* creating an empty resultset comparator object */
254 int i;
255 struct resultset_comparator *p =
256 malloc (sizeof (struct resultset_comparator));
257 p->num_columns = columns;
258 p->previous_rowid = -1;
259 p->current_rowid = -1;
260 p->previous = malloc (sizeof (struct resultset_values) * columns);
261 p->current = malloc (sizeof (struct resultset_values) * columns);
262 for (i = 0; i < columns; i++)
263 {
264 struct resultset_values *value = p->previous + i;
265 value->type = SQLITE_NULL;
266 value->txt_blob_value = NULL;
267 value = p->current + i;
268 value->type = SQLITE_NULL;
269 value->txt_blob_value = NULL;
270 }
271 return p;
272 }
273
274 static void
destroy_resultset_comparator(struct resultset_comparator * ptr)275 destroy_resultset_comparator (struct resultset_comparator *ptr)
276 {
277 /* memory cleanup - destroying a resultset comparator object */
278 int i;
279 if (ptr == NULL)
280 return;
281 for (i = 0; i < ptr->num_columns; i++)
282 {
283 struct resultset_values *value = ptr->previous + i;
284 if (value->txt_blob_value != NULL)
285 free (value->txt_blob_value);
286 value = ptr->current + i;
287 if (value->txt_blob_value != NULL)
288 free (value->txt_blob_value);
289 }
290 if (ptr->previous != NULL)
291 free (ptr->previous);
292 if (ptr->current != NULL)
293 free (ptr->current);
294 free (ptr);
295 }
296
297 static void
save_row_from_resultset(struct resultset_comparator * ptr,sqlite3_stmt * stmt)298 save_row_from_resultset (struct resultset_comparator *ptr, sqlite3_stmt * stmt)
299 {
300 /* saving the current row values */
301 int i;
302 int size;
303 const unsigned char *p;
304 if (ptr == NULL)
305 return;
306 ptr->current_rowid = sqlite3_column_int64 (stmt, 0);
307 for (i = 0; i < ptr->num_columns; i++)
308 {
309 struct resultset_values *value = ptr->current + i;
310 value->type = sqlite3_column_type (stmt, i + 1);
311 switch (value->type)
312 {
313 case SQLITE_INTEGER:
314 value->int_value = sqlite3_column_int64 (stmt, i + 1);
315 break;
316 case SQLITE_FLOAT:
317 value->dbl_value = sqlite3_column_double (stmt, i + 1);
318 break;
319 case SQLITE_TEXT:
320 p = sqlite3_column_text (stmt, i + 1);
321 size = strlen ((const char *) p);
322 value->txt_blob_value = malloc (size + 1);
323 strcpy ((char *) (value->txt_blob_value), (const char *) p);
324 break;
325 case SQLITE_BLOB:
326 p = sqlite3_column_blob (stmt, i + 1);
327 size = sqlite3_column_bytes (stmt, i + 1);
328 value->txt_blob_value = malloc (size);
329 memcpy (value->txt_blob_value, p, size);
330 value->txt_blob_size = size;
331 break;
332 };
333 }
334 }
335
336 static int
resultset_rows_equals(struct resultset_comparator * ptr)337 resultset_rows_equals (struct resultset_comparator *ptr)
338 {
339 /* comparing the current and previous row from the resultset */
340 int i;
341 if (ptr == NULL)
342 return 0;
343 for (i = 0; i < ptr->num_columns; i++)
344 {
345 struct resultset_values *val_prev = ptr->previous + i;
346 struct resultset_values *val_curr = ptr->current + i;
347 if (val_prev->type != val_curr->type)
348 return 0;
349 switch (val_prev->type)
350 {
351 case SQLITE_INTEGER:
352 if (val_prev->int_value != val_curr->int_value)
353 return 0;
354 break;
355 case SQLITE_FLOAT:
356 if (val_prev->dbl_value != val_curr->dbl_value)
357 return 0;
358 break;
359 case SQLITE_TEXT:
360 if (strcmp
361 ((const char *) (val_prev->txt_blob_value),
362 (const char *) (val_curr->txt_blob_value)) != 0)
363 return 0;
364 break;
365 case SQLITE_BLOB:
366 if (val_prev->txt_blob_size != val_curr->txt_blob_size)
367 return 0;
368 if (memcmp
369 (val_prev->txt_blob_value, val_curr->txt_blob_value,
370 val_curr->txt_blob_size) != 0)
371 return 0;
372 break;
373 };
374 }
375 return 1;
376 }
377
378 static sqlite3_int64
get_current_resultset_rowid(struct resultset_comparator * ptr)379 get_current_resultset_rowid (struct resultset_comparator *ptr)
380 {
381 /* returns the current ROWID */
382 if (ptr == NULL)
383 return -1;
384 return ptr->current_rowid;
385 }
386
387 static void
reset_resultset_current_row(struct resultset_comparator * ptr)388 reset_resultset_current_row (struct resultset_comparator *ptr)
389 {
390 /* resetting the resultset current row values */
391 int i;
392 if (ptr == NULL)
393 return;
394 ptr->current_rowid = -1;
395 for (i = 0; i < ptr->num_columns; i++)
396 {
397 struct resultset_values *value = ptr->current + i;
398 value->type = SQLITE_NULL;
399 if (value->txt_blob_value != NULL)
400 free (value->txt_blob_value);
401 value->txt_blob_value = NULL;
402 }
403 }
404
405 static void
swap_resultset_rows(struct resultset_comparator * ptr)406 swap_resultset_rows (struct resultset_comparator *ptr)
407 {
408 /* resetting the resultset comparator */
409 int i;
410 if (ptr == NULL)
411 return;
412 ptr->previous_rowid = ptr->current_rowid;
413 ptr->current_rowid = -1;
414 for (i = 0; i < ptr->num_columns; i++)
415 {
416 struct resultset_values *val_prev = ptr->previous + i;
417 struct resultset_values *val_curr = ptr->current + i;
418 if (val_prev->txt_blob_value != NULL)
419 free (val_prev->txt_blob_value);
420 val_prev->type = val_curr->type;
421 val_prev->int_value = val_curr->int_value;
422 val_prev->dbl_value = val_curr->dbl_value;
423 val_prev->txt_blob_value = val_curr->txt_blob_value;
424 val_prev->txt_blob_size = val_curr->txt_blob_size;
425 val_curr->type = SQLITE_NULL;
426 val_curr->txt_blob_value = NULL;
427 }
428 }
429
430 #ifndef OMIT_ICONV /* ICONV enabled: supporting SHP */
431
432 static struct auxdbf_list *
alloc_auxdbf(gaiaDbfListPtr dbf_list)433 alloc_auxdbf (gaiaDbfListPtr dbf_list)
434 {
435 /* allocating the auxiliary DBF struct */
436 gaiaDbfFieldPtr fld;
437 struct auxdbf_fld *fld_ex;
438 struct auxdbf_list *auxdbf = malloc (sizeof (struct auxdbf_list));
439 auxdbf->first = NULL;
440 auxdbf->last = NULL;
441 fld = dbf_list->First;
442 while (fld)
443 {
444 fld_ex = malloc (sizeof (struct auxdbf_fld));
445 fld_ex->already_used = 0;
446 fld_ex->dbf_field = fld;
447 fld_ex->next = NULL;
448 if (auxdbf->first == NULL)
449 auxdbf->first = fld_ex;
450 if (auxdbf->last != NULL)
451 auxdbf->last->next = fld_ex;
452 auxdbf->last = fld_ex;
453 fld = fld->Next;
454 }
455 return auxdbf;
456 }
457
458 static void
free_auxdbf(struct auxdbf_list * auxdbf)459 free_auxdbf (struct auxdbf_list *auxdbf)
460 {
461 /* freeing an auxiliary DBF struct */
462 struct auxdbf_fld *n_fld;
463 struct auxdbf_fld *fld = auxdbf->first;
464 while (fld != NULL)
465 {
466 n_fld = fld->next;
467 free (fld);
468 fld = n_fld;
469 }
470 free (auxdbf);
471 }
472
473 static gaiaDbfFieldPtr
getDbfField(struct auxdbf_list * aux,char * name)474 getDbfField (struct auxdbf_list *aux, char *name)
475 {
476 /* find a DBF attribute by name */
477 struct auxdbf_fld *fld = aux->first;
478 while (fld)
479 {
480 if (strcasecmp (fld->dbf_field->Name, name) == 0)
481 {
482 fld->already_used = 1;
483 return fld->dbf_field;
484 }
485 fld = fld->next;
486 }
487 fld = aux->first;
488 while (fld)
489 {
490 if (fld->already_used)
491 {
492 fld = fld->next;
493 continue;
494 }
495 if (strncasecmp (fld->dbf_field->Name, name, 9) == 0)
496 {
497 fld->already_used = 1;
498 return fld->dbf_field;
499 }
500 fld = fld->next;
501 }
502 return NULL;
503 }
504
505 static int
do_check_shp_unique_pk_values(sqlite3 * sqlite,gaiaShapefilePtr shp,int srid,int text_dates,const char * pk_name,int pk_type)506 do_check_shp_unique_pk_values (sqlite3 * sqlite, gaiaShapefilePtr shp, int srid,
507 int text_dates, const char *pk_name, int pk_type)
508 {
509 /* checking for duplicate PK values */
510 char *sql;
511 sqlite3_stmt *stmt = NULL;
512 gaiaDbfFieldPtr dbf_field;
513 int ret;
514 int duplicates = 0;
515 int current_row = 0;
516
517 sql = "CREATE TABLE TEMP.check_unique_pk (pkey ANYVALUE)";
518 ret = sqlite3_exec (sqlite, sql, NULL, NULL, NULL);
519 if (ret != SQLITE_OK)
520 return 0;
521
522 sql = "INSERT INTO TEMP.check_unique_pk (pkey) VALUES (?)";
523 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
524 if (ret != SQLITE_OK)
525 goto error;
526
527 sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
528
529 while (1)
530 {
531 /* reading rows from shapefile */
532 int ok_insert = 0;
533 ret = gaiaReadShpEntity_ex (shp, current_row, srid, text_dates);
534 if (ret < 0)
535 {
536 /* found a DBF deleted record */
537 current_row++;
538 continue;
539 }
540 if (!ret)
541 break;
542 current_row++;
543 /* binding query params */
544 sqlite3_reset (stmt);
545 sqlite3_clear_bindings (stmt);
546 dbf_field = shp->Dbf->First;
547 while (dbf_field)
548 {
549 /* Primary Key value */
550 if (strcasecmp (pk_name, dbf_field->Name) == 0)
551 {
552 if (pk_type == SQLITE_TEXT)
553 {
554 ok_insert = 1;
555 sqlite3_bind_text (stmt, 1,
556 dbf_field->Value->TxtValue,
557 strlen (dbf_field->
558 Value->TxtValue),
559 SQLITE_STATIC);
560 }
561 else if (pk_type == SQLITE_FLOAT)
562 {
563 ok_insert = 1;
564 sqlite3_bind_double (stmt, 1,
565 dbf_field->Value->DblValue);
566 }
567 else
568 {
569 ok_insert = 1;
570 sqlite3_bind_int64 (stmt, 1,
571 dbf_field->Value->IntValue);
572 }
573 }
574 dbf_field = dbf_field->Next;
575 }
576 if (ok_insert)
577 {
578 ret = sqlite3_step (stmt);
579 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
580 ;
581 else
582 goto error;
583 }
584 }
585 sqlite3_finalize (stmt);
586 stmt = NULL;
587 sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
588
589 sql = "SELECT Count(*) FROM TEMP.check_unique_pk GROUP BY pkey";
590 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
591 if (ret != SQLITE_OK)
592 goto error;
593
594 while (1)
595 {
596 /* scrolling the result set rows */
597 ret = sqlite3_step (stmt);
598 if (ret == SQLITE_DONE)
599 break; /* end of result set */
600 if (ret == SQLITE_ROW)
601 {
602 if (sqlite3_column_int (stmt, 0) > 1)
603 duplicates = 1;
604 }
605 }
606 sqlite3_finalize (stmt);
607
608 sqlite3_exec (sqlite, "DROP TABLE TEMP.check_unique_pk", NULL, NULL, NULL);
609 if (duplicates)
610 return 0;
611 else
612 return 1;
613
614 error:
615 if (stmt != NULL)
616 sqlite3_finalize (stmt);
617 sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
618 sqlite3_exec (sqlite, "DROP TABLE TEMP.check_unique_pk", NULL, NULL, NULL);
619 return 0;
620 }
621
622 static char *
convert_dbf_colname_case(const char * buf,int colname_case)623 convert_dbf_colname_case (const char *buf, int colname_case)
624 {
625 /* converts a DBF column-name to Lower- or Upper-case */
626 int len = strlen (buf);
627 char *clean = malloc (len + 1);
628 char *p = clean;
629 strcpy (clean, buf);
630 while (*p != '\0')
631 {
632 if (colname_case == GAIA_DBF_COLNAME_LOWERCASE)
633 {
634 if (*p >= 'A' && *p <= 'Z')
635 *p = *p - 'A' + 'a';
636 }
637 if (colname_case == GAIA_DBF_COLNAME_UPPERCASE)
638 {
639 if (*p >= 'a' && *p <= 'z')
640 *p = *p - 'a' + 'A';
641 }
642 p++;
643 }
644 return clean;
645 }
646
647 SPATIALITE_DECLARE int
load_shapefile(sqlite3 * sqlite,char * shp_path,char * table,char * charset,int srid,char * column,int coerce2d,int compressed,int verbose,int spatial_index,int * rows,char * err_msg)648 load_shapefile (sqlite3 * sqlite, char *shp_path, char *table, char *charset,
649 int srid, char *column, int coerce2d, int compressed,
650 int verbose, int spatial_index, int *rows, char *err_msg)
651 {
652 return load_shapefile_ex (sqlite, shp_path, table, charset, srid, column,
653 NULL, NULL, coerce2d, compressed, verbose,
654 spatial_index, rows, err_msg);
655 }
656
657 SPATIALITE_DECLARE int
load_shapefile_ex(sqlite3 * sqlite,char * shp_path,char * table,char * charset,int srid,char * g_column,char * gtype,char * pk_column,int coerce2d,int compressed,int verbose,int spatial_index,int * rows,char * err_msg)658 load_shapefile_ex (sqlite3 * sqlite, char *shp_path, char *table,
659 char *charset, int srid, char *g_column, char *gtype,
660 char *pk_column, int coerce2d, int compressed, int verbose,
661 int spatial_index, int *rows, char *err_msg)
662 {
663 return load_shapefile_ex2 (sqlite, shp_path, table, charset, srid, g_column,
664 gtype, pk_column, coerce2d, compressed, verbose,
665 spatial_index, 0, rows, err_msg);
666 }
667
668 SPATIALITE_DECLARE int
load_shapefile_ex2(sqlite3 * sqlite,char * shp_path,char * table,char * charset,int srid,char * g_column,char * gtype,char * pk_column,int coerce2d,int compressed,int verbose,int spatial_index,int text_dates,int * rows,char * err_msg)669 load_shapefile_ex2 (sqlite3 * sqlite, char *shp_path, char *table,
670 char *charset, int srid, char *g_column, char *gtype,
671 char *pk_column, int coerce2d, int compressed,
672 int verbose, int spatial_index, int text_dates, int *rows,
673 char *err_msg)
674 {
675 return load_shapefile_ex3 (sqlite, shp_path, table, charset, srid, g_column,
676 gtype, pk_column, coerce2d, compressed, verbose,
677 spatial_index, text_dates, rows,
678 GAIA_DBF_COLNAME_LOWERCASE, err_msg);
679 }
680
681 static int
load_shapefile_common(struct zip_mem_shapefile * mem_shape,sqlite3 * sqlite,const char * shp_path,const char * table,const char * charset,int srid,const char * g_column,const char * gtype,const char * pk_column,int coerce2d,int compressed,int verbose,int spatial_index,int text_dates,int * rows,int colname_case,char * err_msg)682 load_shapefile_common (struct zip_mem_shapefile *mem_shape, sqlite3 * sqlite,
683 const char *shp_path, const char *table,
684 const char *charset, int srid, const char *g_column,
685 const char *gtype, const char *pk_column, int coerce2d,
686 int compressed, int verbose, int spatial_index,
687 int text_dates, int *rows, int colname_case,
688 char *err_msg)
689 {
690 sqlite3_stmt *stmt = NULL;
691 int ret;
692 char *errMsg = NULL;
693 char *sql;
694 char *dummy;
695 int already_exists = 0;
696 int metadata = 0;
697 int sqlError = 0;
698 gaiaShapefilePtr shp = NULL;
699 gaiaDbfFieldPtr dbf_field;
700 int cnt;
701 int col_cnt = 0;
702 int seed;
703 int len;
704 int dup;
705 int idup;
706 int current_row = 0;
707 int deleted = 0;
708 char **col_name = NULL;
709 unsigned char *blob;
710 int blob_size;
711 char *geom_type = NULL;
712 char *txt_dims;
713 const char *geo_column = g_column;
714 const char *xgtype = gtype;
715 char *qtable = NULL;
716 char *qpk_name = NULL;
717 const char *pk_name = NULL;
718 char *casename;
719 int pk_autoincr = 1;
720 char *xname;
721 int pk_type = SQLITE_INTEGER;
722 int pk_set;
723 const char *alt_pk[10] =
724 { "PK_ALT0", "PK_ALT1", "PK_ALT2", "PK_ALT3", "PK_ALT4", "PK_ALT5",
725 "PK_ALT6", "PK_ALT7", "PK_ALT8", "PK_ALT9"
726 };
727 gaiaOutBuffer sql_statement;
728 if (!geo_column)
729 geo_column = "Geometry";
730 if (rows)
731 *rows = -1;
732 if (!xgtype)
733 ;
734 else
735 {
736 if (strcasecmp (xgtype, "LINESTRING") == 0)
737 xgtype = "LINESTRING";
738 else if (strcasecmp (xgtype, "LINESTRINGZ") == 0)
739 xgtype = "LINESTRINGZ";
740 else if (strcasecmp (xgtype, "LINESTRINGM") == 0)
741 xgtype = "LINESTRINGM";
742 else if (strcasecmp (xgtype, "LINESTRINGZM") == 0)
743 xgtype = "LINESTRINGZM";
744 else if (strcasecmp (xgtype, "MULTILINESTRING") == 0)
745 xgtype = "MULTILINESTRING";
746 else if (strcasecmp (xgtype, "MULTILINESTRINGZ") == 0)
747 xgtype = "MULTILINESTRINGZ";
748 else if (strcasecmp (xgtype, "MULTILINESTRINGM") == 0)
749 xgtype = "MULTILINESTRINGM";
750 else if (strcasecmp (xgtype, "MULTILINESTRINGZM") == 0)
751 xgtype = "MULTILINESTRINGZM";
752 else if (strcasecmp (xgtype, "POLYGON") == 0)
753 xgtype = "POLYGON";
754 else if (strcasecmp (xgtype, "POLYGONZ") == 0)
755 xgtype = "POLYGONZ";
756 else if (strcasecmp (xgtype, "POLYGONM") == 0)
757 xgtype = "POLYGONM";
758 else if (strcasecmp (xgtype, "POLYGONZM") == 0)
759 xgtype = "POLYGONZM";
760 else if (strcasecmp (xgtype, "MULTIPOLYGON") == 0)
761 xgtype = "MULTIPOLYGON";
762 else if (strcasecmp (xgtype, "MULTIPOLYGONZ") == 0)
763 xgtype = "MULTIPOLYGONZ";
764 else if (strcasecmp (xgtype, "MULTIPOLYGONM") == 0)
765 xgtype = "MULTIPOLYGONM";
766 else if (strcasecmp (xgtype, "MULTIPOLYGONZM") == 0)
767 xgtype = "MULTIPOLYGONZM";
768 else
769 xgtype = NULL;
770 }
771 qtable = gaiaDoubleQuotedSql (table);
772 /* checking if TABLE already exists */
773 sql =
774 sqlite3_mprintf ("SELECT name FROM sqlite_master WHERE type = 'table' "
775 "AND Lower(name) = Lower(%Q)", table);
776 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
777 sqlite3_free (sql);
778 if (ret != SQLITE_OK)
779 {
780 if (!err_msg)
781 spatialite_e ("load shapefile error: <%s>\n",
782 sqlite3_errmsg (sqlite));
783 else
784 sprintf (err_msg, "load shapefile error: <%s>\n",
785 sqlite3_errmsg (sqlite));
786 goto clean_up;
787 }
788 while (1)
789 {
790 /* scrolling the result set */
791 ret = sqlite3_step (stmt);
792 if (ret == SQLITE_DONE)
793 break; /* end of result set */
794 if (ret == SQLITE_ROW)
795 already_exists = 1;
796 else
797 {
798 spatialite_e ("load shapefile error: <%s>\n",
799 sqlite3_errmsg (sqlite));
800 break;
801 }
802 }
803 sqlite3_finalize (stmt);
804 if (already_exists)
805 {
806 if (!err_msg)
807 spatialite_e ("load shapefile error: table '%s' already exists\n",
808 table);
809 else
810 sprintf (err_msg,
811 "load shapefile error: table '%s' already exists\n",
812 table);
813 if (qtable)
814 free (qtable);
815 if (qpk_name)
816 free (qpk_name);
817 return 0;
818 }
819 /* checking if MetaData GEOMETRY_COLUMNS exists */
820 sql =
821 "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'geometry_columns'";
822 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
823 if (ret != SQLITE_OK)
824 {
825 if (!err_msg)
826 spatialite_e ("load shapefile error: <%s>\n",
827 sqlite3_errmsg (sqlite));
828 else
829 sprintf (err_msg, "load shapefile error: <%s>\n",
830 sqlite3_errmsg (sqlite));
831 if (qtable)
832 free (qtable);
833 if (qpk_name)
834 free (qpk_name);
835 return 0;
836 }
837 while (1)
838 {
839 /* scrolling the result set */
840 ret = sqlite3_step (stmt);
841 if (ret == SQLITE_DONE)
842 break; /* end of result set */
843 if (ret == SQLITE_ROW)
844 metadata = 1;
845 else
846 {
847 spatialite_e ("load shapefile error: <%s>\n",
848 sqlite3_errmsg (sqlite));
849 break;
850 }
851 }
852 sqlite3_finalize (stmt);
853 shp = gaiaAllocShapefile ();
854 if (mem_shape != NULL)
855 {
856 /* initializing Memory based files */
857 shp->memShx = &(mem_shape->shx);
858 shp->memShp = &(mem_shape->shp);
859 shp->memDbf = &(mem_shape->dbf);
860 }
861 gaiaOpenShpRead (shp, shp_path, charset, "UTF-8");
862 if (!(shp->Valid))
863 {
864 if (!err_msg)
865 {
866 spatialite_e
867 ("load shapefile error: cannot open shapefile '%s'\n",
868 shp_path);
869 if (shp->LastError)
870 spatialite_e ("\tcause: %s\n", shp->LastError);
871 }
872 else
873 {
874 char extra[512];
875 *extra = '\0';
876 if (shp->LastError)
877 sprintf (extra, "\n\tcause: %s\n", shp->LastError);
878 sprintf (err_msg,
879 "load shapefile error: cannot open shapefile '%s'%s",
880 shp_path, extra);
881 }
882 gaiaFreeShapefile (shp);
883 if (qtable)
884 free (qtable);
885 if (qpk_name)
886 free (qpk_name);
887 return 0;
888 }
889 /* checking for duplicate / illegal column names and antialising them */
890 col_cnt = 0;
891 dbf_field = shp->Dbf->First;
892 while (dbf_field)
893 {
894 /* counting DBF fields */
895 col_cnt++;
896 dbf_field = dbf_field->Next;
897 }
898 col_name = malloc (sizeof (char *) * col_cnt);
899 cnt = 0;
900 seed = 0;
901 if (pk_column != NULL)
902 {
903 /* validating the Primary Key column */
904 dbf_field = shp->Dbf->First;
905 while (dbf_field)
906 {
907 if (strcasecmp (pk_column, dbf_field->Name) == 0)
908 {
909 /* ok, using this field as Primary Key */
910 pk_name = pk_column;
911 pk_autoincr = 0;
912 switch (dbf_field->Type)
913 {
914 case 'C':
915 pk_type = SQLITE_TEXT;
916 break;
917 case 'N':
918 if (dbf_field->Decimals)
919 pk_type = SQLITE_FLOAT;
920 else
921 {
922 if (dbf_field->Length <= 18)
923 pk_type = SQLITE_INTEGER;
924 else
925 pk_type = SQLITE_FLOAT;
926 }
927 break;
928 case 'D':
929 if (text_dates)
930 pk_type = SQLITE_TEXT;
931 else
932 pk_type = SQLITE_FLOAT;
933 break;
934 case 'F':
935 pk_type = SQLITE_FLOAT;
936 break;
937 case 'L':
938 pk_type = SQLITE_INTEGER;
939 break;
940 };
941 }
942 dbf_field = dbf_field->Next;
943 }
944 }
945 if (pk_name == NULL)
946 {
947 if (pk_column != NULL)
948 pk_name = pk_column;
949 else
950 pk_name = "PK_UID";
951 }
952 if (!do_check_shp_unique_pk_values
953 (sqlite, shp, srid, text_dates, pk_name, pk_type))
954 {
955 const char *old_pk = pk_name;
956 int antialias;
957 for (antialias = 0; antialias < 10; antialias++)
958 {
959 /* searching an alternative Primary Key column name */
960 int found = 0;
961 pk_name = alt_pk[antialias];
962 dbf_field = shp->Dbf->First;
963 while (dbf_field)
964 {
965 if (strcasecmp (pk_name, dbf_field->Name) == 0)
966 found = 1;
967 dbf_field = dbf_field->Next;
968 }
969 if (!found)
970 {
971 pk_autoincr = 1;
972 goto ok_pk;
973 }
974 }
975 pk_name = old_pk;
976 }
977 ok_pk:
978 casename = convert_dbf_colname_case (pk_name, colname_case);
979 qpk_name = gaiaDoubleQuotedSql (casename);
980 free (casename);
981 dbf_field = shp->Dbf->First;
982 while (dbf_field)
983 {
984 /* preparing column names */
985 char *xdummy = NULL;
986 if (strcasecmp (pk_name, dbf_field->Name) == 0)
987 {
988 /* skipping the Primary Key field */
989 dummy = dbf_field->Name;
990 len = strlen (dummy);
991 *(col_name + cnt) = malloc (len + 1);
992 strcpy (*(col_name + cnt), dummy);
993 cnt++;
994 dbf_field = dbf_field->Next;
995 continue;
996 }
997 dummy = dbf_field->Name;
998 dup = 0;
999 for (idup = 0; idup < cnt; idup++)
1000 {
1001 if (strcasecmp (dummy, *(col_name + idup)) == 0)
1002 dup = 1;
1003 }
1004 if (strcasecmp (dummy, pk_name) == 0)
1005 dup = 1;
1006 if (strcasecmp (dummy, geo_column) == 0)
1007 dup = 1;
1008 if (dup)
1009 {
1010 xdummy = sqlite3_mprintf ("COL_%d", seed++);
1011 spatialite_e
1012 ("Warning: duplicated fieldName \"%s\" in shapefile \"%s\": "
1013 "renaming the second occurrence in table \"%s\" as \"%s\".\n",
1014 dummy, shp_path, table, xdummy);
1015 dummy = xdummy;
1016 }
1017 len = strlen (dummy);
1018 *(col_name + cnt) = malloc (len + 1);
1019 strcpy (*(col_name + cnt), dummy);
1020 if (xdummy)
1021 sqlite3_free (xdummy);
1022 cnt++;
1023 dbf_field = dbf_field->Next;
1024 }
1025 if (verbose)
1026 spatialite_e
1027 ("========\nLoading shapefile at '%s' into SQLite table '%s'\n",
1028 shp_path, table);
1029 /* starting a transaction */
1030 if (verbose)
1031 spatialite_e ("\nBEGIN;\n");
1032 ret = sqlite3_exec (sqlite, "BEGIN", NULL, 0, &errMsg);
1033 if (ret != SQLITE_OK)
1034 {
1035 if (!err_msg)
1036 spatialite_e ("load shapefile error: <%s>\n", errMsg);
1037 else
1038 sprintf (err_msg, "load shapefile error: <%s>\n", errMsg);
1039 sqlite3_free (errMsg);
1040 sqlError = 1;
1041 goto clean_up;
1042 }
1043 /* creating the Table */
1044 gaiaOutBufferInitialize (&sql_statement);
1045 if (pk_type == SQLITE_TEXT)
1046 {
1047 sql = sqlite3_mprintf ("CREATE TABLE \"%s\" (\n\"%s\" "
1048 "TEXT PRIMARY KEY NOT NULL", qtable, qpk_name);
1049 }
1050 else if (pk_type == SQLITE_FLOAT)
1051 {
1052 sql = sqlite3_mprintf ("CREATE TABLE \"%s\" (\n\"%s\" "
1053 "DOUBLE PRIMARY KEY NOT NULL", qtable,
1054 qpk_name);
1055 }
1056 else
1057 {
1058 if (pk_autoincr)
1059 sql = sqlite3_mprintf ("CREATE TABLE \"%s\" (\n\"%s\" "
1060 "INTEGER PRIMARY KEY AUTOINCREMENT",
1061 qtable, qpk_name);
1062 else
1063 sql = sqlite3_mprintf ("CREATE TABLE \"%s\" (\n\"%s\" "
1064 "INTEGER NOT NULL PRIMARY KEY", qtable,
1065 qpk_name);
1066 }
1067 gaiaAppendToOutBuffer (&sql_statement, sql);
1068 sqlite3_free (sql);
1069 cnt = 0;
1070 dbf_field = shp->Dbf->First;
1071 while (dbf_field)
1072 {
1073 if (strcasecmp (pk_name, dbf_field->Name) == 0)
1074 {
1075 /* skipping the Primary Key field */
1076 dbf_field = dbf_field->Next;
1077 cnt++;
1078 continue;
1079 }
1080 casename = convert_dbf_colname_case (*(col_name + cnt), colname_case);
1081 xname = gaiaDoubleQuotedSql (casename);
1082 free (casename);
1083 sql = sqlite3_mprintf (",\n\"%s\"", xname);
1084 free (xname);
1085 gaiaAppendToOutBuffer (&sql_statement, sql);
1086 sqlite3_free (sql);
1087 cnt++;
1088 switch (dbf_field->Type)
1089 {
1090 case 'C':
1091 gaiaAppendToOutBuffer (&sql_statement, " TEXT");
1092 break;
1093 case 'N':
1094 if (dbf_field->Decimals)
1095 gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
1096 else
1097 {
1098 if (dbf_field->Length <= 18)
1099 gaiaAppendToOutBuffer (&sql_statement, " INTEGER");
1100 else
1101 gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
1102 }
1103 break;
1104 case 'D':
1105 if (text_dates)
1106 gaiaAppendToOutBuffer (&sql_statement, "TEXT");
1107 else
1108 gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
1109 break;
1110 case 'F':
1111 gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
1112 break;
1113 case 'L':
1114 gaiaAppendToOutBuffer (&sql_statement, " INTEGER");
1115 break;
1116 };
1117 dbf_field = dbf_field->Next;
1118 }
1119 if (metadata)
1120 gaiaAppendToOutBuffer (&sql_statement, ")");
1121 else
1122 {
1123 casename = convert_dbf_colname_case (geo_column, colname_case);
1124 xname = gaiaDoubleQuotedSql (casename);
1125 free (casename);
1126 sql = sqlite3_mprintf (",\n\"%s\" BLOB)", xname);
1127 free (xname);
1128 gaiaAppendToOutBuffer (&sql_statement, sql);
1129 sqlite3_free (sql);
1130 }
1131 if (sql_statement.Error == 0 && sql_statement.Buffer != NULL)
1132 {
1133 if (verbose)
1134 spatialite_e ("%s;\n", sql_statement.Buffer);
1135 ret = sqlite3_exec (sqlite, sql_statement.Buffer, NULL, 0, &errMsg);
1136 }
1137 else
1138 ret = SQLITE_ERROR;
1139 gaiaOutBufferReset (&sql_statement);
1140 if (ret != SQLITE_OK)
1141 {
1142 if (!err_msg)
1143 spatialite_e ("load shapefile error: <%s>\n", errMsg);
1144 else
1145 sprintf (err_msg, "load shapefile error: <%s>\n", errMsg);
1146 sqlite3_free (errMsg);
1147 sqlError = 1;
1148 goto clean_up;
1149 }
1150 if (metadata)
1151 {
1152 /* creating Geometry column */
1153 switch (shp->Shape)
1154 {
1155 case GAIA_SHP_POINT:
1156 case GAIA_SHP_POINTM:
1157 case GAIA_SHP_POINTZ:
1158 geom_type = "POINT";
1159 break;
1160 case GAIA_SHP_MULTIPOINT:
1161 case GAIA_SHP_MULTIPOINTM:
1162 case GAIA_SHP_MULTIPOINTZ:
1163 geom_type = "MULTIPOINT";
1164 break;
1165 case GAIA_SHP_POLYLINE:
1166 case GAIA_SHP_POLYLINEM:
1167 case GAIA_SHP_POLYLINEZ:
1168 if (xgtype == NULL)
1169 {
1170 /* auto-decting if MULTILINESTRING is required */
1171 gaiaShpAnalyze (shp);
1172 if (shp->EffectiveType == GAIA_LINESTRING)
1173 geom_type = "LINESTRING";
1174 else
1175 geom_type = "MULTILINESTRING";
1176 }
1177 else
1178 {
1179 /* user-defined geometry type */
1180 if (strcmp (xgtype, "LINESTRING") == 0)
1181 {
1182 geom_type = "LINESTRING";
1183 shp->EffectiveType = GAIA_LINESTRING;
1184 shp->EffectiveDims = GAIA_XY;
1185 }
1186 if (strcmp (xgtype, "LINESTRINGZ") == 0)
1187 {
1188 geom_type = "LINESTRING";
1189 shp->EffectiveType = GAIA_LINESTRING;
1190 shp->EffectiveDims = GAIA_XY_Z;
1191 }
1192 if (strcmp (xgtype, "LINESTRINGM") == 0)
1193 {
1194 geom_type = "LINESTRING";
1195 shp->EffectiveType = GAIA_LINESTRING;
1196 shp->EffectiveDims = GAIA_XY_M;
1197 }
1198 if (strcmp (xgtype, "LINESTRINGZM") == 0)
1199 {
1200 geom_type = "LINESTRING";
1201 shp->EffectiveType = GAIA_LINESTRING;
1202 shp->EffectiveDims = GAIA_XY_Z_M;
1203 }
1204 if (strcmp (xgtype, "MULTILINESTRING") == 0)
1205 {
1206 geom_type = "MULTILINESTRING";
1207 shp->EffectiveType = GAIA_MULTILINESTRING;
1208 shp->EffectiveDims = GAIA_XY;
1209 }
1210 if (strcmp (xgtype, "MULTILINESTRINGZ") == 0)
1211 {
1212 geom_type = "MULTILINESTRING";
1213 shp->EffectiveType = GAIA_MULTILINESTRING;
1214 shp->EffectiveDims = GAIA_XY_Z;
1215 }
1216 if (strcmp (xgtype, "MULTILINESTRINGM") == 0)
1217 {
1218 geom_type = "MULTILINESTRING";
1219 shp->EffectiveType = GAIA_MULTILINESTRING;
1220 shp->EffectiveDims = GAIA_XY_M;
1221 }
1222 if (strcmp (xgtype, "MULTILINESTRINGZM") == 0)
1223 {
1224 geom_type = "MULTILINESTRING";
1225 shp->EffectiveType = GAIA_MULTILINESTRING;
1226 shp->EffectiveDims = GAIA_XY_Z_M;
1227 }
1228 }
1229 break;
1230 case GAIA_SHP_POLYGON:
1231 case GAIA_SHP_POLYGONM:
1232 case GAIA_SHP_POLYGONZ:
1233 if (xgtype == NULL)
1234 {
1235 /* auto-decting if MULTIPOLYGON is required */
1236 gaiaShpAnalyze (shp);
1237 if (shp->EffectiveType == GAIA_POLYGON)
1238 geom_type = "POLYGON";
1239 else
1240 geom_type = "MULTIPOLYGON";
1241 }
1242 else
1243 {
1244 /* user-defined geometry type */
1245 if (strcmp (xgtype, "POLYGON") == 0)
1246 {
1247 geom_type = "POLYGON";
1248 shp->EffectiveType = GAIA_POLYGON;
1249 shp->EffectiveDims = GAIA_XY;
1250 }
1251 if (strcmp (xgtype, "POLYGONZ") == 0)
1252 {
1253 geom_type = "POLYGON";
1254 shp->EffectiveType = GAIA_POLYGON;
1255 shp->EffectiveDims = GAIA_XY_Z;
1256 }
1257 if (strcmp (xgtype, "POLYGONM") == 0)
1258 {
1259 geom_type = "POLYGON";
1260 shp->EffectiveType = GAIA_POLYGON;
1261 shp->EffectiveDims = GAIA_XY_M;
1262 }
1263 if (strcmp (xgtype, "POLYGONZM") == 0)
1264 {
1265 geom_type = "POLYGON";
1266 shp->EffectiveType = GAIA_POLYGON;
1267 shp->EffectiveDims = GAIA_XY_Z_M;
1268 }
1269 if (strcmp (xgtype, "MULTIPOLYGON") == 0)
1270 {
1271 geom_type = "MULTIPOLYGON";
1272 shp->EffectiveType = GAIA_MULTIPOLYGON;
1273 shp->EffectiveDims = GAIA_XY;
1274 }
1275 if (strcmp (xgtype, "MULTIPOLYGONZ") == 0)
1276 {
1277 geom_type = "MULTIPOLYGON";
1278 shp->EffectiveType = GAIA_MULTIPOLYGON;
1279 shp->EffectiveDims = GAIA_XY_Z;
1280 }
1281 if (strcmp (xgtype, "MULTIPOLYGONM") == 0)
1282 {
1283 geom_type = "MULTIPOLYGON";
1284 shp->EffectiveType = GAIA_MULTIPOLYGON;
1285 shp->EffectiveDims = GAIA_XY_M;
1286 }
1287 if (strcmp (xgtype, "MULTIPOLYGONZM") == 0)
1288 {
1289 geom_type = "MULTIPOLYGON";
1290 shp->EffectiveType = GAIA_MULTIPOLYGON;
1291 shp->EffectiveDims = GAIA_XY_Z_M;
1292 }
1293 }
1294 break;
1295 };
1296 if (coerce2d)
1297 shp->EffectiveDims = GAIA_XY;
1298 switch (shp->EffectiveDims)
1299 {
1300 case GAIA_XY_Z:
1301 txt_dims = "XYZ";
1302 break;
1303 case GAIA_XY_M:
1304 txt_dims = "XYM";
1305 break;
1306 case GAIA_XY_Z_M:
1307 txt_dims = "XYZM";
1308 break;
1309 default:
1310 txt_dims = "XY";
1311 break;
1312 };
1313 if (geom_type == NULL)
1314 {
1315 /* undefined Geometry Type */
1316 const char *gt = "UNKNOWN";
1317 switch (shp->Shape)
1318 {
1319 case GAIA_SHP_POINT:
1320 case GAIA_SHP_POINTM:
1321 case GAIA_SHP_POINTZ:
1322 gt = "POINT";
1323 break;
1324 case GAIA_SHP_MULTIPOINT:
1325 case GAIA_SHP_MULTIPOINTM:
1326 case GAIA_SHP_MULTIPOINTZ:
1327 gt = "MULTIPOINT";
1328 break;
1329 case GAIA_SHP_POLYLINE:
1330 case GAIA_SHP_POLYLINEM:
1331 case GAIA_SHP_POLYLINEZ:
1332 if (shp->EffectiveType == GAIA_LINESTRING)
1333 gt = "LINESTRING";
1334 else
1335 gt = "MULTILINESTRING";
1336 break;
1337 case GAIA_SHP_POLYGON:
1338 case GAIA_SHP_POLYGONM:
1339 case GAIA_SHP_POLYGONZ:
1340 if (shp->EffectiveType == GAIA_POLYGON)
1341 gt = "POLYGON";
1342 else
1343 gt = "MULTIPOLYGON";
1344 break;
1345 };
1346 if (!err_msg)
1347 spatialite_e
1348 ("Error: mismatching type: requested %s but Shape is %s %s\n",
1349 xgtype, gt, txt_dims);
1350 else
1351 sprintf (err_msg,
1352 "Error: mismatching type: requested %s but Shape is %s %s\n",
1353 xgtype, gt, txt_dims);
1354 sqlError = 1;
1355 goto clean_up;
1356 }
1357 casename = convert_dbf_colname_case (geo_column, colname_case);
1358 sql = sqlite3_mprintf ("SELECT AddGeometryColumn(%Q, %Q, %d, %Q, %Q)",
1359 table, casename, srid, geom_type, txt_dims);
1360 free (casename);
1361 if (verbose)
1362 spatialite_e ("%s;\n", sql);
1363 ret = sqlite3_exec (sqlite, sql, NULL, 0, &errMsg);
1364 sqlite3_free (sql);
1365 if (ret != SQLITE_OK)
1366 {
1367 if (!err_msg)
1368 spatialite_e ("load shapefile error: <%s>\n", errMsg);
1369 else
1370 sprintf (err_msg, "load shapefile error: <%s>\n", errMsg);
1371 sqlite3_free (errMsg);
1372 sqlError = 1;
1373 goto clean_up;
1374 }
1375 if (spatial_index)
1376 {
1377 /* creating the Spatial Index */
1378 sql = sqlite3_mprintf ("SELECT CreateSpatialIndex(%Q, %Q)",
1379 table, geo_column);
1380 ret = sqlite3_exec (sqlite, sql, NULL, 0, &errMsg);
1381 sqlite3_free (sql);
1382 if (ret != SQLITE_OK)
1383 {
1384 if (!err_msg)
1385 spatialite_e ("load shapefile error: <%s>\n", errMsg);
1386 else
1387 sprintf (err_msg, "load shapefile error: <%s>\n",
1388 errMsg);
1389 sqlite3_free (errMsg);
1390 sqlError = 1;
1391 goto clean_up;
1392 }
1393 }
1394 }
1395 else
1396 {
1397 /* no Metadata */
1398 if (shp->Shape == GAIA_SHP_POLYLINE
1399 || shp->Shape == GAIA_SHP_POLYLINEM
1400 || shp->Shape == GAIA_SHP_POLYLINEZ
1401 || shp->Shape == GAIA_SHP_POLYGON
1402 || shp->Shape == GAIA_SHP_POLYGONM
1403 || shp->Shape == GAIA_SHP_POLYGONZ)
1404 {
1405 /*
1406 / fixing anyway the Geometry type for
1407 / LINESTRING/MULTILINESTRING or
1408 / POLYGON/MULTIPOLYGON
1409 */
1410 gaiaShpAnalyze (shp);
1411 }
1412 }
1413 /* preparing the INSERT INTO parametrerized statement */
1414 gaiaOutBufferInitialize (&sql_statement);
1415 sql = sqlite3_mprintf ("INSERT INTO \"%s\" (\"%s\",", qtable, qpk_name);
1416 gaiaAppendToOutBuffer (&sql_statement, sql);
1417 sqlite3_free (sql);
1418 cnt = 0;
1419 dbf_field = shp->Dbf->First;
1420 while (dbf_field)
1421 {
1422 /* columns corresponding to some DBF attribute */
1423 if (strcasecmp (pk_name, dbf_field->Name) == 0)
1424 {
1425 /* skipping the Primary Key field */
1426 dbf_field = dbf_field->Next;
1427 cnt++;
1428 continue;
1429 }
1430 xname = gaiaDoubleQuotedSql (*(col_name + cnt++));
1431 sql = sqlite3_mprintf ("\"%s\" ,", xname);
1432 free (xname);
1433 gaiaAppendToOutBuffer (&sql_statement, sql);
1434 sqlite3_free (sql);
1435 dbf_field = dbf_field->Next;
1436 }
1437 xname = gaiaDoubleQuotedSql (geo_column); /* the GEOMETRY column */
1438 sql = sqlite3_mprintf ("\"%s\")\n VALUES (?", xname);
1439 free (xname);
1440 gaiaAppendToOutBuffer (&sql_statement, sql);
1441 sqlite3_free (sql);
1442 dbf_field = shp->Dbf->First;
1443 while (dbf_field)
1444 {
1445 /* column values */
1446 if (strcasecmp (pk_name, dbf_field->Name) == 0)
1447 {
1448 /* skipping the Primary Key field */
1449 dbf_field = dbf_field->Next;
1450 continue;
1451 }
1452 gaiaAppendToOutBuffer (&sql_statement, ", ?");
1453 dbf_field = dbf_field->Next;
1454 }
1455 gaiaAppendToOutBuffer (&sql_statement, ", ?)"); /* the GEOMETRY column */
1456 if (sql_statement.Error == 0 && sql_statement.Buffer != NULL)
1457 ret =
1458 sqlite3_prepare_v2 (sqlite, sql_statement.Buffer,
1459 strlen (sql_statement.Buffer), &stmt, NULL);
1460 else
1461 ret = SQLITE_ERROR;
1462 gaiaOutBufferReset (&sql_statement);
1463 if (ret != SQLITE_OK)
1464 {
1465 if (!err_msg)
1466 spatialite_e ("load shapefile error: <%s>\n",
1467 sqlite3_errmsg (sqlite));
1468 else
1469 sprintf (err_msg, "load shapefile error: <%s>\n",
1470 sqlite3_errmsg (sqlite));
1471 sqlError = 1;
1472 goto clean_up;
1473 }
1474 current_row = 0;
1475 while (1)
1476 {
1477 /* inserting rows from shapefile */
1478 ret = gaiaReadShpEntity_ex (shp, current_row, srid, text_dates);
1479 if (ret < 0)
1480 {
1481 /* found a DBF deleted record */
1482 current_row++;
1483 deleted++;
1484 continue;
1485 }
1486 if (!ret)
1487 {
1488 if (!(shp->LastError)) /* normal SHP EOF */
1489 break;
1490 if (!err_msg)
1491 spatialite_e ("%s\n", shp->LastError);
1492 else
1493 sprintf (err_msg, "%s\n", shp->LastError);
1494 sqlError = 1;
1495 sqlite3_finalize (stmt);
1496 goto clean_up;
1497 }
1498 current_row++;
1499 /* binding query params */
1500 sqlite3_reset (stmt);
1501 sqlite3_clear_bindings (stmt);
1502 pk_set = 0;
1503 cnt = 0;
1504 dbf_field = shp->Dbf->First;
1505 while (dbf_field)
1506 {
1507 /* Primary Key value */
1508 if (strcasecmp (pk_name, dbf_field->Name) == 0)
1509 {
1510 if (pk_type == SQLITE_TEXT)
1511 sqlite3_bind_text (stmt, 1,
1512 dbf_field->Value->TxtValue,
1513 strlen (dbf_field->
1514 Value->TxtValue),
1515 SQLITE_STATIC);
1516 else if (pk_type == SQLITE_FLOAT)
1517 sqlite3_bind_double (stmt, 1,
1518 dbf_field->Value->DblValue);
1519 else
1520 sqlite3_bind_int64 (stmt, 1,
1521 dbf_field->Value->IntValue);
1522 pk_set = 1;
1523 }
1524 dbf_field = dbf_field->Next;
1525 }
1526 if (!pk_set)
1527 sqlite3_bind_int (stmt, 1, current_row);
1528 cnt = 0;
1529 dbf_field = shp->Dbf->First;
1530 while (dbf_field)
1531 {
1532 /* column values */
1533 if (strcasecmp (pk_name, dbf_field->Name) == 0)
1534 {
1535 /* skipping the Primary Key field */
1536 dbf_field = dbf_field->Next;
1537 continue;
1538 }
1539 if (!(dbf_field->Value))
1540 sqlite3_bind_null (stmt, cnt + 2);
1541 else
1542 {
1543 switch (dbf_field->Value->Type)
1544 {
1545 case GAIA_INT_VALUE:
1546 sqlite3_bind_int64 (stmt, cnt + 2,
1547 dbf_field->Value->IntValue);
1548 break;
1549 case GAIA_DOUBLE_VALUE:
1550 sqlite3_bind_double (stmt, cnt + 2,
1551 dbf_field->Value->DblValue);
1552 break;
1553 case GAIA_TEXT_VALUE:
1554 sqlite3_bind_text (stmt, cnt + 2,
1555 dbf_field->Value->TxtValue,
1556 strlen (dbf_field->
1557 Value->TxtValue),
1558 SQLITE_STATIC);
1559 break;
1560 default:
1561 sqlite3_bind_null (stmt, cnt + 2);
1562 break;
1563 }
1564 }
1565 cnt++;
1566 dbf_field = dbf_field->Next;
1567 }
1568 if (shp->Dbf->Geometry)
1569 {
1570 if (compressed)
1571 gaiaToCompressedBlobWkb (shp->Dbf->Geometry, &blob,
1572 &blob_size);
1573 else
1574 gaiaToSpatiaLiteBlobWkb (shp->Dbf->Geometry, &blob,
1575 &blob_size);
1576 sqlite3_bind_blob (stmt, cnt + 2, blob, blob_size, free);
1577 }
1578 else
1579 {
1580 /* handling a NULL-Geometry */
1581 sqlite3_bind_null (stmt, cnt + 2);
1582 }
1583 ret = sqlite3_step (stmt);
1584 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
1585 ;
1586 else
1587 {
1588 if (!err_msg)
1589 spatialite_e ("load shapefile error: <%s>\n",
1590 sqlite3_errmsg (sqlite));
1591 else
1592 sprintf (err_msg, "load shapefile error: <%s>\n",
1593 sqlite3_errmsg (sqlite));
1594 sqlite3_finalize (stmt);
1595 sqlError = 1;
1596 goto clean_up;
1597 }
1598 }
1599 sqlite3_finalize (stmt);
1600 clean_up:
1601 if (qtable)
1602 free (qtable);
1603 if (qpk_name)
1604 free (qpk_name);
1605 gaiaFreeShapefile (shp);
1606 if (col_name)
1607 {
1608 /* releasing memory allocation for column names */
1609 for (cnt = 0; cnt < col_cnt; cnt++)
1610 free (*(col_name + cnt));
1611 free (col_name);
1612 }
1613 if (sqlError)
1614 {
1615 /* some error occurred - ROLLBACK */
1616 if (verbose)
1617 spatialite_e ("ROLLBACK;\n");
1618 ret = sqlite3_exec (sqlite, "ROLLBACK", NULL, 0, &errMsg);
1619 if (ret != SQLITE_OK)
1620 {
1621 spatialite_e ("load shapefile error: <%s>\n", errMsg);
1622 sqlite3_free (errMsg);
1623 }
1624 return 0;
1625 }
1626 else
1627 {
1628 /* ok - confirming pending transaction - COMMIT */
1629 if (verbose)
1630 spatialite_e ("COMMIT;\n");
1631 ret = sqlite3_exec (sqlite, "COMMIT", NULL, 0, &errMsg);
1632 if (ret != SQLITE_OK)
1633 {
1634 if (!err_msg)
1635 spatialite_e ("load shapefile error: <%s>\n", errMsg);
1636 else
1637 sprintf (err_msg, "load shapefile error: <%s>\n", errMsg);
1638 sqlite3_free (errMsg);
1639 return 0;
1640 }
1641 if (rows)
1642 *rows = current_row - deleted;
1643 if (verbose)
1644 spatialite_e
1645 ("\nInserted %d rows into '%s' from SHAPEFILE\n========\n",
1646 current_row - deleted, table);
1647 if (err_msg)
1648 sprintf (err_msg, "Inserted %d rows into '%s' from SHAPEFILE",
1649 current_row - deleted, table);
1650 return 1;
1651 }
1652 }
1653
1654 SPATIALITE_DECLARE int
load_shapefile_ex3(sqlite3 * sqlite,const char * shp_path,const char * table,const char * charset,int srid,const char * g_column,const char * gtype,const char * pk_column,int coerce2d,int compressed,int verbose,int spatial_index,int text_dates,int * rows,int colname_case,char * err_msg)1655 load_shapefile_ex3 (sqlite3 * sqlite, const char *shp_path, const char *table,
1656 const char *charset, int srid, const char *g_column,
1657 const char *gtype, const char *pk_column, int coerce2d,
1658 int compressed, int verbose, int spatial_index,
1659 int text_dates, int *rows, int colname_case, char *err_msg)
1660 {
1661 return load_shapefile_common (NULL, sqlite, shp_path, table, charset, srid,
1662 g_column, gtype, pk_column, coerce2d,
1663 compressed, verbose, spatial_index,
1664 text_dates, rows, colname_case, err_msg);
1665 }
1666
1667 static int
do_check_dbf_unique_pk_values(sqlite3 * sqlite,gaiaDbfPtr dbf,int text_dates,const char * pk_name,int pk_type)1668 do_check_dbf_unique_pk_values (sqlite3 * sqlite, gaiaDbfPtr dbf, int text_dates,
1669 const char *pk_name, int pk_type)
1670 {
1671 /* checking for duplicate PK values */
1672 char *sql;
1673 sqlite3_stmt *stmt = NULL;
1674 gaiaDbfFieldPtr dbf_field;
1675 int ret;
1676 int deleted;
1677 int duplicates = 0;
1678 int current_row = 0;
1679
1680 sql = "CREATE TABLE TEMP.check_unique_pk (pkey ANYVALUE)";
1681 ret = sqlite3_exec (sqlite, sql, NULL, NULL, NULL);
1682 if (ret != SQLITE_OK)
1683 return 0;
1684
1685 sql = "INSERT INTO TEMP.check_unique_pk (pkey) VALUES (?)";
1686 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1687 if (ret != SQLITE_OK)
1688 goto error;
1689
1690 sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
1691
1692 while (1)
1693 {
1694 /* reading rows from shapefile */
1695 int ok_insert = 0;
1696 ret = gaiaReadDbfEntity_ex (dbf, current_row, &deleted, text_dates);
1697 if (!ret)
1698 break;
1699 current_row++;
1700 if (deleted)
1701 {
1702 /* skipping DBF deleted row */
1703 continue;
1704 }
1705 /* binding query params */
1706 sqlite3_reset (stmt);
1707 sqlite3_clear_bindings (stmt);
1708 dbf_field = dbf->Dbf->First;
1709 while (dbf_field)
1710 {
1711 /* Primary Key value */
1712 if (strcasecmp (pk_name, dbf_field->Name) == 0)
1713 {
1714 if (pk_type == SQLITE_TEXT)
1715 {
1716 ok_insert = 1;
1717 sqlite3_bind_text (stmt, 1,
1718 dbf_field->Value->TxtValue,
1719 strlen (dbf_field->
1720 Value->TxtValue),
1721 SQLITE_STATIC);
1722 }
1723 else if (pk_type == SQLITE_FLOAT)
1724 {
1725 ok_insert = 1;
1726 sqlite3_bind_double (stmt, 1,
1727 dbf_field->Value->DblValue);
1728 }
1729 else
1730 {
1731 ok_insert = 1;
1732 sqlite3_bind_int64 (stmt, 1,
1733 dbf_field->Value->IntValue);
1734 }
1735 }
1736 dbf_field = dbf_field->Next;
1737 }
1738 if (ok_insert)
1739 {
1740 ret = sqlite3_step (stmt);
1741 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
1742 ;
1743 else
1744 goto error;
1745 }
1746 }
1747 sqlite3_finalize (stmt);
1748 stmt = NULL;
1749 sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
1750
1751 sql = "SELECT Count(*) FROM TEMP.check_unique_pk GROUP BY pkey";
1752 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1753 if (ret != SQLITE_OK)
1754 goto error;
1755
1756 while (1)
1757 {
1758 /* scrolling the result set rows */
1759 ret = sqlite3_step (stmt);
1760 if (ret == SQLITE_DONE)
1761 break; /* end of result set */
1762 if (ret == SQLITE_ROW)
1763 {
1764 if (sqlite3_column_int (stmt, 0) > 1)
1765 duplicates = 1;
1766 }
1767 }
1768 sqlite3_finalize (stmt);
1769
1770 sqlite3_exec (sqlite, "DROP TABLE TEMP.check_unique_pk", NULL, NULL, NULL);
1771 if (duplicates)
1772 return 0;
1773 else
1774 return 1;
1775
1776 error:
1777 if (stmt != NULL)
1778 sqlite3_finalize (stmt);
1779 sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
1780 sqlite3_exec (sqlite, "DROP TABLE TEMP.check_unique_pk", NULL, NULL, NULL);
1781 return 0;
1782 }
1783
1784 SPATIALITE_DECLARE int
load_dbf_common(struct zip_mem_shapefile * mem_shape,sqlite3 * sqlite,const char * dbf_path,const char * table,const char * pk_column,const char * charset,int verbose,int text_dates,int * rows,int colname_case,char * err_msg)1785 load_dbf_common (struct zip_mem_shapefile *mem_shape, sqlite3 * sqlite,
1786 const char *dbf_path, const char *table, const char *pk_column,
1787 const char *charset, int verbose, int text_dates, int *rows,
1788 int colname_case, char *err_msg)
1789 {
1790 sqlite3_stmt *stmt;
1791 int ret;
1792 char *errMsg = NULL;
1793 char *sql;
1794 char *dummy;
1795 char *xname;
1796 int already_exists = 0;
1797 int sqlError = 0;
1798 gaiaDbfPtr dbf = NULL;
1799 gaiaDbfFieldPtr dbf_field;
1800 int cnt;
1801 int col_cnt;
1802 int seed;
1803 int len;
1804 int dup;
1805 int idup;
1806 int current_row = 0;
1807 char **col_name = NULL;
1808 int deleted;
1809 char *qtable = NULL;
1810 char *qpk_name = NULL;
1811 const char *pk_name = NULL;
1812 char *casename;
1813 int pk_autoincr = 1;
1814 gaiaOutBuffer sql_statement;
1815 int pk_type = SQLITE_INTEGER;
1816 int pk_set;
1817 const char *alt_pk[10] =
1818 { "PK_ALT0", "PK_ALT1", "PK_ALT2", "PK_ALT3", "PK_ALT4", "PK_ALT5",
1819 "PK_ALT6", "PK_ALT7", "PK_ALT8", "PK_ALT9"
1820 };
1821 qtable = gaiaDoubleQuotedSql (table);
1822 if (rows)
1823 *rows = -1;
1824 /* checking if TABLE already exists */
1825 sql = sqlite3_mprintf ("SELECT name FROM sqlite_master WHERE "
1826 "type = 'table' AND Lower(name) = Lower(%Q)", table);
1827 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1828 sqlite3_free (sql);
1829 if (ret != SQLITE_OK)
1830 {
1831 if (!err_msg)
1832 spatialite_e ("load DBF error: <%s>\n", sqlite3_errmsg (sqlite));
1833 else
1834 sprintf (err_msg, "load DBF error: <%s>\n",
1835 sqlite3_errmsg (sqlite));
1836 if (qtable)
1837 free (qtable);
1838 if (qpk_name)
1839 free (qpk_name);
1840 return 0;
1841 }
1842 while (1)
1843 {
1844 /* scrolling the result set */
1845 ret = sqlite3_step (stmt);
1846 if (ret == SQLITE_DONE)
1847 break; /* end of result set */
1848 if (ret == SQLITE_ROW)
1849 already_exists = 1;
1850 else
1851 {
1852 spatialite_e ("load DBF error: <%s>\n",
1853 sqlite3_errmsg (sqlite));
1854 break;
1855 }
1856 }
1857 sqlite3_finalize (stmt);
1858 if (already_exists)
1859 {
1860 if (!err_msg)
1861 spatialite_e ("load DBF error: table '%s' already exists\n",
1862 table);
1863 else
1864 sprintf (err_msg, "load DBF error: table '%s' already exists\n",
1865 table);
1866 if (qtable)
1867 free (qtable);
1868 if (qpk_name)
1869 free (qpk_name);
1870 return 0;
1871 }
1872 dbf = gaiaAllocDbf ();
1873 if (mem_shape != NULL)
1874 {
1875 /* initializing Memory based files */
1876 dbf->memDbf = &(mem_shape->dbf);
1877 }
1878 gaiaOpenDbfRead (dbf, dbf_path, charset, "UTF-8");
1879 if (!(dbf->Valid))
1880 {
1881 if (!err_msg)
1882 {
1883 spatialite_e ("load DBF error: cannot open '%s'\n", dbf_path);
1884 if (dbf->LastError)
1885 spatialite_e ("\tcause: %s\n", dbf->LastError);
1886 }
1887 else
1888 {
1889 char extra[512];
1890 *extra = '\0';
1891 if (dbf->LastError)
1892 sprintf (extra, "\n\tcause: %s", dbf->LastError);
1893 sprintf (err_msg, "load DBF error: cannot open '%s'%s",
1894 dbf_path, extra);
1895 }
1896 gaiaFreeDbf (dbf);
1897 if (qtable)
1898 free (qtable);
1899 if (qpk_name)
1900 free (qpk_name);
1901 return 0;
1902 }
1903 /* checking for duplicate / illegal column names and antialising them */
1904 col_cnt = 0;
1905 dbf_field = dbf->Dbf->First;
1906 while (dbf_field)
1907 {
1908 /* counting DBF fields */
1909 col_cnt++;
1910 dbf_field = dbf_field->Next;
1911 }
1912 col_name = malloc (sizeof (char *) * col_cnt);
1913 cnt = 0;
1914 seed = 0;
1915 if (pk_column != NULL)
1916 {
1917 /* validating the Primary Key column */
1918 dbf_field = dbf->Dbf->First;
1919 while (dbf_field)
1920 {
1921 if (strcasecmp (pk_column, dbf_field->Name) == 0)
1922 {
1923 /* ok, using this field as Primary Key */
1924 pk_name = pk_column;
1925 pk_autoincr = 0;
1926 switch (dbf_field->Type)
1927 {
1928 case 'C':
1929 pk_type = SQLITE_TEXT;
1930 break;
1931 case 'N':
1932 if (dbf_field->Decimals)
1933 pk_type = SQLITE_FLOAT;
1934 else
1935 {
1936 if (dbf_field->Length <= 18)
1937 pk_type = SQLITE_INTEGER;
1938 else
1939 pk_type = SQLITE_FLOAT;
1940 }
1941 break;
1942 case 'D':
1943 if (text_dates)
1944 pk_type = SQLITE_TEXT;
1945 else
1946 pk_type = SQLITE_FLOAT;
1947 break;
1948 case 'F':
1949 pk_type = SQLITE_FLOAT;
1950 break;
1951 case 'L':
1952 pk_type = SQLITE_INTEGER;
1953 break;
1954 };
1955 }
1956 dbf_field = dbf_field->Next;
1957 }
1958 }
1959 if (pk_name == NULL)
1960 {
1961 if (pk_column != NULL)
1962 pk_name = pk_column;
1963 else
1964 pk_name = "PK_UID";
1965 }
1966 if (!do_check_dbf_unique_pk_values
1967 (sqlite, dbf, text_dates, pk_name, pk_type))
1968 {
1969 const char *old_pk = pk_name;
1970 int antialias;
1971 for (antialias = 0; antialias < 10; antialias++)
1972 {
1973 /* searching an alternative Primary Key column name */
1974 int found = 0;
1975 pk_name = alt_pk[antialias];
1976 dbf_field = dbf->Dbf->First;
1977 while (dbf_field)
1978 {
1979 if (strcasecmp (pk_name, dbf_field->Name) == 0)
1980 found = 1;
1981 dbf_field = dbf_field->Next;
1982 }
1983 if (!found)
1984 {
1985 pk_autoincr = 1;
1986 goto ok_pk;
1987 }
1988 }
1989 pk_name = old_pk;
1990 }
1991 ok_pk:
1992 casename = convert_dbf_colname_case (pk_name, colname_case);
1993 qpk_name = gaiaDoubleQuotedSql (casename);
1994 free (casename);
1995 dbf_field = dbf->Dbf->First;
1996 while (dbf_field)
1997 {
1998 /* preparing column names */
1999 char *xdummy = NULL;
2000 if (strcasecmp (pk_name, dbf_field->Name) == 0)
2001 {
2002 /* skipping the Primary Key field */
2003 dummy = dbf_field->Name;
2004 len = strlen (dummy);
2005 *(col_name + cnt) = malloc (len + 1);
2006 strcpy (*(col_name + cnt), dummy);
2007 cnt++;
2008 dbf_field = dbf_field->Next;
2009 continue;
2010 }
2011 dummy = dbf_field->Name;
2012 dup = 0;
2013 for (idup = 0; idup < cnt; idup++)
2014 {
2015 if (strcasecmp (dummy, *(col_name + idup)) == 0)
2016 dup = 1;
2017 }
2018 if (dup)
2019 {
2020 xdummy = sqlite3_mprintf ("COL_%d", seed++);
2021 dummy = xdummy;
2022 }
2023 len = strlen (dummy);
2024 *(col_name + cnt) = malloc (len + 1);
2025 strcpy (*(col_name + cnt), dummy);
2026 if (xdummy)
2027 sqlite3_free (xdummy);
2028 cnt++;
2029 dbf_field = dbf_field->Next;
2030 }
2031 if (verbose)
2032 spatialite_e ("========\nLoading DBF at '%s' into SQLite table '%s'\n",
2033 dbf_path, table);
2034 /* starting a transaction */
2035 if (verbose)
2036 spatialite_e ("\nBEGIN;\n");
2037 ret = sqlite3_exec (sqlite, "BEGIN", NULL, 0, &errMsg);
2038 if (ret != SQLITE_OK)
2039 {
2040 if (!err_msg)
2041 spatialite_e ("load DBF error: <%s>\n", errMsg);
2042 else
2043 sprintf (err_msg, "load DBF error: <%s>\n", errMsg);
2044 sqlite3_free (errMsg);
2045 sqlError = 1;
2046 goto clean_up;
2047 }
2048 /* creating the Table */
2049 gaiaOutBufferInitialize (&sql_statement);
2050 if (pk_type == SQLITE_TEXT)
2051 {
2052 sql = sqlite3_mprintf ("CREATE TABLE \"%s\" (\n\"%s\" "
2053 "TEXT PRIMARY KEY NOT NULL", qtable, qpk_name);
2054 }
2055 else if (pk_type == SQLITE_FLOAT)
2056 {
2057 sql = sqlite3_mprintf ("CREATE TABLE \"%s\" (\n\"%s\" "
2058 "DOUBLE PRIMARY KEY NOT NULL", qtable,
2059 qpk_name);
2060 }
2061 else
2062 {
2063 if (pk_autoincr)
2064 sql = sqlite3_mprintf ("CREATE TABLE \"%s\" (\n\"%s\" "
2065 "INTEGER PRIMARY KEY AUTOINCREMENT",
2066 qtable, qpk_name);
2067 else
2068 sql = sqlite3_mprintf ("CREATE TABLE \"%s\" (\n\"%s\" "
2069 "INTEGER NOT NULL PRIMARY KEY", qtable,
2070 qpk_name);
2071 }
2072 gaiaAppendToOutBuffer (&sql_statement, sql);
2073 sqlite3_free (sql);
2074 cnt = 0;
2075 dbf_field = dbf->Dbf->First;
2076 while (dbf_field)
2077 {
2078 if (strcasecmp (pk_name, dbf_field->Name) == 0)
2079 {
2080 /* skipping the Primary Key field */
2081 dbf_field = dbf_field->Next;
2082 cnt++;
2083 continue;
2084 }
2085 casename = convert_dbf_colname_case (*(col_name + cnt), colname_case);
2086 xname = gaiaDoubleQuotedSql (casename);
2087 free (casename);
2088 sql = sqlite3_mprintf (",\n\"%s\"", xname);
2089 free (xname);
2090 gaiaAppendToOutBuffer (&sql_statement, sql);
2091 sqlite3_free (sql);
2092 cnt++;
2093 switch (dbf_field->Type)
2094 {
2095 case 'C':
2096 gaiaAppendToOutBuffer (&sql_statement, " TEXT");
2097 break;
2098 case 'N':
2099 if (dbf_field->Decimals)
2100 gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
2101 else
2102 {
2103 if (dbf_field->Length <= 18)
2104 gaiaAppendToOutBuffer (&sql_statement, " INTEGER");
2105 else
2106 gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
2107 }
2108 break;
2109 case 'D':
2110 if (text_dates)
2111 gaiaAppendToOutBuffer (&sql_statement, " TEXT");
2112 else
2113 gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
2114 break;
2115 case 'F':
2116 gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
2117 break;
2118 case 'L':
2119 gaiaAppendToOutBuffer (&sql_statement, " INTEGER");
2120 break;
2121 };
2122 dbf_field = dbf_field->Next;
2123 }
2124 gaiaAppendToOutBuffer (&sql_statement, ")");
2125 if (sql_statement.Error == 0 && sql_statement.Buffer != NULL)
2126 {
2127 if (verbose)
2128 spatialite_e ("%s;\n", sql_statement.Buffer);
2129 ret = sqlite3_exec (sqlite, sql_statement.Buffer, NULL, 0, &errMsg);
2130 }
2131 else
2132 ret = SQLITE_ERROR;
2133 gaiaOutBufferReset (&sql_statement);
2134 if (ret != SQLITE_OK)
2135 {
2136 if (!err_msg)
2137 spatialite_e ("load DBF error: <%s>\n", errMsg);
2138 else
2139 sprintf (err_msg, "load DBF error: <%s>\n", errMsg);
2140 sqlite3_free (errMsg);
2141 sqlError = 1;
2142 goto clean_up;
2143 }
2144 /* preparing the INSERT INTO parametrerized statement */
2145 sql = sqlite3_mprintf ("INSERT INTO \"%s\" (\"%s\"", qtable, qpk_name);
2146 gaiaAppendToOutBuffer (&sql_statement, sql);
2147 sqlite3_free (sql);
2148 cnt = 0;
2149 dbf_field = dbf->Dbf->First;
2150 while (dbf_field)
2151 {
2152 /* columns corresponding to some DBF attribute */
2153 if (strcasecmp (pk_name, dbf_field->Name) == 0)
2154 {
2155 /* skipping the Primary Key field */
2156 dbf_field = dbf_field->Next;
2157 cnt++;
2158 continue;
2159 }
2160 xname = gaiaDoubleQuotedSql (*(col_name + cnt++));
2161 sql = sqlite3_mprintf (",\"%s\"", xname);
2162 free (xname);
2163 gaiaAppendToOutBuffer (&sql_statement, sql);
2164 sqlite3_free (sql);
2165 dbf_field = dbf_field->Next;
2166 }
2167 gaiaAppendToOutBuffer (&sql_statement, ")\nVALUES (?");
2168 dbf_field = dbf->Dbf->First;
2169 while (dbf_field)
2170 {
2171 /* column values */
2172 if (strcasecmp (pk_name, dbf_field->Name) == 0)
2173 {
2174 /* skipping the Primary Key field */
2175 dbf_field = dbf_field->Next;
2176 continue;
2177 }
2178 gaiaAppendToOutBuffer (&sql_statement, ", ?");
2179 dbf_field = dbf_field->Next;
2180 }
2181 gaiaAppendToOutBuffer (&sql_statement, ")");
2182 if (sql_statement.Error == 0 && sql_statement.Buffer != NULL)
2183 ret =
2184 sqlite3_prepare_v2 (sqlite, sql_statement.Buffer,
2185 strlen (sql_statement.Buffer), &stmt, NULL);
2186 else
2187 ret = SQLITE_ERROR;
2188 gaiaOutBufferReset (&sql_statement);
2189 if (ret != SQLITE_OK)
2190 {
2191 if (!err_msg)
2192 spatialite_e ("load DBF error: <%s>\n", sqlite3_errmsg (sqlite));
2193 else
2194 sprintf (err_msg, "load DBF error: <%s>\n",
2195 sqlite3_errmsg (sqlite));
2196 sqlError = 1;
2197 goto clean_up;
2198 }
2199 current_row = 0;
2200 while (1)
2201 {
2202 /* inserting rows from DBF */
2203 ret = gaiaReadDbfEntity_ex (dbf, current_row, &deleted, text_dates);
2204 if (!ret)
2205 {
2206 if (!(dbf->LastError)) /* normal DBF EOF */
2207 break;
2208 if (!err_msg)
2209 spatialite_e ("%s\n", dbf->LastError);
2210 else
2211 sprintf (err_msg, "%s\n", dbf->LastError);
2212 sqlError = 1;
2213 goto clean_up;
2214 }
2215 current_row++;
2216 if (deleted)
2217 {
2218 /* skipping DBF deleted row */
2219 continue;
2220 }
2221 /* binding query params */
2222 sqlite3_reset (stmt);
2223 sqlite3_clear_bindings (stmt);
2224 pk_set = 0;
2225 cnt = 0;
2226 dbf_field = dbf->Dbf->First;
2227 while (dbf_field)
2228 {
2229 /* Primary Key value */
2230 if (strcasecmp (pk_name, dbf_field->Name) == 0)
2231 {
2232 if (pk_type == SQLITE_TEXT)
2233 sqlite3_bind_text (stmt, 1,
2234 dbf_field->Value->TxtValue,
2235 strlen (dbf_field->
2236 Value->TxtValue),
2237 SQLITE_STATIC);
2238 else if (pk_type == SQLITE_FLOAT)
2239 sqlite3_bind_double (stmt, 1,
2240 dbf_field->Value->DblValue);
2241 else
2242 sqlite3_bind_int64 (stmt, 1,
2243 dbf_field->Value->IntValue);
2244 pk_set = 1;
2245 }
2246 dbf_field = dbf_field->Next;
2247 }
2248 if (!pk_set)
2249 sqlite3_bind_int (stmt, 1, current_row);
2250 cnt = 0;
2251 dbf_field = dbf->Dbf->First;
2252 while (dbf_field)
2253 {
2254 /* column values */
2255 if (strcasecmp (pk_name, dbf_field->Name) == 0)
2256 {
2257 /* skipping the Primary Key field */
2258 dbf_field = dbf_field->Next;
2259 continue;
2260 }
2261 if (!(dbf_field->Value))
2262 sqlite3_bind_null (stmt, cnt + 2);
2263 else
2264 {
2265 switch (dbf_field->Value->Type)
2266 {
2267 case GAIA_INT_VALUE:
2268 sqlite3_bind_int64 (stmt, cnt + 2,
2269 dbf_field->Value->IntValue);
2270 break;
2271 case GAIA_DOUBLE_VALUE:
2272 sqlite3_bind_double (stmt, cnt + 2,
2273 dbf_field->Value->DblValue);
2274 break;
2275 case GAIA_TEXT_VALUE:
2276 sqlite3_bind_text (stmt, cnt + 2,
2277 dbf_field->Value->TxtValue,
2278 strlen (dbf_field->
2279 Value->TxtValue),
2280 SQLITE_STATIC);
2281 break;
2282 default:
2283 sqlite3_bind_null (stmt, cnt + 2);
2284 break;
2285 }
2286 }
2287 cnt++;
2288 dbf_field = dbf_field->Next;
2289 }
2290 ret = sqlite3_step (stmt);
2291 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
2292 ;
2293 else
2294 {
2295 if (!err_msg)
2296 spatialite_e ("load DBF error: <%s>\n",
2297 sqlite3_errmsg (sqlite));
2298 else
2299 sprintf (err_msg, "load DBF error: <%s>\n",
2300 sqlite3_errmsg (sqlite));
2301 sqlite3_finalize (stmt);
2302 sqlError = 1;
2303 goto clean_up;
2304 }
2305 }
2306 sqlite3_finalize (stmt);
2307 clean_up:
2308 if (qtable)
2309 free (qtable);
2310 qtable = NULL;
2311 if (qpk_name)
2312 free (qpk_name);
2313 qpk_name = NULL;
2314 gaiaFreeDbf (dbf);
2315 if (col_name)
2316 {
2317 /* releasing memory allocation for column names */
2318 for (cnt = 0; cnt < col_cnt; cnt++)
2319 free (*(col_name + cnt));
2320 free (col_name);
2321 }
2322 if (sqlError)
2323 {
2324 /* some error occurred - ROLLBACK */
2325 if (verbose)
2326 spatialite_e ("ROLLBACK;\n");
2327 ret = sqlite3_exec (sqlite, "ROLLBACK", NULL, 0, &errMsg);
2328 if (ret != SQLITE_OK)
2329 {
2330 spatialite_e ("load DBF error: <%s>\n", errMsg);
2331 sqlite3_free (errMsg);
2332 };
2333 if (qtable)
2334 free (qtable);
2335 if (qpk_name)
2336 free (qpk_name);
2337 return 0;
2338 }
2339 else
2340 {
2341 /* ok - confirming pending transaction - COMMIT */
2342 if (verbose)
2343 spatialite_e ("COMMIT;\n");
2344 ret = sqlite3_exec (sqlite, "COMMIT", NULL, 0, &errMsg);
2345 if (ret != SQLITE_OK)
2346 {
2347 spatialite_e ("load DBF error: <%s>\n", errMsg);
2348 sqlite3_free (errMsg);
2349 return 0;
2350 }
2351 if (rows)
2352 *rows = current_row;
2353 if (verbose)
2354 spatialite_e ("\nInserted %d rows into '%s' from DBF\n========\n",
2355 current_row, table);
2356 if (err_msg)
2357 sprintf (err_msg, "Inserted %d rows into '%s' from DBF",
2358 current_row, table);
2359 return 1;
2360 }
2361 }
2362
2363 #ifdef ENABLE_MINIZIP /* MINIZIP is enabled */
2364
2365 static struct zip_mem_shp_item *
alloc_zip_mem_shp_item(const char * basename,int wich,int dbf_only)2366 alloc_zip_mem_shp_item (const char *basename, int wich, int dbf_only)
2367 {
2368 /* creating a Shapefile within a Zipfile */
2369 struct zip_mem_shp_item *item = malloc (sizeof (struct zip_mem_shp_item));
2370 if (basename == NULL)
2371 item->basename = NULL;
2372 else
2373 {
2374 int len = strlen (basename);
2375 item->basename = malloc (len + 1);
2376 strcpy (item->basename, basename);
2377 if (!dbf_only)
2378 {
2379 if (*(item->basename + len - 4) == '.')
2380 *(item->basename + len - 4) = '\0';
2381 }
2382 }
2383 item->shp = 0;
2384 item->shx = 0;
2385 item->dbf = 0;
2386 item->prj = 0;
2387 switch (wich)
2388 {
2389 case GAIA_ZIPFILE_SHP:
2390 item->shp = 1;
2391 break;
2392 case GAIA_ZIPFILE_SHX:
2393 item->shx = 1;
2394 break;
2395 case GAIA_ZIPFILE_DBF:
2396 item->dbf = 1;
2397 break;
2398 case GAIA_ZIPFILE_PRJ:
2399 item->prj = 1;
2400 break;
2401 };
2402 item->next = NULL;
2403 return item;
2404 }
2405
2406 static void
add_item_into_zip_mem_shp_list(struct zip_mem_shp_list * list,const char * filename,int wich,int dbf_only)2407 add_item_into_zip_mem_shp_list (struct zip_mem_shp_list *list,
2408 const char *filename, int wich, int dbf_only)
2409 {
2410 /* populating the list of Zipfile Shapefiles */
2411 struct zip_mem_shp_item *item;
2412
2413 if (list == NULL)
2414 return;
2415
2416 item = list->first;
2417 while (item != NULL)
2418 {
2419 /* verifying an already existing basename */
2420 char *name = NULL;
2421 switch (wich)
2422 {
2423 case GAIA_ZIPFILE_SHP:
2424 name = sqlite3_mprintf ("%s.shp", item->basename);
2425 break;
2426 case GAIA_ZIPFILE_SHX:
2427 name = sqlite3_mprintf ("%s.shx", item->basename);
2428 break;
2429 case GAIA_ZIPFILE_DBF:
2430 name = sqlite3_mprintf ("%s.dbf", item->basename);
2431 break;
2432 case GAIA_ZIPFILE_PRJ:
2433 name = sqlite3_mprintf ("%s.prj", item->basename);
2434 break;
2435 };
2436 if (name != NULL)
2437 {
2438 if (strcasecmp (name, filename) == 0)
2439 {
2440 /* found a mathcing basename */
2441 sqlite3_free (name);
2442 switch (wich)
2443 {
2444 case GAIA_ZIPFILE_SHP:
2445 item->shp = 1;
2446 break;
2447 case GAIA_ZIPFILE_SHX:
2448 item->shx = 1;
2449 break;
2450 case GAIA_ZIPFILE_DBF:
2451 item->dbf = 1;
2452 break;
2453 case GAIA_ZIPFILE_PRJ:
2454 item->prj = 1;
2455 break;
2456 };
2457 return;
2458 }
2459 sqlite3_free (name);
2460 }
2461 item = item->next;
2462 }
2463
2464 /* inserting a new basename into the list */
2465 item = alloc_zip_mem_shp_item (filename, wich, dbf_only);
2466 if (list->first == NULL)
2467 list->first = item;
2468 if (list->last != NULL)
2469 list->last->next = item;
2470 list->last = item;
2471 }
2472
2473 static struct zip_mem_shapefile *
alloc_zip_mem_shapefile()2474 alloc_zip_mem_shapefile ()
2475 {
2476 /* allocating a Memory Zip Shapefile */
2477 struct zip_mem_shapefile *mem_shp =
2478 malloc (sizeof (struct zip_mem_shapefile));
2479 mem_shp->shp.path = NULL;
2480 mem_shp->shp.buf = NULL;
2481 mem_shp->shp.size = 0;
2482 mem_shp->shp.offset = 0;
2483 mem_shp->shx.path = NULL;
2484 mem_shp->shx.buf = NULL;
2485 mem_shp->shx.size = 0;
2486 mem_shp->shx.offset = 0;
2487 mem_shp->dbf.path = NULL;
2488 mem_shp->dbf.buf = NULL;
2489 mem_shp->dbf.size = 0;
2490 mem_shp->dbf.offset = 0;
2491 mem_shp->prj.path = NULL;
2492 mem_shp->prj.buf = NULL;
2493 mem_shp->prj.size = 0;
2494 mem_shp->prj.offset = 0;
2495 return mem_shp;
2496 }
2497
2498 static void
destroy_zip_mem_file(gaiaMemFilePtr mem)2499 destroy_zip_mem_file (gaiaMemFilePtr mem)
2500 {
2501 /* memory cleanup: destroying a Memoroy Zip File */
2502 if (mem == NULL)
2503 return;
2504 if (mem->path != NULL)
2505 free (mem->path);
2506 if (mem->buf != NULL)
2507 free (mem->buf);
2508 }
2509
2510 static void
destroy_zip_mem_shapefile(struct zip_mem_shapefile * mem_shp)2511 destroy_zip_mem_shapefile (struct zip_mem_shapefile *mem_shp)
2512 {
2513 /* memory cleanup: destroying a Memory Zip Shapefile */
2514 if (mem_shp == NULL)
2515 return;
2516 destroy_zip_mem_file (&(mem_shp->shp));
2517 destroy_zip_mem_file (&(mem_shp->shx));
2518 destroy_zip_mem_file (&(mem_shp->dbf));
2519 destroy_zip_mem_file (&(mem_shp->prj));
2520 free (mem_shp);
2521 }
2522
2523 static void
destroy_zip_mem_shp_item(struct zip_mem_shp_item * item)2524 destroy_zip_mem_shp_item (struct zip_mem_shp_item *item)
2525 {
2526 /* destroying a Shapefile item */
2527 if (item == NULL)
2528 return;
2529 if (item->basename != NULL)
2530 free (item->basename);
2531 free (item);
2532 }
2533
2534 static struct zip_mem_shp_list *
alloc_zip_mem_shp_list()2535 alloc_zip_mem_shp_list ()
2536 {
2537 /* creating a list of Shapefiles within a Shapefile */
2538 struct zip_mem_shp_list *list = malloc (sizeof (struct zip_mem_shp_list));
2539 list->first = NULL;
2540 list->last = NULL;
2541 return list;
2542 }
2543
2544 static void
destroy_zip_mem_shp_list(struct zip_mem_shp_list * list)2545 destroy_zip_mem_shp_list (struct zip_mem_shp_list *list)
2546 {
2547 /* memory cleanup: destroying a list of Shapefiles within a Shapefile */
2548 struct zip_mem_shp_item *item;
2549 struct zip_mem_shp_item *item_n;
2550
2551 if (list == NULL)
2552 return;
2553 item = list->first;
2554 while (item != NULL)
2555 {
2556 item_n = item->next;
2557 destroy_zip_mem_shp_item (item);
2558 item = item_n;
2559 }
2560 free (list);
2561 }
2562
2563 static int
do_sniff_zipfile_dir(unzFile uf,struct zip_mem_shp_list * list,int dbf_only)2564 do_sniff_zipfile_dir (unzFile uf, struct zip_mem_shp_list *list, int dbf_only)
2565 {
2566 /* sniffing a Zipfile directory */
2567 int retval = 1;
2568 unz_global_info64 gi;
2569 int ret;
2570 unsigned int i;
2571
2572 ret = unzGetGlobalInfo64 (uf, &gi);
2573 if (ret != UNZ_OK)
2574 {
2575 spatialite_e ("Error %d within zipfile in unzGetGlobalInfo\n", ret);
2576 return 0;
2577 }
2578
2579 for (i = 0; i < gi.number_entry; i++)
2580 {
2581 unsigned int len;
2582 char suffix[6];
2583 char filename[256];
2584 unz_file_info64 file_info;
2585
2586 ret =
2587 unzGetCurrentFileInfo64 (uf, &file_info, filename, 256, NULL, 0,
2588 NULL, 0);
2589 if (ret != UNZ_OK)
2590 {
2591 spatialite_e
2592 ("Error %d with zipfile in unzGetCurrentFileInfo\n", ret);
2593 retval = 0;
2594 goto stop;
2595 }
2596
2597 suffix[0] = '\0';
2598 len = strlen (filename);
2599 if (len >= 5)
2600 {
2601 suffix[0] = *(filename + len - 4);
2602 suffix[1] = *(filename + len - 3);
2603 suffix[2] = *(filename + len - 2);
2604 suffix[3] = *(filename + len - 1);
2605 suffix[4] = '\0';
2606 }
2607 if (strcasecmp (suffix, ".shp") == 0)
2608 add_item_into_zip_mem_shp_list (list, filename, GAIA_ZIPFILE_SHP,
2609 0);
2610 if (strcasecmp (suffix, ".shx") == 0)
2611 add_item_into_zip_mem_shp_list (list, filename, GAIA_ZIPFILE_SHX,
2612 0);
2613 if (strcasecmp (suffix, ".dbf") == 0)
2614 add_item_into_zip_mem_shp_list (list, filename, GAIA_ZIPFILE_DBF,
2615 dbf_only);
2616 if (strcasecmp (suffix, ".prj") == 0)
2617 add_item_into_zip_mem_shp_list (list, filename, GAIA_ZIPFILE_PRJ,
2618 0);
2619
2620 if (i + 1 == gi.number_entry)
2621 break;
2622 ret = unzGoToNextFile (uf);
2623 if (ret != UNZ_OK)
2624 {
2625 spatialite_e ("Error %d with zipfile in unzGoToNextFile\n",
2626 ret);
2627 retval = 0;
2628 goto stop;
2629 }
2630 }
2631 stop:
2632 return retval;
2633 }
2634
2635 static struct zip_mem_shapefile *
do_list_zipfile_dir(unzFile uf,const char * shp_path,int dbf_mode)2636 do_list_zipfile_dir (unzFile uf, const char *shp_path, int dbf_mode)
2637 {
2638 /* parsing a Zipfile directory */
2639 unz_global_info64 gi;
2640 int ret;
2641 unsigned int i;
2642 int len;
2643 int shp = 0;
2644 int dbf = 0;
2645 int shx = 0;
2646 int prj = 0;
2647 struct zip_mem_shapefile *mem_shp = NULL;
2648
2649 ret = unzGetGlobalInfo64 (uf, &gi);
2650 if (ret != UNZ_OK)
2651 {
2652 spatialite_e ("Error %d within zipfile in unzGetGlobalInfo\n", ret);
2653 return 0;
2654 }
2655
2656 mem_shp = alloc_zip_mem_shapefile ();
2657 for (i = 0; i < gi.number_entry; i++)
2658 {
2659 char *path;
2660 char filename[256];
2661 unz_file_info64 file_info;
2662
2663 ret =
2664 unzGetCurrentFileInfo64 (uf, &file_info, filename, 256, NULL, 0,
2665 NULL, 0);
2666 if (ret != UNZ_OK)
2667 {
2668 spatialite_e
2669 ("Error %d with zipfile in unzGetCurrentFileInfo\n", ret);
2670 goto error;
2671 }
2672 if (dbf_mode)
2673 {
2674 /* searching for just a bare DBF */
2675 if (!dbf)
2676 {
2677 if (strcasecmp (shp_path, filename) == 0)
2678 {
2679 dbf = 1;
2680 len = strlen (filename);
2681 mem_shp->dbf.path = malloc (len + 1);
2682 strcpy (mem_shp->dbf.path, filename);
2683 }
2684 }
2685 }
2686 else
2687 {
2688 /* searching for a Shapefile */
2689 if (!shp)
2690 {
2691 path = sqlite3_mprintf ("%s.shp", shp_path);
2692 if (strcasecmp (path, filename) == 0)
2693 {
2694 shp = 1;
2695 len = strlen (filename);
2696 mem_shp->shp.path = malloc (len + 1);
2697 strcpy (mem_shp->shp.path, filename);
2698 }
2699 sqlite3_free (path);
2700 }
2701 if (!shx)
2702 {
2703 path = sqlite3_mprintf ("%s.shx", shp_path);
2704 if (strcasecmp (path, filename) == 0)
2705 {
2706 shx = 1;
2707 len = strlen (filename);
2708 mem_shp->shx.path = malloc (len + 1);
2709 strcpy (mem_shp->shx.path, filename);
2710 }
2711 sqlite3_free (path);
2712 }
2713 if (!dbf)
2714 {
2715 path = sqlite3_mprintf ("%s.dbf", shp_path);
2716 if (strcasecmp (path, filename) == 0)
2717 {
2718 dbf = 1;
2719 len = strlen (filename);
2720 mem_shp->dbf.path = malloc (len + 1);
2721 strcpy (mem_shp->dbf.path, filename);
2722 }
2723 sqlite3_free (path);
2724 }
2725 if (!prj)
2726 {
2727 path = sqlite3_mprintf ("%s.prj", shp_path);
2728 if (strcasecmp (path, filename) == 0)
2729 {
2730 prj = 1;
2731 len = strlen (filename);
2732 mem_shp->prj.path = malloc (len + 1);
2733 strcpy (mem_shp->prj.path, filename);
2734 }
2735 sqlite3_free (path);
2736 }
2737 }
2738
2739 if (i + 1 == gi.number_entry)
2740 break;
2741 ret = unzGoToNextFile (uf);
2742 if (ret != UNZ_OK)
2743 {
2744 spatialite_e ("Error %d with zipfile in unzGoToNextFile\n",
2745 ret);
2746 goto error;
2747 }
2748 }
2749 if (dbf_mode && dbf)
2750 return mem_shp;
2751 if (shp && shx && dbf)
2752 return mem_shp;
2753
2754 error:
2755 destroy_zip_mem_shapefile (mem_shp);
2756 return NULL;
2757 }
2758
2759 static int
do_read_zipfile_file(unzFile uf,struct zip_mem_shapefile * mem_shape,int wich)2760 do_read_zipfile_file (unzFile uf, struct zip_mem_shapefile *mem_shape, int wich)
2761 {
2762 //
2763 // impo
2764 int is_open = 0;
2765 int retval = 1;
2766 uint64_t size_buf;
2767 uint64_t rd_cnt;
2768 uint64_t unrd_cnt;
2769 unsigned char *buf = NULL;
2770 char filename[256];
2771 gaiaMemFilePtr mem_file;
2772 unz_file_info64 file_info;
2773 int err;
2774
2775 switch (wich)
2776 {
2777 case GAIA_ZIPFILE_SHP:
2778 mem_file = &(mem_shape->shp);
2779 break;
2780 case GAIA_ZIPFILE_SHX:
2781 mem_file = &(mem_shape->shx);
2782 break;
2783 case GAIA_ZIPFILE_DBF:
2784 mem_file = &(mem_shape->dbf);
2785 break;
2786 case GAIA_ZIPFILE_PRJ:
2787 mem_file = &(mem_shape->prj);
2788 break;
2789 default:
2790 mem_file = NULL;
2791 };
2792 if (mem_file == NULL)
2793 return 0;
2794 if (mem_file->path == NULL)
2795 return 0;
2796
2797 err = unzLocateFile (uf, mem_file->path, 0);
2798 if (err != UNZ_OK)
2799 {
2800 spatialite_e ("File %s not found within zipfile\n", mem_file->path);
2801 retval = 0;
2802 goto skip;
2803 }
2804 err =
2805 unzGetCurrentFileInfo64 (uf, &file_info, filename, 256, NULL, 0, NULL,
2806 0);
2807 if (err != UNZ_OK)
2808 {
2809 spatialite_e ("Error %d with zipfile in unzGetCurrentFileInfo\n",
2810 err);
2811 retval = 0;
2812 goto skip;
2813 }
2814 size_buf = file_info.uncompressed_size;
2815 buf = malloc (size_buf);
2816 err = unzOpenCurrentFile (uf);
2817 if (err != UNZ_OK)
2818 {
2819 spatialite_e ("Error %d with zipfile in unzGetCurrentFileInfo\n",
2820 err);
2821 retval = 0;
2822 goto skip;
2823 }
2824 is_open = 1;
2825 rd_cnt = 0;
2826 while (rd_cnt < size_buf)
2827 {
2828 /* reading big chunks so to avoid large file issues */
2829 uint32_t max = 1000000000; /* max chunk size */
2830 uint32_t len;
2831 unrd_cnt = size_buf - rd_cnt;
2832 if (unrd_cnt < max)
2833 len = unrd_cnt;
2834 else
2835 len = max;
2836 err = unzReadCurrentFile (uf, buf + rd_cnt, len);
2837 if (err < 0)
2838 {
2839 spatialite_e ("Error %d with zipfile in unzReadCurrentFile\n",
2840 err);
2841 retval = 0;
2842 goto skip;
2843 }
2844 rd_cnt += len;
2845 }
2846 mem_file->buf = buf;
2847 mem_file->size = size_buf;
2848
2849 skip:
2850 if (buf != NULL && !retval)
2851 free (buf);
2852 if (is_open)
2853 unzCloseCurrentFile (uf);
2854 return retval;
2855 }
2856
2857 SPATIALITE_DECLARE int
load_zip_shapefile(sqlite3 * sqlite,const char * zip_path,const char * shp_path,const char * table,const char * charset,int srid,const char * g_column,const char * gtype,const char * pk_column,int coerce2d,int compressed,int verbose,int spatial_index,int text_dates,int * rows,int colname_case,char * err_msg)2858 load_zip_shapefile (sqlite3 * sqlite, const char *zip_path,
2859 const char *shp_path, const char *table,
2860 const char *charset, int srid, const char *g_column,
2861 const char *gtype, const char *pk_column, int coerce2d,
2862 int compressed, int verbose, int spatial_index,
2863 int text_dates, int *rows, int colname_case, char *err_msg)
2864 {
2865 /* loading a Shapefile from within a Zipfile */
2866 unzFile uf = NULL;
2867 int retval = 0;
2868 struct zip_mem_shapefile *mem_shape = NULL;
2869
2870 if (zip_path == NULL)
2871 {
2872 spatialite_e ("load zip shapefile error: <%s>\n",
2873 "NULL zipfile path");
2874 return 0;
2875 }
2876 /* opening the Zipfile expected to contain the Shapefile */
2877 uf = unzOpen64 (zip_path);
2878 if (uf == NULL)
2879 {
2880 spatialite_e ("Unable to Open %s\n", zip_path);
2881 return 0;
2882 }
2883 /* parsing the Zipfile directory */
2884 mem_shape = do_list_zipfile_dir (uf, shp_path, 0);
2885 if (mem_shape == NULL)
2886 {
2887 spatialite_e ("No SHP %s with Zipfile\n", shp_path);
2888 goto stop;
2889 }
2890 /* unzipping the SHP member */
2891 if (!do_read_zipfile_file (uf, mem_shape, GAIA_ZIPFILE_SHP))
2892 goto stop;
2893 /* unzipping the SHX member */
2894 if (!do_read_zipfile_file (uf, mem_shape, GAIA_ZIPFILE_SHX))
2895 goto stop;
2896 /* unzipping the DBF member */
2897 if (!do_read_zipfile_file (uf, mem_shape, GAIA_ZIPFILE_DBF))
2898 goto stop;
2899 /* unzipping the PRJ member */
2900 if (!do_read_zipfile_file (uf, mem_shape, GAIA_ZIPFILE_PRJ))
2901 goto stop;
2902
2903 /* doing the hard work */
2904 if (load_shapefile_common
2905 (mem_shape, sqlite, shp_path, table, charset, srid, g_column, gtype,
2906 pk_column, coerce2d, compressed, verbose, spatial_index, text_dates,
2907 rows, colname_case, err_msg))
2908 retval = 1;
2909
2910 stop:
2911 unzClose (uf);
2912 if (mem_shape != NULL)
2913 destroy_zip_mem_shapefile (mem_shape);
2914 return retval;
2915 }
2916
2917 GAIAGEO_DECLARE gaiaDbfPtr
gaiaOpenZipDbf(const char * zip_path,const char * filename,const char * charFrom,const char * charTo)2918 gaiaOpenZipDbf (const char *zip_path, const char *filename,
2919 const char *charFrom, const char *charTo)
2920 {
2921 /* creating a DBF object (just for checking its fields) */
2922 unzFile uf = NULL;
2923 struct zip_mem_shapefile *mem_shape = NULL;
2924 gaiaDbfPtr dbf = NULL;
2925
2926 if (zip_path == NULL)
2927 {
2928 spatialite_e ("open zip dbf error: <%s>\n", "NULL zipfile path");
2929 return 0;
2930 }
2931 /* opening the Zipfile expected to contain the Shapefile */
2932 uf = unzOpen64 (zip_path);
2933 if (uf == NULL)
2934 {
2935 spatialite_e ("Unable to Open %s\n", zip_path);
2936 return 0;
2937 }
2938 /* parsing the Zipfile directory */
2939 mem_shape = do_list_zipfile_dir (uf, filename, 1);
2940 if (mem_shape == NULL)
2941 {
2942 spatialite_e ("No DBF %s with Zipfile\n", filename);
2943 goto stop;
2944 }
2945 /* unzipping the DBF member */
2946 if (!do_read_zipfile_file (uf, mem_shape, GAIA_ZIPFILE_DBF))
2947 goto stop;
2948 /* attempting to create and initialize the DBF object */
2949 dbf = gaiaAllocDbf ();
2950 dbf->memDbf = &(mem_shape->dbf);
2951 gaiaOpenDbfRead (dbf, filename, charFrom, charTo);
2952
2953 stop:
2954 unzClose (uf);
2955 destroy_zip_mem_shapefile (mem_shape);
2956 return dbf;
2957 }
2958
2959 SPATIALITE_DECLARE int
load_zip_dbf(sqlite3 * sqlite,const char * zip_path,const char * dbf_path,const char * table,const char * pk_column,const char * charset,int verbose,int text_dates,int * rows,int colname_case,char * err_msg)2960 load_zip_dbf (sqlite3 * sqlite, const char *zip_path, const char *dbf_path,
2961 const char *table, const char *pk_column, const char *charset,
2962 int verbose, int text_dates, int *rows,
2963 int colname_case, char *err_msg)
2964 {
2965 /* loading a DBF file from within a Zipfile */
2966 unzFile uf = NULL;
2967 int retval = 0;
2968 struct zip_mem_shapefile *mem_shape = NULL;
2969
2970 if (zip_path == NULL)
2971 {
2972 spatialite_e ("load zip shapefile error: <%s>\n",
2973 "NULL zipfile path");
2974 return 0;
2975 }
2976 /* opening the Zipfile expected to contain the Shapefile */
2977 uf = unzOpen64 (zip_path);
2978 if (uf == NULL)
2979 {
2980 spatialite_e ("Unable to Open %s\n", zip_path);
2981 return 0;
2982 }
2983 /* parsing the Zipfile directory */
2984 mem_shape = do_list_zipfile_dir (uf, dbf_path, 1);
2985 if (mem_shape == NULL)
2986 {
2987 spatialite_e ("No DBF %s with Zipfile\n", dbf_path);
2988 goto stop;
2989 }
2990 /* unzipping the DBF member */
2991 if (!do_read_zipfile_file (uf, mem_shape, GAIA_ZIPFILE_DBF))
2992 goto stop;
2993
2994 /* doing the hard work */
2995 if (load_dbf_common
2996 (mem_shape, sqlite, dbf_path, table, pk_column, charset, verbose,
2997 text_dates, rows, colname_case, err_msg))
2998 retval = 1;
2999
3000 stop:
3001 unzClose (uf);
3002 if (mem_shape != NULL)
3003 destroy_zip_mem_shapefile (mem_shape);
3004 return retval;
3005 }
3006
3007 #endif /* end MINIZIP */
3008
3009 #ifndef OMIT_PROJ /* including PROJ */
3010 #ifdef PROJ_NEW /* only if new PROJ.6 is supported */
3011 static int
output_prj_file_proj_new(int srid,const char * path,void * proj_ctx)3012 output_prj_file_proj_new (int srid, const char *path, void *proj_ctx)
3013 {
3014 /* attempting to export a genuine ESRI WKT */
3015 PJ_CONTEXT *ctx = (PJ_CONTEXT *) proj_ctx;
3016 PJ *crs_def;
3017 FILE *out;
3018 const char *projPath;
3019 const char *auth_name = "EPSG";
3020 char dummy[64];
3021 const char *wkt;
3022 char *prj_path;
3023 char *options[4];
3024 options[0] = "MULTILINE=NO";
3025 options[1] = "INDENTATION_WIDTH=4";
3026 options[2] = "OUTPUT_AXIS=AUTO";
3027 options[3] = NULL;
3028
3029 if (ctx == NULL)
3030 goto error;
3031 projPath = proj_context_get_database_path (ctx);
3032 if (projPath == NULL)
3033 goto error; /* PROJ's own SQLite DB is undefined */
3034
3035 /* attemping to get an ESRI WKT from PROJ.6 */
3036 sprintf (dummy, "%d", srid);
3037 crs_def =
3038 proj_create_from_database (ctx, auth_name, dummy, PJ_CATEGORY_CRS, 0,
3039 NULL);
3040 if (crs_def != NULL)
3041 {
3042 wkt =
3043 proj_as_wkt (ctx, crs_def, PJ_WKT1_ESRI,
3044 (const char *const *) options);
3045 if (wkt != NULL)
3046 {
3047 /* generating the .PRJ file */
3048 prj_path = sqlite3_mprintf ("%s.prj", path);
3049 #ifdef _WIN32
3050 out = gaia_win_fopen (prj_path, "wb");
3051 #else
3052 out = fopen (prj_path, "wb");
3053 #endif
3054 sqlite3_free (prj_path);
3055 if (out)
3056 {
3057 fprintf (out, "%s\r\n", wkt);
3058 fclose (out);
3059 }
3060 }
3061 proj_destroy (crs_def);
3062 }
3063 return 1;
3064
3065 error:
3066 return 0;
3067 }
3068 #endif
3069 #endif
3070
3071 static void
output_prj_file(sqlite3 * sqlite,char * path,char * table,char * column,void * proj_ctx)3072 output_prj_file (sqlite3 * sqlite, char *path, char *table, char *column,
3073 void *proj_ctx)
3074 {
3075 /* exporting [if possible] a .PRJ file */
3076 char **results;
3077 int rows;
3078 int columns;
3079 int i;
3080 char *errMsg = NULL;
3081 int srid = -1;
3082 char *sql;
3083 int ret;
3084 int rs_srid = 0;
3085 int rs_srs_wkt = 0;
3086 int rs_srtext = 0;
3087 int has_srtext = 0;
3088 const char *name;
3089 char *srsWkt = NULL;
3090 FILE *out;
3091
3092 /* step I: retrieving the SRID */
3093 sql = sqlite3_mprintf ("SELECT srid FROM geometry_columns WHERE "
3094 "Lower(f_table_name) = Lower(%Q) AND "
3095 "Lower(f_geometry_column) = Lower(%Q)",
3096 table, column);
3097 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
3098 sqlite3_free (sql);
3099 if (ret != SQLITE_OK)
3100 {
3101 spatialite_e ("dump shapefile MetaData error: <%s>\n", errMsg);
3102 sqlite3_free (errMsg);
3103 return;
3104 }
3105 for (i = 1; i <= rows; i++)
3106 {
3107 srid = atoi (results[(i * columns) + 0]);
3108 }
3109 sqlite3_free_table (results);
3110 if (srid <= 0)
3111 {
3112 /* srid still undefined, so we'll read VIEWS_GEOMETRY_COLUMNS */
3113 sql = sqlite3_mprintf ("SELECT srid FROM views_geometry_columns "
3114 "JOIN geometry_columns USING (f_table_name, f_geometry_column) "
3115 "WHERE Lower(view_name) = Lower(%Q) AND "
3116 "Lower(view_geometry) = Lower(%Q)",
3117 table, column);
3118 ret =
3119 sqlite3_get_table (sqlite, sql, &results, &rows, &columns,
3120 &errMsg);
3121 sqlite3_free (sql);
3122 if (ret != SQLITE_OK)
3123 {
3124 spatialite_e ("dump shapefile MetaData error: <%s>\n", errMsg);
3125 sqlite3_free (errMsg);
3126 return;
3127 }
3128 for (i = 1; i <= rows; i++)
3129 {
3130 srid = atoi (results[(i * columns) + 0]);
3131 }
3132 sqlite3_free_table (results);
3133 }
3134 if (srid <= 0)
3135 return;
3136
3137 #ifndef OMIT_PROJ /* including PROJ */
3138 #ifdef PROJ_NEW
3139 /* if new PROJ.6 is available we'll attempt first to export a genuine ESRI WKT */
3140 if (proj_ctx != NULL)
3141 {
3142 if (output_prj_file_proj_new (srid, path, proj_ctx))
3143 return;
3144 }
3145 #else
3146 /* suppressing stupid compiler warnings about unused args */
3147 if (proj_ctx == NULL)
3148 proj_ctx = NULL;
3149 #endif
3150 #endif
3151
3152 /* step II: checking if the SRS_WKT or SRTEXT column actually exists */
3153 ret =
3154 sqlite3_get_table (sqlite, "PRAGMA table_info(spatial_ref_sys)",
3155 &results, &rows, &columns, &errMsg);
3156 if (ret != SQLITE_OK)
3157 {
3158 spatialite_e ("dump shapefile MetaData error: <%s>\n", errMsg);
3159 sqlite3_free (errMsg);
3160 return;
3161 }
3162 if (rows < 1)
3163 ;
3164 else
3165 {
3166 for (i = 1; i <= rows; i++)
3167 {
3168 name = results[(i * columns) + 1];
3169 if (strcasecmp (name, "srid") == 0)
3170 rs_srid = 1;
3171 if (strcasecmp (name, "srs_wkt") == 0)
3172 rs_srs_wkt = 1;
3173 if (strcasecmp (name, "srtext") == 0)
3174 rs_srtext = 1;
3175 }
3176 }
3177 sqlite3_free_table (results);
3178 if (rs_srs_wkt == 1 || rs_srtext == 1)
3179 has_srtext = 1;
3180 if (rs_srid == 0 || has_srtext == 0)
3181 return;
3182
3183 /* step III: fetching WKT SRS */
3184 if (rs_srtext)
3185 {
3186 sql = sqlite3_mprintf ("SELECT srtext FROM spatial_ref_sys "
3187 "WHERE srid = %d AND srtext IS NOT NULL",
3188 srid);
3189 }
3190 else
3191 {
3192 sql = sqlite3_mprintf ("SELECT srs_wkt FROM spatial_ref_sys "
3193 "WHERE srid = %d AND srs_wkt IS NOT NULL",
3194 srid);
3195 }
3196 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
3197 sqlite3_free (sql);
3198 if (ret != SQLITE_OK)
3199 {
3200 spatialite_e ("dump shapefile MetaData error: <%s>\n", errMsg);
3201 sqlite3_free (errMsg);
3202 goto end;
3203 }
3204 if (rows < 1)
3205 ;
3206 else
3207 {
3208 for (i = 1; i <= rows; i++)
3209 {
3210 char *srs = results[(i * columns) + 0];
3211 int len = strlen (srs);
3212 if (srsWkt)
3213 free (srsWkt);
3214 srsWkt = malloc (len + 1);
3215 strcpy (srsWkt, srs);
3216 }
3217 }
3218 sqlite3_free_table (results);
3219 if (srsWkt == NULL)
3220 goto end;
3221
3222 /* step IV: generating the .PRJ file */
3223 sql = sqlite3_mprintf ("%s.prj", path);
3224 #ifdef _WIN32
3225 out = gaia_win_fopen (sql, "wb");
3226 #else
3227 out = fopen (sql, "wb");
3228 #endif
3229 sqlite3_free (sql);
3230 if (!out)
3231 goto end;
3232 fprintf (out, "%s\r\n", srsWkt);
3233 fclose (out);
3234 end:
3235 if (srsWkt)
3236 free (srsWkt);
3237 return;
3238 }
3239
3240 static int
get_default_dbf_fields(sqlite3 * sqlite,const char * xtable,const char * db_prefix,const char * table_name,gaiaDbfListPtr * dbf_export_list)3241 get_default_dbf_fields (sqlite3 * sqlite, const char *xtable,
3242 const char *db_prefix, const char *table_name,
3243 gaiaDbfListPtr * dbf_export_list)
3244 {
3245 /* creating DBF field definitions for an empty DBF */
3246 int row = 0;
3247 char *sql;
3248 sqlite3_stmt *stmt;
3249 int ret;
3250 int offset = 0;
3251 gaiaDbfListPtr list = NULL;
3252
3253 if (db_prefix != NULL && table_name != NULL)
3254 {
3255 char *xprefix = gaiaDoubleQuotedSql (db_prefix);
3256 char *xxtable = gaiaDoubleQuotedSql (table_name);
3257 sql =
3258 sqlite3_mprintf ("PRAGMA \"%s\".table_info(\"%s\")", xprefix,
3259 xxtable);
3260 free (xprefix);
3261 free (xxtable);
3262 }
3263 else
3264 sql = sqlite3_mprintf ("PRAGMA table_info(\"%s\")", xtable);
3265 /*
3266 / compiling SQL prepared statement
3267 */
3268
3269 list = gaiaAllocDbfList ();
3270 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
3271 sqlite3_free (sql);
3272 if (ret != SQLITE_OK)
3273 goto sql_error;
3274 while (1)
3275 {
3276 ret = sqlite3_step (stmt);
3277 if (ret == SQLITE_DONE)
3278 break; /* end of result set */
3279 if (ret == SQLITE_ROW)
3280 {
3281 /* processing a result set row */
3282 int xtype = SQLITE_TEXT;
3283 int length = 60;
3284 char *name = (char *) sqlite3_column_text (stmt, 1);
3285 const char *type = (const char *) sqlite3_column_text (stmt, 2);
3286
3287 if (strcasecmp (type, "INT") == 0
3288 || strcasecmp (type, "INTEGER") == 0
3289 || strcasecmp (type, "SMALLINT") == 0
3290 || strcasecmp (type, "BIGINT") == 0
3291 || strcasecmp (type, "TINYINT") == 0)
3292 xtype = SQLITE_INTEGER;
3293 if (strcasecmp (type, "DOUBLE") == 0
3294 || strcasecmp (type, "REAL") == 0
3295 || strcasecmp (type, "DOUBLE PRECISION") == 0
3296 || strcasecmp (type, "NUMERIC") == 0
3297 || strcasecmp (type, "FLOAT") == 0)
3298 xtype = SQLITE_FLOAT;
3299 if (strncasecmp (type, "VARCHAR(", 8) == 0)
3300 length = atoi (type + 8);
3301 if (strncasecmp (type, "CHAR(", 5) == 0)
3302 length = atoi (type + 5);
3303
3304 if (xtype == SQLITE_FLOAT)
3305 {
3306 gaiaAddDbfField (list, name, 'N', offset, 19, 6);
3307 offset += 19;
3308 }
3309 else if (xtype == SQLITE_INTEGER)
3310 {
3311 gaiaAddDbfField (list, name, 'N', offset, 18, 0);
3312 offset += 18;
3313 }
3314 else
3315 {
3316 gaiaAddDbfField (list, name, 'C', offset, (char) length,
3317 0);
3318 offset += length;
3319 }
3320 row++;
3321 }
3322 else
3323 goto sql_error;
3324 }
3325 sqlite3_finalize (stmt);
3326 if (row == 0)
3327 goto sql_error;
3328 *dbf_export_list = list;
3329 return 1;
3330 sql_error:
3331 gaiaFreeDbfList (list);
3332 *dbf_export_list = NULL;
3333 return 0;
3334 }
3335
3336 static gaiaVectorLayersListPtr
recover_unregistered_geometry(sqlite3 * handle,const char * table,const char * geometry)3337 recover_unregistered_geometry (sqlite3 * handle, const char *table,
3338 const char *geometry)
3339 {
3340 /* attempting to recover an unregistered Geometry */
3341 int len;
3342 int error = 0;
3343 gaiaVectorLayersListPtr list;
3344 gaiaVectorLayerPtr lyr;
3345
3346 /* allocating a VectorLayersList */
3347 list = malloc (sizeof (gaiaVectorLayersList));
3348 list->First = NULL;
3349 list->Last = NULL;
3350 list->Current = NULL;
3351
3352 lyr = malloc (sizeof (gaiaVectorLayer));
3353 lyr->LayerType = GAIA_VECTOR_UNKNOWN;
3354 len = strlen (table);
3355 lyr->TableName = malloc (len + 1);
3356 strcpy (lyr->TableName, table);
3357 len = strlen (geometry);
3358 lyr->GeometryName = malloc (len + 1);
3359 strcpy (lyr->GeometryName, geometry);
3360 lyr->Srid = 0;
3361 lyr->GeometryType = GAIA_VECTOR_UNKNOWN;
3362 lyr->Dimensions = GAIA_VECTOR_UNKNOWN;
3363 lyr->SpatialIndex = GAIA_SPATIAL_INDEX_NONE;
3364 lyr->ExtentInfos = NULL;
3365 lyr->AuthInfos = NULL;
3366 lyr->First = NULL;
3367 lyr->Last = NULL;
3368 lyr->Next = NULL;
3369 list->Current = NULL;
3370 if (list->First == NULL)
3371 list->First = lyr;
3372 if (list->Last != NULL)
3373 list->Last->Next = lyr;
3374 list->Last = lyr;
3375
3376 if (!doComputeFieldInfos
3377 (handle, lyr->TableName, lyr->GeometryName,
3378 SPATIALITE_STATISTICS_LEGACY, lyr))
3379 error = 1;
3380
3381 if (list->First == NULL || error)
3382 {
3383 gaiaFreeVectorLayersList (list);
3384 return NULL;
3385 }
3386 return list;
3387 }
3388
3389 static int
compute_max_int_length(sqlite3_int64 min,sqlite3_int64 max)3390 compute_max_int_length (sqlite3_int64 min, sqlite3_int64 max)
3391 {
3392 /* determining the buffer size for some INT */
3393 int pos_len = 0;
3394 int neg_len = 1;
3395 sqlite3_int64 value = max;
3396 if (value == 0)
3397 pos_len = 1;
3398 else
3399 {
3400 while (value != 0)
3401 {
3402 pos_len++;
3403 value /= 10;
3404 }
3405 }
3406 if (min >= 0)
3407 return pos_len;
3408 value = min;
3409 while (value != 0)
3410 {
3411 neg_len++;
3412 value /= 10;
3413 }
3414 if (neg_len > pos_len)
3415 return neg_len;
3416 return pos_len;
3417 }
3418
3419 static int
compute_max_dbl_length(double min,double max)3420 compute_max_dbl_length (double min, double max)
3421 {
3422 /* determining the buffer size for some DOUBLE */
3423 int pos_len = 0;
3424 int neg_len = 1;
3425 sqlite3_int64 value;
3426 if (max >= 0.0)
3427 value = (sqlite3_int64) floor (max);
3428 else
3429 value = (sqlite3_int64) ceil (max);
3430 while (value != 0)
3431 {
3432 pos_len++;
3433 value /= 10;
3434 }
3435 if (min >= 0.0)
3436 return pos_len + 7;
3437 value = (sqlite3_int64) ceil (min);
3438 while (value != 0)
3439 {
3440 neg_len++;
3441 value /= 10;
3442 }
3443 if (neg_len > pos_len)
3444 return neg_len + 7;
3445 return pos_len + 7;
3446 }
3447
3448 static void
shp_parse_table_name(const char * tn,char ** db_prefix,char ** table_name)3449 shp_parse_table_name (const char *tn, char **db_prefix, char **table_name)
3450 {
3451 /* attempting to extract an eventual DB prefix */
3452 int i;
3453 int len = strlen (tn);
3454 int i_dot = -1;
3455 int l_db;
3456 int l_tbl;
3457 for (i = 0; i < len; i++)
3458 {
3459 if (tn[i] == '.')
3460 {
3461 i_dot = i;
3462 break;
3463 }
3464 }
3465 if (i_dot >= 1)
3466 {
3467 l_db = i_dot;
3468 l_tbl = len - (i_dot + 1);
3469 *db_prefix = malloc (l_db + 1);
3470 memset (*db_prefix, '\0', l_db + 1);
3471 memcpy (*db_prefix, tn, l_db);
3472 *table_name = malloc (l_tbl + 1);
3473 strcpy (*table_name, tn + i_dot + 1);
3474 return;
3475 }
3476 *table_name = malloc (len + 1);
3477 strcpy (*table_name, tn);
3478 }
3479
3480 static int
get_attached_layer_v4(sqlite3 * handle,const char * db_prefix,const char * table,const char * geometry,gaiaVectorLayersListPtr list)3481 get_attached_layer_v4 (sqlite3 * handle, const char *db_prefix,
3482 const char *table, const char *geometry,
3483 gaiaVectorLayersListPtr list)
3484 {
3485 /* creating a VectorLayersList object - v.4.0.0 DB layout */
3486 char *sql;
3487 int ret;
3488 sqlite3_stmt *stmt;
3489 int error = 0;
3490 char *xdb;
3491
3492 /* querying the vector_layers view */
3493 xdb = gaiaDoubleQuotedSql (db_prefix);
3494 sql =
3495 sqlite3_mprintf
3496 ("SELECT layer_type, table_name, geometry_column, geometry_type, "
3497 "srid, spatial_index_enabled FROM \"%s\".vector_layers "
3498 "WHERE Lower(table_name) = Lower(%Q) AND "
3499 "Lower(geometry_column) = Lower(%Q)", xdb, table, geometry);
3500 free (xdb);
3501 /* compiling SQL prepared statement */
3502 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
3503 sqlite3_free (sql);
3504 if (ret != SQLITE_OK)
3505 {
3506 error = 1;
3507 goto stop;
3508 }
3509 while (1)
3510 {
3511 /* scrolling the result set rows */
3512 ret = sqlite3_step (stmt);
3513 if (ret == SQLITE_DONE)
3514 break; /* end of result set */
3515 if (ret == SQLITE_ROW)
3516 {
3517 /* processing a VectorLayer row */
3518 const char *layer_type =
3519 (const char *) sqlite3_column_text (stmt, 0);
3520 const char *table_name =
3521 (const char *) sqlite3_column_text (stmt, 1);
3522 const char *geometry_column =
3523 (const char *) sqlite3_column_text (stmt, 2);
3524 int geometry_type = sqlite3_column_int (stmt, 3);
3525 int srid = sqlite3_column_int (stmt, 4);
3526 int spatial_index = sqlite3_column_int (stmt, 5);
3527 addVectorLayer (list, layer_type, table_name, geometry_column,
3528 geometry_type, srid, spatial_index);
3529 }
3530 else
3531 error = 1;
3532 }
3533 ret = sqlite3_finalize (stmt);
3534
3535 stop:
3536 if (error)
3537 return 0;
3538
3539 /* querying the vector_layers_statistics view */
3540 xdb = gaiaDoubleQuotedSql (db_prefix);
3541 sql =
3542 sqlite3_mprintf
3543 ("SELECT table_name, geometry_column, row_count, extent_min_x, "
3544 "extent_min_y, extent_max_x, extent_max_y FROM \"%s\".vector_layers_statistics "
3545 "WHERE Lower(table_name) = Lower(%Q) AND "
3546 "Lower(geometry_column) = Lower(%Q)", xdb, table, geometry);
3547 free (xdb);
3548 /* compiling SQL prepared statement */
3549 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
3550 sqlite3_free (sql);
3551 if (ret != SQLITE_OK)
3552 {
3553 error = 1;
3554 goto stop2;
3555 }
3556 while (1)
3557 {
3558 /* scrolling the result set rows */
3559 ret = sqlite3_step (stmt);
3560 if (ret == SQLITE_DONE)
3561 break; /* end of result set */
3562 if (ret == SQLITE_ROW)
3563 {
3564 /* processing a VectorLayer row */
3565 int is_null = 0;
3566 const char *table_name =
3567 (const char *) sqlite3_column_text (stmt, 0);
3568 const char *geometry_column =
3569 (const char *) sqlite3_column_text (stmt, 1);
3570 int count = 0;
3571 double min_x = 0.0;
3572 double min_y = 0.0;
3573 double max_x = 0.0;
3574 double max_y = 0.0;
3575 if (sqlite3_column_type (stmt, 2) == SQLITE_NULL)
3576 is_null = 1;
3577 else
3578 count = sqlite3_column_int (stmt, 2);
3579 if (sqlite3_column_type (stmt, 3) == SQLITE_NULL)
3580 is_null = 1;
3581 else
3582 min_x = sqlite3_column_double (stmt, 3);
3583 if (sqlite3_column_type (stmt, 4) == SQLITE_NULL)
3584 is_null = 1;
3585 else
3586 min_y = sqlite3_column_double (stmt, 4);
3587 if (sqlite3_column_type (stmt, 5) == SQLITE_NULL)
3588 is_null = 1;
3589 else
3590 max_x = sqlite3_column_double (stmt, 5);
3591 if (sqlite3_column_type (stmt, 6) == SQLITE_NULL)
3592 is_null = 1;
3593 else
3594 max_y = sqlite3_column_double (stmt, 6);
3595 if (!is_null)
3596 addVectorLayerExtent (list, table_name, geometry_column,
3597 count, min_x, min_y, max_x, max_y);
3598 }
3599 }
3600 ret = sqlite3_finalize (stmt);
3601
3602 stop2:
3603 /* querying the vector_layers_field_infos view */
3604 xdb = gaiaDoubleQuotedSql (db_prefix);
3605 sql =
3606 sqlite3_mprintf
3607 ("SELECT table_name, geometry_column, ordinal, column_name, "
3608 "null_values, integer_values, double_values, text_values, blob_values,"
3609 "max_size, integer_min, integer_max, double_min, double_max "
3610 "FROM \"%s\".vector_layers_field_infos "
3611 "WHERE Lower(table_name) = Lower(%Q) AND "
3612 "Lower(geometry_column) = Lower(%Q)", xdb, table, geometry);
3613 free (xdb);
3614 /* compiling SQL prepared statement */
3615 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
3616 sqlite3_free (sql);
3617 if (ret != SQLITE_OK)
3618 {
3619 error = 1;
3620 goto stop4;
3621 }
3622 while (1)
3623 {
3624 /* scrolling the result set rows */
3625 ret = sqlite3_step (stmt);
3626 if (ret == SQLITE_DONE)
3627 break; /* end of result set */
3628 if (ret == SQLITE_ROW)
3629 {
3630 /* processing a VectorLayer row */
3631 int null_max_size = 0;
3632 int null_int_range = 0;
3633 int null_double_range = 0;
3634 int max_size = 0;
3635 sqlite3_int64 integer_min;
3636 sqlite3_int64 integer_max;
3637 double double_min = DBL_MAX;
3638 double double_max = 0.0 - DBL_MAX;
3639 const char *table_name =
3640 (const char *) sqlite3_column_text (stmt, 0);
3641 const char *geometry_column =
3642 (const char *) sqlite3_column_text (stmt, 1);
3643 int ordinal = sqlite3_column_int (stmt, 2);
3644 const char *column_name =
3645 (const char *) sqlite3_column_text (stmt, 3);
3646 int null_values = sqlite3_column_int (stmt, 4);
3647 int integer_values = sqlite3_column_int (stmt, 5);
3648 int double_values = sqlite3_column_int (stmt, 6);
3649 int text_values = sqlite3_column_int (stmt, 7);
3650 int blob_values = sqlite3_column_int (stmt, 8);
3651 if (sqlite3_column_type (stmt, 9) == SQLITE_NULL)
3652 null_max_size = 1;
3653 else
3654 max_size = sqlite3_column_int (stmt, 9);
3655 if (sqlite3_column_type (stmt, 10) == SQLITE_NULL
3656 || sqlite3_column_type (stmt, 11) == SQLITE_NULL)
3657 null_int_range = 1;
3658 else
3659 {
3660 integer_min = sqlite3_column_int64 (stmt, 10);
3661 integer_max = sqlite3_column_int64 (stmt, 11);
3662 }
3663 if (sqlite3_column_type (stmt, 12) == SQLITE_NULL
3664 || sqlite3_column_type (stmt, 13) == SQLITE_NULL)
3665 null_double_range = 1;
3666 else
3667 {
3668 double_min = sqlite3_column_double (stmt, 12);
3669 double_max = sqlite3_column_double (stmt, 13);
3670 }
3671 addLayerAttributeField (list, table_name, geometry_column,
3672 ordinal, column_name, null_values,
3673 integer_values, double_values,
3674 text_values, blob_values, null_max_size,
3675 max_size, null_int_range, &integer_min,
3676 &integer_max, null_double_range,
3677 double_min, double_max);
3678 }
3679 }
3680 ret = sqlite3_finalize (stmt);
3681
3682 stop4:
3683 if (error)
3684 return 0;
3685 return 1;
3686 }
3687
3688 static int
check_spatial_metadata(const void * handle,const char * db_prefix)3689 check_spatial_metadata (const void *handle, const char *db_prefix)
3690 {
3691 /* internal utility function:
3692 /
3693 / 0 - if no valid SpatialMetaData were found
3694 / 1 - if SpatiaLite-like (legacy) SpatialMetadata were found
3695 / 2 - if FDO-OGR-like SpatialMetadata were found
3696 / 3 - if SpatiaLite-like (current) SpatialMetadata were found
3697 /
3698 */
3699 sqlite3 *sqlite = (sqlite3 *) handle;
3700 int spatialite_legacy_rs = 0;
3701 int spatialite_rs = 0;
3702 int fdo_rs = 0;
3703 int spatialite_legacy_gc = 0;
3704 int spatialite_gc = 0;
3705 int fdo_gc = 0;
3706 int rs_srid = 0;
3707 int auth_name = 0;
3708 int auth_srid = 0;
3709 int srtext = 0;
3710 int ref_sys_name = 0;
3711 int proj4text = 0;
3712 int f_table_name = 0;
3713 int f_geometry_column = 0;
3714 int geometry_type = 0;
3715 int coord_dimension = 0;
3716 int gc_srid = 0;
3717 int geometry_format = 0;
3718 int type = 0;
3719 int spatial_index_enabled = 0;
3720 char *sql;
3721 int ret;
3722 const char *name;
3723 int i;
3724 char **results;
3725 int rows;
3726 int columns;
3727 char *xdb;
3728 /* checking the GEOMETRY_COLUMNS table */
3729 xdb = gaiaDoubleQuotedSql (db_prefix);
3730 sql = sqlite3_mprintf ("PRAGMA \"%s\".table_info(geometry_columns)", xdb);
3731 free (xdb);
3732 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, NULL);
3733 sqlite3_free (sql);
3734 if (ret != SQLITE_OK)
3735 goto unknown;
3736 if (rows < 1)
3737 ;
3738 else
3739 {
3740 for (i = 1; i <= rows; i++)
3741 {
3742 name = results[(i * columns) + 1];
3743 if (strcasecmp (name, "f_table_name") == 0)
3744 f_table_name = 1;
3745 if (strcasecmp (name, "f_geometry_column") == 0)
3746 f_geometry_column = 1;
3747 if (strcasecmp (name, "geometry_type") == 0)
3748 geometry_type = 1;
3749 if (strcasecmp (name, "coord_dimension") == 0)
3750 coord_dimension = 1;
3751 if (strcasecmp (name, "srid") == 0)
3752 gc_srid = 1;
3753 if (strcasecmp (name, "geometry_format") == 0)
3754 geometry_format = 1;
3755 if (strcasecmp (name, "type") == 0)
3756 type = 1;
3757 if (strcasecmp (name, "spatial_index_enabled") == 0)
3758 spatial_index_enabled = 1;
3759 }
3760 }
3761 sqlite3_free_table (results);
3762 if (f_table_name && f_geometry_column && type && coord_dimension
3763 && gc_srid && spatial_index_enabled)
3764 spatialite_legacy_gc = 1;
3765 if (f_table_name && f_geometry_column && geometry_type && coord_dimension
3766 && gc_srid && spatial_index_enabled)
3767 spatialite_gc = 1;
3768 if (f_table_name && f_geometry_column && geometry_type && coord_dimension
3769 && gc_srid && geometry_format)
3770 fdo_gc = 1;
3771 /* checking the SPATIAL_REF_SYS table */
3772 xdb = gaiaDoubleQuotedSql (db_prefix);
3773 sql = sqlite3_mprintf ("PRAGMA \"%s\".table_info(spatial_ref_sys)", xdb);
3774 free (xdb);
3775 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, NULL);
3776 sqlite3_free (sql);
3777 if (ret != SQLITE_OK)
3778 goto unknown;
3779 if (rows < 1)
3780 ;
3781 else
3782 {
3783 for (i = 1; i <= rows; i++)
3784 {
3785 name = results[(i * columns) + 1];
3786 if (strcasecmp (name, "srid") == 0)
3787 rs_srid = 1;
3788 if (strcasecmp (name, "auth_name") == 0)
3789 auth_name = 1;
3790 if (strcasecmp (name, "auth_srid") == 0)
3791 auth_srid = 1;
3792 if (strcasecmp (name, "srtext") == 0)
3793 srtext = 1;
3794 if (strcasecmp (name, "ref_sys_name") == 0)
3795 ref_sys_name = 1;
3796 if (strcasecmp (name, "proj4text") == 0)
3797 proj4text = 1;
3798 if (strcasecmp (name, "srtext") == 0)
3799 srtext = 1;
3800 }
3801 }
3802 sqlite3_free_table (results);
3803 if (rs_srid && auth_name && auth_srid && ref_sys_name && proj4text
3804 && srtext)
3805 spatialite_rs = 1;
3806 if (rs_srid && auth_name && auth_srid && ref_sys_name && proj4text)
3807 spatialite_legacy_rs = 1;
3808 if (rs_srid && auth_name && auth_srid && srtext)
3809 fdo_rs = 1;
3810 /* verifying the MetaData format */
3811 if (spatialite_legacy_gc && spatialite_legacy_rs)
3812 return 1;
3813 if (fdo_gc && fdo_rs)
3814 return 2;
3815 if (spatialite_gc && spatialite_rs)
3816 return 3;
3817 unknown:
3818 return 0;
3819 }
3820
3821 static int
get_attached_table_layer_legacy(sqlite3 * handle,const char * db_prefix,const char * table,const char * geometry,gaiaVectorLayersListPtr list)3822 get_attached_table_layer_legacy (sqlite3 * handle, const char *db_prefix,
3823 const char *table, const char *geometry,
3824 gaiaVectorLayersListPtr list)
3825 {
3826 /* fetching Table-based geometries */
3827 int ret;
3828 char *sql;
3829 const char *name;
3830 int i;
3831 char **results;
3832 int rows;
3833 int columns;
3834 int f_table = 0;
3835 int f_geometry = 0;
3836 int type = 0;
3837 int dims = 0;
3838 int srid = 0;
3839 int spatial_index = 0;
3840 sqlite3_stmt *stmt;
3841 int error = 0;
3842 char *xdb;
3843
3844 /* checking the GEOMETRY_COLUMN table */
3845 xdb = gaiaDoubleQuotedSql (db_prefix);
3846 sql = sqlite3_mprintf ("PRAGMA \"%s\".table_info(geometry_columns)", xdb);
3847 free (xdb);
3848 ret = sqlite3_get_table (handle, sql, &results, &rows, &columns, NULL);
3849 sqlite3_free (sql);
3850 if (ret != SQLITE_OK)
3851 return 0;
3852 if (rows < 1)
3853 ;
3854 else
3855 {
3856 for (i = 1; i <= rows; i++)
3857 {
3858 name = results[(i * columns) + 1];
3859 if (strcasecmp (name, "f_table_name") == 0)
3860 f_table = 1;
3861 if (strcasecmp (name, "f_geometry_column") == 0)
3862 f_geometry = 1;
3863 if (strcasecmp (name, "type") == 0)
3864 type = 1;
3865 if (strcasecmp (name, "coord_dimension") == 0)
3866 dims = 1;
3867 if (strcasecmp (name, "srid") == 0)
3868 srid = 1;
3869 if (strcasecmp (name, "spatial_index_enabled") == 0)
3870 spatial_index = 1;
3871 }
3872 }
3873 sqlite3_free_table (results);
3874 if (f_table && f_geometry && type && dims && srid && spatial_index)
3875 ;
3876 else
3877 return 1;
3878
3879
3880 xdb = gaiaDoubleQuotedSql (db_prefix);
3881 sql =
3882 sqlite3_mprintf
3883 ("SELECT f_table_name, f_geometry_column, type, coord_dimension, "
3884 "srid, spatial_index_enabled FROM \"%s\".geometry_columns "
3885 "WHERE Lower(f_table_name) = Lower(%Q) AND "
3886 "Lower(f_geometry_column) = Lower(%Q)", xdb, table, geometry);
3887 free (xdb);
3888 /* compiling SQL prepared statement */
3889 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
3890 sqlite3_free (sql);
3891 if (ret != SQLITE_OK)
3892 {
3893 error = 1;
3894 goto stop;
3895 }
3896 while (1)
3897 {
3898 /* scrolling the result set rows */
3899 ret = sqlite3_step (stmt);
3900 if (ret == SQLITE_DONE)
3901 break; /* end of result set */
3902 if (ret == SQLITE_ROW)
3903 {
3904 /* processing a VectorLayer row */
3905 const char *table_name =
3906 (const char *) sqlite3_column_text (stmt, 0);
3907 const char *geometry_column =
3908 (const char *) sqlite3_column_text (stmt, 1);
3909 const char *type = (const char *) sqlite3_column_text (stmt, 2);
3910 const char *dims = (const char *) sqlite3_column_text (stmt, 3);
3911 int srid = sqlite3_column_int (stmt, 4);
3912 int spatial_index = sqlite3_column_int (stmt, 5);
3913 int geometry_type = -1;
3914 if (strcasecmp (type, "POINT") == 0)
3915 geometry_type = 1;
3916 if (strcasecmp (type, "LINESTRING") == 0)
3917 geometry_type = 2;
3918 if (strcasecmp (type, "POLYGON") == 0)
3919 geometry_type = 3;
3920 if (strcasecmp (type, "MULTIPOINT") == 0)
3921 geometry_type = 4;
3922 if (strcasecmp (type, "MULTILINESTRING") == 0)
3923 geometry_type = 5;
3924 if (strcasecmp (type, "MULTIPOLYGON") == 0)
3925 geometry_type = 6;
3926 if (strcasecmp (type, "GEOMETRYCOLLECTION") == 0)
3927 geometry_type = 7;
3928 if (strcasecmp (type, "GEOMETRY") == 0)
3929 geometry_type = 0;
3930 if (strcasecmp (dims, "XYZ") == 0
3931 || strcasecmp (dims, "3") == 0)
3932 geometry_type += 1000;
3933 if (strcasecmp (dims, "XYM") == 0)
3934 geometry_type += 2000;
3935 if (strcasecmp (dims, "XYZM") == 0
3936 || strcasecmp (dims, "4") == 0)
3937 geometry_type += 3000;
3938 addVectorLayer (list, "SpatialTable", table_name,
3939 geometry_column, geometry_type, srid,
3940 spatial_index);
3941 }
3942 else
3943 error = 1;
3944 }
3945 ret = sqlite3_finalize (stmt);
3946
3947 stop:
3948 if (error)
3949 return 0;
3950 return 1;
3951 }
3952
3953 static int
get_attached_view_layer_legacy(sqlite3 * handle,const char * db_prefix,const char * table,const char * geometry,gaiaVectorLayersListPtr list)3954 get_attached_view_layer_legacy (sqlite3 * handle, const char *db_prefix,
3955 const char *table, const char *geometry,
3956 gaiaVectorLayersListPtr list)
3957 {
3958 /* fetching View-based geometries */
3959 int ret;
3960 char *sql;
3961 const char *name;
3962 int i;
3963 char **results;
3964 int rows;
3965 int columns;
3966 int f_table = 0;
3967 int f_geometry = 0;
3968 int type = 0;
3969 int dims = 0;
3970 int srid = 0;
3971 int spatial_index = 0;
3972 int view_name = 0;
3973 int view_geometry = 0;
3974 int fvw_table = 0;
3975 int fvw_geometry = 0;
3976 sqlite3_stmt *stmt;
3977 int error = 0;
3978 char *xdb;
3979
3980 /* checking the GEOMETRY_COLUMN table */
3981 xdb = gaiaDoubleQuotedSql (db_prefix);
3982 sql = sqlite3_mprintf ("PRAGMA \"%s\".table_info(geometry_columns)", xdb);
3983 free (xdb);
3984 ret = sqlite3_get_table (handle, sql, &results, &rows, &columns, NULL);
3985 sqlite3_free (sql);
3986 if (ret != SQLITE_OK)
3987 return 0;
3988 if (rows < 1)
3989 ;
3990 else
3991 {
3992 for (i = 1; i <= rows; i++)
3993 {
3994 name = results[(i * columns) + 1];
3995 if (strcasecmp (name, "f_table_name") == 0)
3996 f_table = 1;
3997 if (strcasecmp (name, "f_geometry_column") == 0)
3998 f_geometry = 1;
3999 if (strcasecmp (name, "type") == 0)
4000 type = 1;
4001 if (strcasecmp (name, "coord_dimension") == 0)
4002 dims = 1;
4003 if (strcasecmp (name, "srid") == 0)
4004 srid = 1;
4005 if (strcasecmp (name, "spatial_index_enabled") == 0)
4006 spatial_index = 1;
4007 }
4008 }
4009 sqlite3_free_table (results);
4010 if (f_table && f_geometry && type && dims && srid && spatial_index)
4011 ;
4012 else
4013 return 1;
4014
4015 /* checking the VIEWS_GEOMETRY_COLUMN table */
4016 xdb = gaiaDoubleQuotedSql (db_prefix);
4017 sql =
4018 sqlite3_mprintf ("PRAGMA \"%s\".table_info(views_geometry_columns)",
4019 xdb);
4020 free (xdb);
4021 ret = sqlite3_get_table (handle, sql, &results, &rows, &columns, NULL);
4022 sqlite3_free (sql);
4023 if (ret != SQLITE_OK)
4024 return 0;
4025 if (rows < 1)
4026 ;
4027 else
4028 {
4029 for (i = 1; i <= rows; i++)
4030 {
4031 name = results[(i * columns) + 1];
4032 if (strcasecmp (name, "view_name") == 0)
4033 view_name = 1;
4034 if (strcasecmp (name, "view_geometry") == 0)
4035 view_geometry = 1;
4036 if (strcasecmp (name, "f_table_name") == 0)
4037 fvw_table = 1;
4038 if (strcasecmp (name, "f_geometry_column") == 0)
4039 fvw_geometry = 1;
4040 }
4041 }
4042 sqlite3_free_table (results);
4043 if (view_name && view_geometry && fvw_table && fvw_geometry)
4044 ;
4045 else
4046 return 1;
4047
4048 xdb = gaiaDoubleQuotedSql (db_prefix);
4049 sql =
4050 sqlite3_mprintf
4051 ("SELECT a.view_name, a.view_geometry, b.type, b.coord_dimension, "
4052 "b.srid, b.spatial_index_enabled FROM \"%s\".views_geometry_columns AS a "
4053 "JOIN \"%s\".geometry_columns AS b ON (Lower(a.f_table_name) = Lower(b.f_table_name) "
4054 "AND Lower(a.f_geometry_column) = Lower(b.f_geometry_column)) "
4055 "WHERE Lower(a.view_name) = Lower(%Q) AND "
4056 "Lower(a.view_geometry) = Lower(%Q)", xdb, xdb, table, geometry);
4057 free (xdb);
4058 /* compiling SQL prepared statement */
4059 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
4060 sqlite3_free (sql);
4061 if (ret != SQLITE_OK)
4062 {
4063 error = 1;
4064 goto stop;
4065 }
4066 while (1)
4067 {
4068 /* scrolling the result set rows */
4069 ret = sqlite3_step (stmt);
4070 if (ret == SQLITE_DONE)
4071 break; /* end of result set */
4072 if (ret == SQLITE_ROW)
4073 {
4074 /* processing a VectorLayer row */
4075 const char *table_name =
4076 (const char *) sqlite3_column_text (stmt, 0);
4077 const char *geometry_column =
4078 (const char *) sqlite3_column_text (stmt, 1);
4079 const char *type = (const char *) sqlite3_column_text (stmt, 2);
4080 const char *dims = (const char *) sqlite3_column_text (stmt, 3);
4081 int srid = sqlite3_column_int (stmt, 4);
4082 int spatial_index = sqlite3_column_int (stmt, 5);
4083 int geometry_type = -1;
4084 if (strcasecmp (type, "POINT") == 0)
4085 geometry_type = 1;
4086 if (strcasecmp (type, "LINESTRING") == 0)
4087 geometry_type = 2;
4088 if (strcasecmp (type, "POLYGON") == 0)
4089 geometry_type = 3;
4090 if (strcasecmp (type, "MULTIPOINT") == 0)
4091 geometry_type = 4;
4092 if (strcasecmp (type, "MULTILINESTRING") == 0)
4093 geometry_type = 5;
4094 if (strcasecmp (type, "MULTIPOLYGON") == 0)
4095 geometry_type = 6;
4096 if (strcasecmp (type, "GEOMETRYCOLLECTION") == 0)
4097 geometry_type = 7;
4098 if (strcasecmp (type, "GEOMETRY") == 0)
4099 geometry_type = 0;
4100 if (strcasecmp (dims, "XYZ") == 0
4101 || strcasecmp (dims, "3") == 0)
4102 geometry_type += 1000;
4103 if (strcasecmp (dims, "XYM") == 0)
4104 geometry_type += 2000;
4105 if (strcasecmp (dims, "XYZM") == 0
4106 || strcasecmp (dims, "4") == 0)
4107 geometry_type += 3000;
4108 addVectorLayer (list, "SpatialView", table_name,
4109 geometry_column, geometry_type, srid,
4110 spatial_index);
4111 }
4112 else
4113 error = 1;
4114 }
4115 ret = sqlite3_finalize (stmt);
4116
4117 stop:
4118 if (error)
4119 return 0;
4120 return 1;
4121 }
4122
4123 static int
get_attached_table_extent_legacy(sqlite3 * handle,const char * db_prefix,const char * table,const char * geometry,gaiaVectorLayersListPtr list)4124 get_attached_table_extent_legacy (sqlite3 * handle, const char *db_prefix,
4125 const char *table, const char *geometry,
4126 gaiaVectorLayersListPtr list)
4127 {
4128 /* fetching Table-based extents */
4129 int ret;
4130 char *sql;
4131 const char *name;
4132 int i;
4133 char **results;
4134 int rows;
4135 int columns;
4136 int f_table = 0;
4137 int f_geometry = 0;
4138 int count = 0;
4139 int minx = 0;
4140 int miny = 0;
4141 int maxx = 0;
4142 int maxy = 0;
4143 sqlite3_stmt *stmt;
4144 char *xdb;
4145
4146 /* checking the LAYER_STATISTICS table */
4147 xdb = gaiaDoubleQuotedSql (db_prefix);
4148 sql = sqlite3_mprintf ("PRAGMA \"%s\".table_info(layer_statistics)", xdb);
4149 free (xdb);
4150 ret = sqlite3_get_table (handle, sql, &results, &rows, &columns, NULL);
4151 sqlite3_free (sql);
4152 if (ret != SQLITE_OK)
4153 return 0;
4154 if (rows < 1)
4155 ;
4156 else
4157 {
4158 for (i = 1; i <= rows; i++)
4159 {
4160 name = results[(i * columns) + 1];
4161 if (strcasecmp (name, "table_name") == 0)
4162 f_table = 1;
4163 if (strcasecmp (name, "geometry_column") == 0)
4164 f_geometry = 1;
4165 if (strcasecmp (name, "row_count") == 0)
4166 count = 1;
4167 if (strcasecmp (name, "extent_min_x") == 0)
4168 minx = 1;
4169 if (strcasecmp (name, "extent_min_y") == 0)
4170 miny = 1;
4171 if (strcasecmp (name, "extent_max_x") == 0)
4172 maxx = 1;
4173 if (strcasecmp (name, "extent_max_y") == 0)
4174 maxy = 1;
4175 }
4176 }
4177 sqlite3_free_table (results);
4178 if (f_table && f_geometry && count && minx && miny && maxx && maxy)
4179 ;
4180 else
4181 return 1;
4182
4183 /* querying the layer_statistics table */
4184 xdb = gaiaDoubleQuotedSql (db_prefix);
4185 sql =
4186 sqlite3_mprintf
4187 ("SELECT table_name, geometry_column, row_count, extent_min_x, "
4188 "extent_min_y, extent_max_x, extent_max_y FROM \"%s\".layer_statistics "
4189 "WHERE Lower(table_name) = Lower(%Q) AND "
4190 "Lower(geometry_column) = Lower(%Q)", xdb, table, geometry);
4191 free (xdb);
4192 /* compiling SQL prepared statement */
4193 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
4194 sqlite3_free (sql);
4195 if (ret != SQLITE_OK)
4196 goto stop;
4197 while (1)
4198 {
4199 /* scrolling the result set rows */
4200 ret = sqlite3_step (stmt);
4201 if (ret == SQLITE_DONE)
4202 break; /* end of result set */
4203 if (ret == SQLITE_ROW)
4204 {
4205 /* processing a VectorLayer row */
4206 int is_null = 0;
4207 const char *table_name =
4208 (const char *) sqlite3_column_text (stmt, 0);
4209 const char *geometry_column =
4210 (const char *) sqlite3_column_text (stmt, 1);
4211 int count = 0;
4212 double min_x = 0.0;
4213 double min_y = 0.0;
4214 double max_x = 0.0;
4215 double max_y = 0.0;
4216 if (sqlite3_column_type (stmt, 2) == SQLITE_NULL)
4217 is_null = 1;
4218 else
4219 count = sqlite3_column_int (stmt, 2);
4220 if (sqlite3_column_type (stmt, 3) == SQLITE_NULL)
4221 is_null = 1;
4222 else
4223 min_x = sqlite3_column_double (stmt, 3);
4224 if (sqlite3_column_type (stmt, 4) == SQLITE_NULL)
4225 is_null = 1;
4226 else
4227 min_y = sqlite3_column_double (stmt, 4);
4228 if (sqlite3_column_type (stmt, 5) == SQLITE_NULL)
4229 is_null = 1;
4230 else
4231 max_x = sqlite3_column_double (stmt, 5);
4232 if (sqlite3_column_type (stmt, 6) == SQLITE_NULL)
4233 is_null = 1;
4234 else
4235 max_y = sqlite3_column_double (stmt, 6);
4236 if (!is_null)
4237 addVectorLayerExtent (list, table_name, geometry_column,
4238 count, min_x, min_y, max_x, max_y);
4239 }
4240 }
4241 ret = sqlite3_finalize (stmt);
4242 stop:
4243 return 1;
4244 }
4245
4246 static int
get_attached_view_extent_legacy(sqlite3 * handle,const char * db_prefix,const char * table,const char * geometry,gaiaVectorLayersListPtr list)4247 get_attached_view_extent_legacy (sqlite3 * handle, const char *db_prefix,
4248 const char *table, const char *geometry,
4249 gaiaVectorLayersListPtr list)
4250 {
4251 /* fetching View-based extents */
4252 int ret;
4253 char *sql;
4254 const char *name;
4255 int i;
4256 char **results;
4257 int rows;
4258 int columns;
4259 int f_table = 0;
4260 int f_geometry = 0;
4261 int count = 0;
4262 int minx = 0;
4263 int miny = 0;
4264 int maxx = 0;
4265 int maxy = 0;
4266 sqlite3_stmt *stmt;
4267 char *xdb;
4268
4269 /* checking the VIEWS_LAYER_STATISTICS table */
4270 xdb = gaiaDoubleQuotedSql (db_prefix);
4271 sql =
4272 sqlite3_mprintf ("PRAGMA \"%s\".table_info(views_layer_statistics)",
4273 xdb);
4274 free (xdb);
4275 ret = sqlite3_get_table (handle, sql, &results, &rows, &columns, NULL);
4276 sqlite3_free (sql);
4277 if (ret != SQLITE_OK)
4278 return 0;
4279 if (rows < 1)
4280 ;
4281 else
4282 {
4283 for (i = 1; i <= rows; i++)
4284 {
4285 name = results[(i * columns) + 1];
4286 if (strcasecmp (name, "view_name") == 0)
4287 f_table = 1;
4288 if (strcasecmp (name, "view_geometry") == 0)
4289 f_geometry = 1;
4290 if (strcasecmp (name, "row_count") == 0)
4291 count = 1;
4292 if (strcasecmp (name, "extent_min_x") == 0)
4293 minx = 1;
4294 if (strcasecmp (name, "extent_min_y") == 0)
4295 miny = 1;
4296 if (strcasecmp (name, "extent_max_x") == 0)
4297 maxx = 1;
4298 if (strcasecmp (name, "extent_max_y") == 0)
4299 maxy = 1;
4300 }
4301 }
4302 sqlite3_free_table (results);
4303 if (f_table && f_geometry && count && minx && miny && maxx && maxy)
4304 ;
4305 else
4306 return 1;
4307
4308 /* querying the views_layer_statistics table */
4309
4310 xdb = gaiaDoubleQuotedSql (db_prefix);
4311 sql =
4312 sqlite3_mprintf
4313 ("SELECT view_name, view_geometry, row_count, extent_min_x, "
4314 "extent_min_y, extent_max_x, extent_max_y FROM \"%s\".views_layer_statistics "
4315 "WHERE Lower(view_name) = Lower(%Q) AND "
4316 "Lower(view_geometry) = Lower(%Q)", xdb, table, geometry);
4317 free (xdb);
4318 /* compiling SQL prepared statement */
4319 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
4320 sqlite3_free (sql);
4321 if (ret != SQLITE_OK)
4322 goto stop;
4323 while (1)
4324 {
4325 /* scrolling the result set rows */
4326 ret = sqlite3_step (stmt);
4327 if (ret == SQLITE_DONE)
4328 break; /* end of result set */
4329 if (ret == SQLITE_ROW)
4330 {
4331 /* processing a VectorLayer row */
4332 int is_null = 0;
4333 const char *table_name =
4334 (const char *) sqlite3_column_text (stmt, 0);
4335 const char *geometry_column =
4336 (const char *) sqlite3_column_text (stmt, 1);
4337 int count = 0;
4338 double min_x = DBL_MAX;
4339 double min_y = DBL_MAX;
4340 double max_x = 0.0 - DBL_MAX;
4341 double max_y = 0.0 - DBL_MAX;
4342 if (sqlite3_column_type (stmt, 2) == SQLITE_NULL)
4343 is_null = 1;
4344 else
4345 count = sqlite3_column_int (stmt, 2);
4346 if (sqlite3_column_type (stmt, 3) == SQLITE_NULL)
4347 is_null = 1;
4348 else
4349 min_x = sqlite3_column_double (stmt, 3);
4350 if (sqlite3_column_type (stmt, 4) == SQLITE_NULL)
4351 is_null = 1;
4352 else
4353 min_y = sqlite3_column_double (stmt, 4);
4354 if (sqlite3_column_type (stmt, 5) == SQLITE_NULL)
4355 is_null = 1;
4356 else
4357 max_x = sqlite3_column_double (stmt, 5);
4358 if (sqlite3_column_type (stmt, 6) == SQLITE_NULL)
4359 is_null = 1;
4360 else
4361 max_y = sqlite3_column_double (stmt, 6);
4362 if (!is_null)
4363 addVectorLayerExtent (list, table_name, geometry_column,
4364 count, min_x, min_y, max_x, max_y);
4365 }
4366 }
4367 ret = sqlite3_finalize (stmt);
4368 stop:
4369 return 1;
4370 }
4371
4372 static gaiaVectorLayersListPtr
attached_layer(sqlite3 * handle,const char * db_prefix,const char * table,const char * geometry)4373 attached_layer (sqlite3 * handle, const char *db_prefix, const char *table,
4374 const char *geometry)
4375 {
4376 /* attempting to support a "layer" from within an attached DB */
4377 gaiaVectorLayersListPtr list;
4378 int metadata_version;
4379 list = malloc (sizeof (gaiaVectorLayersList));
4380 list->First = NULL;
4381 list->Last = NULL;
4382 list->Current = NULL;
4383
4384 metadata_version = check_spatial_metadata (handle, db_prefix);
4385 if (metadata_version == 3)
4386 {
4387 /* current metadata style >= v.4.0.0 */
4388 if (!get_attached_layer_v4 (handle, db_prefix, table, geometry, list))
4389 {
4390 gaiaFreeVectorLayersList (list);
4391 return NULL;
4392 }
4393 if (list->First == NULL)
4394 {
4395 gaiaFreeVectorLayersList (list);
4396 return NULL;
4397 }
4398 return list;
4399 }
4400
4401 /* legacy metadata style <= v.3.x.x */
4402 if (!get_attached_table_layer_legacy
4403 (handle, db_prefix, table, geometry, list))
4404 goto error;
4405 if (!get_attached_view_layer_legacy
4406 (handle, db_prefix, table, geometry, list))
4407 goto error;
4408 if (!get_attached_table_extent_legacy
4409 (handle, db_prefix, table, geometry, list))
4410 goto error;
4411 if (!get_attached_view_extent_legacy
4412 (handle, db_prefix, table, geometry, list))
4413 goto error;
4414
4415 if (list->First == NULL)
4416 {
4417 gaiaFreeVectorLayersList (list);
4418 return NULL;
4419 }
4420 return list;
4421
4422 error:
4423 gaiaFreeVectorLayersList (list);
4424 return NULL;
4425 }
4426
4427 static int
compute_text_length(const char * string,const char * charset)4428 compute_text_length (const char *string, const char *charset)
4429 {
4430 /* computing the actual length of TEXT fields */
4431 int len = 0;
4432 char *converted = sqlite3_malloc (strlen (string) + 1);
4433 strcpy (converted, string);
4434 if (gaiaConvertCharset (&converted, "UTF-8", charset))
4435 len = strlen (converted);
4436 sqlite3_free (converted);
4437 return len;
4438 }
4439
4440 static void
compute_exact_text_max_length(sqlite3 * sqlite,gaiaDbfListPtr dbf_list,const char * table,const char * charset)4441 compute_exact_text_max_length (sqlite3 * sqlite, gaiaDbfListPtr dbf_list,
4442 const char *table, const char *charset)
4443 {
4444 /* computing the exact max length of TEXT fields */
4445 char *sql;
4446 char *prevsql;
4447 char *xtable;
4448 gaiaDbfFieldPtr fld;
4449 int first = 1;
4450 int ok = 0;
4451 int ret;
4452 sqlite3_stmt *stmt = NULL;
4453 int offset = 0;
4454
4455 /* preparing the SQL query */
4456 sql = sqlite3_mprintf ("SELECT");
4457 prevsql = sql;
4458 fld = dbf_list->First;
4459 while (fld)
4460 {
4461 char *xcolumn;
4462 if (fld->Type != 'C')
4463 goto skip_field;
4464 ok = 1;
4465 xcolumn = gaiaDoubleQuotedSql (fld->Name);
4466 if (first)
4467 {
4468 sql = sqlite3_mprintf ("%s \"%s\"", prevsql, xcolumn);
4469 first = 0;
4470 }
4471 else
4472 sql = sqlite3_mprintf ("%s, \"%s\"", prevsql, xcolumn);
4473 free (xcolumn);
4474 sqlite3_free (prevsql);
4475 prevsql = sql;
4476
4477 skip_field:
4478 fld = fld->Next;
4479 }
4480 if (!ok)
4481 {
4482 sqlite3_free (sql);
4483 return;
4484 }
4485
4486 xtable = gaiaDoubleQuotedSql (table);
4487 sql = sqlite3_mprintf ("%s FROM \"%s\"", prevsql, xtable);
4488 sqlite3_free (prevsql);
4489 free (xtable);
4490 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
4491 sqlite3_free (sql);
4492 if (ret != SQLITE_OK)
4493 return;
4494 while (1)
4495 {
4496 /* scrolling the result set rows */
4497 ret = sqlite3_step (stmt);
4498 if (ret == SQLITE_DONE)
4499 break; /* end of result set */
4500 if (ret == SQLITE_ROW)
4501 {
4502 int col = 0;
4503 fld = dbf_list->First;
4504 while (fld)
4505 {
4506 if (fld->Type != 'C')
4507 goto skip_field2;
4508 if (sqlite3_column_type (stmt, col) == SQLITE_TEXT)
4509 {
4510 const char *string = (const char *)
4511 sqlite3_column_text (stmt, col);
4512 char *converted =
4513 sqlite3_malloc (strlen (string) + 1);
4514 strcpy (converted, string);
4515 if (gaiaConvertCharset
4516 (&converted, "UTF-8", charset))
4517 {
4518 /* we need to determine the field length _AFTER_ converting to the output charset */
4519 int len = strlen (converted);
4520 if (len > fld->Length)
4521 fld->Length = len;
4522 sqlite3_free (converted);
4523 }
4524 col++;
4525 }
4526 skip_field2:
4527 fld = fld->Next;
4528 }
4529 }
4530 }
4531 sqlite3_finalize (stmt);
4532
4533 fld = dbf_list->First;
4534 while (fld)
4535 {
4536 /* readjusting all offsets */
4537 fld->Offset = offset;
4538 offset += fld->Length;
4539 fld = fld->Next;
4540 }
4541 }
4542
4543 SPATIALITE_DECLARE int
dump_shapefile(sqlite3 * sqlite,char * table,char * column,char * shp_path,char * charset,char * geom_type,int verbose,int * xrows,char * err_msg)4544 dump_shapefile (sqlite3 * sqlite, char *table, char *column, char *shp_path,
4545 char *charset, char *geom_type, int verbose, int *xrows,
4546 char *err_msg)
4547 {
4548 return dump_shapefile_ex (sqlite, table, column, shp_path, charset,
4549 geom_type, verbose, xrows,
4550 GAIA_DBF_COLNAME_CASE_IGNORE, err_msg);
4551 }
4552
4553 SPATIALITE_DECLARE int
dump_shapefile_ex(sqlite3 * sqlite,char * table,char * column,char * shp_path,char * charset,char * geom_type,int verbose,int * xrows,int colname_case,char * err_msg)4554 dump_shapefile_ex (sqlite3 * sqlite, char *table, char *column, char *shp_path,
4555 char *charset, char *geom_type, int verbose, int *xrows,
4556 int colname_case, char *err_msg)
4557 {
4558 return dump_shapefile_ex2 (sqlite, NULL, table, column, shp_path, charset,
4559 geom_type, verbose, xrows,
4560 colname_case, err_msg);
4561 }
4562
4563 SPATIALITE_DECLARE int
dump_shapefile_ex2(sqlite3 * sqlite,void * proj_ctx,char * table,char * column,char * shp_path,char * charset,char * geom_type,int verbose,int * xrows,int colname_case,char * err_msg)4564 dump_shapefile_ex2 (sqlite3 * sqlite, void *proj_ctx, char *table, char *column,
4565 char *shp_path, char *charset, char *geom_type, int verbose,
4566 int *xrows, int colname_case, char *err_msg)
4567 {
4568 /* SHAPEFILE dump */
4569 char *sql;
4570 char *dummy;
4571 int shape = -1;
4572 int len;
4573 int ret;
4574 sqlite3_stmt *stmt;
4575 int n_cols = 0;
4576 int offset = 0;
4577 int i;
4578 int rows = 0;
4579 char buf[256];
4580 char *xtable;
4581 char *xcolumn;
4582 const void *blob_value;
4583 gaiaShapefilePtr shp = NULL;
4584 gaiaDbfListPtr dbf_list = NULL;
4585 gaiaDbfListPtr dbf_write;
4586 gaiaDbfFieldPtr dbf_field;
4587 gaiaVectorLayerPtr lyr = NULL;
4588 gaiaLayerAttributeFieldPtr fld;
4589 gaiaVectorLayersListPtr list;
4590 char *db_prefix = NULL;
4591 char *table_name = NULL;
4592 char *xprefix;
4593 char *xxtable;
4594 struct auxdbf_list *auxdbf = NULL;
4595
4596 if (xrows)
4597 *xrows = -1;
4598 if (geom_type)
4599 {
4600 /* normalizing required geometry type */
4601 if (strcasecmp ((char *) geom_type, "POINT") == 0)
4602 shape = GAIA_POINT;
4603 if (strcasecmp ((char *) geom_type, "LINESTRING") == 0)
4604 shape = GAIA_LINESTRING;
4605 if (strcasecmp ((char *) geom_type, "POLYGON") == 0)
4606 shape = GAIA_POLYGON;
4607 if (strcasecmp ((char *) geom_type, "MULTIPOINT") == 0)
4608 shape = GAIA_MULTIPOINT;
4609 }
4610 /* is the datasource a genuine registered Geometry ?? */
4611 list = gaiaGetVectorLayersList (sqlite, table, column,
4612 GAIA_VECTORS_LIST_PESSIMISTIC);
4613 if (list == NULL)
4614 {
4615 /* attempting to recover an unregistered Geometry */
4616 list = recover_unregistered_geometry (sqlite, table, column);
4617 }
4618
4619 if (list == NULL)
4620 {
4621 /* attempting to enucleate an eventual DB-prefix */
4622 shp_parse_table_name (table, &db_prefix, &table_name);
4623 if (db_prefix != NULL && table_name != NULL)
4624 list = attached_layer (sqlite, db_prefix, table_name, column);
4625 }
4626
4627 if (list != NULL)
4628 lyr = list->First;
4629 if (lyr == NULL)
4630 {
4631 gaiaFreeVectorLayersList (list);
4632 if (!err_msg)
4633 spatialite_e
4634 ("Unable to detect GeometryType for \"%s\".\"%s\" ... sorry\n",
4635 table, column);
4636 else
4637 sprintf (err_msg,
4638 "Unable to detect GeometryType for \"%s\".\"%s\" ... sorry\n",
4639 table, column);
4640 return 0;
4641 }
4642
4643 switch (lyr->GeometryType)
4644 {
4645 case GAIA_VECTOR_POINT:
4646 switch (lyr->Dimensions)
4647 {
4648 case GAIA_XY:
4649 shape = GAIA_POINT;
4650 break;
4651 case GAIA_XY_Z:
4652 shape = GAIA_POINTZ;
4653 break;
4654 case GAIA_XY_M:
4655 shape = GAIA_POINTM;
4656 break;
4657 case GAIA_XY_Z_M:
4658 shape = GAIA_POINTZM;
4659 break;
4660 };
4661 break;
4662 case GAIA_VECTOR_LINESTRING:
4663 switch (lyr->Dimensions)
4664 {
4665 case GAIA_XY:
4666 shape = GAIA_LINESTRING;
4667 break;
4668 case GAIA_XY_Z:
4669 shape = GAIA_LINESTRINGZ;
4670 break;
4671 case GAIA_XY_M:
4672 shape = GAIA_LINESTRINGM;
4673 break;
4674 case GAIA_XY_Z_M:
4675 shape = GAIA_LINESTRINGZM;
4676 break;
4677 };
4678 break;
4679 case GAIA_VECTOR_POLYGON:
4680 switch (lyr->Dimensions)
4681 {
4682 case GAIA_XY:
4683 shape = GAIA_POLYGON;
4684 break;
4685 case GAIA_XY_Z:
4686 shape = GAIA_POLYGONZ;
4687 break;
4688 case GAIA_XY_M:
4689 shape = GAIA_POLYGONM;
4690 break;
4691 case GAIA_XY_Z_M:
4692 shape = GAIA_POLYGONZM;
4693 break;
4694 };
4695 break;
4696 case GAIA_VECTOR_MULTIPOINT:
4697 switch (lyr->Dimensions)
4698 {
4699 case GAIA_XY:
4700 shape = GAIA_MULTIPOINT;
4701 break;
4702 case GAIA_XY_Z:
4703 shape = GAIA_MULTIPOINTZ;
4704 break;
4705 case GAIA_XY_M:
4706 shape = GAIA_MULTIPOINTM;
4707 break;
4708 case GAIA_XY_Z_M:
4709 shape = GAIA_MULTIPOINTZM;
4710 break;
4711 };
4712 break;
4713 case GAIA_VECTOR_MULTILINESTRING:
4714 switch (lyr->Dimensions)
4715 {
4716 case GAIA_XY:
4717 shape = GAIA_MULTILINESTRING;
4718 break;
4719 case GAIA_XY_Z:
4720 shape = GAIA_MULTILINESTRINGZ;
4721 break;
4722 case GAIA_XY_M:
4723 shape = GAIA_MULTILINESTRINGM;
4724 break;
4725 case GAIA_XY_Z_M:
4726 shape = GAIA_MULTILINESTRINGZM;
4727 break;
4728 };
4729 break;
4730 case GAIA_VECTOR_MULTIPOLYGON:
4731 switch (lyr->Dimensions)
4732 {
4733 case GAIA_XY:
4734 shape = GAIA_MULTIPOLYGON;
4735 break;
4736 case GAIA_XY_Z:
4737 shape = GAIA_MULTIPOLYGONZ;
4738 break;
4739 case GAIA_XY_M:
4740 shape = GAIA_MULTIPOLYGONM;
4741 break;
4742 case GAIA_XY_Z_M:
4743 shape = GAIA_MULTIPOLYGONZM;
4744 break;
4745 };
4746 break;
4747 };
4748
4749 if (shape < 0)
4750 {
4751 if (!err_msg)
4752 spatialite_e
4753 ("Unable to detect GeometryType for \"%s\".\"%s\" ... sorry\n",
4754 table, column);
4755 else
4756 sprintf (err_msg,
4757 "Unable to detect GeometryType for \"%s\".\"%s\" ... sorry\n",
4758 table, column);
4759 return 0;
4760 }
4761 if (verbose)
4762 spatialite_e
4763 ("========\nDumping SQLite table '%s' into shapefile at '%s'\n",
4764 table, shp_path);
4765 /* preparing SQL statement */
4766 xtable = gaiaDoubleQuotedSql (table);
4767 xcolumn = gaiaDoubleQuotedSql (column);
4768 if (shape == GAIA_LINESTRING || shape == GAIA_LINESTRINGZ
4769 || shape == GAIA_LINESTRINGM || shape == GAIA_LINESTRINGZM ||
4770 shape == GAIA_MULTILINESTRING || shape == GAIA_MULTILINESTRINGZ
4771 || shape == GAIA_MULTILINESTRINGM || shape == GAIA_MULTILINESTRINGZM)
4772 {
4773 if (db_prefix != NULL && table_name != NULL)
4774 {
4775 xprefix = gaiaDoubleQuotedSql (db_prefix);
4776 xxtable = gaiaDoubleQuotedSql (table_name);
4777 sql =
4778 sqlite3_mprintf
4779 ("SELECT * FROM \"%s\".\"%s\" WHERE GeometryAliasType(\"%w\") = "
4780 "'LINESTRING' OR GeometryAliasType(\"%w\") = 'MULTILINESTRING' "
4781 "OR \"%s\" IS NULL", xprefix, xxtable, column, column,
4782 xcolumn);
4783 free (xprefix);
4784 free (xxtable);
4785 }
4786 else
4787 sql =
4788 sqlite3_mprintf
4789 ("SELECT * FROM \"%s\" WHERE GeometryAliasType(\"%w\") = "
4790 "'LINESTRING' OR GeometryAliasType(\"%w\") = 'MULTILINESTRING' "
4791 "OR \"%s\" IS NULL", xtable, column, column, xcolumn);
4792 }
4793 else if (shape == GAIA_POLYGON || shape == GAIA_POLYGONZ
4794 || shape == GAIA_POLYGONM || shape == GAIA_POLYGONZM ||
4795 shape == GAIA_MULTIPOLYGON || shape == GAIA_MULTIPOLYGONZ
4796 || shape == GAIA_MULTIPOLYGONM || shape == GAIA_MULTIPOLYGONZM)
4797 {
4798 if (db_prefix != NULL && table_name != NULL)
4799 {
4800 xprefix = gaiaDoubleQuotedSql (db_prefix);
4801 xxtable = gaiaDoubleQuotedSql (table_name);
4802 sql =
4803 sqlite3_mprintf
4804 ("SELECT * FROM \"%s\".\"%s\" WHERE GeometryAliasType(\"%w\") = "
4805 "'POLYGON' OR GeometryAliasType(\"%w\") = 'MULTIPOLYGON'"
4806 "OR \"%s\" IS NULL", xprefix, xxtable, column, column,
4807 xcolumn);
4808 free (xprefix);
4809 free (xxtable);
4810 }
4811 else
4812 sql =
4813 sqlite3_mprintf
4814 ("SELECT * FROM \"%s\" WHERE GeometryAliasType(\"%w\") = "
4815 "'POLYGON' OR GeometryAliasType(\"%w\") = 'MULTIPOLYGON'"
4816 "OR \"%s\" IS NULL", xtable, column, column, xcolumn);
4817 }
4818 else if (shape == GAIA_MULTIPOINT || shape == GAIA_MULTIPOINTZ
4819 || shape == GAIA_MULTIPOINTM || shape == GAIA_MULTIPOINTZM)
4820 {
4821 if (db_prefix != NULL && table_name != NULL)
4822 {
4823 xprefix = gaiaDoubleQuotedSql (db_prefix);
4824 xxtable = gaiaDoubleQuotedSql (table_name);
4825 sql =
4826 sqlite3_mprintf
4827 ("SELECT * FROM \"%s\".\"%s\" WHERE GeometryAliasType(\"%w\") = "
4828 "'POINT' OR GeometryAliasType(\"%w\") = 'MULTIPOINT'"
4829 "OR \"%s\" IS NULL", xprefix, xxtable, column, column,
4830 xcolumn);
4831 free (xprefix);
4832 free (xxtable);
4833 }
4834 else
4835 sql =
4836 sqlite3_mprintf
4837 ("SELECT * FROM \"%s\" WHERE GeometryAliasType(\"%w\") = "
4838 "'POINT' OR GeometryAliasType(\"%w\") = 'MULTIPOINT'"
4839 "OR \"%s\" IS NULL", xtable, column, column, xcolumn);
4840 }
4841 else
4842 {
4843 if (db_prefix != NULL && table_name != NULL)
4844 {
4845 xprefix = gaiaDoubleQuotedSql (db_prefix);
4846 xxtable = gaiaDoubleQuotedSql (table_name);
4847 sql =
4848 sqlite3_mprintf
4849 ("SELECT * FROM \"%s\".\"%s\" WHERE GeometryAliasType(\"%w\") = "
4850 "'POINT' OR \"%s\" IS NULL", xprefix, xxtable, column,
4851 xcolumn);
4852 free (xprefix);
4853 free (xxtable);
4854 }
4855 else
4856 sql =
4857 sqlite3_mprintf
4858 ("SELECT * FROM \"%s\" WHERE GeometryAliasType(\"%w\") = "
4859 "'POINT' OR \"%s\" IS NULL", xtable, column, xcolumn);
4860 }
4861 /* compiling SQL prepared statement */
4862 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
4863 sqlite3_free (sql);
4864 if (ret != SQLITE_OK)
4865 goto sql_error;
4866
4867 if (lyr->First == NULL)
4868 {
4869 /* the datasource is probably empty - zero rows */
4870 if (get_default_dbf_fields
4871 (sqlite, xtable, db_prefix, table_name, &dbf_list))
4872 goto continue_exporting;
4873 }
4874
4875 /* preparing the DBF fields list */
4876 dbf_list = gaiaAllocDbfList ();
4877 offset = 0;
4878 fld = lyr->First;
4879 while (fld)
4880 {
4881 int sql_type = SQLITE_NULL;
4882 int max_len = 0;
4883 if (strcasecmp (fld->AttributeFieldName, column) == 0)
4884 {
4885 /* ignoring the Geometry itself */
4886 fld = fld->Next;
4887 continue;
4888 }
4889 if (fld->IntegerValuesCount > 0 && fld->DoubleValuesCount == 0
4890 && fld->TextValuesCount == 0)
4891 {
4892 sql_type = SQLITE_INTEGER;
4893 max_len = 18;
4894 if (fld->IntRange)
4895 max_len =
4896 compute_max_int_length (fld->IntRange->MinValue,
4897 fld->IntRange->MaxValue);
4898 }
4899 if (fld->DoubleValuesCount > 0 && fld->TextValuesCount == 0)
4900 {
4901 sql_type = SQLITE_FLOAT;
4902 max_len = 19;
4903 if (fld->DoubleRange)
4904 max_len =
4905 compute_max_dbl_length (fld->DoubleRange->MinValue,
4906 fld->DoubleRange->MaxValue);
4907 }
4908 if (fld->TextValuesCount > 0)
4909 {
4910 sql_type = SQLITE_TEXT;
4911 max_len = 254;
4912 if (fld->MaxSize)
4913 max_len = fld->MaxSize->MaxSize;
4914 }
4915 if (sql_type == SQLITE_NULL)
4916 {
4917 /* considering as TEXT(1) */
4918 sql_type = SQLITE_TEXT;
4919 max_len = 1;
4920 }
4921 /* adding a DBF field */
4922 if (sql_type == SQLITE_TEXT)
4923 {
4924 if (max_len == 0) /* avoiding ZERO-length fields */
4925 max_len = 1;
4926 if (max_len > 254)
4927 {
4928 /* DBF C: max allowed lenght */
4929 max_len = 254;
4930 }
4931 gaiaAddDbfField (dbf_list, fld->AttributeFieldName, 'C', offset,
4932 (unsigned char) max_len, 0);
4933 offset += max_len;
4934 }
4935 if (sql_type == SQLITE_FLOAT)
4936 {
4937 if (max_len > 19)
4938 max_len = 19;
4939 if (max_len < 8)
4940 max_len = 8;
4941 gaiaAddDbfField (dbf_list, fld->AttributeFieldName, 'N', offset,
4942 (unsigned char) max_len, 6);
4943 offset += max_len;
4944 }
4945 if (sql_type == SQLITE_INTEGER)
4946 {
4947 if (max_len > 18)
4948 max_len = 18;
4949 gaiaAddDbfField (dbf_list, fld->AttributeFieldName, 'N', offset,
4950 (unsigned char) max_len, 0);
4951 offset += max_len;
4952 }
4953 fld = fld->Next;
4954 }
4955
4956 /* exact computation of TEXT fields max length */
4957 compute_exact_text_max_length (sqlite, dbf_list, table, charset);
4958
4959 /* resetting SQLite query */
4960 continue_exporting:
4961 ret = sqlite3_reset (stmt);
4962 if (ret != SQLITE_OK)
4963 goto sql_error;
4964 /* trying to open shapefile files */
4965 shp = gaiaAllocShapefile ();
4966 gaiaOpenShpWriteEx (shp, shp_path, shape, dbf_list, "UTF-8", charset,
4967 colname_case);
4968 if (!(shp->Valid))
4969 goto no_file;
4970 /* trying to export the .PRJ file */
4971 output_prj_file (sqlite, shp_path, table, column, proj_ctx);
4972 while (1)
4973 {
4974 /* scrolling the result set to dump data into shapefile */
4975 ret = sqlite3_step (stmt);
4976 if (ret == SQLITE_DONE)
4977 break; /* end of result set */
4978 if (ret == SQLITE_ROW)
4979 {
4980 if (n_cols == 0)
4981 n_cols = sqlite3_column_count (stmt);
4982 rows++;
4983 dbf_write = gaiaCloneDbfEntity (dbf_list);
4984 auxdbf = alloc_auxdbf (dbf_write);
4985 for (i = 0; i < n_cols; i++)
4986 {
4987 if (strcasecmp
4988 ((char *) column,
4989 (char *) sqlite3_column_name (stmt, i)) == 0)
4990 {
4991 /* this one is the internal BLOB encoded GEOMETRY to be exported */
4992 if (sqlite3_column_type (stmt, i) != SQLITE_BLOB)
4993 {
4994 /* this one is a NULL Geometry */
4995 dbf_write->Geometry = NULL;
4996 }
4997 else
4998 {
4999 blob_value = sqlite3_column_blob (stmt, i);
5000 len = sqlite3_column_bytes (stmt, i);
5001 dbf_write->Geometry =
5002 gaiaFromSpatiaLiteBlobWkb (blob_value,
5003 len);
5004 }
5005 }
5006 dummy = (char *) sqlite3_column_name (stmt, i);
5007 dbf_field = getDbfField (auxdbf, dummy);
5008 if (!dbf_field)
5009 continue;
5010 if (sqlite3_column_type (stmt, i) == SQLITE_NULL)
5011 {
5012 /* handling NULL values */
5013 gaiaSetNullValue (dbf_field);
5014 }
5015 else
5016 {
5017 switch (dbf_field->Type)
5018 {
5019 case 'N':
5020 if (sqlite3_column_type (stmt, i) ==
5021 SQLITE_INTEGER)
5022 gaiaSetIntValue (dbf_field,
5023 sqlite3_column_int64
5024 (stmt, i));
5025 else if (sqlite3_column_type (stmt, i) ==
5026 SQLITE_FLOAT)
5027 gaiaSetDoubleValue (dbf_field,
5028 sqlite3_column_double
5029 (stmt, i));
5030 else
5031 gaiaSetNullValue (dbf_field);
5032 break;
5033 case 'C':
5034 if (sqlite3_column_type (stmt, i) ==
5035 SQLITE_TEXT)
5036 {
5037 dummy =
5038 (char *) sqlite3_column_text (stmt,
5039 i);
5040 gaiaSetStrValue (dbf_field, dummy);
5041 }
5042 else if (sqlite3_column_type (stmt, i) ==
5043 SQLITE_INTEGER)
5044 {
5045 sprintf (buf, FRMT64,
5046 sqlite3_column_int64 (stmt,
5047 i));
5048 gaiaSetStrValue (dbf_field, buf);
5049 }
5050 else if (sqlite3_column_type (stmt, i) ==
5051 SQLITE_FLOAT)
5052 {
5053 sql = sqlite3_mprintf ("%1.6f",
5054 sqlite3_column_double
5055 (stmt, i));
5056 gaiaSetStrValue (dbf_field, sql);
5057 sqlite3_free (sql);
5058 }
5059 else
5060 gaiaSetNullValue (dbf_field);
5061 break;
5062 };
5063 }
5064 }
5065 free_auxdbf (auxdbf);
5066 auxdbf = NULL;
5067 if (!gaiaWriteShpEntity (shp, dbf_write))
5068 spatialite_e ("shapefile write error\n");
5069 gaiaFreeDbfList (dbf_write);
5070 }
5071 else
5072 goto sql_error;
5073 }
5074 if (auxdbf != NULL)
5075 free_auxdbf (auxdbf);
5076 sqlite3_finalize (stmt);
5077 gaiaFlushShpHeaders (shp);
5078 gaiaFreeShapefile (shp);
5079 free (xtable);
5080 free (xcolumn);
5081 gaiaFreeVectorLayersList (list);
5082 if (verbose)
5083 spatialite_e ("\nExported %d rows into SHAPEFILE\n========\n", rows);
5084 if (xrows)
5085 *xrows = rows;
5086 if (err_msg)
5087 sprintf (err_msg, "Exported %d rows into SHAPEFILE", rows);
5088 if (db_prefix != NULL)
5089 free (db_prefix);
5090 if (table_name != NULL)
5091 free (table_name);
5092 return 1;
5093 sql_error:
5094 /* some SQL error occurred */
5095 if (auxdbf != NULL)
5096 free_auxdbf (auxdbf);
5097 sqlite3_finalize (stmt);
5098 free (xtable);
5099 free (xcolumn);
5100 gaiaFreeVectorLayersList (list);
5101 if (dbf_list)
5102 gaiaFreeDbfList (dbf_list);
5103 if (shp)
5104 gaiaFreeShapefile (shp);
5105 if (!err_msg)
5106 spatialite_e ("SELECT failed: %s", sqlite3_errmsg (sqlite));
5107 else
5108 sprintf (err_msg, "SELECT failed: %s", sqlite3_errmsg (sqlite));
5109 if (db_prefix != NULL)
5110 free (db_prefix);
5111 if (table_name != NULL)
5112 free (table_name);
5113 return 0;
5114 no_file:
5115 /* shapefile can't be created/opened */
5116 if (auxdbf != NULL)
5117 free_auxdbf (auxdbf);
5118 free (xtable);
5119 free (xcolumn);
5120 gaiaFreeVectorLayersList (list);
5121 if (dbf_list)
5122 gaiaFreeDbfList (dbf_list);
5123 if (shp)
5124 gaiaFreeShapefile (shp);
5125 if (!err_msg)
5126 spatialite_e ("ERROR: unable to open '%s' for writing", shp_path);
5127 else
5128 sprintf (err_msg, "ERROR: unable to open '%s' for writing", shp_path);
5129 if (db_prefix != NULL)
5130 free (db_prefix);
5131 if (table_name != NULL)
5132 free (table_name);
5133 return 0;
5134 }
5135
5136 SPATIALITE_DECLARE int
load_dbf(sqlite3 * sqlite,char * dbf_path,char * table,char * charset,int verbose,int * rows,char * err_msg)5137 load_dbf (sqlite3 * sqlite, char *dbf_path, char *table, char *charset,
5138 int verbose, int *rows, char *err_msg)
5139 {
5140 return load_dbf_ex (sqlite, dbf_path, table, NULL, charset, verbose, rows,
5141 err_msg);
5142 }
5143
5144 SPATIALITE_DECLARE int
load_dbf_ex(sqlite3 * sqlite,char * dbf_path,char * table,char * pk_column,char * charset,int verbose,int * rows,char * err_msg)5145 load_dbf_ex (sqlite3 * sqlite, char *dbf_path, char *table, char *pk_column,
5146 char *charset, int verbose, int *rows, char *err_msg)
5147 {
5148 return load_dbf_ex2 (sqlite, dbf_path, table, pk_column, charset, verbose,
5149 0, rows, err_msg);
5150 }
5151
5152 SPATIALITE_DECLARE int
load_dbf_ex2(sqlite3 * sqlite,char * dbf_path,char * table,char * pk_column,char * charset,int verbose,int text_dates,int * rows,char * err_msg)5153 load_dbf_ex2 (sqlite3 * sqlite, char *dbf_path, char *table, char *pk_column,
5154 char *charset, int verbose, int text_dates, int *rows,
5155 char *err_msg)
5156 {
5157 return load_dbf_ex3 (sqlite, dbf_path, table, pk_column, charset, verbose,
5158 text_dates, rows, GAIA_DBF_COLNAME_LOWERCASE, err_msg);
5159 }
5160
5161 SPATIALITE_DECLARE int
load_dbf_ex3(sqlite3 * sqlite,const char * dbf_path,const char * table,const char * pk_column,const char * charset,int verbose,int text_dates,int * rows,int colname_case,char * err_msg)5162 load_dbf_ex3 (sqlite3 * sqlite, const char *dbf_path, const char *table,
5163 const char *pk_column, const char *charset, int verbose,
5164 int text_dates, int *rows, int colname_case, char *err_msg)
5165 {
5166 return load_dbf_common (NULL, sqlite, dbf_path, table, pk_column, charset,
5167 verbose, text_dates, rows, colname_case, err_msg);
5168 }
5169
5170 SPATIALITE_DECLARE int
dump_dbf(sqlite3 * sqlite,char * table,char * dbf_path,char * charset,char * err_msg)5171 dump_dbf (sqlite3 * sqlite, char *table, char *dbf_path, char *charset,
5172 char *err_msg)
5173 {
5174 int rows;
5175 return dump_dbf_ex (sqlite, table, dbf_path, charset, &rows, err_msg);
5176 }
5177
5178 SPATIALITE_DECLARE int
dump_dbf_ex(sqlite3 * sqlite,char * table,char * dbf_path,char * charset,int * xrows,char * err_msg)5179 dump_dbf_ex (sqlite3 * sqlite, char *table, char *dbf_path, char *charset,
5180 int *xrows, char *err_msg)
5181 {
5182 return dump_dbf_ex2 (sqlite, table, dbf_path, charset, xrows,
5183 GAIA_DBF_COLNAME_CASE_IGNORE, err_msg);
5184 }
5185
5186 SPATIALITE_DECLARE int
dump_dbf_ex2(sqlite3 * sqlite,char * table,char * dbf_path,char * charset,int * xrows,int colname_case,char * err_msg)5187 dump_dbf_ex2 (sqlite3 * sqlite, char *table, char *dbf_path, char *charset,
5188 int *xrows, int colname_case, char *err_msg)
5189 {
5190 /* DBF dump */
5191 int rows;
5192 int i;
5193 char *sql;
5194 char *xtable = NULL;
5195 sqlite3_stmt *stmt;
5196 int row1 = 0;
5197 int n_cols = 0;
5198 int offset = 0;
5199 int type;
5200 gaiaDbfPtr dbf = NULL;
5201 gaiaDbfListPtr dbf_export_list = NULL;
5202 gaiaDbfListPtr dbf_list = NULL;
5203 gaiaDbfListPtr dbf_write;
5204 gaiaDbfFieldPtr dbf_field;
5205 int *max_length = NULL;
5206 int *sql_type = NULL;
5207 char *dummy;
5208 char buf[256];
5209 int len;
5210 int ret;
5211 char *db_prefix = NULL;
5212 char *table_name = NULL;
5213 struct auxdbf_list *auxdbf = NULL;
5214
5215 *xrows = -1;
5216 shp_parse_table_name (table, &db_prefix, &table_name);
5217 /*
5218 / preparing SQL statement
5219 */
5220 if (db_prefix != NULL && table_name != NULL)
5221 {
5222 char *xdb = gaiaDoubleQuotedSql (db_prefix);
5223 char *xxtable = gaiaDoubleQuotedSql (table_name);
5224 sql = sqlite3_mprintf ("SELECT * FROM \"%s\".\"%s\"", xdb, xxtable);
5225 free (xdb);
5226 free (xxtable);
5227 }
5228 else
5229 {
5230 xtable = gaiaDoubleQuotedSql (table);
5231 sql = sqlite3_mprintf ("SELECT * FROM \"%s\"", xtable);
5232 }
5233 /*
5234 / compiling SQL prepared statement
5235 */
5236 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5237 sqlite3_free (sql);
5238 if (ret != SQLITE_OK)
5239 goto sql_error;
5240 rows = 0;
5241 while (1)
5242 {
5243 /*
5244 / Pass I - scrolling the result set to compute real DBF attributes' sizes and types
5245 */
5246 ret = sqlite3_step (stmt);
5247 if (ret == SQLITE_DONE)
5248 break; /* end of result set */
5249 if (ret == SQLITE_ROW)
5250 {
5251 /* processing a result set row */
5252 row1++;
5253 if (n_cols == 0)
5254 {
5255 /* this one is the first row, so we are going to prepare the DBF Fields list */
5256 n_cols = sqlite3_column_count (stmt);
5257 dbf_export_list = gaiaAllocDbfList ();
5258 max_length = (int *) malloc (sizeof (int) * n_cols);
5259 sql_type = (int *) malloc (sizeof (int) * n_cols);
5260 for (i = 0; i < n_cols; i++)
5261 {
5262 /* initializes the DBF export fields */
5263 dummy = (char *) sqlite3_column_name (stmt, i);
5264 gaiaAddDbfField (dbf_export_list, dummy, '\0', 0, 0,
5265 0);
5266 max_length[i] = 0;
5267 sql_type[i] = SQLITE_NULL;
5268 }
5269 }
5270 for (i = 0; i < n_cols; i++)
5271 {
5272 /* update the DBF export fields analyzing fetched data */
5273 type = sqlite3_column_type (stmt, i);
5274 if (type == SQLITE_NULL || type == SQLITE_BLOB)
5275 continue;
5276 if (type == SQLITE_TEXT)
5277 {
5278 const char *string =
5279 (const char *) sqlite3_column_text (stmt, i);
5280 len = compute_text_length (string, charset);
5281 if (len > 254)
5282 {
5283 /* DBF C type: max allowed length */
5284 len = 254;
5285 }
5286 sql_type[i] = SQLITE_TEXT;
5287 if (len > max_length[i])
5288 max_length[i] = len;
5289 }
5290 else if (type == SQLITE_FLOAT
5291 && sql_type[i] != SQLITE_TEXT)
5292 sql_type[i] = SQLITE_FLOAT; /* promoting a numeric column to be DOUBLE */
5293 else if (type == SQLITE_INTEGER
5294 && (sql_type[i] == SQLITE_NULL
5295 || sql_type[i] == SQLITE_INTEGER))
5296 sql_type[i] = SQLITE_INTEGER; /* promoting a null column to be INTEGER */
5297 if (type == SQLITE_INTEGER && max_length[i] < 18)
5298 max_length[i] = 18;
5299 if (type == SQLITE_FLOAT && max_length[i] < 24)
5300 max_length[i] = 24;
5301 }
5302 }
5303 else
5304 goto sql_error;
5305 }
5306 if (!row1)
5307 goto empty_result_set;
5308 i = 0;
5309 offset = 0;
5310 dbf_list = gaiaAllocDbfList ();
5311 dbf_field = dbf_export_list->First;
5312 while (dbf_field)
5313 {
5314 /* preparing the final DBF attribute list */
5315 if (sql_type[i] == SQLITE_NULL || sql_type[i] == SQLITE_BLOB)
5316 {
5317 i++;
5318 dbf_field = dbf_field->Next;
5319 continue;
5320 }
5321 if (sql_type[i] == SQLITE_TEXT)
5322 {
5323 gaiaAddDbfField (dbf_list, dbf_field->Name, 'C', offset,
5324 (unsigned char) (max_length[i]), 0);
5325 offset += max_length[i];
5326 }
5327 if (sql_type[i] == SQLITE_FLOAT)
5328 {
5329 gaiaAddDbfField (dbf_list, dbf_field->Name, 'N', offset, 19, 6);
5330 offset += 19;
5331 }
5332 if (sql_type[i] == SQLITE_INTEGER)
5333 {
5334 gaiaAddDbfField (dbf_list, dbf_field->Name, 'N', offset, 18, 0);
5335 offset += 18;
5336 }
5337 i++;
5338 dbf_field = dbf_field->Next;
5339 }
5340 free (max_length);
5341 free (sql_type);
5342 gaiaFreeDbfList (dbf_export_list);
5343 dbf_export_list = NULL;
5344
5345 continue_exporting:
5346 /* resetting SQLite query */
5347 ret = sqlite3_reset (stmt);
5348 if (ret != SQLITE_OK)
5349 goto sql_error;
5350 /* trying to open the DBF file */
5351 dbf = gaiaAllocDbf ();
5352 /* xfering export-list ownership */
5353 dbf->Dbf = dbf_list;
5354 dbf_list = NULL;
5355 gaiaOpenDbfWriteEx (dbf, dbf_path, "UTF-8", charset, colname_case);
5356 if (!(dbf->Valid))
5357 goto no_file;
5358 while (1)
5359 {
5360 /* Pass II - scrolling the result set to dump data into DBF */
5361 ret = sqlite3_step (stmt);
5362 if (ret == SQLITE_DONE)
5363 break; /* end of result set */
5364 if (ret == SQLITE_ROW)
5365 {
5366 rows++;
5367 dbf_write = gaiaCloneDbfEntity (dbf->Dbf);
5368 auxdbf = alloc_auxdbf (dbf_write);
5369 for (i = 0; i < n_cols; i++)
5370 {
5371 dummy = (char *) sqlite3_column_name (stmt, i);
5372 dbf_field = getDbfField (auxdbf, dummy);
5373 if (!dbf_field)
5374 continue;
5375 if (sqlite3_column_type (stmt, i) == SQLITE_NULL
5376 || sqlite3_column_type (stmt, i) == SQLITE_BLOB)
5377 {
5378 /* handling NULL values */
5379 gaiaSetNullValue (dbf_field);
5380 }
5381 else
5382 {
5383 switch (dbf_field->Type)
5384 {
5385 case 'N':
5386 if (sqlite3_column_type (stmt, i) ==
5387 SQLITE_INTEGER)
5388 gaiaSetIntValue (dbf_field,
5389 sqlite3_column_int64
5390 (stmt, i));
5391 else if (sqlite3_column_type (stmt, i) ==
5392 SQLITE_FLOAT)
5393 gaiaSetDoubleValue (dbf_field,
5394 sqlite3_column_double
5395 (stmt, i));
5396 else
5397 gaiaSetNullValue (dbf_field);
5398 break;
5399 case 'C':
5400 if (sqlite3_column_type (stmt, i) ==
5401 SQLITE_TEXT)
5402 {
5403 dummy =
5404 (char *) sqlite3_column_text (stmt,
5405 i);
5406 gaiaSetStrValue (dbf_field, dummy);
5407 }
5408 else if (sqlite3_column_type (stmt, i) ==
5409 SQLITE_INTEGER)
5410 {
5411 sprintf (buf, FRMT64,
5412 sqlite3_column_int64 (stmt,
5413 i));
5414 gaiaSetStrValue (dbf_field, buf);
5415 }
5416 else if (sqlite3_column_type (stmt, i) ==
5417 SQLITE_FLOAT)
5418 {
5419 sql = sqlite3_mprintf ("%1.6f",
5420 sqlite3_column_double
5421 (stmt, i));
5422 gaiaSetStrValue (dbf_field, sql);
5423 sqlite3_free (sql);
5424 }
5425 else
5426 gaiaSetNullValue (dbf_field);
5427 break;
5428 };
5429 }
5430 }
5431 free_auxdbf (auxdbf);
5432 auxdbf = NULL;
5433 if (!gaiaWriteDbfEntity (dbf, dbf_write))
5434 spatialite_e ("DBF write error\n");
5435 gaiaFreeDbfList (dbf_write);
5436 }
5437 else
5438 goto sql_error;
5439 }
5440 if (auxdbf != NULL)
5441 free_auxdbf (auxdbf);
5442 sqlite3_finalize (stmt);
5443 gaiaFlushDbfHeader (dbf);
5444 gaiaFreeDbf (dbf);
5445 free (xtable);
5446 if (!err_msg)
5447 spatialite_e ("Exported %d rows into the DBF file\n", rows);
5448 else
5449 sprintf (err_msg, "Exported %d rows into the DBF file\n", rows);
5450 if (db_prefix != NULL)
5451 free (db_prefix);
5452 if (table_name != NULL)
5453 free (table_name);
5454 *xrows = rows;
5455 return 1;
5456 sql_error:
5457 /* some SQL error occurred */
5458 if (auxdbf != NULL)
5459 free_auxdbf (auxdbf);
5460 free (xtable);
5461 sqlite3_finalize (stmt);
5462 if (dbf_export_list)
5463 gaiaFreeDbfList (dbf_export_list);
5464 if (dbf_list)
5465 gaiaFreeDbfList (dbf_list);
5466 if (dbf)
5467 gaiaFreeDbf (dbf);
5468 if (!err_msg)
5469 spatialite_e ("dump DBF file error: %s\n", sqlite3_errmsg (sqlite));
5470 else
5471 sprintf (err_msg, "dump DBF file error: %s\n", sqlite3_errmsg (sqlite));
5472 if (db_prefix != NULL)
5473 free (db_prefix);
5474 if (table_name != NULL)
5475 free (table_name);
5476 return 0;
5477 no_file:
5478 /* DBF can't be created/opened */
5479 if (auxdbf != NULL)
5480 free_auxdbf (auxdbf);
5481 free (xtable);
5482 if (dbf_export_list)
5483 gaiaFreeDbfList (dbf_export_list);
5484 if (dbf_list)
5485 gaiaFreeDbfList (dbf_list);
5486 if (dbf)
5487 gaiaFreeDbf (dbf);
5488 if (!err_msg)
5489 spatialite_e ("ERROR: unable to open '%s' for writing\n", dbf_path);
5490 else
5491 sprintf (err_msg, "ERROR: unable to open '%s' for writing\n", dbf_path);
5492 if (db_prefix != NULL)
5493 free (db_prefix);
5494 if (table_name != NULL)
5495 free (table_name);
5496 return 0;
5497 empty_result_set:
5498 /* the result set is empty - nothing to do */
5499 if (auxdbf != NULL)
5500 free_auxdbf (auxdbf);
5501 if (get_default_dbf_fields
5502 (sqlite, xtable, db_prefix, table_name, &dbf_list))
5503 goto continue_exporting;
5504 free (xtable);
5505 sqlite3_finalize (stmt);
5506 if (dbf_export_list)
5507 gaiaFreeDbfList (dbf_export_list);
5508 if (dbf_list)
5509 gaiaFreeDbfList (dbf_list);
5510 if (dbf)
5511 gaiaFreeDbf (dbf);
5512 if (!err_msg)
5513 spatialite_e
5514 ("The SQL SELECT returned an empty result set ... there is nothing to export ...\n");
5515 else
5516 sprintf (err_msg,
5517 "The SQL SELECT returned an empty result set ... there is nothing to export ...\n");
5518 if (db_prefix != NULL)
5519 free (db_prefix);
5520 if (table_name != NULL)
5521 free (table_name);
5522 return 0;
5523 }
5524
5525 SPATIALITE_DECLARE int
is_kml_constant(sqlite3 * sqlite,char * table,char * column)5526 is_kml_constant (sqlite3 * sqlite, char *table, char *column)
5527 {
5528 /* checking a possible column name for KML dump */
5529 char *sql;
5530 char *xname;
5531 int ret;
5532 int k = 1;
5533 const char *name;
5534 char **results;
5535 int rows;
5536 int columns;
5537 int i;
5538 char *errMsg = NULL;
5539
5540 xname = gaiaDoubleQuotedSql (table);
5541 sql = sqlite3_mprintf ("PRAGMA table_info(\"%s\")", xname);
5542 free (xname);
5543 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
5544 sqlite3_free (sql);
5545 if (ret != SQLITE_OK)
5546 return 1;
5547 if (rows < 1)
5548 ;
5549 else
5550 {
5551 for (i = 1; i <= rows; i++)
5552 {
5553 name = results[(i * columns) + 1];
5554 if (strcasecmp (name, column) == 0)
5555 k = 0;
5556 }
5557 }
5558 sqlite3_free_table (results);
5559 return k;
5560 }
5561
5562 SPATIALITE_DECLARE int
dump_kml(sqlite3 * sqlite,char * table,char * geom_col,char * kml_path,char * name_col,char * desc_col,int precision)5563 dump_kml (sqlite3 * sqlite, char *table, char *geom_col, char *kml_path,
5564 char *name_col, char *desc_col, int precision)
5565 {
5566 int rows;
5567 return dump_kml_ex (sqlite, table, geom_col, kml_path, name_col, desc_col,
5568 precision, &rows);
5569 }
5570
5571 SPATIALITE_DECLARE int
dump_kml_ex(sqlite3 * sqlite,char * table,char * geom_col,char * kml_path,char * name_col,char * desc_col,int precision,int * xrows)5572 dump_kml_ex (sqlite3 * sqlite, char *table, char *geom_col, char *kml_path,
5573 char *name_col, char *desc_col, int precision, int *xrows)
5574 {
5575 /* dumping a geometry table as KML */
5576 char *sql;
5577 char *xname;
5578 char *xdesc;
5579 char *xgeom_col;
5580 char *xtable;
5581 sqlite3_stmt *stmt = NULL;
5582 FILE *out = NULL;
5583 int ret;
5584 int rows = 0;
5585 int is_const = 1;
5586
5587 *xrows = -1;
5588 /* opening/creating the KML file */
5589 #ifdef _WIN32
5590 out = gaia_win_fopen (kml_path, "wb");
5591 #else
5592 out = fopen (kml_path, "wb");
5593 #endif
5594 if (!out)
5595 goto no_file;
5596
5597 /* preparing SQL statement */
5598 if (name_col == NULL)
5599 xname = sqlite3_mprintf ("%Q", "name");
5600 else
5601 {
5602 is_const = is_kml_constant (sqlite, table, name_col);
5603 if (is_const)
5604 xname = sqlite3_mprintf ("%Q", name_col);
5605 else
5606 {
5607 xname = gaiaDoubleQuotedSql (name_col);
5608 sql = sqlite3_mprintf ("\"%s\"", xname);
5609 free (xname);
5610 xname = sql;
5611 }
5612 }
5613 if (desc_col == NULL)
5614 xdesc = sqlite3_mprintf ("%Q", "description");
5615 else
5616 {
5617 is_const = is_kml_constant (sqlite, table, desc_col);
5618 if (is_const)
5619 xdesc = sqlite3_mprintf ("%Q", desc_col);
5620 else
5621 {
5622 xdesc = gaiaDoubleQuotedSql (desc_col);
5623 sql = sqlite3_mprintf ("\"%s\"", xdesc);
5624 free (xdesc);
5625 xdesc = sql;
5626 }
5627 }
5628 xgeom_col = gaiaDoubleQuotedSql (geom_col);
5629 xtable = gaiaDoubleQuotedSql (table);
5630 sql = sqlite3_mprintf ("SELECT AsKML(%s, %s, %s, %d) FROM \"%s\" "
5631 "WHERE \"%s\" IS NOT NULL", xname, xdesc,
5632 xgeom_col, precision, xtable, xgeom_col);
5633 sqlite3_free (xname);
5634 sqlite3_free (xdesc);
5635 free (xgeom_col);
5636 free (xtable);
5637 /* compiling SQL prepared statement */
5638 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5639 sqlite3_free (sql);
5640 if (ret != SQLITE_OK)
5641 goto sql_error;
5642
5643 while (1)
5644 {
5645 /* scrolling the result set */
5646 ret = sqlite3_step (stmt);
5647 if (ret == SQLITE_DONE)
5648 break; /* end of result set */
5649 if (ret == SQLITE_ROW)
5650 {
5651 /* processing a result set row */
5652 if (rows == 0)
5653 {
5654 fprintf (out,
5655 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
5656 fprintf (out,
5657 "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\r\n");
5658 fprintf (out, "<Document>\r\n");
5659 }
5660 rows++;
5661 fprintf (out, "\t%s\r\n", sqlite3_column_text (stmt, 0));
5662 }
5663 else
5664 goto sql_error;
5665 }
5666 if (!rows)
5667 goto empty_result_set;
5668
5669
5670 fprintf (out, "</Document>\r\n");
5671 fprintf (out, "</kml>\r\n");
5672 sqlite3_finalize (stmt);
5673 fclose (out);
5674 *xrows = rows;
5675 return 1;
5676
5677 sql_error:
5678 /* some SQL error occurred */
5679 if (stmt)
5680 sqlite3_finalize (stmt);
5681 if (out)
5682 fclose (out);
5683 spatialite_e ("Dump KML error: %s\n", sqlite3_errmsg (sqlite));
5684 return 0;
5685 no_file:
5686 /* KML file can't be created/opened */
5687 if (stmt)
5688 sqlite3_finalize (stmt);
5689 if (out)
5690 fclose (out);
5691 spatialite_e ("ERROR: unable to open '%s' for writing\n", kml_path);
5692 return 0;
5693 empty_result_set:
5694 /* the result set is empty - nothing to do */
5695 if (stmt)
5696 sqlite3_finalize (stmt);
5697 if (out)
5698 fclose (out);
5699 spatialite_e
5700 ("The SQL SELECT returned an empty result set\n... there is nothing to export ...\n");
5701 return 0;
5702 }
5703
5704 SPATIALITE_DECLARE int
dump_geojson(sqlite3 * sqlite,char * table,char * geom_col,char * outfile_path,int precision,int option)5705 dump_geojson (sqlite3 * sqlite, char *table, char *geom_col,
5706 char *outfile_path, int precision, int option)
5707 {
5708 int rows;
5709 return dump_geojson_ex (sqlite, table, geom_col, outfile_path, precision,
5710 option, &rows);
5711 }
5712
5713 SPATIALITE_DECLARE int
dump_geojson_ex(sqlite3 * sqlite,char * table,char * geom_col,char * outfile_path,int precision,int option,int * xrows)5714 dump_geojson_ex (sqlite3 * sqlite, char *table, char *geom_col,
5715 char *outfile_path, int precision, int option, int *xrows)
5716 {
5717 /* dumping a geometry table as GeoJSON - Brad Hards 2011-11-09 */
5718 /* sandro furieri 2014-08-30: adding the "int *xrows" argument */
5719 char *sql;
5720 char *xgeom_col;
5721 char *xtable;
5722 sqlite3_stmt *stmt = NULL;
5723 FILE *out = NULL;
5724 int ret;
5725 int rows = 0;
5726
5727 *xrows = -1;
5728 /* opening/creating the GeoJSON output file */
5729 #ifdef _WIN32
5730 out = gaia_win_fopen (outfile_path, "wb");
5731 #else
5732 out = fopen (outfile_path, "wb");
5733 #endif
5734 if (!out)
5735 goto no_file;
5736
5737 /* preparing SQL statement */
5738 xtable = gaiaDoubleQuotedSql (table);
5739 xgeom_col = gaiaDoubleQuotedSql (geom_col);
5740 sql =
5741 sqlite3_mprintf
5742 ("SELECT AsGeoJSON(\"%s\", %d, %d) FROM \"%s\" WHERE \"%s\" IS NOT NULL",
5743 xgeom_col, precision, option, xtable, xgeom_col);
5744 free (xtable);
5745 free (xgeom_col);
5746 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5747 sqlite3_free (sql);
5748 if (ret != SQLITE_OK)
5749 goto sql_error;
5750
5751 while (1)
5752 {
5753 /* scrolling the result set */
5754 ret = sqlite3_step (stmt);
5755 if (ret == SQLITE_DONE)
5756 {
5757 break; /* end of result set */
5758 }
5759 if (ret == SQLITE_ROW)
5760 {
5761 rows++;
5762 fprintf (out, "%s\r\n", sqlite3_column_text (stmt, 0));
5763 }
5764 else
5765 {
5766 goto sql_error;
5767 }
5768 }
5769 if (rows == 0)
5770 {
5771 goto empty_result_set;
5772 }
5773
5774 sqlite3_finalize (stmt);
5775 fclose (out);
5776 *xrows = rows;
5777 return 1;
5778
5779 sql_error:
5780 /* an SQL error occurred */
5781 if (stmt)
5782 {
5783 sqlite3_finalize (stmt);
5784 }
5785 if (out)
5786 {
5787 fclose (out);
5788 }
5789 spatialite_e ("Dump GeoJSON error: %s\n", sqlite3_errmsg (sqlite));
5790 return 0;
5791
5792 no_file:
5793 /* Output file could not be created / opened */
5794 if (stmt)
5795 {
5796 sqlite3_finalize (stmt);
5797 }
5798 if (out)
5799 {
5800 fclose (out);
5801 }
5802 spatialite_e ("ERROR: unable to open '%s' for writing\n", outfile_path);
5803 return 0;
5804
5805 empty_result_set:
5806 /* the result set is empty - nothing to do */
5807 if (stmt)
5808 {
5809 sqlite3_finalize (stmt);
5810 }
5811 if (out)
5812 {
5813 fclose (out);
5814 }
5815 spatialite_e ("The SQL SELECT returned no data to export...\n");
5816 return 0;
5817 }
5818
5819 static int
do_check_geometry(sqlite3 * sqlite,const char * table,const char * geom_col,char ** geoname,int * srid,int * dims)5820 do_check_geometry (sqlite3 * sqlite, const char *table, const char *geom_col,
5821 char **geoname, int *srid, int *dims)
5822 {
5823 /* checking Geometry Column, SRID and Dimensions */
5824 char *sql;
5825 int ret;
5826 char **results;
5827 int rows;
5828 int columns;
5829 int i;
5830 char *errMsg = NULL;
5831
5832 if (geom_col == NULL)
5833 sql = sqlite3_mprintf ("SELECT f_geometry_column, srid, geometry_type "
5834 "FROM geometry_columns WHERE Lower(f_table_name) = Lower(%Q)",
5835 table);
5836 else
5837 sql = sqlite3_mprintf ("SELECT f_geometry_column, srid, geometry_type "
5838 "FROM geometry_columns WHERE Lower(f_table_name) = Lower(%Q) AND "
5839 "Lower(f_geometry_column) = Lower(%Q)",
5840 table, geom_col);
5841 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
5842 sqlite3_free (sql);
5843 if (ret != SQLITE_OK)
5844 {
5845 spatialite_e ("dump GeoJSON2 MetaData error: <%s>\n", errMsg);
5846 sqlite3_free (errMsg);
5847 return 0;
5848 }
5849 if (rows == 1)
5850 goto ok;
5851
5852 /* it could be a possible Spatial View */
5853 if (geom_col == NULL)
5854 sql =
5855 sqlite3_mprintf
5856 ("SELECT g.f_geometry_column, g.srid, g.geometry_type "
5857 "FROM views_geometry_columns AS v "
5858 "JOIN geometry_columns AS g ON (v.f_table_name = g.f_table_name) "
5859 "WHERE Lower(v.view_name) = Lower(%Q)", table);
5860 else
5861 sql =
5862 sqlite3_mprintf
5863 ("SELECT g.f_geometry_column, g.srid, g.geometry_type "
5864 "FROM views_geometry_columns AS v "
5865 "JOIN geometry_columns AS g ON (v.f_table_name = g.f_table_name) "
5866 "WHERE Lower(v.view_name) = Lower(%Q) AND "
5867 "Lower(v.view_geometry) = Lower(%Q)", table, geom_col);
5868 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
5869 sqlite3_free (sql);
5870 if (ret != SQLITE_OK)
5871 {
5872 spatialite_e ("dump GeoJSON2 MetaData error: <%s>\n", errMsg);
5873 sqlite3_free (errMsg);
5874 return 0;
5875 }
5876 if (rows == 1)
5877 goto ok;
5878
5879 /* it could be a possible Spatial Virtual Table */
5880 if (geom_col == NULL)
5881 sql = sqlite3_mprintf ("SELECT virt_geometry, srid, geometry_type "
5882 "FROM virts_geometry_columns "
5883 "WHERE Lower(virt_name) = Lower(%Q)", table);
5884 else
5885 sql = sqlite3_mprintf ("SELECT virt_geometry, srid, geometry_type "
5886 "FROM virts_geometry_columns "
5887 "WHERE Lower(virt_name) = Lower(%Q) AND "
5888 "Lower(virt_geometry) = Lower(%Q)",
5889 table, geom_col);
5890 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
5891 sqlite3_free (sql);
5892 if (ret != SQLITE_OK)
5893 {
5894 spatialite_e ("dump GeoJSON2 MetaData error: <%s>\n", errMsg);
5895 sqlite3_free (errMsg);
5896 return 0;
5897 }
5898 if (rows != 1)
5899 goto error;
5900
5901 ok:
5902 for (i = 1; i <= rows; i++)
5903 {
5904 int gtype;
5905 const char *x = results[(i * columns) + 0];
5906 int len = strlen (x);
5907 *geoname = malloc (len + 1);
5908 strcpy (*geoname, x);
5909 *srid = atoi (results[(i * columns) + 1]);
5910 gtype = atoi (results[(i * columns) + 2]);
5911 switch (gtype)
5912 {
5913 case GAIA_POINT:
5914 case GAIA_LINESTRING:
5915 case GAIA_POLYGON:
5916 case GAIA_MULTIPOINT:
5917 case GAIA_MULTILINESTRING:
5918 case GAIA_MULTIPOLYGON:
5919 case GAIA_GEOMETRYCOLLECTION:
5920 *dims = GAIA_XY;
5921 break;
5922 case GAIA_POINTZ:
5923 case GAIA_LINESTRINGZ:
5924 case GAIA_POLYGONZ:
5925 case GAIA_MULTIPOINTZ:
5926 case GAIA_MULTILINESTRINGZ:
5927 case GAIA_MULTIPOLYGONZ:
5928 case GAIA_GEOMETRYCOLLECTIONZ:
5929 *dims = GAIA_XY_Z;
5930 break;
5931 case GAIA_POINTM:
5932 case GAIA_LINESTRINGM:
5933 case GAIA_POLYGONM:
5934 case GAIA_MULTIPOINTM:
5935 case GAIA_MULTILINESTRINGM:
5936 case GAIA_MULTIPOLYGONM:
5937 case GAIA_GEOMETRYCOLLECTIONM:
5938 *dims = GAIA_XY_M;
5939 break;
5940 case GAIA_POINTZM:
5941 case GAIA_LINESTRINGZM:
5942 case GAIA_POLYGONZM:
5943 case GAIA_MULTIPOINTZM:
5944 case GAIA_MULTILINESTRINGZM:
5945 case GAIA_MULTIPOLYGONZM:
5946 case GAIA_GEOMETRYCOLLECTIONZM:
5947 *dims = GAIA_XY_Z_M;
5948 break;
5949 default:
5950 goto error;
5951 };
5952 }
5953 sqlite3_free_table (results);
5954 return 1;
5955
5956 error:
5957 sqlite3_free_table (results);
5958 return 0;
5959 }
5960
5961 static char *
do_prepare_sql(sqlite3 * sqlite,const char * table,const char * geom_col,int srid,int dims,int precision,int lon_lat,int m_coords)5962 do_prepare_sql (sqlite3 * sqlite, const char *table, const char *geom_col,
5963 int srid, int dims, int precision, int lon_lat, int m_coords)
5964 {
5965 /* preparing the SQL statement */
5966 char *sql;
5967 char *prev;
5968 char *xtable;
5969 char *x_col;
5970 int ret;
5971 char **results;
5972 int rows;
5973 int columns;
5974 int i;
5975 char *errMsg = NULL;
5976
5977 xtable = gaiaDoubleQuotedSql (table);
5978 sql = sqlite3_mprintf ("PRAGMA table_info(\"%s\")", table);
5979 free (xtable);
5980 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
5981 sqlite3_free (sql);
5982 if (ret != SQLITE_OK)
5983 {
5984 spatialite_e ("dump GeoJSON2 PRAGMA error: <%s>\n", errMsg);
5985 sqlite3_free (errMsg);
5986 return 0;
5987 }
5988
5989 /* defining the Geometry first */
5990 x_col = gaiaDoubleQuotedSql (geom_col);
5991 if (lon_lat)
5992 {
5993 /* exporting Geographic coordinates (lon-lat) */
5994 if (srid == 0 || srid == 4326)
5995 {
5996 /* already lon-lan, no transformation is required */
5997 if (m_coords)
5998 {
5999 /* exporting eventual M-Values */
6000 sql =
6001 sqlite3_mprintf
6002 ("SELECT AsGeoJSON(ST_ForcePolygonCCW(\"%s\"), %d)",
6003 x_col, precision);
6004 }
6005 else
6006 {
6007 if (dims == GAIA_XY_M)
6008 {
6009 /* exporting XYM as XY */
6010 sql =
6011 sqlite3_mprintf
6012 ("SELECT AsGeoJSON(CastToXY(ST_ForcePolygonCCW(\"%s\")), %d)",
6013 x_col, precision);
6014 }
6015 else if (dims == GAIA_XY_Z_M)
6016 {
6017 /* exporting XYZM as XYZ */
6018 sql =
6019 sqlite3_mprintf
6020 ("SELECT AsGeoJSON(CastToXYZ(ST_ForcePolygonCCW(\"%s\")), %d)",
6021 x_col, precision);
6022 }
6023 else
6024 {
6025 /* unchanged dimensions */
6026 sql =
6027 sqlite3_mprintf
6028 ("SELECT AsGeoJSON(ST_ForcePolygonCCW(\"%s\"), %d)",
6029 x_col, precision);
6030 }
6031 }
6032 }
6033 else
6034 {
6035 /* converting to lon-lat WGS84 */
6036 if (m_coords)
6037 {
6038 /* exporting eventual M-Values */
6039 sql =
6040 sqlite3_mprintf
6041 ("SELECT AsGeoJSON(ST_Transform(ST_ForcePolygonCCW(\"%s\"), 4326), %d)",
6042 x_col, precision);
6043 }
6044 else
6045 {
6046 if (dims == GAIA_XY_M)
6047 {
6048 /* exporting XYM as XY */
6049 sql =
6050 sqlite3_mprintf
6051 ("SELECT AsGeoJSON(ST_Transform(CastToXY(ST_ForcePolygonCCW(\"%s\")), 4326), %d)",
6052 x_col, precision);
6053 }
6054 else if (dims == GAIA_XY_Z_M)
6055 {
6056 /* exporting XYZM as XYZ */
6057 sql =
6058 sqlite3_mprintf
6059 ("SELECT AsGeoJSON(ST_TransformCastToXYZ(ST_ForcePolygonCCW(\"%s\")), 4326), %d)",
6060 x_col, precision);
6061 }
6062 else
6063 {
6064 /* unchanged dimensions */
6065 sql =
6066 sqlite3_mprintf
6067 ("SELECT AsGeoJSON(ST_Transform(ST_ForcePolygonCCW(\"%s\"), 4326), %d)",
6068 x_col, precision);
6069 }
6070 }
6071 }
6072 }
6073 else
6074 {
6075 /* exporting coordinates as they are without any transformation */
6076 if (m_coords)
6077 {
6078 /* exporting eventual M-Values */
6079 sql =
6080 sqlite3_mprintf
6081 ("SELECT AsGeoJSON(ST_ForcePolygonCCW(\"%s\"), %d)", x_col,
6082 precision);
6083 }
6084 else
6085 {
6086 if (dims == GAIA_XY_M)
6087 {
6088 /* exporting XYM as XY */
6089 sql =
6090 sqlite3_mprintf
6091 ("SELECT AsGeoJSON(CastToXY(ST_ForcePolygonCCW(\"%s\")), %d)",
6092 x_col, precision);
6093 }
6094 else if (dims == GAIA_XY_Z_M)
6095 {
6096 /* exporting XYZM as XYZ */
6097 sql =
6098 sqlite3_mprintf
6099 ("SELECT AsGeoJSON(CastToXYZ(ST_ForcePolygonCCW(\"%s\")), %d)",
6100 x_col, precision);
6101 }
6102 else
6103 {
6104 /* unchanged dimensions */
6105 sql =
6106 sqlite3_mprintf
6107 ("SELECT AsGeoJSON(ST_ForcePolygonCCW(\"%s\"), %d)",
6108 x_col, precision);
6109 }
6110 }
6111 }
6112 free (x_col);
6113
6114 for (i = 1; i <= rows; i++)
6115 {
6116 /* then adding all Properties */
6117 const char *col = results[(i * columns) + 1];
6118 if (strcasecmp (col, geom_col) == 0)
6119 continue; /* skipping the Geometry itself */
6120 x_col = gaiaDoubleQuotedSql (col);
6121 prev = sql;
6122 sql = sqlite3_mprintf ("%s, \"%s\"", prev, x_col);
6123 free (x_col);
6124 sqlite3_free (prev);
6125 }
6126 sqlite3_free_table (results);
6127 prev = sql;
6128 xtable = gaiaDoubleQuotedSql (table);
6129 sql = sqlite3_mprintf ("%s FROM \"%s\"", prev, xtable);
6130 free (xtable);
6131 sqlite3_free (prev);
6132 return sql;
6133 }
6134
6135 static char *
do_normalize_case(const char * name,int colname_case)6136 do_normalize_case (const char *name, int colname_case)
6137 {
6138 /* transforming a name in full lower- or upper-case */
6139 int len = strlen (name);
6140 char *clean = malloc (len + 1);
6141 char *p = clean;
6142 strcpy (clean, name);
6143 while (*p != '\0')
6144 {
6145 if (colname_case == GAIA_DBF_COLNAME_LOWERCASE)
6146 {
6147 if (*p >= 'A' && *p <= 'Z')
6148 *p = *p - 'A' + 'a';
6149 }
6150 if (colname_case == GAIA_DBF_COLNAME_UPPERCASE)
6151 {
6152 if (*p >= 'a' && *p <= 'z')
6153 *p = *p - 'a' + 'A';
6154 }
6155 p++;
6156 }
6157 return clean;
6158 }
6159
6160 SPATIALITE_DECLARE int
dump_geojson2(sqlite3 * sqlite,char * table,char * geom_col,char * outfile_path,int precision,int lon_lat,int m_coords,int indented,int colname_case,int * xrows,char ** error_message)6161 dump_geojson2 (sqlite3 * sqlite, char *table, char *geom_col,
6162 char *outfile_path, int precision, int lon_lat,
6163 int m_coords, int indented, int colname_case, int *xrows,
6164 char **error_message)
6165 {
6166 /* dumping a geometry table as GeoJSON FeatureCollection (RFC 7946) */
6167 /* sandro furieri 2018-11-25 */
6168 char *sql;
6169 sqlite3_stmt *stmt = NULL;
6170 FILE *out = NULL;
6171 int ret;
6172 int rows = 0;
6173 char *geoname = NULL;
6174 int srid;
6175 int dims;
6176 int first_feature = 1;
6177 sqlite3_int64 ival;
6178 double dval;
6179 const char *tval;
6180 char *xtval;
6181 *error_message = NULL;
6182
6183 /* checking Geometry Column, SRID and Dimensions */
6184 if (!do_check_geometry (sqlite, table, geom_col, &geoname, &srid, &dims))
6185 goto no_geom;
6186
6187 *xrows = -1;
6188 /* opening/creating the GeoJSON output file */
6189 #ifdef _WIN32
6190 out = gaia_win_fopen (outfile_path, "wb");
6191 #else
6192 out = fopen (outfile_path, "wb");
6193 #endif
6194 if (!out)
6195 goto no_file;
6196
6197 /* preparing SQL statement */
6198 sql =
6199 do_prepare_sql (sqlite, table, geoname, srid, dims, precision, lon_lat,
6200 m_coords);
6201 if (sql == NULL)
6202 goto no_sql;
6203 free (geoname);
6204
6205 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6206 sqlite3_free (sql);
6207 if (ret != SQLITE_OK)
6208 goto sql_error;
6209
6210 while (1)
6211 {
6212 /* scrolling the result set */
6213 ret = sqlite3_step (stmt);
6214 if (ret == SQLITE_DONE)
6215 {
6216 break; /* end of result set */
6217 }
6218 if (ret == SQLITE_ROW)
6219 {
6220 int c;
6221 int cols = sqlite3_column_count (stmt);
6222 if (first_feature)
6223 {
6224 /* FeatureCollection */
6225 if (indented)
6226 fprintf (out,
6227 "{\r\n\t\"type\" : \"FeatureCollection\",\r\n\t\"features\" : [{\r\n");
6228 else
6229 fprintf (out,
6230 "{\"type\":\"FeatureCollection\",\"features\":[{");
6231 first_feature = 0;
6232 }
6233 /* Feature */
6234 if (rows == 0)
6235 {
6236 /* first Feature */
6237 if (indented)
6238 fprintf (out,
6239 "\t\t\"type\" : \"Feature\",\r\n\t\t\"properties\" : ");
6240 else
6241 fprintf (out, "\"type\":\"Feature\",\"properties\":");
6242 }
6243 else
6244 {
6245 /* any other Feature except the first one */
6246 if (indented)
6247 fprintf (out,
6248 ", {\r\n\t\t\"type\" : \"Feature\",\r\n\t\t\"properties\" : ");
6249 else
6250 fprintf (out,
6251 ",{\"type\":\"Feature\",\"properties\":");
6252 }
6253 for (c = 1; c < cols; c++)
6254 {
6255 /* Properties */
6256 const char *col_name = sqlite3_column_name (stmt, c);
6257 char *norm_name =
6258 do_normalize_case (col_name, colname_case);
6259 char *xcol_name = gaiaDoubleQuotedSql (norm_name);
6260 free (norm_name);
6261 if (c == 1)
6262 {
6263 if (indented)
6264 fprintf (out, "{\r\n\t\t\t\"%s\" : ",
6265 xcol_name);
6266 else
6267 fprintf (out, "{\"%s\":", xcol_name);
6268 }
6269 else
6270 {
6271 if (indented)
6272 fprintf (out, ",\r\n\t\t\t\"%s\" : ",
6273 xcol_name);
6274 else
6275 fprintf (out, ",\"%s\":", xcol_name);
6276 }
6277 free (xcol_name);
6278 switch (sqlite3_column_type (stmt, c))
6279 {
6280 case SQLITE_INTEGER:
6281 ival = sqlite3_column_int64 (stmt, c);
6282 fprintf (out, "%lld", ival);
6283 break;
6284 case SQLITE_FLOAT:
6285 dval = sqlite3_column_double (stmt, c);
6286 fprintf (out, "%f", dval);
6287 break;
6288 case SQLITE_TEXT:
6289 tval = (const char *) sqlite3_column_text (stmt, c);
6290 xtval = gaiaDoubleQuotedSql (tval);
6291 fprintf (out, "\"%s\"", xtval);
6292 free (xtval);
6293 break;
6294 case SQLITE_BLOB:
6295 fprintf (out, "\"BLOB value\"");
6296 break;
6297 case SQLITE_NULL:
6298 default:
6299 fprintf (out, "null");
6300 break;
6301 };
6302 }
6303 /* geometry */
6304 if (indented)
6305 fprintf (out, "\r\n\t\t},\r\n\t\t\"geometry\" : ");
6306 else
6307 fprintf (out, "},\"geomety\":");
6308 switch (sqlite3_column_type (stmt, 0))
6309 {
6310 case SQLITE_NULL:
6311 fprintf (out, "null");
6312 break;
6313 default:
6314 tval = (const char *) sqlite3_column_text (stmt, 0);
6315 fprintf (out, "%s", tval);
6316 break;
6317 };
6318 /* end Feature */
6319 if (indented)
6320 fprintf (out, "\r\n\t}");
6321 else
6322 fprintf (out, "}");
6323 rows++;
6324 }
6325 else
6326 {
6327 goto sql_error;
6328 }
6329 }
6330 if (rows == 0)
6331 {
6332 goto empty_result_set;
6333 }
6334 if (indented)
6335 fprintf (out, "]\r\n}\r\n");
6336 else
6337 fprintf (out, "]}");
6338
6339 sqlite3_finalize (stmt);
6340 fclose (out);
6341 *xrows = rows;
6342 return 1;
6343
6344 sql_error:
6345 /* an SQL error occurred */
6346 if (stmt)
6347 {
6348 sqlite3_finalize (stmt);
6349 }
6350 if (out)
6351 {
6352 fclose (out);
6353 }
6354 *error_message =
6355 sqlite3_mprintf ("Dump GeoJSON2 error: %s\n", sqlite3_errmsg (sqlite));
6356 return 0;
6357
6358 no_file:
6359 /* Output file could not be created / opened */
6360 if (stmt)
6361 {
6362 sqlite3_finalize (stmt);
6363 }
6364 if (out)
6365 {
6366 fclose (out);
6367 }
6368 if (geoname != NULL)
6369 free (geoname);
6370 *error_message =
6371 sqlite3_mprintf ("ERROR: unable to open '%s' for writing\n",
6372 outfile_path);
6373 return 0;
6374
6375 empty_result_set:
6376 /* the result set is empty - nothing to do */
6377 if (stmt)
6378 {
6379 sqlite3_finalize (stmt);
6380 }
6381 if (out)
6382 {
6383 fclose (out);
6384 }
6385 *error_message =
6386 sqlite3_mprintf ("The SQL SELECT returned no data to export...\n");
6387 return 0;
6388
6389 no_geom:
6390 /* not a valid Geometry Column */
6391 if (out)
6392 {
6393 fclose (out);
6394 }
6395 *error_message = sqlite3_mprintf ("Not a valid Geometry Column.\n");
6396 return 0;
6397
6398 no_sql:
6399 /* unable to create a valid SQL query */
6400 if (out)
6401 {
6402 fclose (out);
6403 }
6404 *error_message = sqlite3_mprintf ("Unable to create a valid SQL query.\n");
6405 return 0;
6406 }
6407
6408 SPATIALITE_DECLARE int
load_geojson(sqlite3 * sqlite,char * path,char * table,char * geom_col,int spatial_index,int srid,int colname_case,int * rows,char ** error_message)6409 load_geojson (sqlite3 * sqlite, char *path, char *table, char *geom_col,
6410 int spatial_index, int srid, int colname_case, int *rows,
6411 char **error_message)
6412 {
6413 /* Loads an external GeoJSON file into a newly created table */
6414 FILE *in = NULL;
6415 sqlite3_stmt *stmt = NULL;
6416 geojson_parser_ptr parser = NULL;
6417 geojson_feature_ptr ft;
6418 int i;
6419 int ret;
6420 int pending = 0;
6421 char *sql;
6422 int ins_rows = 0;
6423 *error_message = NULL;
6424
6425 /* attempting to open the GeoJSON file for reading */
6426 #ifdef _WIN32
6427 in = gaia_win_fopen (path, "rb");
6428 #else
6429 in = fopen (path, "rb");
6430 #endif
6431 if (in == NULL)
6432 {
6433 *error_message =
6434 sqlite3_mprintf
6435 ("GeoJSON parser: unable to open %s for reading\n", path);
6436 return 0;
6437 }
6438
6439 /* creating the GeoJSON parser */
6440 parser = geojson_create_parser (in);
6441 if (!geojson_parser_init (parser, error_message))
6442 goto err;
6443 if (!geojson_create_features_index (parser, error_message))
6444 goto err;
6445 if (!geojson_check_features (parser, error_message))
6446 goto err;
6447
6448 /* creating the output table */
6449 sql = geojson_sql_create_table (parser, table, colname_case);
6450 if (sql == NULL)
6451 goto err;
6452 ret = sqlite3_exec (sqlite, sql, NULL, NULL, NULL);
6453 sqlite3_free (sql);
6454 if (ret != SQLITE_OK)
6455 {
6456 *error_message =
6457 sqlite3_mprintf
6458 ("GeoJSON import: unable to create the output table (%s)\n",
6459 sqlite3_errmsg (sqlite));
6460 goto err;
6461 }
6462
6463 /* adding the Geometry Column */
6464 sql =
6465 geojson_sql_add_geometry (parser, table, geom_col, colname_case, srid);
6466 if (sql == NULL)
6467 goto err;
6468 ret = sqlite3_exec (sqlite, sql, NULL, NULL, NULL);
6469 sqlite3_free (sql);
6470 if (ret != SQLITE_OK)
6471 {
6472 *error_message =
6473 sqlite3_mprintf
6474 ("GeoJSON import: unable to create the Geometry column (%s)\n",
6475 sqlite3_errmsg (sqlite));
6476 goto err;
6477 }
6478
6479 if (spatial_index)
6480 {
6481 /* creating the Spatial Index */
6482 sql = geojson_sql_create_rtree (table, geom_col, colname_case);
6483 if (sql == NULL)
6484 goto err;
6485 ret = sqlite3_exec (sqlite, sql, NULL, NULL, NULL);
6486 sqlite3_free (sql);
6487 if (ret != SQLITE_OK)
6488 {
6489 *error_message =
6490 sqlite3_mprintf
6491 ("GeoJSON import: unable to create the SpatialIndex (%s)\n",
6492 sqlite3_errmsg (sqlite));
6493 goto err;
6494 }
6495 }
6496
6497 /* the whole import will be enclosed in a single Transaction */
6498 ret = sqlite3_exec (sqlite, "SAVEPOINT import_geo_json", NULL, NULL, NULL);
6499 if (ret != SQLITE_OK)
6500 {
6501 *error_message =
6502 sqlite3_mprintf ("GeoJSON import: SAVEPOINT error (%s)\n",
6503 sqlite3_errmsg (sqlite));
6504 goto err;
6505 }
6506 pending = 1;
6507
6508 sql = geojson_sql_insert_into (parser, table);
6509 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6510 sqlite3_free (sql);
6511 if (ret != SQLITE_OK)
6512 {
6513 *error_message =
6514 sqlite3_mprintf ("GeoJSON import: INSERT INTO error (%s)\n",
6515 sqlite3_errmsg (sqlite));
6516 goto err;
6517 }
6518
6519 for (i = 0; i < parser->count; i++)
6520 {
6521 /* inserting all features into the output table */
6522 ft = parser->features + i;
6523 if (geojson_init_feature (parser, ft, error_message))
6524 {
6525 /* inserting a single Feature */
6526 geojson_column_ptr col;
6527 int cnt = 1;
6528 sqlite3_reset (stmt);
6529 sqlite3_clear_bindings (stmt);
6530 col = parser->first_col;
6531 while (col != NULL)
6532 {
6533 /* binding column values */
6534 geojson_property_ptr prop =
6535 geojson_get_property_by_name (ft, col->name);
6536 if (prop == NULL)
6537 sqlite3_bind_null (stmt, cnt++);
6538 else
6539 {
6540 switch (prop->type)
6541 {
6542 case GEOJSON_TEXT:
6543 sqlite3_bind_text (stmt, cnt++,
6544 prop->txt_value,
6545 strlen (prop->txt_value),
6546 SQLITE_STATIC);
6547 break;
6548 case GEOJSON_INTEGER:
6549 sqlite3_bind_int64 (stmt, cnt++,
6550 prop->int_value);
6551 break;
6552 case GEOJSON_DOUBLE:
6553 sqlite3_bind_double (stmt, cnt++,
6554 prop->dbl_value);
6555 break;
6556 case GEOJSON_FALSE:
6557 sqlite3_bind_int (stmt, cnt++, 0);
6558 break;
6559 case GEOJSON_TRUE:
6560 sqlite3_bind_int (stmt, cnt++, 0);
6561 break;
6562 case GEOJSON_NULL:
6563 default:
6564 sqlite3_bind_null (stmt, cnt++);
6565 break;
6566 };
6567 }
6568 col = col->next;
6569 }
6570 if (ft->geometry == NULL)
6571 sqlite3_bind_null (stmt, cnt++);
6572 else
6573 {
6574 gaiaGeomCollPtr geo =
6575 gaiaParseGeoJSON ((const unsigned char
6576 *) (ft->geometry));
6577 if (geo != NULL)
6578 {
6579 /* binding the Geometry BLOB */
6580 unsigned char *blob;
6581 int blob_size;
6582 geo->Srid = srid;
6583 gaiaToSpatiaLiteBlobWkb (geo, &blob, &blob_size);
6584 sqlite3_bind_blob (stmt, cnt, blob, blob_size,
6585 free);
6586 gaiaFreeGeomColl (geo);
6587 }
6588 else
6589 {
6590 *error_message =
6591 sqlite3_mprintf
6592 ("GeoJSON import: invalid Geometry (fid=%d)\n",
6593 ft->fid);
6594 goto err;
6595 }
6596 }
6597 /* inserting the Feature into the DB Table */
6598 ret = sqlite3_step (stmt);
6599 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6600 ins_rows++;
6601 else
6602 {
6603 *error_message =
6604 sqlite3_mprintf
6605 ("GeoJSON import: INSERT INTO failure (fid=%d) %s\n",
6606 ft->fid, sqlite3_errmsg (sqlite));
6607 goto err;
6608 }
6609 geojson_reset_feature (ft);
6610 }
6611 else
6612 goto err;
6613 }
6614 sqlite3_finalize (stmt);
6615 stmt = NULL;
6616
6617 /* Committing the still pending Transaction */
6618 ret =
6619 sqlite3_exec (sqlite, "RELEASE SAVEPOINT import_geo_json", NULL, NULL,
6620 NULL);
6621 if (ret != SQLITE_OK)
6622 {
6623 *error_message =
6624 sqlite3_mprintf ("GeoJSON import: RELEASE SAVEPOINT error (%s)\n",
6625 sqlite3_errmsg (sqlite));
6626 goto err;
6627 }
6628
6629 geojson_destroy_parser (parser);
6630 *rows = ins_rows;
6631 return 1;
6632
6633 err:
6634 if (stmt != NULL)
6635 sqlite3_finalize (stmt);
6636 if (pending)
6637 {
6638 /* Rolling back the Transaction */
6639 sqlite3_exec (sqlite, "ROLLBAKC TO SAVEPOINT import_geo_json", NULL,
6640 NULL, NULL);
6641 sqlite3_exec (sqlite, "RELEASE SAVEPOINT import_geo_json", NULL, NULL,
6642 NULL);
6643 }
6644 geojson_destroy_parser (parser);
6645 *rows = 0;
6646 return 0;
6647 }
6648
6649 #ifdef ENABLE_MINIZIP /* MINIZIP is enabled */
6650
6651 GAIAGEO_DECLARE char *
gaiaReadWktFromZipShp(const char * zip_path,const char * basename)6652 gaiaReadWktFromZipShp (const char *zip_path, const char *basename)
6653 {
6654 /* attempting to read the .PRJ member of some zipped Shapefile */
6655 char *wkt = NULL;
6656 unzFile uf = NULL;
6657 struct zip_mem_shapefile *mem_shape = NULL;
6658
6659 if (zip_path == NULL)
6660 {
6661 spatialite_e ("read_wkt_from_zipshp error: <%s>\n",
6662 "NULL zipfile path");
6663 return NULL;
6664 }
6665 /* opening the Zipfile expected to contain the Shapefile */
6666 uf = unzOpen64 (zip_path);
6667 if (uf == NULL)
6668 {
6669 spatialite_e ("Unable to Open %s\n", zip_path);
6670 return NULL;
6671 }
6672 /* parsing the Zipfile directory */
6673 mem_shape = do_list_zipfile_dir (uf, basename, 0);
6674 if (mem_shape == NULL)
6675 {
6676 spatialite_e ("No SHP %s with Zipfile\n", basename);
6677 goto stop;
6678 }
6679 /* unzipping the PRJ member (if any) */
6680 do_read_zipfile_file (uf, mem_shape, GAIA_ZIPFILE_PRJ);
6681 if (mem_shape->prj.buf != NULL)
6682 {
6683 wkt = malloc (mem_shape->prj.size + 1);
6684 memcpy (wkt, mem_shape->prj.buf, mem_shape->prj.size);
6685 *(wkt + mem_shape->prj.size) = '\0';
6686 }
6687
6688 stop:
6689 unzClose (uf);
6690 if (mem_shape != NULL)
6691 destroy_zip_mem_shapefile (mem_shape);
6692 return wkt;
6693 }
6694
6695 GAIAGEO_DECLARE int
gaiaZipfileNumSHP(const char * zip_path,int * count)6696 gaiaZipfileNumSHP (const char *zip_path, int *count)
6697 {
6698 /* attempting to count how many Shapefiles are within a given Zipfile */
6699 int ret;
6700 int retval = 1;
6701 struct zip_mem_shp_item *item;
6702 struct zip_mem_shp_list *list = alloc_zip_mem_shp_list ();
6703 unzFile uf = NULL;
6704
6705 *count = 0;
6706 if (zip_path == NULL)
6707 {
6708 spatialite_e ("zipfile NumSHP error: <%s>\n", "NULL zipfile path");
6709 retval = 0;
6710 goto stop;
6711 }
6712 /* opening the Zipfile expected to contain the Shapefile */
6713 uf = unzOpen64 (zip_path);
6714 if (uf == NULL)
6715 {
6716 spatialite_e ("Unable to Open %s\n", zip_path);
6717 retval = 0;
6718 goto stop;
6719 }
6720 /* sniffing the Zipfile */
6721 ret = do_sniff_zipfile_dir (uf, list, 0);
6722 if (!ret)
6723 {
6724 retval = 0;
6725 goto stop;
6726 }
6727 item = list->first;
6728 while (item != NULL)
6729 {
6730 /* counting how many Shapefiles are there */
6731 if (item->shp && item->shx && item->dbf)
6732 *count += 1;
6733 item = item->next;
6734 }
6735 stop:
6736 unzClose (uf);
6737 destroy_zip_mem_shp_list (list);
6738 return retval;
6739 }
6740
6741 GAIAGEO_DECLARE char *
gaiaZipfileShpN(const char * zip_path,int idx)6742 gaiaZipfileShpN (const char *zip_path, int idx)
6743 {
6744 /* attempting to return the Nth Shapefile's basename fromt within a given Zipfile */
6745 int ret;
6746 int count = 0;
6747 char *basename = NULL;
6748 struct zip_mem_shp_item *item;
6749 struct zip_mem_shp_list *list = alloc_zip_mem_shp_list ();
6750 unzFile uf = NULL;
6751
6752 count = 0;
6753 if (zip_path == NULL)
6754 {
6755 spatialite_e ("zipfile NumSHP error: <%s>\n", "NULL zipfile path");
6756 goto stop;
6757 }
6758 /* opening the Zipfile expected to contain the Shapefile */
6759 uf = unzOpen64 (zip_path);
6760 if (uf == NULL)
6761 {
6762 spatialite_e ("Unable to Open %s\n", zip_path);
6763 goto stop;
6764 }
6765 /* sniffing the Zipfile */
6766 ret = do_sniff_zipfile_dir (uf, list, 0);
6767 if (!ret)
6768 goto stop;
6769 item = list->first;
6770 while (item != NULL)
6771 {
6772 /* counting how many Shapefiles are there */
6773 if (item->shp && item->shx && item->dbf)
6774 count++;
6775 if (count == idx)
6776 {
6777 int len = strlen (item->basename);
6778 basename = malloc (len + 1);
6779 strcpy (basename, item->basename);
6780 break;
6781 }
6782 item = item->next;
6783 }
6784 stop:
6785 unzClose (uf);
6786 destroy_zip_mem_shp_list (list);
6787 return basename;
6788 }
6789
6790 GAIAGEO_DECLARE int
gaiaZipfileNumDBF(const char * zip_path,int * count)6791 gaiaZipfileNumDBF (const char *zip_path, int *count)
6792 {
6793 /* attempting to count how many DBF files are within a given Zipfile */
6794 int ret;
6795 int retval = 1;
6796 struct zip_mem_shp_item *item;
6797 struct zip_mem_shp_list *list = alloc_zip_mem_shp_list ();
6798 unzFile uf = NULL;
6799
6800 *count = 0;
6801 if (zip_path == NULL)
6802 {
6803 spatialite_e ("zipfile NumDBF error: <%s>\n", "NULL zipfile path");
6804 retval = 0;
6805 goto stop;
6806 }
6807 /* opening the Zipfile expected to contain the DBF file */
6808 uf = unzOpen64 (zip_path);
6809 if (uf == NULL)
6810 {
6811 spatialite_e ("Unable to Open %s\n", zip_path);
6812 retval = 0;
6813 goto stop;
6814 }
6815 /* sniffing the Zipfile */
6816 ret = do_sniff_zipfile_dir (uf, list, 1);
6817 if (!ret)
6818 {
6819 retval = 0;
6820 goto stop;
6821 }
6822 item = list->first;
6823 while (item != NULL)
6824 {
6825 /* counting how many DBF files are there */
6826 if (item->dbf)
6827 *count += 1;
6828 item = item->next;
6829 }
6830 stop:
6831 unzClose (uf);
6832 destroy_zip_mem_shp_list (list);
6833 return retval;
6834 }
6835
6836 GAIAGEO_DECLARE char *
gaiaZipfileDbfN(const char * zip_path,int idx)6837 gaiaZipfileDbfN (const char *zip_path, int idx)
6838 {
6839 /* attempting to return the Nth DBF filename fromt within a given Zipfile */
6840 int ret;
6841 int count = 0;
6842 char *filename = NULL;
6843 struct zip_mem_shp_item *item;
6844 struct zip_mem_shp_list *list = alloc_zip_mem_shp_list ();
6845 unzFile uf = NULL;
6846
6847 count = 0;
6848 if (zip_path == NULL)
6849 {
6850 spatialite_e ("zipfile NumDBF error: <%s>\n", "NULL zipfile path");
6851 goto stop;
6852 }
6853 /* opening the Zipfile expected to contain the DBF file */
6854 uf = unzOpen64 (zip_path);
6855 if (uf == NULL)
6856 {
6857 spatialite_e ("Unable to Open %s\n", zip_path);
6858 goto stop;
6859 }
6860 /* sniffing the Zipfile */
6861 ret = do_sniff_zipfile_dir (uf, list, 1);
6862 if (!ret)
6863 goto stop;
6864 item = list->first;
6865 while (item != NULL)
6866 {
6867 /* counting how many DBF files are there */
6868 if (item->dbf)
6869 count++;
6870 if (count == idx)
6871 {
6872 int len = strlen (item->basename);
6873 filename = malloc (len + 1);
6874 strcpy (filename, item->basename);
6875 break;
6876 }
6877 item = item->next;
6878 }
6879 stop:
6880 unzClose (uf);
6881 destroy_zip_mem_shp_list (list);
6882 return filename;
6883 }
6884
6885 #endif /* end MINIZIP */
6886
6887 #endif /* end ICONV (SHP) */
6888
6889 static int
is_table(sqlite3 * sqlite,const char * table)6890 is_table (sqlite3 * sqlite, const char *table)
6891 {
6892 /* check if this one really is a TABLE */
6893 char *sql;
6894 int ret;
6895 char **results;
6896 int rows;
6897 int columns;
6898 char *errMsg = NULL;
6899 int ok = 0;
6900
6901 sql = sqlite3_mprintf ("SELECT tbl_name FROM sqlite_master "
6902 "WHERE type = 'table' AND Lower(tbl_name) = Lower(%Q)",
6903 table);
6904 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
6905 sqlite3_free (sql);
6906 if (ret != SQLITE_OK)
6907 {
6908 spatialite_e ("SQLite SQL error: %s\n", errMsg);
6909 sqlite3_free (errMsg);
6910 return ok;
6911 }
6912 if (rows < 1)
6913 ;
6914 else
6915 ok = 1;
6916 sqlite3_free_table (results);
6917 return ok;
6918 }
6919
6920 SPATIALITE_DECLARE void
check_duplicated_rows(sqlite3 * sqlite,char * table,int * dupl_count)6921 check_duplicated_rows (sqlite3 * sqlite, char *table, int *dupl_count)
6922 {
6923 /* Checking a Table for Duplicate rows */
6924 char *sql;
6925 int first = 1;
6926 char *xname;
6927 int pk;
6928 int ret;
6929 char **results;
6930 int rows;
6931 int columns;
6932 int i;
6933 char *errMsg = NULL;
6934 sqlite3_stmt *stmt = NULL;
6935 gaiaOutBuffer sql_statement;
6936 gaiaOutBuffer col_list;
6937
6938 *dupl_count = 0;
6939
6940 if (is_table (sqlite, table) == 0)
6941 {
6942 spatialite_e (".chkdupl %s: no such table\n", table);
6943 *dupl_count = -1;
6944 return;
6945 }
6946 /* extracting the column names (excluding any Primary Key) */
6947 gaiaOutBufferInitialize (&col_list);
6948 xname = gaiaDoubleQuotedSql (table);
6949 sql = sqlite3_mprintf ("PRAGMA table_info(\"%s\")", xname);
6950 free (xname);
6951 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
6952 sqlite3_free (sql);
6953 if (ret != SQLITE_OK)
6954 {
6955 spatialite_e ("SQLite SQL error: %s\n", errMsg);
6956 sqlite3_free (errMsg);
6957 return;
6958 }
6959 if (rows < 1)
6960 ;
6961 else
6962 {
6963 for (i = 1; i <= rows; i++)
6964 {
6965 sql = results[(i * columns) + 1];
6966 pk = atoi (results[(i * columns) + 5]);
6967 if (!pk)
6968 {
6969 xname = gaiaDoubleQuotedSql (sql);
6970 if (first)
6971 {
6972 sql = sqlite3_mprintf ("\"%s\"", xname);
6973 first = 0;
6974 }
6975 else
6976 sql = sqlite3_mprintf (", \"%s\"", xname);
6977 free (xname);
6978 gaiaAppendToOutBuffer (&col_list, sql);
6979 sqlite3_free (sql);
6980 }
6981 }
6982 }
6983 sqlite3_free_table (results);
6984 /* preparing the SQL statement */
6985 gaiaOutBufferInitialize (&sql_statement);
6986 gaiaAppendToOutBuffer (&sql_statement,
6987 "SELECT Count(*) AS \"[dupl-count]\", ");
6988 if (col_list.Error == 0 && col_list.Buffer != NULL)
6989 gaiaAppendToOutBuffer (&sql_statement, col_list.Buffer);
6990 xname = gaiaDoubleQuotedSql (table);
6991 sql = sqlite3_mprintf ("\nFROM \"%s\"\nGROUP BY ", xname);
6992 free (xname);
6993 gaiaAppendToOutBuffer (&sql_statement, sql);
6994 sqlite3_free (sql);
6995 if (col_list.Error == 0 && col_list.Buffer != NULL)
6996 gaiaAppendToOutBuffer (&sql_statement, col_list.Buffer);
6997 gaiaOutBufferReset (&col_list);
6998 gaiaAppendToOutBuffer (&sql_statement, "\nHAVING \"[dupl-count]\" > 1");
6999 if (sql_statement.Error == 0 && sql_statement.Buffer != NULL)
7000 {
7001 ret =
7002 sqlite3_prepare_v2 (sqlite, sql_statement.Buffer,
7003 strlen (sql_statement.Buffer), &stmt, NULL);
7004 gaiaOutBufferReset (&sql_statement);
7005 if (ret != SQLITE_OK)
7006 {
7007 spatialite_e ("SQL error: %s\n", sqlite3_errmsg (sqlite));
7008 return;
7009 }
7010 }
7011 while (1)
7012 {
7013 /* fetching the result set rows */
7014 ret = sqlite3_step (stmt);
7015 if (ret == SQLITE_DONE)
7016 break; /* end of result set */
7017 if (ret == SQLITE_ROW)
7018 {
7019 /* fetching a row */
7020 *dupl_count += sqlite3_column_int (stmt, 0) - 1;
7021 }
7022 else
7023 {
7024 spatialite_e ("SQL error: %s", sqlite3_errmsg (sqlite));
7025 sqlite3_finalize (stmt);
7026 return;
7027 }
7028 }
7029 sqlite3_finalize (stmt);
7030 if (*dupl_count)
7031 spatialite_e ("%d duplicated rows found !!!\n", *dupl_count);
7032 else
7033 spatialite_e ("No duplicated rows have been identified\n");
7034 }
7035
7036 static int
do_delete_duplicates2(sqlite3 * sqlite,sqlite3_int64 rowid,sqlite3_stmt * stmt1)7037 do_delete_duplicates2 (sqlite3 * sqlite, sqlite3_int64 rowid,
7038 sqlite3_stmt * stmt1)
7039 {
7040 /* deleting duplicate rows [actual delete] */
7041 int ret;
7042
7043 sqlite3_reset (stmt1);
7044 sqlite3_clear_bindings (stmt1);
7045 sqlite3_bind_int64 (stmt1, 1, rowid);
7046 ret = sqlite3_step (stmt1);
7047 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
7048 ;
7049 else
7050 {
7051 spatialite_e ("SQL error: %s\n", sqlite3_errmsg (sqlite));
7052 return 0;
7053 }
7054 return 1;
7055 }
7056
7057 static int
do_delete_duplicates(sqlite3 * sqlite,const char * sql1,const char * sql2,int * count,int transaction)7058 do_delete_duplicates (sqlite3 * sqlite, const char *sql1, const char *sql2,
7059 int *count, int transaction)
7060 {
7061 /* deleting duplicate rows */
7062 struct resultset_comparator *rs_obj = NULL;
7063 sqlite3_stmt *stmt1 = NULL;
7064 sqlite3_stmt *stmt2 = NULL;
7065 int ret;
7066 int cnt = 0;
7067 char *sql_err = NULL;
7068
7069 *count = 0;
7070
7071 if (transaction)
7072 {
7073 /* the complete operation is handled as an unique SQL Transaction */
7074 ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, &sql_err);
7075 if (ret != SQLITE_OK)
7076 {
7077 spatialite_e ("BEGIN TRANSACTION error: %s\n", sql_err);
7078 sqlite3_free (sql_err);
7079 return 0;
7080 }
7081 }
7082
7083 /* preparing the main SELECT statement */
7084 ret = sqlite3_prepare_v2 (sqlite, sql1, strlen (sql1), &stmt1, NULL);
7085 if (ret != SQLITE_OK)
7086 {
7087 spatialite_e ("SQL error: %s\n", sqlite3_errmsg (sqlite));
7088 return 0;
7089 }
7090 /* preparing the DELETE statement */
7091 ret = sqlite3_prepare_v2 (sqlite, sql2, strlen (sql2), &stmt2, NULL);
7092 if (ret != SQLITE_OK)
7093 {
7094 spatialite_e ("SQL error: %s\n", sqlite3_errmsg (sqlite));
7095 goto error;
7096 }
7097
7098 rs_obj = create_resultset_comparator (sqlite3_column_count (stmt1) - 1);
7099 while (1)
7100 {
7101 /* fetching the result set rows */
7102 ret = sqlite3_step (stmt1);
7103 if (ret == SQLITE_DONE)
7104 break; /* end of result set */
7105 if (ret == SQLITE_ROW)
7106 {
7107 /* fetching a row */
7108 save_row_from_resultset (rs_obj, stmt1);
7109 if (resultset_rows_equals (rs_obj))
7110 {
7111 if (do_delete_duplicates2
7112 (sqlite, get_current_resultset_rowid (rs_obj), stmt2))
7113 {
7114 cnt += 1;
7115 reset_resultset_current_row (rs_obj);
7116 continue;
7117 }
7118 else
7119 goto error;
7120 }
7121 }
7122 else
7123 {
7124 spatialite_e ("SQL error: %s\n", sqlite3_errmsg (sqlite));
7125 goto error;
7126 }
7127 swap_resultset_rows (rs_obj);
7128 }
7129
7130 sqlite3_finalize (stmt1);
7131 sqlite3_finalize (stmt2);
7132 destroy_resultset_comparator (rs_obj);
7133
7134 if (transaction)
7135 {
7136 /* confirm the still pending Transaction */
7137 ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, &sql_err);
7138 if (ret != SQLITE_OK)
7139 {
7140 spatialite_e ("COMMIT TRANSACTION error: %s\n", sql_err);
7141 sqlite3_free (sql_err);
7142 return 0;
7143 }
7144 }
7145
7146 *count = cnt;
7147 return 1;
7148
7149 error:
7150 *count = 0;
7151 if (stmt1)
7152 sqlite3_finalize (stmt1);
7153 if (stmt2)
7154 sqlite3_finalize (stmt2);
7155
7156 if (transaction)
7157 {
7158 /* performing a ROLLBACK anyway */
7159 ret = sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, &sql_err);
7160 if (ret != SQLITE_OK)
7161 {
7162 spatialite_e ("ROLLBACK TRANSACTION error: %s\n", sql_err);
7163 sqlite3_free (sql_err);
7164 return 0;
7165 }
7166 }
7167
7168 return 0;
7169 }
7170
7171 SPATIALITE_DECLARE void
remove_duplicated_rows_ex2(sqlite3 * sqlite,char * table,int * removed,int transaction)7172 remove_duplicated_rows_ex2 (sqlite3 * sqlite, char *table, int *removed,
7173 int transaction)
7174 {
7175 /* attempting to delete Duplicate rows from a table */
7176 char *sql;
7177 char *sql2;
7178 int first = 1;
7179 char *xname;
7180 int pk;
7181 int ret;
7182 char **results;
7183 int rows;
7184 int columns;
7185 int i;
7186 char *errMsg = NULL;
7187 int count;
7188 gaiaOutBuffer sql_statement;
7189 gaiaOutBuffer col_list;
7190
7191 if (removed != NULL)
7192 *removed = 0;
7193
7194 if (is_table (sqlite, table) == 0)
7195 {
7196 spatialite_e (".remdupl %s: no such table\n", table);
7197 if (removed != NULL)
7198 *removed = -1;
7199 return;
7200 }
7201 /* extracting the column names (excluding any Primary Key) */
7202 gaiaOutBufferInitialize (&col_list);
7203 xname = gaiaDoubleQuotedSql (table);
7204 sql = sqlite3_mprintf ("PRAGMA table_info(\"%s\")", xname);
7205 free (xname);
7206 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
7207 sqlite3_free (sql);
7208 if (ret != SQLITE_OK)
7209 {
7210 spatialite_e ("SQLite SQL error: %s\n", errMsg);
7211 sqlite3_free (errMsg);
7212 return;
7213 }
7214 if (rows < 1)
7215 ;
7216 else
7217 {
7218 for (i = 1; i <= rows; i++)
7219 {
7220 sql = results[(i * columns) + 1];
7221 pk = atoi (results[(i * columns) + 5]);
7222 if (!pk)
7223 {
7224 if (first)
7225 first = 0;
7226 else
7227 gaiaAppendToOutBuffer (&col_list, ", ");
7228 xname = gaiaDoubleQuotedSql (sql);
7229 sql = sqlite3_mprintf ("\"%s\"", xname);
7230 free (xname);
7231 gaiaAppendToOutBuffer (&col_list, sql);
7232 sqlite3_free (sql);
7233 }
7234 }
7235 }
7236 sqlite3_free_table (results);
7237 /* preparing the SQL statement (identifying duplicated rows) */
7238 gaiaOutBufferInitialize (&sql_statement);
7239 gaiaAppendToOutBuffer (&sql_statement, "SELECT ROWID, ");
7240 if (col_list.Error == 0 && col_list.Buffer != NULL)
7241 gaiaAppendToOutBuffer (&sql_statement, col_list.Buffer);
7242 xname = gaiaDoubleQuotedSql (table);
7243 sql = sqlite3_mprintf ("\nFROM \"%s\"\nORDER BY ", xname);
7244 free (xname);
7245 gaiaAppendToOutBuffer (&sql_statement, sql);
7246 sqlite3_free (sql);
7247 if (col_list.Error == 0 && col_list.Buffer != NULL)
7248 gaiaAppendToOutBuffer (&sql_statement, col_list.Buffer);
7249 gaiaOutBufferReset (&col_list);
7250 gaiaAppendToOutBuffer (&sql_statement, ", ROWID");
7251 /* preparing the SQL statement [delete] */
7252 xname = gaiaDoubleQuotedSql (table);
7253 sql2 = sqlite3_mprintf ("DELETE FROM \"%s\" WHERE ROWID = ?", xname);
7254 free (xname);
7255
7256 if (sql_statement.Error == 0 && sql_statement.Buffer != NULL)
7257 sql = sql_statement.Buffer;
7258 else
7259 sql = "NULL-SELECT";
7260 if (do_delete_duplicates (sqlite, sql, sql2, &count, transaction))
7261 {
7262 if (removed == NULL)
7263 {
7264 if (!count)
7265 spatialite_e ("No duplicated rows have been identified\n");
7266 else
7267 spatialite_e ("%d duplicated rows deleted from: %s\n",
7268 count, table);
7269 }
7270 else
7271 *removed = count;
7272 }
7273 gaiaOutBufferReset (&sql_statement);
7274 sqlite3_free (sql2);
7275 }
7276
7277 SPATIALITE_DECLARE void
remove_duplicated_rows_ex(sqlite3 * sqlite,char * table,int * removed)7278 remove_duplicated_rows_ex (sqlite3 * sqlite, char *table, int *removed)
7279 {
7280 /* attempting to delete Duplicate rows from a table */
7281 remove_duplicated_rows_ex2 (sqlite, table, removed, 1);
7282 }
7283
7284 SPATIALITE_DECLARE void
remove_duplicated_rows(sqlite3 * sqlite,char * table)7285 remove_duplicated_rows (sqlite3 * sqlite, char *table)
7286 {
7287 /* attempting to delete Duplicate rows from a table */
7288 remove_duplicated_rows_ex (sqlite, table, NULL);
7289 }
7290
7291 static int
check_elementary(sqlite3 * sqlite,const char * inTable,const char * geom,const char * outTable,const char * pKey,const char * multiID,char * type,int * srid,char * coordDims)7292 check_elementary (sqlite3 * sqlite, const char *inTable, const char *geom,
7293 const char *outTable, const char *pKey, const char *multiID,
7294 char *type, int *srid, char *coordDims)
7295 {
7296 /* preliminary check for ELEMENTARY GEOMETRIES */
7297 char *sql;
7298 char *xtable;
7299 int ret;
7300 char **results;
7301 int rows;
7302 int columns;
7303 char *errMsg = NULL;
7304 int ok = 0;
7305 int i;
7306 char *gtp;
7307 char *dims;
7308 int metadata_version = checkSpatialMetaData (sqlite);
7309
7310 /* fetching metadata */
7311 if (metadata_version == 3)
7312 {
7313 /* current metadata style >= v.4.0.0 */
7314 sql = sqlite3_mprintf ("SELECT geometry_type, srid "
7315 "FROM geometry_columns WHERE Lower(f_table_name) = Lower(%Q) "
7316 "AND Lower(f_geometry_column) = Lower(%Q)",
7317 inTable, geom);
7318 }
7319 else
7320 {
7321 /* legacy metadata style <= v.3.1.0 */
7322 sql = sqlite3_mprintf ("SELECT type, coord_dimension, srid "
7323 "FROM geometry_columns WHERE Lower(f_table_name) = Lower(%Q) "
7324 "AND Lower(f_geometry_column) = Lower(%Q)",
7325 inTable, geom);
7326 }
7327 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
7328 sqlite3_free (sql);
7329 if (ret != SQLITE_OK)
7330 {
7331 spatialite_e ("SQL error: %s\n", errMsg);
7332 sqlite3_free (errMsg);
7333 return 0;
7334 }
7335 if (rows < 1)
7336 ;
7337 else
7338 {
7339 for (i = 1; i <= rows; i++)
7340 {
7341 if (metadata_version == 3)
7342 {
7343 /* current metadata style >= v.4.0.0 */
7344 gtp = "UNKNOWN";
7345 dims = "UNKNOWN";
7346 switch (atoi (results[(i * columns) + 0]))
7347 {
7348 case 0:
7349 gtp = "GEOMETRY";
7350 dims = "XY";
7351 break;
7352 case 1:
7353 gtp = "POINT";
7354 dims = "XY";
7355 break;
7356 case 2:
7357 gtp = "LINESTRING";
7358 dims = "XY";
7359 break;
7360 case 3:
7361 gtp = "POLYGON";
7362 dims = "XY";
7363 break;
7364 case 4:
7365 gtp = "MULTIPOINT";
7366 dims = "XY";
7367 break;
7368 case 5:
7369 gtp = "MULTILINESTRING";
7370 dims = "XY";
7371 break;
7372 case 6:
7373 gtp = "MULTIPOLYGON";
7374 dims = "XY";
7375 break;
7376 case 7:
7377 gtp = "GEOMETRYCOLLECTION";
7378 dims = "XY";
7379 break;
7380 case 1000:
7381 gtp = "GEOMETRY";
7382 dims = "XYZ";
7383 break;
7384 case 1001:
7385 gtp = "POINT";
7386 dims = "XYZ";
7387 break;
7388 case 1002:
7389 gtp = "LINESTRING";
7390 dims = "XYZ";
7391 break;
7392 case 1003:
7393 gtp = "POLYGON";
7394 dims = "XYZ";
7395 break;
7396 case 1004:
7397 gtp = "MULTIPOINT";
7398 dims = "XYZ";
7399 break;
7400 case 1005:
7401 gtp = "MULTILINESTRING";
7402 dims = "XYZ";
7403 break;
7404 case 1006:
7405 gtp = "MULTIPOLYGON";
7406 dims = "XYZ";
7407 break;
7408 case 1007:
7409 gtp = "GEOMETRYCOLLECTION";
7410 dims = "XYZ";
7411 break;
7412 case 2000:
7413 gtp = "GEOMETRY";
7414 dims = "XYM";
7415 break;
7416 case 2001:
7417 gtp = "POINT";
7418 dims = "XYM";
7419 break;
7420 case 2002:
7421 gtp = "LINESTRING";
7422 dims = "XYM";
7423 break;
7424 case 2003:
7425 gtp = "POLYGON";
7426 dims = "XYM";
7427 break;
7428 case 2004:
7429 gtp = "MULTIPOINT";
7430 dims = "XYM";
7431 break;
7432 case 2005:
7433 gtp = "MULTILINESTRING";
7434 dims = "XYM";
7435 break;
7436 case 2006:
7437 gtp = "MULTIPOLYGON";
7438 dims = "XYM";
7439 break;
7440 case 2007:
7441 gtp = "GEOMETRYCOLLECTION";
7442 dims = "XYM";
7443 break;
7444 case 3000:
7445 gtp = "GEOMETRY";
7446 dims = "XYZM";
7447 break;
7448 case 3001:
7449 gtp = "POINT";
7450 dims = "XYZM";
7451 break;
7452 case 3002:
7453 gtp = "LINESTRING";
7454 dims = "XYZM";
7455 break;
7456 case 3003:
7457 gtp = "POLYGON";
7458 dims = "XYZM";
7459 break;
7460 case 3004:
7461 gtp = "MULTIPOINT";
7462 dims = "XYZM";
7463 break;
7464 case 3005:
7465 gtp = "MULTILINESTRING";
7466 dims = "XYZM";
7467 break;
7468 case 3006:
7469 gtp = "MULTIPOLYGON";
7470 dims = "XYZM";
7471 break;
7472 case 3007:
7473 gtp = "GEOMETRYCOLLECTION";
7474 dims = "XYZM";
7475 break;
7476 };
7477 *srid = atoi (results[(i * columns) + 1]);
7478 }
7479 else
7480 {
7481 /* legacy metadata style <= v.3.1.0 */
7482 gtp = results[(i * columns) + 0];
7483 dims = results[(i * columns) + 1];
7484 *srid = atoi (results[(i * columns) + 2]);
7485 }
7486 if (strcasecmp (gtp, "POINT") == 0
7487 || strcasecmp (gtp, "MULTIPOINT") == 0)
7488 strcpy (type, "POINT");
7489 else if (strcasecmp (gtp, "LINESTRING") == 0
7490 || strcasecmp (gtp, "MULTILINESTRING") == 0)
7491 strcpy (type, "LINESTRING");
7492 else if (strcasecmp (gtp, "POLYGON") == 0
7493 || strcasecmp (gtp, "MULTIPOLYGON") == 0)
7494 strcpy (type, "POLYGON");
7495 else
7496 strcpy (type, "GEOMETRY");
7497 strcpy (coordDims, dims);
7498 ok = 1;
7499 }
7500 }
7501 sqlite3_free_table (results);
7502 if (!ok)
7503 return 0;
7504
7505 /* checking if PrimaryKey already exists */
7506 xtable = gaiaDoubleQuotedSql (inTable);
7507 sql = sqlite3_mprintf ("PRAGMA table_info(\"%s\")", xtable);
7508 free (xtable);
7509 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
7510 sqlite3_free (sql);
7511 if (ret != SQLITE_OK)
7512 {
7513 spatialite_e ("SQL error: %s\n", errMsg);
7514 sqlite3_free (errMsg);
7515 return 0;
7516 }
7517 if (rows < 1)
7518 ;
7519 else
7520 {
7521 for (i = 1; i <= rows; i++)
7522 {
7523 if (strcasecmp (pKey, results[(i * columns) + 1]) == 0)
7524 ok = 0;
7525 }
7526 }
7527 sqlite3_free_table (results);
7528 if (!ok)
7529 return 0;
7530
7531 /* checking if MultiID already exists */
7532 xtable = gaiaDoubleQuotedSql (inTable);
7533 sql = sqlite3_mprintf ("PRAGMA table_info(\"%s\")", xtable);
7534 free (xtable);
7535 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
7536 sqlite3_free (sql);
7537 if (ret != SQLITE_OK)
7538 {
7539 spatialite_e ("SQL error: %s\n", errMsg);
7540 sqlite3_free (errMsg);
7541 return 0;
7542 }
7543 if (rows < 1)
7544 ;
7545 else
7546 {
7547 for (i = 1; i <= rows; i++)
7548 {
7549 if (strcasecmp (multiID, results[(i * columns) + 1]) == 0)
7550 ok = 0;
7551 }
7552 }
7553 sqlite3_free_table (results);
7554 if (!ok)
7555 return 0;
7556
7557 /* cheching if Output Table already exists */
7558 sql = sqlite3_mprintf ("SELECT Count(*) FROM sqlite_master "
7559 "WHERE type = 'table' AND Lower(tbl_name) = Lower(%Q)",
7560 outTable);
7561 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
7562 sqlite3_free (sql);
7563 if (ret != SQLITE_OK)
7564 {
7565 spatialite_e ("SQL error: %s\n", errMsg);
7566 sqlite3_free (errMsg);
7567 return 0;
7568 }
7569 if (rows < 1)
7570 ;
7571 else
7572 {
7573 for (i = 1; i <= rows; i++)
7574 {
7575 if (atoi (results[(i * columns) + 0]) != 0)
7576 ok = 0;
7577 }
7578 }
7579 sqlite3_free_table (results);
7580
7581 return ok;
7582 }
7583
7584 static gaiaGeomCollPtr
elemGeomFromPoint(gaiaPointPtr pt,int srid)7585 elemGeomFromPoint (gaiaPointPtr pt, int srid)
7586 {
7587 /* creating a Geometry containing a single Point */
7588 gaiaGeomCollPtr g = NULL;
7589 switch (pt->DimensionModel)
7590 {
7591 case GAIA_XY_Z_M:
7592 g = gaiaAllocGeomCollXYZM ();
7593 break;
7594 case GAIA_XY_Z:
7595 g = gaiaAllocGeomCollXYZ ();
7596 break;
7597 case GAIA_XY_M:
7598 g = gaiaAllocGeomCollXYM ();
7599 break;
7600 default:
7601 g = gaiaAllocGeomColl ();
7602 break;
7603 };
7604 if (!g)
7605 return NULL;
7606 g->Srid = srid;
7607 g->DeclaredType = GAIA_POINT;
7608 switch (pt->DimensionModel)
7609 {
7610 case GAIA_XY_Z_M:
7611 gaiaAddPointToGeomCollXYZM (g, pt->X, pt->Y, pt->Z, pt->M);
7612 break;
7613 case GAIA_XY_Z:
7614 gaiaAddPointToGeomCollXYZ (g, pt->X, pt->Y, pt->Z);
7615 break;
7616 case GAIA_XY_M:
7617 gaiaAddPointToGeomCollXYM (g, pt->X, pt->Y, pt->M);
7618 break;
7619 default:
7620 gaiaAddPointToGeomColl (g, pt->X, pt->Y);
7621 break;
7622 };
7623 return g;
7624 }
7625
7626 static gaiaGeomCollPtr
elemGeomFromLinestring(gaiaLinestringPtr ln,int srid)7627 elemGeomFromLinestring (gaiaLinestringPtr ln, int srid)
7628 {
7629 /* creating a Geometry containing a single Linestring */
7630 gaiaGeomCollPtr g = NULL;
7631 gaiaLinestringPtr ln2;
7632 int iv;
7633 double x;
7634 double y;
7635 double z;
7636 double m;
7637 switch (ln->DimensionModel)
7638 {
7639 case GAIA_XY_Z_M:
7640 g = gaiaAllocGeomCollXYZM ();
7641 break;
7642 case GAIA_XY_Z:
7643 g = gaiaAllocGeomCollXYZ ();
7644 break;
7645 case GAIA_XY_M:
7646 g = gaiaAllocGeomCollXYM ();
7647 break;
7648 default:
7649 g = gaiaAllocGeomColl ();
7650 break;
7651 };
7652 if (!g)
7653 return NULL;
7654 g->Srid = srid;
7655 g->DeclaredType = GAIA_LINESTRING;
7656 ln2 = gaiaAddLinestringToGeomColl (g, ln->Points);
7657 switch (ln->DimensionModel)
7658 {
7659 case GAIA_XY_Z_M:
7660 for (iv = 0; iv < ln->Points; iv++)
7661 {
7662 gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m);
7663 gaiaSetPointXYZM (ln2->Coords, iv, x, y, z, m);
7664 }
7665 break;
7666 case GAIA_XY_Z:
7667 for (iv = 0; iv < ln->Points; iv++)
7668 {
7669 gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z);
7670 gaiaSetPointXYZ (ln2->Coords, iv, x, y, z);
7671 }
7672 break;
7673 case GAIA_XY_M:
7674 for (iv = 0; iv < ln->Points; iv++)
7675 {
7676 gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m);
7677 gaiaSetPointXYM (ln2->Coords, iv, x, y, m);
7678 }
7679 break;
7680 default:
7681 for (iv = 0; iv < ln->Points; iv++)
7682 {
7683 gaiaGetPoint (ln->Coords, iv, &x, &y);
7684 gaiaSetPoint (ln2->Coords, iv, x, y);
7685 }
7686 break;
7687 };
7688 return g;
7689 }
7690
7691 static gaiaGeomCollPtr
elemGeomFromPolygon(gaiaPolygonPtr pg,int srid)7692 elemGeomFromPolygon (gaiaPolygonPtr pg, int srid)
7693 {
7694 /* creating a Geometry containing a single Polygon */
7695 gaiaGeomCollPtr g = NULL;
7696 gaiaPolygonPtr pg2;
7697 gaiaRingPtr rng;
7698 gaiaRingPtr rng2;
7699 int ib;
7700 int iv;
7701 double x;
7702 double y;
7703 double z;
7704 double m;
7705 switch (pg->DimensionModel)
7706 {
7707 case GAIA_XY_Z_M:
7708 g = gaiaAllocGeomCollXYZM ();
7709 break;
7710 case GAIA_XY_Z:
7711 g = gaiaAllocGeomCollXYZ ();
7712 break;
7713 case GAIA_XY_M:
7714 g = gaiaAllocGeomCollXYM ();
7715 break;
7716 default:
7717 g = gaiaAllocGeomColl ();
7718 break;
7719 };
7720 if (!g)
7721 return NULL;
7722 g->Srid = srid;
7723 g->DeclaredType = GAIA_POLYGON;
7724 rng = pg->Exterior;
7725 pg2 = gaiaAddPolygonToGeomColl (g, rng->Points, pg->NumInteriors);
7726 rng2 = pg2->Exterior;
7727 switch (pg->DimensionModel)
7728 {
7729 case GAIA_XY_Z_M:
7730 for (iv = 0; iv < rng->Points; iv++)
7731 {
7732 gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
7733 gaiaSetPointXYZM (rng2->Coords, iv, x, y, z, m);
7734 }
7735 for (ib = 0; ib < pg->NumInteriors; ib++)
7736 {
7737 rng = pg->Interiors + ib;
7738 rng2 = gaiaAddInteriorRing (pg2, ib, rng->Points);
7739 for (iv = 0; iv < rng->Points; iv++)
7740 {
7741 gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m);
7742 gaiaSetPointXYZM (rng2->Coords, iv, x, y, z, m);
7743 }
7744 }
7745 break;
7746 case GAIA_XY_Z:
7747 for (iv = 0; iv < rng->Points; iv++)
7748 {
7749 gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
7750 gaiaSetPointXYZ (rng2->Coords, iv, x, y, z);
7751 }
7752 for (ib = 0; ib < pg->NumInteriors; ib++)
7753 {
7754 rng = pg->Interiors + ib;
7755 rng2 = gaiaAddInteriorRing (pg2, ib, rng->Points);
7756 for (iv = 0; iv < rng->Points; iv++)
7757 {
7758 gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z);
7759 gaiaSetPointXYZ (rng2->Coords, iv, x, y, z);
7760 }
7761 }
7762 break;
7763 case GAIA_XY_M:
7764 for (iv = 0; iv < rng->Points; iv++)
7765 {
7766 gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
7767 gaiaSetPointXYM (rng2->Coords, iv, x, y, m);
7768 }
7769 for (ib = 0; ib < pg->NumInteriors; ib++)
7770 {
7771 rng = pg->Interiors + ib;
7772 rng2 = gaiaAddInteriorRing (pg2, ib, rng->Points);
7773 for (iv = 0; iv < rng->Points; iv++)
7774 {
7775 gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m);
7776 gaiaSetPointXYM (rng2->Coords, iv, x, y, m);
7777 }
7778 }
7779 break;
7780 default:
7781 for (iv = 0; iv < rng->Points; iv++)
7782 {
7783 gaiaGetPoint (rng->Coords, iv, &x, &y);
7784 gaiaSetPoint (rng2->Coords, iv, x, y);
7785 }
7786 for (ib = 0; ib < pg->NumInteriors; ib++)
7787 {
7788 rng = pg->Interiors + ib;
7789 rng2 = gaiaAddInteriorRing (pg2, ib, rng->Points);
7790 for (iv = 0; iv < rng->Points; iv++)
7791 {
7792 gaiaGetPoint (rng->Coords, iv, &x, &y);
7793 gaiaSetPoint (rng2->Coords, iv, x, y);
7794 }
7795 }
7796 break;
7797 };
7798 return g;
7799 }
7800
7801 SPATIALITE_DECLARE void
elementary_geometries(sqlite3 * sqlite,char * inTable,char * geometry,char * outTable,char * pKey,char * multiId)7802 elementary_geometries (sqlite3 * sqlite,
7803 char *inTable, char *geometry, char *outTable,
7804 char *pKey, char *multiId)
7805 {
7806 /* attempting to create a derived table surely containing elemetary Geoms */
7807 int rows;
7808 elementary_geometries_ex (sqlite, inTable, geometry, outTable, pKey,
7809 multiId, &rows);
7810 }
7811
7812 SPATIALITE_DECLARE void
elementary_geometries_ex(sqlite3 * sqlite,char * inTable,char * geometry,char * outTable,char * pKey,char * multiId,int * xrows)7813 elementary_geometries_ex (sqlite3 * sqlite,
7814 char *inTable, char *geometry, char *outTable,
7815 char *pKey, char *multiId, int *xrows)
7816 {
7817 /* attempting to create a derived table surely containing elemetary Geoms */
7818 elementary_geometries_ex2 (sqlite, inTable, geometry, outTable, pKey,
7819 multiId, xrows, 1);
7820 }
7821
7822 SPATIALITE_DECLARE void
elementary_geometries_ex2(sqlite3 * sqlite,char * inTable,char * geometry,char * outTable,char * pKey,char * multiId,int * xrows,int transaction)7823 elementary_geometries_ex2 (sqlite3 * sqlite,
7824 char *inTable, char *geometry, char *outTable,
7825 char *pKey, char *multiId, int *xrows,
7826 int transaction)
7827 {
7828 /* attempting to create a derived table surely containing elemetary Geoms */
7829 elementary_geometries_ex3 (sqlite, inTable, geometry, outTable, pKey,
7830 multiId, NULL, xrows, transaction);
7831 }
7832
7833 static int
test_elemgeom_ignore(struct aux_elemgeom_options * options,const char * column)7834 test_elemgeom_ignore (struct aux_elemgeom_options *options, const char *column)
7835 {
7836 /* testing for a column to be ignored */
7837 struct aux_elemgeom_ignore *ign;
7838 if (options == NULL)
7839 return 0;
7840
7841 ign = options->first;
7842 while (ign != NULL)
7843 {
7844 if (strcasecmp (ign->column, column) == 0)
7845 return 1;
7846 ign = ign->next;
7847 }
7848 return 0;
7849 }
7850
7851 SPATIALITE_DECLARE void
elementary_geometries_ex3(sqlite3 * sqlite,char * inTable,char * geometry,char * outTable,char * pKey,char * multiId,const void * opts,int * xrows,int transaction)7852 elementary_geometries_ex3 (sqlite3 * sqlite,
7853 char *inTable, char *geometry, char *outTable,
7854 char *pKey, char *multiId, const void *opts,
7855 int *xrows, int transaction)
7856 {
7857 /* attempting to create a derived table surely containing elemetary Geoms */
7858 char type[128];
7859 int srid;
7860 char dims[64];
7861 char *sql;
7862 char *xname;
7863 char *xpk;
7864 char *xmulti;
7865 gaiaOutBuffer sql_statement;
7866 gaiaOutBuffer sql2;
7867 gaiaOutBuffer sql3;
7868 gaiaOutBuffer sql4;
7869 char *sql_geom;
7870 int ret;
7871 int comma = 0;
7872 char *errMsg = NULL;
7873 int i;
7874 char **results;
7875 int rows;
7876 int columns;
7877 int i_col;
7878 int geom_idx = -1;
7879 sqlite3_stmt *stmt_in = NULL;
7880 sqlite3_stmt *stmt_out = NULL;
7881 int n_columns;
7882 sqlite3_int64 id = 0;
7883 int inserted = 0;
7884 struct aux_elemgeom_options *options = (struct aux_elemgeom_options *) opts;
7885
7886 if (check_elementary
7887 (sqlite, inTable, geometry, outTable, pKey, multiId, type, &srid,
7888 dims) == 0)
7889 {
7890 spatialite_e (".elemgeo: invalid args\n");
7891 *xrows = 0;
7892 return;
7893 }
7894
7895 if (transaction)
7896 {
7897 /* starts a transaction */
7898 ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, &errMsg);
7899 if (ret != SQLITE_OK)
7900 {
7901 spatialite_e ("SQL error: %s\n", errMsg);
7902 sqlite3_free (errMsg);
7903 goto abort;
7904 }
7905 }
7906
7907 gaiaOutBufferInitialize (&sql_statement);
7908 gaiaOutBufferInitialize (&sql2);
7909 gaiaOutBufferInitialize (&sql3);
7910 gaiaOutBufferInitialize (&sql4);
7911
7912 gaiaAppendToOutBuffer (&sql_statement, "SELECT ");
7913 xname = gaiaDoubleQuotedSql (outTable);
7914 xpk = gaiaDoubleQuotedSql (pKey);
7915 xmulti = gaiaDoubleQuotedSql (multiId);
7916 sql =
7917 sqlite3_mprintf ("INSERT INTO \"%s\" (\"%s\", \"%s\", ", xname, xpk,
7918 xmulti);
7919 free (xname);
7920 free (xpk);
7921 free (xmulti);
7922 gaiaAppendToOutBuffer (&sql2, sql);
7923 sqlite3_free (sql);
7924 gaiaAppendToOutBuffer (&sql3, ") VALUES (NULL, ?");
7925 xname = gaiaDoubleQuotedSql (outTable);
7926 xpk = gaiaDoubleQuotedSql (pKey);
7927 xmulti = gaiaDoubleQuotedSql (multiId);
7928 sql = sqlite3_mprintf ("CREATE TABLE \"%s\" (\n"
7929 "\t\"%s\" INTEGER PRIMARY KEY AUTOINCREMENT"
7930 ",\n\t\"%s\" INTEGER NOT NULL", xname, xpk, xmulti);
7931 free (xname);
7932 free (xpk);
7933 free (xmulti);
7934 gaiaAppendToOutBuffer (&sql4, sql);
7935 sqlite3_free (sql);
7936
7937 xname = gaiaDoubleQuotedSql (inTable);
7938 sql = sqlite3_mprintf ("PRAGMA table_info(\"%s\")", xname);
7939 free (xname);
7940 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
7941 sqlite3_free (sql);
7942 if (ret != SQLITE_OK)
7943 {
7944 spatialite_e ("SQL error: %s\n", errMsg);
7945 sqlite3_free (errMsg);
7946 goto abort;
7947 }
7948 if (rows < 1)
7949 ;
7950 else
7951 {
7952 i_col = 0;
7953 for (i = 1; i <= rows; i++)
7954 {
7955 if (test_elemgeom_ignore (options, results[(i * columns) + 1])
7956 && strcasecmp (geometry, results[(i * columns) + 1]) != 0)
7957 {
7958 /* skipping a column to be ignored */
7959 continue;
7960 }
7961 i_col++;
7962 xname = gaiaDoubleQuotedSql (results[(i * columns) + 1]);
7963 if (comma)
7964 sql = sqlite3_mprintf (", \"%s\"", xname);
7965 else
7966 {
7967 comma = 1;
7968 sql = sqlite3_mprintf ("\"%s\"", xname);
7969 }
7970 free (xname);
7971 gaiaAppendToOutBuffer (&sql_statement, sql);
7972 gaiaAppendToOutBuffer (&sql2, sql);
7973 if (strcasecmp (geometry, results[(i * columns) + 1]) == 0)
7974 {
7975 int cast2multi = 0;
7976 if (options != NULL)
7977 cast2multi = options->cast2multi;
7978 if (cast2multi)
7979 gaiaAppendToOutBuffer (&sql3, ", CastToMulti(?)");
7980 else
7981 gaiaAppendToOutBuffer (&sql3, ", ?");
7982 }
7983 else
7984 gaiaAppendToOutBuffer (&sql3, ", ?");
7985 sqlite3_free (sql);
7986
7987 if (strcasecmp (geometry, results[(i * columns) + 1]) == 0)
7988 geom_idx = i_col - 1;
7989 else
7990 {
7991 xname = gaiaDoubleQuotedSql (results[(i * columns) + 1]);
7992 if (atoi (results[(i * columns) + 3]) != 0)
7993 sql =
7994 sqlite3_mprintf (",\n\t\"%s\" %s NOT NULL", xname,
7995 results[(i * columns) + 2]);
7996 else
7997 sql =
7998 sqlite3_mprintf (",\n\t\"%s\" %s", xname,
7999 results[(i * columns) + 2]);
8000 free (xname);
8001 gaiaAppendToOutBuffer (&sql4, sql);
8002 sqlite3_free (sql);
8003 }
8004 }
8005 }
8006 sqlite3_free_table (results);
8007 if (geom_idx < 0)
8008 goto abort;
8009
8010 xname = gaiaDoubleQuotedSql (inTable);
8011 sql = sqlite3_mprintf (" FROM \"%s\"", xname);
8012 free (xname);
8013 gaiaAppendToOutBuffer (&sql_statement, sql);
8014 sqlite3_free (sql);
8015 gaiaAppendToOutBuffer (&sql2, sql3.Buffer);
8016 gaiaAppendToOutBuffer (&sql2, ")");
8017 gaiaAppendToOutBuffer (&sql4, ")");
8018 gaiaOutBufferReset (&sql3);
8019
8020 if (options != NULL)
8021 {
8022 if (options->cast2multi)
8023 {
8024 char multi_type[128];
8025 if (strcasecmp (type, "POINT") == 0)
8026 strcpy (multi_type, "MULTIPOINT");
8027 else if (strcasecmp (type, "LINESTRING") == 0)
8028 strcpy (multi_type, "MULTILINESTRING");
8029 else if (strcasecmp (type, "POLYGON") == 0)
8030 strcpy (multi_type, "MULTIPOLYGON");
8031 else
8032 strcpy (multi_type, type);
8033 sql_geom =
8034 sqlite3_mprintf
8035 ("SELECT AddGeometryColumn(%Q, %Q, %d, %Q, %Q)", outTable,
8036 geometry, srid, multi_type, dims);
8037 }
8038 else
8039 {
8040 sql_geom =
8041 sqlite3_mprintf
8042 ("SELECT AddGeometryColumn(%Q, %Q, %d, %Q, %Q)", outTable,
8043 geometry, srid, type, dims);
8044 }
8045 }
8046 else
8047 {
8048 sql_geom =
8049 sqlite3_mprintf ("SELECT AddGeometryColumn(%Q, %Q, %d, %Q, %Q)",
8050 outTable, geometry, srid, type, dims);
8051 }
8052
8053 /* creating the output table */
8054 ret = sqlite3_exec (sqlite, sql4.Buffer, NULL, NULL, &errMsg);
8055 gaiaOutBufferReset (&sql4);
8056 if (ret != SQLITE_OK)
8057 {
8058 spatialite_e ("SQL error: %s\n", errMsg);
8059 sqlite3_free (errMsg);
8060 goto abort;
8061 }
8062 /* creating the output Geometry */
8063 ret = sqlite3_exec (sqlite, sql_geom, NULL, NULL, &errMsg);
8064 sqlite3_free (sql_geom);
8065 if (ret != SQLITE_OK)
8066 {
8067 spatialite_e ("SQL error: %s\n", errMsg);
8068 sqlite3_free (errMsg);
8069 goto abort;
8070 }
8071
8072 /* preparing the INPUT statement */
8073 ret =
8074 sqlite3_prepare_v2 (sqlite, sql_statement.Buffer,
8075 strlen (sql_statement.Buffer), &stmt_in, NULL);
8076 gaiaOutBufferReset (&sql_statement);
8077 if (ret != SQLITE_OK)
8078 {
8079 spatialite_e ("SQL error: %s\n", sqlite3_errmsg (sqlite));
8080 goto abort;
8081 }
8082
8083 /* preparing the OUTPUT statement */
8084 ret =
8085 sqlite3_prepare_v2 (sqlite, sql2.Buffer, strlen (sql2.Buffer),
8086 &stmt_out, NULL);
8087 gaiaOutBufferReset (&sql2);
8088 if (ret != SQLITE_OK)
8089 {
8090 spatialite_e ("SQL error: %s\n", sqlite3_errmsg (sqlite));
8091 goto abort;
8092 }
8093
8094 /* data transfer */
8095 n_columns = sqlite3_column_count (stmt_in);
8096 while (1)
8097 {
8098 ret = sqlite3_step (stmt_in);
8099 if (ret == SQLITE_DONE)
8100 break;
8101 if (ret == SQLITE_ROW)
8102 {
8103 gaiaGeomCollPtr g =
8104 gaiaFromSpatiaLiteBlobWkb ((const unsigned char *)
8105 sqlite3_column_blob (stmt_in,
8106 geom_idx),
8107 sqlite3_column_bytes (stmt_in,
8108 geom_idx));
8109 if (!g)
8110 {
8111 /* NULL input geometry */
8112 sqlite3_reset (stmt_out);
8113 sqlite3_clear_bindings (stmt_out);
8114 sqlite3_bind_int64 (stmt_out, 1, id);
8115 sqlite3_bind_null (stmt_out, geom_idx + 2);
8116
8117 for (i = 0; i < n_columns; i++)
8118 {
8119 int type = sqlite3_column_type (stmt_in, i);
8120 if (i == geom_idx)
8121 continue;
8122 switch (type)
8123 {
8124 case SQLITE_INTEGER:
8125 sqlite3_bind_int64 (stmt_out, i + 2,
8126 sqlite3_column_int64
8127 (stmt_in, i));
8128 break;
8129 case SQLITE_FLOAT:
8130 sqlite3_bind_double (stmt_out, i + 2,
8131 sqlite3_column_double
8132 (stmt_in, i));
8133 break;
8134 case SQLITE_TEXT:
8135 sqlite3_bind_text (stmt_out, i + 2,
8136 (const char *)
8137 sqlite3_column_text
8138 (stmt_in, i),
8139 sqlite3_column_bytes
8140 (stmt_in, i),
8141 SQLITE_STATIC);
8142 break;
8143 case SQLITE_BLOB:
8144 sqlite3_bind_blob (stmt_out, i + 2,
8145 sqlite3_column_blob
8146 (stmt_in, i),
8147 sqlite3_column_bytes
8148 (stmt_in, i),
8149 SQLITE_STATIC);
8150 break;
8151 case SQLITE_NULL:
8152 default:
8153 sqlite3_bind_null (stmt_out, i + 2);
8154 break;
8155 };
8156 }
8157
8158 ret = sqlite3_step (stmt_out);
8159 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
8160 ;
8161 else
8162 {
8163 spatialite_e ("[OUT]step error: %s\n",
8164 sqlite3_errmsg (sqlite));
8165 goto abort;
8166 }
8167 inserted++;
8168 }
8169 else
8170 {
8171 /* separating Elementary Geoms */
8172 gaiaPointPtr pt;
8173 gaiaLinestringPtr ln;
8174 gaiaPolygonPtr pg;
8175 gaiaGeomCollPtr outGeom;
8176 pt = g->FirstPoint;
8177 while (pt)
8178 {
8179 /* separating Points */
8180 outGeom = elemGeomFromPoint (pt, g->Srid);
8181 sqlite3_reset (stmt_out);
8182 sqlite3_clear_bindings (stmt_out);
8183 sqlite3_bind_int64 (stmt_out, 1, id);
8184 if (!outGeom)
8185 sqlite3_bind_null (stmt_out, geom_idx + 2);
8186 else
8187 {
8188 unsigned char *blob;
8189 int size;
8190 gaiaToSpatiaLiteBlobWkb (outGeom, &blob,
8191 &size);
8192 sqlite3_bind_blob (stmt_out, geom_idx + 2,
8193 blob, size, free);
8194 gaiaFreeGeomColl (outGeom);
8195 }
8196
8197 for (i = 0; i < n_columns; i++)
8198 {
8199 int type = sqlite3_column_type (stmt_in, i);
8200 if (i == geom_idx)
8201 continue;
8202 switch (type)
8203 {
8204 case SQLITE_INTEGER:
8205 sqlite3_bind_int64 (stmt_out, i + 2,
8206 sqlite3_column_int64
8207 (stmt_in, i));
8208 break;
8209 case SQLITE_FLOAT:
8210 sqlite3_bind_double (stmt_out, i + 2,
8211 sqlite3_column_double
8212 (stmt_in, i));
8213 break;
8214 case SQLITE_TEXT:
8215 sqlite3_bind_text (stmt_out, i + 2,
8216 (const char *)
8217 sqlite3_column_text
8218 (stmt_in, i),
8219 sqlite3_column_bytes
8220 (stmt_in, i),
8221 SQLITE_STATIC);
8222 break;
8223 case SQLITE_BLOB:
8224 sqlite3_bind_blob (stmt_out, i + 2,
8225 sqlite3_column_blob
8226 (stmt_in, i),
8227 sqlite3_column_bytes
8228 (stmt_in, i),
8229 SQLITE_STATIC);
8230 break;
8231 case SQLITE_NULL:
8232 default:
8233 sqlite3_bind_null (stmt_out, i + 2);
8234 break;
8235 };
8236 }
8237
8238 ret = sqlite3_step (stmt_out);
8239 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
8240 ;
8241 else
8242 {
8243 spatialite_e ("[OUT]step error: %s\n",
8244 sqlite3_errmsg (sqlite));
8245 goto abort;
8246 }
8247 inserted++;
8248 pt = pt->Next;
8249 }
8250 ln = g->FirstLinestring;
8251 while (ln)
8252 {
8253 /* separating Linestrings */
8254 outGeom = elemGeomFromLinestring (ln, g->Srid);
8255 sqlite3_reset (stmt_out);
8256 sqlite3_clear_bindings (stmt_out);
8257 sqlite3_bind_int64 (stmt_out, 1, id);
8258 if (!outGeom)
8259 sqlite3_bind_null (stmt_out, geom_idx + 2);
8260 else
8261 {
8262 unsigned char *blob;
8263 int size;
8264 gaiaToSpatiaLiteBlobWkb (outGeom, &blob,
8265 &size);
8266 sqlite3_bind_blob (stmt_out, geom_idx + 2,
8267 blob, size, free);
8268 gaiaFreeGeomColl (outGeom);
8269 }
8270
8271 for (i = 0; i < n_columns; i++)
8272 {
8273 int type = sqlite3_column_type (stmt_in, i);
8274 if (i == geom_idx)
8275 continue;
8276 switch (type)
8277 {
8278 case SQLITE_INTEGER:
8279 sqlite3_bind_int64 (stmt_out, i + 2,
8280 sqlite3_column_int64
8281 (stmt_in, i));
8282 break;
8283 case SQLITE_FLOAT:
8284 sqlite3_bind_double (stmt_out, i + 2,
8285 sqlite3_column_double
8286 (stmt_in, i));
8287 break;
8288 case SQLITE_TEXT:
8289 sqlite3_bind_text (stmt_out, i + 2,
8290 (const char *)
8291 sqlite3_column_text
8292 (stmt_in, i),
8293 sqlite3_column_bytes
8294 (stmt_in, i),
8295 SQLITE_STATIC);
8296 break;
8297 case SQLITE_BLOB:
8298 sqlite3_bind_blob (stmt_out, i + 2,
8299 sqlite3_column_blob
8300 (stmt_in, i),
8301 sqlite3_column_bytes
8302 (stmt_in, i),
8303 SQLITE_STATIC);
8304 break;
8305 case SQLITE_NULL:
8306 default:
8307 sqlite3_bind_null (stmt_out, i + 2);
8308 break;
8309 };
8310 }
8311
8312 ret = sqlite3_step (stmt_out);
8313 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
8314 ;
8315 else
8316 {
8317 spatialite_e ("[OUT]step error: %s\n",
8318 sqlite3_errmsg (sqlite));
8319 goto abort;
8320 }
8321 inserted++;
8322 ln = ln->Next;
8323 }
8324 pg = g->FirstPolygon;
8325 while (pg)
8326 {
8327 /* separating Polygons */
8328 outGeom = elemGeomFromPolygon (pg, g->Srid);
8329 sqlite3_reset (stmt_out);
8330 sqlite3_clear_bindings (stmt_out);
8331 sqlite3_bind_int64 (stmt_out, 1, id);
8332 if (!outGeom)
8333 sqlite3_bind_null (stmt_out, geom_idx + 2);
8334 else
8335 {
8336 unsigned char *blob;
8337 int size;
8338 gaiaToSpatiaLiteBlobWkb (outGeom, &blob,
8339 &size);
8340 sqlite3_bind_blob (stmt_out, geom_idx + 2,
8341 blob, size, free);
8342 gaiaFreeGeomColl (outGeom);
8343 }
8344
8345 for (i = 0; i < n_columns; i++)
8346 {
8347 int type = sqlite3_column_type (stmt_in, i);
8348 if (i == geom_idx)
8349 continue;
8350 switch (type)
8351 {
8352 case SQLITE_INTEGER:
8353 sqlite3_bind_int64 (stmt_out, i + 2,
8354 sqlite3_column_int64
8355 (stmt_in, i));
8356 break;
8357 case SQLITE_FLOAT:
8358 sqlite3_bind_double (stmt_out, i + 2,
8359 sqlite3_column_double
8360 (stmt_in, i));
8361 break;
8362 case SQLITE_TEXT:
8363 sqlite3_bind_text (stmt_out, i + 2,
8364 (const char *)
8365 sqlite3_column_text
8366 (stmt_in, i),
8367 sqlite3_column_bytes
8368 (stmt_in, i),
8369 SQLITE_STATIC);
8370 break;
8371 case SQLITE_BLOB:
8372 sqlite3_bind_blob (stmt_out, i + 2,
8373 sqlite3_column_blob
8374 (stmt_in, i),
8375 sqlite3_column_bytes
8376 (stmt_in, i),
8377 SQLITE_STATIC);
8378 break;
8379 case SQLITE_NULL:
8380 default:
8381 sqlite3_bind_null (stmt_out, i + 2);
8382 break;
8383 };
8384 }
8385
8386 ret = sqlite3_step (stmt_out);
8387 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
8388 ;
8389 else
8390 {
8391 spatialite_e ("[OUT]step error: %s\n",
8392 sqlite3_errmsg (sqlite));
8393 goto abort;
8394 }
8395 inserted++;
8396 pg = pg->Next;
8397 }
8398 gaiaFreeGeomColl (g);
8399 }
8400 id++;
8401 }
8402 else
8403 {
8404 spatialite_e ("[IN]step error: %s\n", sqlite3_errmsg (sqlite));
8405 goto abort;
8406 }
8407 }
8408 sqlite3_finalize (stmt_in);
8409 sqlite3_finalize (stmt_out);
8410
8411 if (transaction)
8412 {
8413 /* commits the transaction */
8414 ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, &errMsg);
8415 if (ret != SQLITE_OK)
8416 {
8417 spatialite_e ("SQL error: %s\n", errMsg);
8418 sqlite3_free (errMsg);
8419 goto abort;
8420 }
8421 }
8422 *xrows = inserted;
8423 return;
8424
8425 abort:
8426 if (stmt_in)
8427 sqlite3_finalize (stmt_in);
8428 if (stmt_out)
8429 sqlite3_finalize (stmt_out);
8430
8431 if (transaction)
8432 {
8433 /* rolling bacj the transaction */
8434 ret = sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, &errMsg);
8435 if (ret != SQLITE_OK)
8436 {
8437 spatialite_e ("SQL error: %s\n", errMsg);
8438 sqlite3_free (errMsg);
8439 }
8440 }
8441 *xrows = 0;
8442 }
8443
8444 #ifndef OMIT_FREEXL /* including FreeXL */
8445
8446 SPATIALITE_DECLARE int
load_XL(sqlite3 * sqlite,const char * path,const char * table,unsigned int worksheetIndex,int first_titles,unsigned int * rows,char * err_msg)8447 load_XL (sqlite3 * sqlite, const char *path, const char *table,
8448 unsigned int worksheetIndex, int first_titles, unsigned int *rows,
8449 char *err_msg)
8450 {
8451 /* loading an XL spreadsheet as a new DB table */
8452 sqlite3_stmt *stmt;
8453 unsigned int current_row;
8454 int ret;
8455 char *errMsg = NULL;
8456 char *xname;
8457 char *dummy;
8458 char *xdummy;
8459 char *sql;
8460 int sqlError = 0;
8461 const void *xl_handle;
8462 unsigned int info;
8463 unsigned short columns;
8464 unsigned short col;
8465 gaiaOutBuffer sql_statement;
8466 FreeXL_CellValue cell;
8467 int already_exists = 0;
8468
8469 *rows = 0;
8470 /* checking if TABLE already exists */
8471 sql =
8472 sqlite3_mprintf ("SELECT name FROM sqlite_master WHERE type = 'table' "
8473 "AND Lower(name) = Lower(%Q)", table);
8474 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
8475 sqlite3_free (sql);
8476 if (ret != SQLITE_OK)
8477 {
8478 if (!err_msg)
8479 spatialite_e ("load XL error: <%s>\n", sqlite3_errmsg (sqlite));
8480 else
8481 sprintf (err_msg, "load XL error: <%s>\n",
8482 sqlite3_errmsg (sqlite));
8483 return 0;
8484 }
8485 while (1)
8486 {
8487 /* scrolling the result set */
8488 ret = sqlite3_step (stmt);
8489 if (ret == SQLITE_DONE)
8490 break; /* end of result set */
8491 if (ret == SQLITE_ROW)
8492 already_exists = 1;
8493 else
8494 {
8495 spatialite_e ("load XL error: <%s>\n", sqlite3_errmsg (sqlite));
8496 break;
8497 }
8498 }
8499 sqlite3_finalize (stmt);
8500 if (already_exists)
8501 {
8502 if (!err_msg)
8503 spatialite_e ("load XL error: table '%s' already exists\n",
8504 table);
8505 else
8506 sprintf (err_msg, "load XL error: table '%s' already exists\n",
8507 table);
8508 return 0;
8509 }
8510 /* opening the .XLS file [Workbook] */
8511 ret = freexl_open (path, &xl_handle);
8512 if (ret != FREEXL_OK)
8513 goto error;
8514 /* checking if Password protected */
8515 ret = freexl_get_info (xl_handle, FREEXL_BIFF_PASSWORD, &info);
8516 if (ret != FREEXL_OK)
8517 goto error;
8518 if (info != FREEXL_BIFF_PLAIN)
8519 goto error;
8520 /* Worksheet entries */
8521 ret = freexl_get_info (xl_handle, FREEXL_BIFF_SHEET_COUNT, &info);
8522 if (ret != FREEXL_OK)
8523 goto error;
8524 if (info == 0)
8525 goto error;
8526 if (worksheetIndex < info)
8527 ;
8528 else
8529 goto error;
8530 ret =
8531 freexl_select_active_worksheet (xl_handle,
8532 (unsigned short) worksheetIndex);
8533 if (ret != FREEXL_OK)
8534 goto error;
8535 ret = freexl_worksheet_dimensions (xl_handle, rows, &columns);
8536 if (ret != FREEXL_OK)
8537 goto error;
8538 /* starting a transaction */
8539 ret = sqlite3_exec (sqlite, "BEGIN", NULL, 0, &errMsg);
8540 if (ret != SQLITE_OK)
8541 {
8542 spatialite_e ("load XL error: %s\n", errMsg);
8543 sqlite3_free (errMsg);
8544 sqlError = 1;
8545 goto clean_up;
8546 }
8547 /* creating the Table */
8548 gaiaOutBufferInitialize (&sql_statement);
8549 xname = gaiaDoubleQuotedSql (table);
8550 sql = sqlite3_mprintf ("CREATE TABLE \"%s\"", xname);
8551 free (xname);
8552 gaiaAppendToOutBuffer (&sql_statement, sql);
8553 sqlite3_free (sql);
8554 gaiaAppendToOutBuffer (&sql_statement,
8555 " (\nPK_UID INTEGER PRIMARY KEY AUTOINCREMENT");
8556 for (col = 0; col < columns; col++)
8557 {
8558 if (first_titles)
8559 {
8560 /* fetching column names */
8561 for (col = 0; col < columns; col++)
8562 {
8563 ret = freexl_get_cell_value (xl_handle, 0, col, &cell);
8564 if (ret != FREEXL_OK)
8565 dummy = sqlite3_mprintf ("col_%d", col);
8566 else
8567 {
8568 if (cell.type == FREEXL_CELL_INT)
8569 dummy =
8570 sqlite3_mprintf ("%d",
8571 cell.value.int_value);
8572 else if (cell.type == FREEXL_CELL_DOUBLE)
8573 dummy = sqlite3_mprintf ("%1.2f ",
8574 cell.
8575 value.double_value);
8576 else if (cell.type == FREEXL_CELL_TEXT
8577 || cell.type == FREEXL_CELL_SST_TEXT
8578 || cell.type == FREEXL_CELL_DATE
8579 || cell.type == FREEXL_CELL_DATETIME
8580 || cell.type == FREEXL_CELL_TIME)
8581 {
8582 int len = strlen (cell.value.text_value);
8583 if (len < 256)
8584 dummy =
8585 sqlite3_mprintf ("%s",
8586 cell.
8587 value.text_value);
8588 else
8589 dummy = sqlite3_mprintf ("col_%d", col);
8590 }
8591 else
8592 dummy = sqlite3_mprintf ("col_%d", col);
8593 }
8594 xdummy = gaiaDoubleQuotedSql (dummy);
8595 sqlite3_free (dummy);
8596 sql = sqlite3_mprintf (", \"%s\"", xdummy);
8597 free (xdummy);
8598 gaiaAppendToOutBuffer (&sql_statement, sql);
8599 sqlite3_free (sql);
8600 }
8601 }
8602 else
8603 {
8604 /* setting default column names */
8605 for (col = 0; col < columns; col++)
8606 {
8607 dummy = sqlite3_mprintf ("col_%d", col);
8608 xdummy = gaiaDoubleQuotedSql (dummy);
8609 sqlite3_free (dummy);
8610 sql = sqlite3_mprintf (", \"%s\"", xdummy);
8611 free (xdummy);
8612 gaiaAppendToOutBuffer (&sql_statement, sql);
8613 sqlite3_free (sql);
8614 }
8615 }
8616 }
8617 gaiaAppendToOutBuffer (&sql_statement, ")");
8618 if (sql_statement.Error == 0 && sql_statement.Buffer != NULL)
8619 {
8620 ret = sqlite3_exec (sqlite, sql_statement.Buffer, NULL, 0, &errMsg);
8621 gaiaOutBufferReset (&sql_statement);
8622 if (ret != SQLITE_OK)
8623 {
8624 spatialite_e ("load XL error: %s\n", errMsg);
8625 sqlite3_free (errMsg);
8626 sqlError = 1;
8627 goto clean_up;
8628 }
8629 }
8630 /* preparing the INSERT INTO parameterized statement */
8631 gaiaOutBufferReset (&sql_statement);
8632 xname = gaiaDoubleQuotedSql (table);
8633 sql = sqlite3_mprintf ("INSERT INTO \"%s\" (PK_UID", xname);
8634 free (xname);
8635 gaiaAppendToOutBuffer (&sql_statement, sql);
8636 sqlite3_free (sql);
8637 for (col = 0; col < columns; col++)
8638 {
8639 if (first_titles)
8640 {
8641 ret = freexl_get_cell_value (xl_handle, 0, col, &cell);
8642 if (ret != FREEXL_OK)
8643 dummy = sqlite3_mprintf ("col_%d", col);
8644 else
8645 {
8646 if (cell.type == FREEXL_CELL_INT)
8647 dummy = sqlite3_mprintf ("%d", cell.value.int_value);
8648 else if (cell.type == FREEXL_CELL_DOUBLE)
8649 dummy =
8650 sqlite3_mprintf ("%1.2f",
8651 cell.value.double_value);
8652 else if (cell.type == FREEXL_CELL_TEXT
8653 || cell.type == FREEXL_CELL_SST_TEXT
8654 || cell.type == FREEXL_CELL_DATE
8655 || cell.type == FREEXL_CELL_DATETIME
8656 || cell.type == FREEXL_CELL_TIME)
8657 {
8658 int len = strlen (cell.value.text_value);
8659 if (len < 256)
8660 dummy =
8661 sqlite3_mprintf ("%s",
8662 cell.value.text_value);
8663 else
8664 dummy = sqlite3_mprintf ("col_%d", col);
8665 }
8666 else
8667 dummy = sqlite3_mprintf ("col_%d", col);
8668 }
8669 xdummy = gaiaDoubleQuotedSql (dummy);
8670 sqlite3_free (dummy);
8671 sql = sqlite3_mprintf (", \"%s\"", xdummy);
8672 free (xdummy);
8673 gaiaAppendToOutBuffer (&sql_statement, sql);
8674 sqlite3_free (sql);
8675 }
8676 else
8677 {
8678 /* setting default column names */
8679 dummy = sqlite3_mprintf ("col_%d", col);
8680 xdummy = gaiaDoubleQuotedSql (dummy);
8681 sqlite3_free (dummy);
8682 sql = sqlite3_mprintf (", \"%s\"", xdummy);
8683 free (xdummy);
8684 gaiaAppendToOutBuffer (&sql_statement, sql);
8685 sqlite3_free (sql);
8686 }
8687 }
8688 gaiaAppendToOutBuffer (&sql_statement, ")\nVALUES (NULL");
8689 for (col = 0; col < columns; col++)
8690 {
8691 /* column values */
8692 gaiaAppendToOutBuffer (&sql_statement, ", ?");
8693 }
8694 gaiaAppendToOutBuffer (&sql_statement, ")");
8695 if (sql_statement.Error == 0 && sql_statement.Buffer != NULL)
8696 {
8697 ret =
8698 sqlite3_prepare_v2 (sqlite, sql_statement.Buffer,
8699 strlen (sql_statement.Buffer), &stmt, NULL);
8700 gaiaOutBufferReset (&sql_statement);
8701 if (ret != SQLITE_OK)
8702 {
8703 spatialite_e ("load XL error: %s\n", sqlite3_errmsg (sqlite));
8704 sqlError = 1;
8705 goto clean_up;
8706 }
8707 }
8708 if (first_titles)
8709 current_row = 1;
8710 else
8711 current_row = 0;
8712 while (current_row < *rows)
8713 {
8714 /* binding query params */
8715 sqlite3_reset (stmt);
8716 sqlite3_clear_bindings (stmt);
8717 for (col = 0; col < columns; col++)
8718 {
8719 /* column values */
8720 ret =
8721 freexl_get_cell_value (xl_handle, current_row, col, &cell);
8722 if (ret != FREEXL_OK)
8723 sqlite3_bind_null (stmt, col + 1);
8724 else
8725 {
8726 switch (cell.type)
8727 {
8728 case FREEXL_CELL_INT:
8729 sqlite3_bind_int (stmt, col + 1,
8730 cell.value.int_value);
8731 break;
8732 case FREEXL_CELL_DOUBLE:
8733 sqlite3_bind_double (stmt, col + 1,
8734 cell.value.double_value);
8735 break;
8736 case FREEXL_CELL_TEXT:
8737 case FREEXL_CELL_SST_TEXT:
8738 case FREEXL_CELL_DATE:
8739 case FREEXL_CELL_DATETIME:
8740 case FREEXL_CELL_TIME:
8741 sqlite3_bind_text (stmt, col + 1,
8742 cell.value.text_value,
8743 strlen (cell.value.text_value),
8744 SQLITE_STATIC);
8745 break;
8746 default:
8747 sqlite3_bind_null (stmt, col + 1);
8748 break;
8749 };
8750 }
8751 }
8752 ret = sqlite3_step (stmt);
8753 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
8754 ;
8755 else
8756 {
8757 spatialite_e ("load XL error: %s\n", sqlite3_errmsg (sqlite));
8758 sqlite3_finalize (stmt);
8759 sqlError = 1;
8760 goto clean_up;
8761 }
8762 current_row++;
8763 }
8764 sqlite3_finalize (stmt);
8765 clean_up:
8766 if (sqlError)
8767 {
8768 /* some error occurred - ROLLBACK */
8769 ret = sqlite3_exec (sqlite, "ROLLBACK", NULL, 0, &errMsg);
8770 if (ret != SQLITE_OK)
8771 {
8772 spatialite_e ("load XL error: %s\n", errMsg);
8773 sqlite3_free (errMsg);
8774 }
8775 spatialite_e
8776 ("XL not loaded\n\n\na ROLLBACK was automatically performed\n");
8777 }
8778 else
8779 {
8780 /* ok - confirming pending transaction - COMMIT */
8781 ret = sqlite3_exec (sqlite, "COMMIT", NULL, 0, &errMsg);
8782 if (ret != SQLITE_OK)
8783 {
8784 if (!err_msg)
8785 spatialite_e ("load XL error: %s\n", errMsg);
8786 else
8787 sprintf (err_msg, "load XL error: %s\n", errMsg);
8788 sqlite3_free (errMsg);
8789 return 0;
8790 }
8791 if (first_titles)
8792 *rows = *rows - 1; /* allow for header row */
8793 spatialite_e ("XL loaded\n\n%d inserted rows\n", *rows);
8794 }
8795 freexl_close (xl_handle);
8796 return 1;
8797
8798 error:
8799 freexl_close (xl_handle);
8800 if (!err_msg)
8801 spatialite_e ("XL datasource '%s' is not valid\n", path);
8802 else
8803 sprintf (err_msg, "XL datasource '%s' is not valid\n", path);
8804 *rows = 0;
8805 return 0;
8806 }
8807
8808 #endif /* FreeXL enabled/disabled */
8809