~ubuntu-branches/ubuntu/wily/spatialite/wily-proposed

« back to all changes in this revision

Viewing changes to src/shapefiles/shapefiles.c

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-07-14 11:57:46 UTC
  • mfrom: (16.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20150714115746-e2iljfmb5sq7o5hh
Tags: 4.3.0-1
Move from experimental to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
 shapefiles.c -- implements shapefile support [import - export]
4
4
 
5
 
 version 4.1, 2013 May 8
 
5
 version 4.3, 2015 June 29
6
6
 
7
7
 Author: Sandro Furieri a.furieri@lqt.it
8
8
 
24
24
 
25
25
The Initial Developer of the Original Code is Alessandro Furieri
26
26
 
27
 
Portions created by the Initial Developer are Copyright (C) 2008-2013
 
27
Portions created by the Initial Developer are Copyright (C) 2008-2015
28
28
the Initial Developer. All Rights Reserved.
29
29
 
30
30
Contributor(s): Brad Hards <bradh@frogmouth.net>
52
52
#include <stdio.h>
53
53
#include <string.h>
54
54
#include <math.h>
 
55
#include <float.h>
55
56
 
56
57
#if defined(_WIN32) && !defined(__MINGW32__)
57
58
#include "config-msvc.h"
98
99
    struct auxdbf_fld *last;
99
100
};
100
101
 
101
 
struct dupl_column
 
102
struct resultset_values
102
103
{
103
 
/* a column value in a duplicated row */
104
 
    int pos;
105
 
    char *name;
 
104
/* a struct wrapping values from a resultset */
106
105
    int type;
107
106
    sqlite3_int64 int_value;
108
107
    double dbl_value;
109
 
    const char *txt_value;
110
 
    const void *blob;
 
108
    unsigned char *txt_blob_value;
 
109
    int txt_blob_size;
 
110
};
 
111
 
 
112
struct resultset_comparator
 
113
{
 
114
/* object for comparing two rows of the same resultset */
 
115
    struct resultset_values *previous;
 
116
    struct resultset_values *current;
 
117
    int num_columns;
 
118
    sqlite3_int64 previous_rowid;
 
119
    sqlite3_int64 current_rowid;
 
120
};
 
121
 
 
122
static struct resultset_comparator *
 
123
create_resultset_comparator (int columns)
 
124
{
 
125
/* creating an empty resultset comparator object */
 
126
    int i;
 
127
    struct resultset_comparator *p =
 
128
        malloc (sizeof (struct resultset_comparator));
 
129
    p->num_columns = columns;
 
130
    p->previous_rowid = -1;
 
131
    p->current_rowid = -1;
 
132
    p->previous = malloc (sizeof (struct resultset_values) * columns);
 
133
    p->current = malloc (sizeof (struct resultset_values) * columns);
 
134
    for (i = 0; i < columns; i++)
 
135
      {
 
136
          struct resultset_values *value = p->previous + i;
 
137
          value->type = SQLITE_NULL;
 
138
          value->txt_blob_value = NULL;
 
139
          value = p->current + i;
 
140
          value->type = SQLITE_NULL;
 
141
          value->txt_blob_value = NULL;
 
142
      }
 
143
    return p;
 
144
}
 
145
 
 
146
static void
 
147
destroy_resultset_comparator (struct resultset_comparator *ptr)
 
148
{
 
149
/* memory cleanup - destroying a resultset comparator object */
 
150
    int i;
 
151
    if (ptr == NULL)
 
152
        return;
 
153
    for (i = 0; i < ptr->num_columns; i++)
 
154
      {
 
155
          struct resultset_values *value = ptr->previous + i;
 
156
          if (value->txt_blob_value != NULL)
 
157
              free (value->txt_blob_value);
 
158
          value = ptr->current + i;
 
159
          if (value->txt_blob_value != NULL)
 
160
              free (value->txt_blob_value);
 
161
      }
 
162
    if (ptr->previous != NULL)
 
163
        free (ptr->previous);
 
164
    if (ptr->current != NULL)
 
165
        free (ptr->current);
 
166
    free (ptr);
 
167
}
 
168
 
 
169
static void
 
170
save_row_from_resultset (struct resultset_comparator *ptr, sqlite3_stmt * stmt)
 
171
{
 
172
/* saving the current row values */
 
173
    int i;
111
174
    int size;
112
 
    int query_pos;
113
 
    struct dupl_column *next;
114
 
};
115
 
 
116
 
struct dupl_row
117
 
{
118
 
/* a duplicated row with column values */
119
 
    int count;
120
 
    struct dupl_column *first;
121
 
    struct dupl_column *last;
122
 
    const char *table;
123
 
};
124
 
 
125
 
static void
126
 
clean_dupl_row (struct dupl_row *str)
127
 
{
128
 
/* destroying a duplicated row struct */
129
 
    struct dupl_column *p;
130
 
    struct dupl_column *pn;
131
 
    p = str->first;
132
 
    while (p)
133
 
      {
134
 
          pn = p->next;
135
 
          free (p->name);
136
 
          free (p);
137
 
          p = pn;
138
 
      }
139
 
}
140
 
 
141
 
static void
142
 
add_to_dupl_row (struct dupl_row *str, const char *name)
143
 
{
144
 
/* adding a column to the duplicated row struct */
145
 
    int len;
146
 
    struct dupl_column *p = malloc (sizeof (struct dupl_column));
147
 
    p->pos = str->count;
148
 
    len = strlen (name);
149
 
    p->name = malloc (len + 1);
150
 
    strcpy (p->name, name);
151
 
    str->count++;
152
 
    p->type = SQLITE_NULL;
153
 
    p->next = NULL;
154
 
    if (str->first == NULL)
155
 
        str->first = p;
156
 
    if (str->last)
157
 
        str->last->next = p;
158
 
    str->last = p;
159
 
}
160
 
 
161
 
static void
162
 
set_int_value (struct dupl_row *str, int pos, sqlite3_int64 value)
163
 
{
164
 
/* setting up an integer value */
165
 
    struct dupl_column *p = str->first;
166
 
    while (p)
167
 
      {
168
 
          if (p->pos == pos)
169
 
            {
170
 
                p->type = SQLITE_INTEGER;
171
 
                p->int_value = value;
172
 
                return;
173
 
            }
174
 
          p = p->next;
175
 
      }
176
 
}
177
 
 
178
 
static void
179
 
set_double_value (struct dupl_row *str, int pos, double value)
180
 
{
181
 
/* setting up a double value */
182
 
    struct dupl_column *p = str->first;
183
 
    while (p)
184
 
      {
185
 
          if (p->pos == pos)
186
 
            {
187
 
                p->type = SQLITE_FLOAT;
188
 
                p->dbl_value = value;
189
 
                return;
190
 
            }
191
 
          p = p->next;
192
 
      }
193
 
}
194
 
 
195
 
static void
196
 
set_text_value (struct dupl_row *str, int pos, const char *value)
197
 
{
198
 
/* setting up a text value */
199
 
    struct dupl_column *p = str->first;
200
 
    while (p)
201
 
      {
202
 
          if (p->pos == pos)
203
 
            {
204
 
                p->type = SQLITE_TEXT;
205
 
                p->txt_value = value;
206
 
                return;
207
 
            }
208
 
          p = p->next;
209
 
      }
210
 
}
211
 
 
212
 
static void
213
 
set_blob_value (struct dupl_row *str, int pos, const void *blob, int size)
214
 
{
215
 
/* setting up a blob value */
216
 
    struct dupl_column *p = str->first;
217
 
    while (p)
218
 
      {
219
 
          if (p->pos == pos)
220
 
            {
221
 
                p->type = SQLITE_BLOB;
222
 
                p->blob = blob;
223
 
                p->size = size;
224
 
                return;
225
 
            }
226
 
          p = p->next;
227
 
      }
228
 
}
229
 
 
230
 
static void
231
 
set_null_value (struct dupl_row *str, int pos)
232
 
{
233
 
/* setting up a NULL value */
234
 
    struct dupl_column *p = str->first;
235
 
    while (p)
236
 
      {
237
 
          if (p->pos == pos)
238
 
            {
239
 
                p->type = SQLITE_NULL;
240
 
                return;
241
 
            }
242
 
          p = p->next;
243
 
      }
244
 
}
245
 
 
246
 
static void
247
 
reset_query_pos (struct dupl_row *str)
248
 
{
249
 
/* resetting QueryPos for BLOBs */
250
 
    struct dupl_column *p = str->first;
251
 
    while (p)
252
 
      {
253
 
          p->query_pos = -1;
254
 
          p = p->next;
 
175
    const unsigned char *p;
 
176
    if (ptr == NULL)
 
177
        return;
 
178
    ptr->current_rowid = sqlite3_column_int64 (stmt, 0);
 
179
    for (i = 0; i < ptr->num_columns; i++)
 
180
      {
 
181
          struct resultset_values *value = ptr->current + i;
 
182
          value->type = sqlite3_column_type (stmt, i + 1);
 
183
          switch (value->type)
 
184
            {
 
185
            case SQLITE_INTEGER:
 
186
                value->int_value = sqlite3_column_int64 (stmt, i + 1);
 
187
                break;
 
188
            case SQLITE_FLOAT:
 
189
                value->dbl_value = sqlite3_column_double (stmt, i + 1);
 
190
                break;
 
191
            case SQLITE_TEXT:
 
192
                p = sqlite3_column_text (stmt, i + 1);
 
193
                size = strlen ((const char *) p);
 
194
                value->txt_blob_value = malloc (size + 1);
 
195
                strcpy ((char *) (value->txt_blob_value), (const char *) p);
 
196
                break;
 
197
            case SQLITE_BLOB:
 
198
                p = sqlite3_column_blob (stmt, i + 1);
 
199
                size = sqlite3_column_bytes (stmt, i + 1);
 
200
                value->txt_blob_value = malloc (size);
 
201
                memcpy (value->txt_blob_value, p, size);
 
202
                value->txt_blob_size = size;
 
203
                break;
 
204
            };
255
205
      }
256
206
}
257
207
 
258
208
static int
259
 
check_dupl_blob2 (struct dupl_column *ptr, const void *blob, int size)
 
209
resultset_rows_equals (struct resultset_comparator *ptr)
260
210
{
261
 
/* checking a BLOB value */
262
 
    if (ptr->type != SQLITE_BLOB)
263
 
        return 0;
264
 
    if (ptr->size != size)
265
 
        return 0;
266
 
    if (memcmp (ptr->blob, blob, size) != 0)
267
 
        return 0;
 
211
/* comparing the current and previous row from the resultset */
 
212
    int i;
 
213
    if (ptr == NULL)
 
214
        return 0;
 
215
    for (i = 0; i < ptr->num_columns; i++)
 
216
      {
 
217
          struct resultset_values *val_prev = ptr->previous + i;
 
218
          struct resultset_values *val_curr = ptr->current + i;
 
219
          if (val_prev->type != val_curr->type)
 
220
              return 0;
 
221
          switch (val_prev->type)
 
222
            {
 
223
            case SQLITE_INTEGER:
 
224
                if (val_prev->int_value != val_curr->int_value)
 
225
                    return 0;
 
226
                break;
 
227
            case SQLITE_FLOAT:
 
228
                if (val_prev->dbl_value != val_curr->dbl_value)
 
229
                    return 0;
 
230
                break;
 
231
            case SQLITE_TEXT:
 
232
                if (strcmp
 
233
                    ((const char *) (val_prev->txt_blob_value),
 
234
                     (const char *) (val_curr->txt_blob_value)) != 0)
 
235
                    return 0;
 
236
                break;
 
237
            case SQLITE_BLOB:
 
238
                if (val_prev->txt_blob_size != val_curr->txt_blob_size)
 
239
                    return 0;
 
240
                if (memcmp
 
241
                    (val_prev->txt_blob_value, val_curr->txt_blob_value,
 
242
                     val_curr->txt_blob_size) != 0)
 
243
                    return 0;
 
244
                break;
 
245
            };
 
246
      }
268
247
    return 1;
269
248
}
270
249
 
271
 
static int
272
 
check_dupl_blob (struct dupl_row *str, int pos, const void *blob, int size)
273
 
{
274
 
/* checking a BLOB value */
275
 
    struct dupl_column *p = str->first;
276
 
    while (p)
277
 
      {
278
 
          if (p->query_pos == pos)
279
 
            {
280
 
                return check_dupl_blob2 (p, blob, size);
281
 
            }
282
 
          p = p->next;
283
 
      }
284
 
    return 0;
 
250
static sqlite3_int64
 
251
get_current_resultset_rowid (struct resultset_comparator *ptr)
 
252
{
 
253
/* returns the current ROWID */
 
254
    if (ptr == NULL)
 
255
        return -1;
 
256
    return ptr->current_rowid;
 
257
}
 
258
 
 
259
static void
 
260
reset_resultset_current_row (struct resultset_comparator *ptr)
 
261
{
 
262
/* resetting the resultset current row values */
 
263
    int i;
 
264
    if (ptr == NULL)
 
265
        return;
 
266
    ptr->current_rowid = -1;
 
267
    for (i = 0; i < ptr->num_columns; i++)
 
268
      {
 
269
          struct resultset_values *value = ptr->current + i;
 
270
          value->type = SQLITE_NULL;
 
271
          if (value->txt_blob_value != NULL)
 
272
              free (value->txt_blob_value);
 
273
          value->txt_blob_value = NULL;
 
274
      }
 
275
}
 
276
 
 
277
static void
 
278
swap_resultset_rows (struct resultset_comparator *ptr)
 
279
{
 
280
/* resetting the resultset comparator */
 
281
    int i;
 
282
    if (ptr == NULL)
 
283
        return;
 
284
    ptr->previous_rowid = ptr->current_rowid;
 
285
    ptr->current_rowid = -1;
 
286
    for (i = 0; i < ptr->num_columns; i++)
 
287
      {
 
288
          struct resultset_values *val_prev = ptr->previous + i;
 
289
          struct resultset_values *val_curr = ptr->current + i;
 
290
          if (val_prev->txt_blob_value != NULL)
 
291
              free (val_prev->txt_blob_value);
 
292
          val_prev->type = val_curr->type;
 
293
          val_prev->int_value = val_curr->int_value;
 
294
          val_prev->dbl_value = val_curr->dbl_value;
 
295
          val_prev->txt_blob_value = val_curr->txt_blob_value;
 
296
          val_prev->txt_blob_size = val_curr->txt_blob_size;
 
297
          val_curr->type = SQLITE_NULL;
 
298
          val_curr->txt_blob_value = NULL;
 
299
      }
285
300
}
286
301
 
287
302
static struct auxdbf_list *
370
385
}
371
386
 
372
387
SPATIALITE_DECLARE int
373
 
load_shapefile_ex (sqlite3 * sqlite, char *shp_path, char *table, char *charset,
374
 
                   int srid, char *g_column, char *gtype, char *pk_column,
375
 
                   int coerce2d, int compressed, int verbose, int spatial_index,
376
 
                   int *rows, char *err_msg)
 
388
load_shapefile_ex (sqlite3 * sqlite, char *shp_path, char *table,
 
389
                   char *charset, int srid, char *g_column, char *gtype,
 
390
                   char *pk_column, int coerce2d, int compressed, int verbose,
 
391
                   int spatial_index, int *rows, char *err_msg)
 
392
{
 
393
    return load_shapefile_ex2 (sqlite, shp_path, table, charset, srid, g_column,
 
394
                               gtype, pk_column, coerce2d, compressed, verbose,
 
395
                               spatial_index, 0, rows, err_msg);
 
396
}
 
397
 
 
398
SPATIALITE_DECLARE int
 
399
load_shapefile_ex2 (sqlite3 * sqlite, char *shp_path, char *table,
 
400
                    char *charset, int srid, char *g_column, char *gtype,
 
401
                    char *pk_column, int coerce2d, int compressed,
 
402
                    int verbose, int spatial_index, int text_dates, int *rows,
 
403
                    char *err_msg)
377
404
{
378
405
    sqlite3_stmt *stmt = NULL;
379
406
    int ret;
409
436
    gaiaOutBuffer sql_statement;
410
437
    if (!geo_column)
411
438
        geo_column = "Geometry";
 
439
    if (rows)
 
440
        *rows = -1;
412
441
    if (!xgtype)
413
442
        ;
414
443
    else
599
628
                              }
600
629
                            break;
601
630
                        case 'D':
602
 
                            pk_type = SQLITE_FLOAT;
 
631
                            if (text_dates)
 
632
                                pk_type = SQLITE_TEXT;
 
633
                            else
 
634
                                pk_type = SQLITE_FLOAT;
603
635
                            break;
604
636
                        case 'F':
605
637
                            pk_type = SQLITE_FLOAT;
742
774
                  }
743
775
                break;
744
776
            case 'D':
745
 
                gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
 
777
                if (text_dates)
 
778
                    gaiaAppendToOutBuffer (&sql_statement, "TEXT");
 
779
                else
 
780
                    gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
746
781
                break;
747
782
            case 'F':
748
783
                gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
1064
1099
    while (1)
1065
1100
      {
1066
1101
          /* inserting rows from shapefile */
1067
 
          ret = gaiaReadShpEntity (shp, current_row, srid);
 
1102
          ret = gaiaReadShpEntity_ex (shp, current_row, srid, text_dates);
1068
1103
          if (!ret)
1069
1104
            {
1070
1105
                if (!(shp->LastError))  /* normal SHP EOF */
1135
1170
                        case GAIA_TEXT_VALUE:
1136
1171
                            sqlite3_bind_text (stmt, cnt + 2,
1137
1172
                                               dbf_field->Value->TxtValue,
1138
 
                                               strlen (dbf_field->Value->
1139
 
                                                       TxtValue),
 
1173
                                               strlen (dbf_field->
 
1174
                                                       Value->TxtValue),
1140
1175
                                               SQLITE_STATIC);
1141
1176
                            break;
1142
1177
                        default:
1203
1238
                spatialite_e ("load shapefile error: <%s>\n", errMsg);
1204
1239
                sqlite3_free (errMsg);
1205
1240
            }
1206
 
          if (rows)
1207
 
              *rows = current_row;
1208
1241
          return 0;
1209
1242
      }
1210
1243
    else
1259
1292
 
1260
1293
/* step I: retrieving the SRID */
1261
1294
    sql = sqlite3_mprintf ("SELECT srid FROM geometry_columns WHERE "
1262
 
                           "f_table_name = %Q AND f_geometry_column = %Q",
 
1295
                           "Lower(f_table_name) = Lower(%Q) AND "
 
1296
                           "Lower(f_geometry_column) = Lower(%Q)",
1263
1297
                           table, column);
1264
1298
    ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
1265
1299
    sqlite3_free (sql);
1279
1313
          /* srid still undefined, so we'll read VIEWS_GEOMETRY_COLUMNS */
1280
1314
          sql = sqlite3_mprintf ("SELECT srid FROM views_geometry_columns "
1281
1315
                                 "JOIN geometry_columns USING (f_table_name, f_geometry_column) "
1282
 
                                 "WHERE view_name = %Q AND view_geometry = %Q",
 
1316
                                 "WHERE Lower(view_name) = Lower(%Q) AND "
 
1317
                                 "Lower(view_geometry) = Lower(%Q)",
1283
1318
                                 table, column);
1284
1319
          ret =
1285
1320
              sqlite3_get_table (sqlite, sql, &results, &rows, &columns,
1542
1577
    int pos_len = 0;
1543
1578
    int neg_len = 1;
1544
1579
    sqlite3_int64 value = max;
1545
 
    while (value != 0)
 
1580
    if (value == 0)
 
1581
        pos_len = 1;
 
1582
    else
1546
1583
      {
1547
 
          pos_len++;
1548
 
          value /= 10;
 
1584
          while (value != 0)
 
1585
            {
 
1586
                pos_len++;
 
1587
                value /= 10;
 
1588
            }
1549
1589
      }
1550
1590
    if (min >= 0)
1551
1591
        return pos_len;
1568
1608
    int neg_len = 1;
1569
1609
    sqlite3_int64 value;
1570
1610
    if (max >= 0.0)
1571
 
        value = floor (max);
 
1611
        value = (sqlite3_int64) floor (max);
1572
1612
    else
1573
 
        value = ceil (max);
 
1613
        value = (sqlite3_int64) ceil (max);
1574
1614
    while (value != 0)
1575
1615
      {
1576
1616
          pos_len++;
1578
1618
      }
1579
1619
    if (min >= 0.0)
1580
1620
        return pos_len + 7;
1581
 
    value = ceil (min);
 
1621
    value = (sqlite3_int64) ceil (min);
1582
1622
    while (value != 0)
1583
1623
      {
1584
1624
          neg_len++;
1834
1874
{
1835
1875
/* internal utility function:
1836
1876
/
1837
 
/ 0 - if no valid SpatialMetaData where found
1838
 
/ 1 - if SpatiaLite-like (legacy) SpatialMetadata where found
1839
 
/ 2 - if FDO-OGR-like SpatialMetadata where found
1840
 
/ 3 - if SpatiaLite-like (current) SpatialMetadata where found
 
1877
/ 0 - if no valid SpatialMetaData were found
 
1878
/ 1 - if SpatiaLite-like (legacy) SpatialMetadata were found
 
1879
/ 2 - if FDO-OGR-like SpatialMetadata were found
 
1880
/ 3 - if SpatiaLite-like (current) SpatialMetadata were found
1841
1881
/
1842
1882
*/
1843
1883
    sqlite3 *sqlite = (sqlite3 *) handle;
2478
2518
                    (const char *) sqlite3_column_text (stmt, 0);
2479
2519
                const char *geometry_column =
2480
2520
                    (const char *) sqlite3_column_text (stmt, 1);
2481
 
                int count;
2482
 
                double min_x;
2483
 
                double min_y;
2484
 
                double max_x;
2485
 
                double max_y;
 
2521
                int count = 0;
 
2522
                double min_x = DBL_MAX;
 
2523
                double min_y = DBL_MAX;
 
2524
                double max_x = 0.0 - DBL_MAX;
 
2525
                double max_y = 0.0 - DBL_MAX;
2486
2526
                if (sqlite3_column_type (stmt, 2) == SQLITE_NULL)
2487
2527
                    is_null = 1;
2488
2528
                else
2601
2641
    char *xxtable;
2602
2642
    struct auxdbf_list *auxdbf = NULL;
2603
2643
 
 
2644
    if (xrows)
 
2645
        *xrows = -1;
2604
2646
    if (geom_type)
2605
2647
      {
2606
2648
          /* normalizing required geometry type */
2914
2956
          if (fld->TextValuesCount > 0)
2915
2957
            {
2916
2958
                sql_type = SQLITE_TEXT;
2917
 
                max_len = 255;
 
2959
                max_len = 254;
2918
2960
                if (fld->MaxSize)
2919
2961
                    max_len = fld->MaxSize->MaxSize;
2920
2962
            }
2929
2971
            {
2930
2972
                if (max_len == 0)       /* avoiding ZERO-length fields */
2931
2973
                    max_len = 1;
 
2974
                if (max_len > 254)
 
2975
                  {
 
2976
                      /* DBF C: max allowed lenght */
 
2977
                      max_len = 254;
 
2978
                  }
2932
2979
                gaiaAddDbfField (dbf_list, fld->AttributeFieldName, 'C', offset,
2933
2980
                                 max_len, 0);
2934
2981
                offset += max_len;
3032
3079
                                      SQLITE_TEXT)
3033
3080
                                    {
3034
3081
                                        dummy =
3035
 
                                            (char *)
3036
 
                                            sqlite3_column_text (stmt, i);
 
3082
                                            (char *) sqlite3_column_text (stmt,
 
3083
                                                                          i);
3037
3084
                                        gaiaSetStrValue (dbf_field, dummy);
3038
3085
                                    }
3039
3086
                                  else if (sqlite3_column_type (stmt, i) ==
3142
3189
load_dbf_ex (sqlite3 * sqlite, char *dbf_path, char *table, char *pk_column,
3143
3190
             char *charset, int verbose, int *rows, char *err_msg)
3144
3191
{
 
3192
    return load_dbf_ex2 (sqlite, dbf_path, table, pk_column, charset, verbose,
 
3193
                         0, rows, err_msg);
 
3194
}
 
3195
 
 
3196
SPATIALITE_DECLARE int
 
3197
load_dbf_ex2 (sqlite3 * sqlite, char *dbf_path, char *table, char *pk_column,
 
3198
              char *charset, int verbose, int text_dates, int *rows,
 
3199
              char *err_msg)
 
3200
{
3145
3201
    sqlite3_stmt *stmt;
3146
3202
    int ret;
3147
3203
    char *errMsg = NULL;
3169
3225
    int pk_type = SQLITE_INTEGER;
3170
3226
    int pk_set;
3171
3227
    qtable = gaiaDoubleQuotedSql (table);
 
3228
    if (rows)
 
3229
        *rows = -1;
3172
3230
/* checking if TABLE already exists */
3173
3231
    sql = sqlite3_mprintf ("SELECT name FROM sqlite_master WHERE "
3174
3232
                           "type = 'table' AND Lower(name) = Lower(%Q)", table);
3283
3341
                              }
3284
3342
                            break;
3285
3343
                        case 'D':
3286
 
                            pk_type = SQLITE_FLOAT;
 
3344
                            if (text_dates)
 
3345
                                pk_type = SQLITE_TEXT;
 
3346
                            else
 
3347
                                pk_type = SQLITE_FLOAT;
3287
3348
                            break;
3288
3349
                        case 'F':
3289
3350
                            pk_type = SQLITE_FLOAT;
3417
3478
                  }
3418
3479
                break;
3419
3480
            case 'D':
3420
 
                gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
 
3481
                if (text_dates)
 
3482
                    gaiaAppendToOutBuffer (&sql_statement, " TEXT");
 
3483
                else
 
3484
                    gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
3421
3485
                break;
3422
3486
            case 'F':
3423
3487
                gaiaAppendToOutBuffer (&sql_statement, " DOUBLE");
3507
3571
    while (1)
3508
3572
      {
3509
3573
          /* inserting rows from DBF */
3510
 
          ret = gaiaReadDbfEntity (dbf, current_row, &deleted);
 
3574
          ret = gaiaReadDbfEntity_ex (dbf, current_row, &deleted, text_dates);
3511
3575
          if (!ret)
3512
3576
            {
3513
3577
                if (!(dbf->LastError))  /* normal DBF EOF */
3554
3618
            }
3555
3619
          if (!pk_set)
3556
3620
              sqlite3_bind_int (stmt, 1, current_row);
3557
 
          sqlite3_bind_int (stmt, 1, current_row);
3558
3621
          cnt = 0;
3559
3622
          dbf_field = dbf->Dbf->First;
3560
3623
          while (dbf_field)
3583
3646
                        case GAIA_TEXT_VALUE:
3584
3647
                            sqlite3_bind_text (stmt, cnt + 2,
3585
3648
                                               dbf_field->Value->TxtValue,
3586
 
                                               strlen (dbf_field->Value->
3587
 
                                                       TxtValue),
 
3649
                                               strlen (dbf_field->
 
3650
                                                       Value->TxtValue),
3588
3651
                                               SQLITE_STATIC);
3589
3652
                            break;
3590
3653
                        default:
3636
3699
                spatialite_e ("load DBF error: <%s>\n", errMsg);
3637
3700
                sqlite3_free (errMsg);
3638
3701
            };
3639
 
          if (rows)
3640
 
              *rows = current_row;
3641
3702
          if (qtable)
3642
3703
              free (qtable);
3643
3704
          if (qpk_name)
3672
3733
dump_dbf (sqlite3 * sqlite, char *table, char *dbf_path, char *charset,
3673
3734
          char *err_msg)
3674
3735
{
 
3736
    int rows;
 
3737
    return dump_dbf_ex (sqlite, table, dbf_path, charset, &rows, err_msg);
 
3738
}
 
3739
 
 
3740
SPATIALITE_DECLARE int
 
3741
dump_dbf_ex (sqlite3 * sqlite, char *table, char *dbf_path, char *charset,
 
3742
             int *xrows, char *err_msg)
 
3743
{
3675
3744
/* DBF dump */
3676
3745
    int rows;
3677
3746
    int i;
3697
3766
    char *table_name = NULL;
3698
3767
    struct auxdbf_list *auxdbf = NULL;
3699
3768
 
 
3769
    *xrows = -1;
3700
3770
    shp_parse_table_name (table, &db_prefix, &table_name);
3701
3771
/*
3702
3772
/ preparing SQL statement 
3760
3830
                      if (type == SQLITE_TEXT)
3761
3831
                        {
3762
3832
                            len = sqlite3_column_bytes (stmt, i);
 
3833
                            if (len > 254)
 
3834
                              {
 
3835
                                  /* DBF C type: max allowed length */
 
3836
                                  len = 254;
 
3837
                              }
3763
3838
                            sql_type[i] = SQLITE_TEXT;
3764
3839
                            if (len > max_length[i])
3765
3840
                                max_length[i] = len;
3877
3952
                                  if (sqlite3_column_type (stmt, i) ==
3878
3953
                                      SQLITE_TEXT)
3879
3954
                                    {
3880
 
                                        dummy = (char *)
3881
 
                                            sqlite3_column_text (stmt, i);
 
3955
                                        dummy =
 
3956
                                            (char *) sqlite3_column_text (stmt,
 
3957
                                                                          i);
3882
3958
                                        gaiaSetStrValue (dbf_field, dummy);
3883
3959
                                    }
3884
3960
                                  else if (sqlite3_column_type (stmt, i) ==
3927
4003
        free (db_prefix);
3928
4004
    if (table_name != NULL)
3929
4005
        free (table_name);
 
4006
    *xrows = rows;
3930
4007
    return 1;
3931
4008
  sql_error:
3932
4009
/* some SQL error occurred */
4040
4117
dump_kml (sqlite3 * sqlite, char *table, char *geom_col, char *kml_path,
4041
4118
          char *name_col, char *desc_col, int precision)
4042
4119
{
 
4120
    int rows;
 
4121
    return dump_kml_ex (sqlite, table, geom_col, kml_path, name_col, desc_col,
 
4122
                        precision, &rows);
 
4123
}
 
4124
 
 
4125
SPATIALITE_DECLARE int
 
4126
dump_kml_ex (sqlite3 * sqlite, char *table, char *geom_col, char *kml_path,
 
4127
             char *name_col, char *desc_col, int precision, int *xrows)
 
4128
{
4043
4129
/* dumping a  geometry table as KML */
4044
4130
    char *sql;
4045
4131
    char *xname;
4052
4138
    int rows = 0;
4053
4139
    int is_const = 1;
4054
4140
 
 
4141
    *xrows = -1;
4055
4142
/* opening/creating the KML file */
4056
4143
    out = fopen (kml_path, "wb");
4057
4144
    if (!out)
4134
4221
    fprintf (out, "</kml>\r\n");
4135
4222
    sqlite3_finalize (stmt);
4136
4223
    fclose (out);
 
4224
    *xrows = rows;
4137
4225
    return 1;
4138
4226
 
4139
4227
  sql_error:
4217
4305
    if (is_table (sqlite, table) == 0)
4218
4306
      {
4219
4307
          spatialite_e (".chkdupl %s: no such table\n", table);
 
4308
          *dupl_count = -1;
4220
4309
          return;
4221
4310
      }
4222
4311
/* extracting the column names (excluding any Primary Key) */
4272
4361
        gaiaAppendToOutBuffer (&sql_statement, col_list.Buffer);
4273
4362
    gaiaOutBufferReset (&col_list);
4274
4363
    gaiaAppendToOutBuffer (&sql_statement, "\nHAVING \"[dupl-count]\" > 1");
4275
 
    gaiaAppendToOutBuffer (&sql_statement, "\nORDER BY \"[dupl-count]\" DESC");
4276
4364
    if (sql_statement.Error == 0 && sql_statement.Buffer != NULL)
4277
4365
      {
4278
4366
          ret =
4311
4399
}
4312
4400
 
4313
4401
static int
4314
 
do_delete_duplicates2 (sqlite3 * sqlite, sqlite3_stmt * stmt1,
4315
 
                       struct dupl_row *value_list, int *count)
 
4402
do_delete_duplicates2 (sqlite3 * sqlite, sqlite3_int64 rowid,
 
4403
                       sqlite3_stmt * stmt1)
4316
4404
{
4317
4405
/* deleting duplicate rows [actual delete] */
4318
 
    int cnt = 0;
4319
 
    int row_no = 0;
4320
 
    char *sql;
4321
 
    char *xname;
4322
4406
    int ret;
4323
 
    sqlite3_stmt *stmt2 = NULL;
4324
 
    struct dupl_column *col;
4325
 
    int first = 1;
4326
 
    int qcnt = 0;
4327
 
    int param = 1;
4328
 
    int match;
4329
 
    int n_cols;
4330
 
    int col_no;
4331
 
    gaiaOutBuffer sql_statement;
4332
 
    gaiaOutBuffer where;
4333
 
    gaiaOutBuffer condition;
4334
 
 
4335
 
    *count = 0;
4336
 
    reset_query_pos (value_list);
4337
 
    gaiaOutBufferInitialize (&sql_statement);
4338
 
    gaiaOutBufferInitialize (&where);
4339
 
    gaiaOutBufferInitialize (&condition);
4340
 
 
4341
 
/* preparing the query statement */
4342
 
    gaiaAppendToOutBuffer (&sql_statement, "SELECT ROWID");
4343
 
    gaiaAppendToOutBuffer (&where, "\nWHERE ");
4344
 
    col = value_list->first;
4345
 
    while (col)
4346
 
      {
4347
 
          if (col->type == SQLITE_BLOB)
4348
 
            {
4349
 
                sql = sqlite3_mprintf (", %s", col->name);
4350
 
                gaiaAppendToOutBuffer (&sql_statement, sql);
4351
 
                sqlite3_free (sql);
4352
 
                col->query_pos = qcnt++;
4353
 
            }
4354
 
          else if (col->type == SQLITE_NULL)
4355
 
            {
4356
 
                if (first)
4357
 
                  {
4358
 
                      first = 0;
4359
 
                      sql = sqlite3_mprintf ("%s", col->name);
4360
 
                      gaiaAppendToOutBuffer (&condition, sql);
4361
 
                      sqlite3_free (sql);
4362
 
                  }
4363
 
                else
4364
 
                  {
4365
 
                      sql = sqlite3_mprintf (" AND %s", col->name);
4366
 
                      gaiaAppendToOutBuffer (&condition, sql);
4367
 
                      sqlite3_free (sql);
4368
 
                  }
4369
 
                gaiaAppendToOutBuffer (&condition, " IS NULL");
4370
 
                gaiaAppendToOutBuffer (&where, condition.Buffer);
4371
 
                gaiaOutBufferReset (&condition);
4372
 
            }
4373
 
          else
4374
 
            {
4375
 
                if (first)
4376
 
                  {
4377
 
                      first = 0;
4378
 
                      sql = sqlite3_mprintf ("%s", col->name);
4379
 
                      gaiaAppendToOutBuffer (&condition, sql);
4380
 
                      sqlite3_free (sql);
4381
 
                  }
4382
 
                else
4383
 
                  {
4384
 
                      sql = sqlite3_mprintf (" AND %s", col->name);
4385
 
                      gaiaAppendToOutBuffer (&condition, sql);
4386
 
                      sqlite3_free (sql);
4387
 
                  }
4388
 
                gaiaAppendToOutBuffer (&condition, " = ?");
4389
 
                gaiaAppendToOutBuffer (&where, condition.Buffer);
4390
 
                gaiaOutBufferReset (&condition);
4391
 
                col->query_pos = param++;
4392
 
            }
4393
 
          col = col->next;
4394
 
      }
4395
 
    xname = gaiaDoubleQuotedSql (value_list->table);
4396
 
    sql = sqlite3_mprintf ("\nFROM \"%s\"", xname);
4397
 
    free (xname);
4398
 
    gaiaAppendToOutBuffer (&sql_statement, sql);
4399
 
    sqlite3_free (sql);
4400
 
    gaiaAppendToOutBuffer (&sql_statement, where.Buffer);
4401
 
    gaiaOutBufferReset (&where);
4402
 
 
4403
 
    if (sql_statement.Error == 0 && sql_statement.Buffer != NULL)
4404
 
        ret =
4405
 
            sqlite3_prepare_v2 (sqlite, sql_statement.Buffer,
4406
 
                                strlen (sql_statement.Buffer), &stmt2, NULL);
 
4407
 
 
4408
    sqlite3_reset (stmt1);
 
4409
    sqlite3_clear_bindings (stmt1);
 
4410
    sqlite3_bind_int64 (stmt1, 1, rowid);
 
4411
    ret = sqlite3_step (stmt1);
 
4412
    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 
4413
        ;
4407
4414
    else
4408
 
        ret = SQLITE_ERROR;
4409
 
    gaiaOutBufferReset (&sql_statement);
4410
 
    if (ret != SQLITE_OK)
4411
4415
      {
4412
4416
          spatialite_e ("SQL error: %s\n", sqlite3_errmsg (sqlite));
4413
 
          goto error;
4414
 
      }
4415
 
 
4416
 
    sqlite3_reset (stmt2);
4417
 
    sqlite3_clear_bindings (stmt2);
4418
 
    col = value_list->first;
4419
 
    while (col)
4420
 
      {
4421
 
          /* binding query params */
4422
 
          if (col->type == SQLITE_INTEGER)
4423
 
              sqlite3_bind_int64 (stmt2, col->query_pos, col->int_value);
4424
 
          if (col->type == SQLITE_FLOAT)
4425
 
              sqlite3_bind_double (stmt2, col->query_pos, col->dbl_value);
4426
 
          if (col->type == SQLITE_TEXT)
4427
 
              sqlite3_bind_text (stmt2, col->query_pos, col->txt_value,
4428
 
                                 strlen (col->txt_value), SQLITE_STATIC);
4429
 
          col = col->next;
4430
 
      }
4431
 
 
4432
 
    while (1)
4433
 
      {
4434
 
          /* fetching the result set rows */
4435
 
          ret = sqlite3_step (stmt2);
4436
 
          if (ret == SQLITE_DONE)
4437
 
              break;            /* end of result set */
4438
 
          if (ret == SQLITE_ROW)
4439
 
            {
4440
 
                /* fetching a row */
4441
 
                match = 1;
4442
 
                n_cols = sqlite3_column_count (stmt2);
4443
 
                for (col_no = 1; col_no < n_cols; col_no++)
4444
 
                  {
4445
 
                      /* checking blob columns */
4446
 
                      if (sqlite3_column_type (stmt2, col_no) == SQLITE_BLOB)
4447
 
                        {
4448
 
                            const void *blob =
4449
 
                                sqlite3_column_blob (stmt2, col_no);
4450
 
                            int blob_size =
4451
 
                                sqlite3_column_bytes (stmt2, col_no);
4452
 
                            if (check_dupl_blob
4453
 
                                (value_list, col_no - 1, blob, blob_size) == 0)
4454
 
                                match = 0;
4455
 
                        }
4456
 
                      else
4457
 
                          match = 0;
4458
 
                      if (match == 0)
4459
 
                          break;
4460
 
                  }
4461
 
                if (match == 0)
4462
 
                    continue;
4463
 
                row_no++;
4464
 
                if (row_no > 1)
4465
 
                  {
4466
 
                      /* deleting any duplicated row except the first one */
4467
 
                      sqlite3_reset (stmt1);
4468
 
                      sqlite3_clear_bindings (stmt1);
4469
 
                      sqlite3_bind_int64 (stmt1, 1,
4470
 
                                          sqlite3_column_int64 (stmt2, 0));
4471
 
                      ret = sqlite3_step (stmt1);
4472
 
                      if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4473
 
                          cnt++;
4474
 
                      else
4475
 
                        {
4476
 
                            spatialite_e ("SQL error: %s\n",
4477
 
                                          sqlite3_errmsg (sqlite));
4478
 
                            goto error;
4479
 
                        }
4480
 
                  }
4481
 
            }
4482
 
          else
4483
 
            {
4484
 
                spatialite_e ("SQL error: %s\n", sqlite3_errmsg (sqlite));
4485
 
                goto error;
4486
 
            }
4487
 
      }
4488
 
    if (stmt2)
4489
 
        sqlite3_finalize (stmt2);
4490
 
    *count = cnt;
 
4417
          return 0;
 
4418
      }
4491
4419
    return 1;
4492
 
 
4493
 
  error:
4494
 
    if (stmt2)
4495
 
        sqlite3_finalize (stmt2);
4496
 
    *count = 0;
4497
 
 
4498
 
    return 0;
4499
4420
}
4500
4421
 
4501
4422
static int
4502
4423
do_delete_duplicates (sqlite3 * sqlite, const char *sql1, const char *sql2,
4503
 
                      struct dupl_row *value_list, int *count)
 
4424
                      int *count, int transaction)
4504
4425
{
4505
4426
/* deleting duplicate rows */
 
4427
    struct resultset_comparator *rs_obj = NULL;
4506
4428
    sqlite3_stmt *stmt1 = NULL;
4507
4429
    sqlite3_stmt *stmt2 = NULL;
4508
4430
    int ret;
4509
 
    int xcnt;
4510
4431
    int cnt = 0;
4511
 
    int n_cols;
4512
 
    int col_no;
4513
4432
    char *sql_err = NULL;
4514
4433
 
4515
4434
    *count = 0;
4516
4435
 
4517
 
/* the complete operation is handled as an unique SQL Transaction */
4518
 
    ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, &sql_err);
4519
 
    if (ret != SQLITE_OK)
 
4436
    if (transaction)
4520
4437
      {
4521
 
          spatialite_e ("BEGIN TRANSACTION error: %s\n", sql_err);
4522
 
          sqlite3_free (sql_err);
4523
 
          return 0;
 
4438
          /* the complete operation is handled as an unique SQL Transaction */
 
4439
          ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, &sql_err);
 
4440
          if (ret != SQLITE_OK)
 
4441
            {
 
4442
                spatialite_e ("BEGIN TRANSACTION error: %s\n", sql_err);
 
4443
                sqlite3_free (sql_err);
 
4444
                return 0;
 
4445
            }
4524
4446
      }
 
4447
 
4525
4448
/* preparing the main SELECT statement */
4526
4449
    ret = sqlite3_prepare_v2 (sqlite, sql1, strlen (sql1), &stmt1, NULL);
4527
4450
    if (ret != SQLITE_OK)
4537
4460
          goto error;
4538
4461
      }
4539
4462
 
 
4463
    rs_obj = create_resultset_comparator (sqlite3_column_count (stmt1) - 1);
4540
4464
    while (1)
4541
4465
      {
4542
4466
          /* fetching the result set rows */
4546
4470
          if (ret == SQLITE_ROW)
4547
4471
            {
4548
4472
                /* fetching a row */
4549
 
                sqlite3_reset (stmt2);
4550
 
                sqlite3_clear_bindings (stmt2);
4551
 
                n_cols = sqlite3_column_count (stmt1);
4552
 
                for (col_no = 1; col_no < n_cols; col_no++)
 
4473
                save_row_from_resultset (rs_obj, stmt1);
 
4474
                if (resultset_rows_equals (rs_obj))
4553
4475
                  {
4554
 
                      /* saving column values */
4555
 
                      if (sqlite3_column_type (stmt1, col_no) == SQLITE_INTEGER)
4556
 
                          set_int_value (value_list, col_no - 1,
4557
 
                                         sqlite3_column_int64 (stmt1, col_no));
4558
 
                      if (sqlite3_column_type (stmt1, col_no) == SQLITE_FLOAT)
4559
 
                          set_double_value (value_list, col_no - 1,
4560
 
                                            sqlite3_column_double (stmt1,
4561
 
                                                                   col_no));
4562
 
                      if (sqlite3_column_type (stmt1, col_no) == SQLITE_TEXT)
4563
 
                        {
4564
 
                            const char *xtext =
4565
 
                                (const char *) sqlite3_column_text (stmt1,
4566
 
                                                                    col_no);
4567
 
                            set_text_value (value_list, col_no - 1, xtext);
4568
 
                        }
4569
 
                      if (sqlite3_column_type (stmt1, col_no) == SQLITE_BLOB)
4570
 
                        {
4571
 
                            const void *blob =
4572
 
                                sqlite3_column_blob (stmt1, col_no);
4573
 
                            int blob_size =
4574
 
                                sqlite3_column_bytes (stmt1, col_no);
4575
 
                            set_blob_value (value_list, col_no - 1, blob,
4576
 
                                            blob_size);
4577
 
                        }
4578
 
                      if (sqlite3_column_type (stmt1, col_no) == SQLITE_NULL)
4579
 
                          set_null_value (value_list, col_no - 1);
 
4476
                      if (do_delete_duplicates2
 
4477
                          (sqlite, get_current_resultset_rowid (rs_obj), stmt2))
 
4478
                        {
 
4479
                            cnt += 1;
 
4480
                            reset_resultset_current_row (rs_obj);
 
4481
                            continue;
 
4482
                        }
 
4483
                      else
 
4484
                          goto error;
4580
4485
                  }
4581
 
                if (do_delete_duplicates2 (sqlite, stmt2, value_list, &xcnt))
4582
 
                    cnt += xcnt;
4583
 
                else
4584
 
                    goto error;
4585
4486
            }
4586
4487
          else
4587
4488
            {
4588
4489
                spatialite_e ("SQL error: %s\n", sqlite3_errmsg (sqlite));
4589
4490
                goto error;
4590
4491
            }
 
4492
          swap_resultset_rows (rs_obj);
4591
4493
      }
4592
4494
 
4593
4495
    sqlite3_finalize (stmt1);
4594
4496
    sqlite3_finalize (stmt2);
 
4497
    destroy_resultset_comparator (rs_obj);
4595
4498
 
4596
 
/* confirm the still pending Transaction */
4597
 
    ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, &sql_err);
4598
 
    if (ret != SQLITE_OK)
 
4499
    if (transaction)
4599
4500
      {
4600
 
          spatialite_e ("COMMIT TRANSACTION error: %s\n", sql_err);
4601
 
          sqlite3_free (sql_err);
4602
 
          return 0;
 
4501
          /* confirm the still pending Transaction */
 
4502
          ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, &sql_err);
 
4503
          if (ret != SQLITE_OK)
 
4504
            {
 
4505
                spatialite_e ("COMMIT TRANSACTION error: %s\n", sql_err);
 
4506
                sqlite3_free (sql_err);
 
4507
                return 0;
 
4508
            }
4603
4509
      }
4604
4510
 
4605
4511
    *count = cnt;
4612
4518
    if (stmt2)
4613
4519
        sqlite3_finalize (stmt2);
4614
4520
 
4615
 
/* performing a ROLLBACK anyway */
4616
 
    ret = sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, &sql_err);
4617
 
    if (ret != SQLITE_OK)
 
4521
    if (transaction)
4618
4522
      {
4619
 
          spatialite_e ("ROLLBACK TRANSACTION error: %s\n", sql_err);
4620
 
          sqlite3_free (sql_err);
4621
 
          return 0;
 
4523
          /* performing a ROLLBACK anyway */
 
4524
          ret = sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, &sql_err);
 
4525
          if (ret != SQLITE_OK)
 
4526
            {
 
4527
                spatialite_e ("ROLLBACK TRANSACTION error: %s\n", sql_err);
 
4528
                sqlite3_free (sql_err);
 
4529
                return 0;
 
4530
            }
4622
4531
      }
4623
4532
 
4624
4533
    return 0;
4625
4534
}
4626
4535
 
4627
4536
SPATIALITE_DECLARE void
4628
 
remove_duplicated_rows (sqlite3 * sqlite, char *table)
 
4537
remove_duplicated_rows_ex2 (sqlite3 * sqlite, char *table, int *removed,
 
4538
                            int transaction)
4629
4539
{
4630
4540
/* attempting to delete Duplicate rows from a table */
4631
 
    struct dupl_row value_list;
4632
4541
    char *sql;
4633
4542
    char *sql2;
4634
4543
    int first = 1;
4644
4553
    gaiaOutBuffer sql_statement;
4645
4554
    gaiaOutBuffer col_list;
4646
4555
 
4647
 
    value_list.count = 0;
4648
 
    value_list.first = NULL;
4649
 
    value_list.last = NULL;
4650
 
    value_list.table = table;
 
4556
    if (removed != NULL)
 
4557
        *removed = 0;
4651
4558
 
4652
4559
    if (is_table (sqlite, table) == 0)
4653
4560
      {
4654
4561
          spatialite_e (".remdupl %s: no such table\n", table);
 
4562
          if (removed != NULL)
 
4563
              *removed = -1;
4655
4564
          return;
4656
4565
      }
4657
4566
/* extracting the column names (excluding any Primary Key) */
4685
4594
                      sql = sqlite3_mprintf ("\"%s\"", xname);
4686
4595
                      free (xname);
4687
4596
                      gaiaAppendToOutBuffer (&col_list, sql);
4688
 
                      add_to_dupl_row (&value_list, sql);
4689
4597
                      sqlite3_free (sql);
4690
4598
                  }
4691
4599
            }
4693
4601
    sqlite3_free_table (results);
4694
4602
/* preparing the SQL statement (identifying duplicated rows) */
4695
4603
    gaiaOutBufferInitialize (&sql_statement);
4696
 
    gaiaAppendToOutBuffer (&sql_statement,
4697
 
                           "SELECT Count(*) AS \"[dupl-count]\", ");
 
4604
    gaiaAppendToOutBuffer (&sql_statement, "SELECT ROWID, ");
4698
4605
    if (col_list.Error == 0 && col_list.Buffer != NULL)
4699
4606
        gaiaAppendToOutBuffer (&sql_statement, col_list.Buffer);
4700
4607
    xname = gaiaDoubleQuotedSql (table);
4701
 
    sql = sqlite3_mprintf ("\nFROM \"%s\"\nGROUP BY ", xname);
 
4608
    sql = sqlite3_mprintf ("\nFROM \"%s\"\nORDER BY ", xname);
4702
4609
    free (xname);
4703
4610
    gaiaAppendToOutBuffer (&sql_statement, sql);
4704
4611
    sqlite3_free (sql);
4705
4612
    if (col_list.Error == 0 && col_list.Buffer != NULL)
4706
4613
        gaiaAppendToOutBuffer (&sql_statement, col_list.Buffer);
4707
4614
    gaiaOutBufferReset (&col_list);
4708
 
    gaiaAppendToOutBuffer (&sql_statement, "\nHAVING \"[dupl-count]\" > 1");
 
4615
    gaiaAppendToOutBuffer (&sql_statement, ", ROWID");
4709
4616
/* preparing the SQL statement [delete] */
4710
4617
    xname = gaiaDoubleQuotedSql (table);
4711
4618
    sql2 = sqlite3_mprintf ("DELETE FROM \"%s\" WHERE ROWID = ?", xname);
4715
4622
        sql = sql_statement.Buffer;
4716
4623
    else
4717
4624
        sql = "NULL-SELECT";
4718
 
    if (do_delete_duplicates (sqlite, sql, sql2, &value_list, &count))
 
4625
    if (do_delete_duplicates (sqlite, sql, sql2, &count, transaction))
4719
4626
      {
4720
 
          if (!count)
4721
 
              spatialite_e ("No duplicated rows have been identified\n");
 
4627
          if (removed == NULL)
 
4628
            {
 
4629
                if (!count)
 
4630
                    spatialite_e ("No duplicated rows have been identified\n");
 
4631
                else
 
4632
                    spatialite_e ("%d duplicated rows deleted from: %s\n",
 
4633
                                  count, table);
 
4634
            }
4722
4635
          else
4723
 
              spatialite_e ("%d duplicated rows deleted from: %s\n", count,
4724
 
                            table);
 
4636
              *removed = count;
4725
4637
      }
4726
4638
    gaiaOutBufferReset (&sql_statement);
4727
4639
    sqlite3_free (sql2);
4728
 
    clean_dupl_row (&value_list);
 
4640
}
 
4641
 
 
4642
SPATIALITE_DECLARE void
 
4643
remove_duplicated_rows_ex (sqlite3 * sqlite, char *table, int *removed)
 
4644
{
 
4645
/* attempting to delete Duplicate rows from a table */
 
4646
    remove_duplicated_rows_ex2 (sqlite, table, removed, 1);
 
4647
}
 
4648
 
 
4649
SPATIALITE_DECLARE void
 
4650
remove_duplicated_rows (sqlite3 * sqlite, char *table)
 
4651
{
 
4652
/* attempting to delete Duplicate rows from a table */
 
4653
    remove_duplicated_rows_ex (sqlite, table, NULL);
4729
4654
}
4730
4655
 
4731
4656
static int
5244
5169
                       char *pKey, char *multiId)
5245
5170
{
5246
5171
/* attempting to create a derived table surely containing elemetary Geoms */
 
5172
    int rows;
 
5173
    elementary_geometries_ex (sqlite, inTable, geometry, outTable, pKey,
 
5174
                              multiId, &rows);
 
5175
}
 
5176
 
 
5177
SPATIALITE_DECLARE void
 
5178
elementary_geometries_ex (sqlite3 * sqlite,
 
5179
                          char *inTable, char *geometry, char *outTable,
 
5180
                          char *pKey, char *multiId, int *xrows)
 
5181
{
 
5182
/* attempting to create a derived table surely containing elemetary Geoms */
 
5183
    elementary_geometries_ex2 (sqlite, inTable, geometry, outTable, pKey,
 
5184
                               multiId, xrows, 1);
 
5185
}
 
5186
 
 
5187
SPATIALITE_DECLARE void
 
5188
elementary_geometries_ex2 (sqlite3 * sqlite,
 
5189
                           char *inTable, char *geometry, char *outTable,
 
5190
                           char *pKey, char *multiId, int *xrows,
 
5191
                           int transaction)
 
5192
{
 
5193
/* attempting to create a derived table surely containing elemetary Geoms */
5247
5194
    char type[128];
5248
5195
    int srid;
5249
5196
    char dims[64];
5268
5215
    sqlite3_stmt *stmt_out = NULL;
5269
5216
    int n_columns;
5270
5217
    sqlite3_int64 id = 0;
 
5218
    int inserted = 0;
5271
5219
 
5272
5220
    if (check_elementary
5273
5221
        (sqlite, inTable, geometry, outTable, pKey, multiId, type, &srid,
5274
5222
         dims) == 0)
5275
5223
      {
5276
5224
          spatialite_e (".elemgeo: invalid args\n");
 
5225
          *xrows = 0;
5277
5226
          return;
5278
5227
      }
5279
5228
 
5280
 
/* starts a transaction */
5281
 
    ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, &errMsg);
5282
 
    if (ret != SQLITE_OK)
 
5229
    if (transaction)
5283
5230
      {
5284
 
          spatialite_e ("SQL error: %s\n", errMsg);
5285
 
          sqlite3_free (errMsg);
5286
 
          goto abort;
 
5231
          /* starts a transaction */
 
5232
          ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, &errMsg);
 
5233
          if (ret != SQLITE_OK)
 
5234
            {
 
5235
                spatialite_e ("SQL error: %s\n", errMsg);
 
5236
                sqlite3_free (errMsg);
 
5237
                goto abort;
 
5238
            }
5287
5239
      }
5288
5240
 
5289
5241
    gaiaOutBufferInitialize (&sql_statement);
5498
5450
                                          sqlite3_errmsg (sqlite));
5499
5451
                            goto abort;
5500
5452
                        }
 
5453
                      inserted++;
5501
5454
                  }
5502
5455
                else
5503
5456
                  {
5577
5530
                                                sqlite3_errmsg (sqlite));
5578
5531
                                  goto abort;
5579
5532
                              }
 
5533
                            inserted++;
5580
5534
                            pt = pt->Next;
5581
5535
                        }
5582
5536
                      ln = g->FirstLinestring;
5650
5604
                                                sqlite3_errmsg (sqlite));
5651
5605
                                  goto abort;
5652
5606
                              }
 
5607
                            inserted++;
5653
5608
                            ln = ln->Next;
5654
5609
                        }
5655
5610
                      pg = g->FirstPolygon;
5723
5678
                                                sqlite3_errmsg (sqlite));
5724
5679
                                  goto abort;
5725
5680
                              }
 
5681
                            inserted++;
5726
5682
                            pg = pg->Next;
5727
5683
                        }
5728
5684
                      gaiaFreeGeomColl (g);
5738
5694
    sqlite3_finalize (stmt_in);
5739
5695
    sqlite3_finalize (stmt_out);
5740
5696
 
5741
 
/* commits the transaction */
5742
 
    ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, &errMsg);
5743
 
    if (ret != SQLITE_OK)
 
5697
    if (transaction)
5744
5698
      {
5745
 
          spatialite_e ("SQL error: %s\n", errMsg);
5746
 
          sqlite3_free (errMsg);
5747
 
          goto abort;
 
5699
          /* commits the transaction */
 
5700
          ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, &errMsg);
 
5701
          if (ret != SQLITE_OK)
 
5702
            {
 
5703
                spatialite_e ("SQL error: %s\n", errMsg);
 
5704
                sqlite3_free (errMsg);
 
5705
                goto abort;
 
5706
            }
5748
5707
      }
 
5708
    *xrows = inserted;
5749
5709
    return;
5750
5710
 
5751
5711
  abort:
5753
5713
        sqlite3_finalize (stmt_in);
5754
5714
    if (stmt_out)
5755
5715
        sqlite3_finalize (stmt_out);
 
5716
 
 
5717
    if (transaction)
 
5718
      {
 
5719
          /* rolling bacj the transaction */
 
5720
          ret = sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, &errMsg);
 
5721
          if (ret != SQLITE_OK)
 
5722
            {
 
5723
                spatialite_e ("SQL error: %s\n", errMsg);
 
5724
                sqlite3_free (errMsg);
 
5725
            }
 
5726
      }
 
5727
    *xrows = 0;
5756
5728
}
5757
5729
 
5758
5730
#ifndef OMIT_FREEXL             /* including FreeXL */
5779
5751
    gaiaOutBuffer sql_statement;
5780
5752
    FreeXL_CellValue cell;
5781
5753
    int already_exists = 0;
 
5754
 
 
5755
    *rows = 0;
5782
5756
/* checking if TABLE already exists */
5783
5757
    sql =
5784
5758
        sqlite3_mprintf ("SELECT name FROM sqlite_master WHERE type = 'table' "
6111
6085
        spatialite_e ("XL datasource '%s' is not valid\n", path);
6112
6086
    else
6113
6087
        sprintf (err_msg, "XL datasource '%s' is not valid\n", path);
 
6088
    *rows = 0;
6114
6089
    return 0;
6115
6090
}
6116
6091
 
6117
6092
#endif /* FreeXL enabled/disabled */
6118
6093
 
6119
6094
SPATIALITE_DECLARE int
6120
 
dump_geojson (sqlite3 * sqlite, char *table, char *geom_col, char *outfile_path,
6121
 
              int precision, int option)
 
6095
dump_geojson (sqlite3 * sqlite, char *table, char *geom_col,
 
6096
              char *outfile_path, int precision, int option)
 
6097
{
 
6098
    int rows;
 
6099
    return dump_geojson_ex (sqlite, table, geom_col, outfile_path, precision,
 
6100
                            option, &rows);
 
6101
}
 
6102
 
 
6103
SPATIALITE_DECLARE int
 
6104
dump_geojson_ex (sqlite3 * sqlite, char *table, char *geom_col,
 
6105
                 char *outfile_path, int precision, int option, int *xrows)
6122
6106
{
6123
6107
/* dumping a  geometry table as GeoJSON - Brad Hards 2011-11-09 */
 
6108
/* sandro furieri 2014-08-30: adding the "int *xrows" argument */
6124
6109
    char *sql;
6125
6110
    char *xgeom_col;
6126
6111
    char *xtable;
6129
6114
    int ret;
6130
6115
    int rows = 0;
6131
6116
 
 
6117
    *xrows = -1;
6132
6118
/* opening/creating the GeoJSON output file */
6133
6119
    out = fopen (outfile_path, "wb");
6134
6120
    if (!out)
6173
6159
 
6174
6160
    sqlite3_finalize (stmt);
6175
6161
    fclose (out);
 
6162
    *xrows = rows;
6176
6163
    return 1;
6177
6164
 
6178
6165
  sql_error: