1 /*
2 
3  se_helpers.c -- SLD/SE helper functions
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):
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 /*
47 
48 CREDITS:
49 
50 this module has been partly funded by:
51 Regione Toscana - Settore Sistema Informativo Territoriale ed Ambientale
52 (implementing XML support - ISO Metadata and SLD/SE Styles)
53 
54 */
55 
56 #include <stdlib.h>
57 #include <stdio.h>
58 #include <string.h>
59 
60 #if defined(_WIN32) && !defined(__MINGW32__)
61 #include "config-msvc.h"
62 #else
63 #include "config.h"
64 #endif
65 
66 #include <spatialite/sqlite.h>
67 #include <spatialite/debug.h>
68 #include <spatialite/gaiaaux.h>
69 
70 #include <spatialite.h>
71 #include <spatialite_private.h>
72 
73 #ifdef _WIN32
74 #define strcasecmp	_stricmp
75 #endif /* not WIN32 */
76 
77 #ifdef ENABLE_LIBXML2		/* including LIBXML2 */
78 
79 /* Constant definitions: Vector Coverage Types */
80 #define VECTOR_UNKNOWN		0
81 #define VECTOR_GEOTABLE		1
82 #define VECTOR_SPATIALVIEW	2
83 #define VECTOR_VIRTUALSHP	3
84 #define VECTOR_TOPOGEO		4
85 #define VECTOR_TOPONET		5
86 
87 static int
check_external_graphic(sqlite3 * sqlite,const char * xlink_href)88 check_external_graphic (sqlite3 * sqlite, const char *xlink_href)
89 {
90 /* checks if an ExternalGraphic Resource already exists */
91     int ret;
92     const char *sql;
93     sqlite3_stmt *stmt;
94     int exists = 0;
95     sql = "SELECT xlink_href FROM SE_external_graphics WHERE xlink_href = ?";
96     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
97     if (ret != SQLITE_OK)
98       {
99 	  spatialite_e ("checkExternalGraphic: \"%s\"\n",
100 			sqlite3_errmsg (sqlite));
101 	  return 0;
102       }
103     sqlite3_reset (stmt);
104     sqlite3_clear_bindings (stmt);
105     sqlite3_bind_text (stmt, 1, xlink_href, strlen (xlink_href), SQLITE_STATIC);
106     while (1)
107       {
108 	  /* scrolling the result set rows */
109 	  ret = sqlite3_step (stmt);
110 	  if (ret == SQLITE_DONE)
111 	      break;		/* end of result set */
112 	  if (ret == SQLITE_ROW)
113 	      exists = 1;
114       }
115     sqlite3_finalize (stmt);
116     return exists;
117 }
118 
119 SPATIALITE_PRIVATE int
register_external_graphic(void * p_sqlite,const char * xlink_href,const unsigned char * p_blob,int n_bytes,const char * title,const char * abstract,const char * file_name)120 register_external_graphic (void *p_sqlite, const char *xlink_href,
121 			   const unsigned char *p_blob, int n_bytes,
122 			   const char *title, const char *abstract,
123 			   const char *file_name)
124 {
125 /* auxiliary function: inserts or updates an ExternalGraphic Resource */
126     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
127     int ret;
128     const char *sql;
129     sqlite3_stmt *stmt;
130     int exists = 0;
131     int extras = 0;
132     int retval = 0;
133 
134 /* checking if already exists */
135     if (xlink_href == NULL)
136 	return 0;
137     exists = check_external_graphic (sqlite, xlink_href);
138 
139     if (title != NULL && abstract != NULL && file_name != NULL)
140 	extras = 1;
141     if (exists)
142       {
143 	  /* update */
144 	  if (extras)
145 	    {
146 		/* full infos */
147 		sql = "UPDATE SE_external_graphics "
148 		    "SET resource = ?, title = ?, abstract = ?, file_name = ? "
149 		    "WHERE xlink_href = ?";
150 	    }
151 	  else
152 	    {
153 		/* limited basic infos */
154 		sql = "UPDATE SE_external_graphics "
155 		    "SET resource = ? WHERE xlink_href = ?";
156 	    }
157       }
158     else
159       {
160 	  /* insert */
161 	  if (extras)
162 	    {
163 		/* full infos */
164 		sql = "INSERT INTO SE_external_graphics "
165 		    "(xlink_href, resource, title, abstract, file_name) "
166 		    "VALUES (?, ?, ?, ?, ?)";
167 	    }
168 	  else
169 	    {
170 		/* limited basic infos */
171 		sql = "INSERT INTO SE_external_graphics "
172 		    "(xlink_href, resource) VALUES (?, ?)";
173 	    }
174       }
175     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
176     if (ret != SQLITE_OK)
177       {
178 	  spatialite_e ("registerExternalGraphic: \"%s\"\n",
179 			sqlite3_errmsg (sqlite));
180 	  goto stop;
181       }
182     sqlite3_reset (stmt);
183     sqlite3_clear_bindings (stmt);
184     if (exists)
185       {
186 	  /* update */
187 	  if (extras)
188 	    {
189 		/* full infos */
190 		sqlite3_bind_blob (stmt, 1, p_blob, n_bytes, SQLITE_STATIC);
191 		sqlite3_bind_text (stmt, 2, title, strlen (title),
192 				   SQLITE_STATIC);
193 		sqlite3_bind_text (stmt, 3, abstract, strlen (abstract),
194 				   SQLITE_STATIC);
195 		sqlite3_bind_text (stmt, 4, file_name, strlen (file_name),
196 				   SQLITE_STATIC);
197 		sqlite3_bind_text (stmt, 5, xlink_href, strlen (xlink_href),
198 				   SQLITE_STATIC);
199 	    }
200 	  else
201 	    {
202 		/* limited basic infos */
203 		sqlite3_bind_blob (stmt, 1, p_blob, n_bytes, SQLITE_STATIC);
204 		sqlite3_bind_text (stmt, 2, xlink_href, strlen (xlink_href),
205 				   SQLITE_STATIC);
206 	    }
207       }
208     else
209       {
210 	  /* insert */
211 	  if (extras)
212 	    {
213 		/* full infos */
214 		sqlite3_bind_text (stmt, 1, xlink_href, strlen (xlink_href),
215 				   SQLITE_STATIC);
216 		sqlite3_bind_blob (stmt, 2, p_blob, n_bytes, SQLITE_STATIC);
217 		sqlite3_bind_text (stmt, 3, title, strlen (title),
218 				   SQLITE_STATIC);
219 		sqlite3_bind_text (stmt, 4, abstract, strlen (abstract),
220 				   SQLITE_STATIC);
221 		sqlite3_bind_text (stmt, 5, file_name, strlen (file_name),
222 				   SQLITE_STATIC);
223 	    }
224 	  else
225 	    {
226 		/* limited basic infos */
227 		sqlite3_bind_text (stmt, 1, xlink_href, strlen (xlink_href),
228 				   SQLITE_STATIC);
229 		sqlite3_bind_blob (stmt, 2, p_blob, n_bytes, SQLITE_STATIC);
230 	    }
231       }
232     ret = sqlite3_step (stmt);
233     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
234 	retval = 1;
235     else
236 	spatialite_e ("registerExternalGraphic() error: \"%s\"\n",
237 		      sqlite3_errmsg (sqlite));
238     sqlite3_finalize (stmt);
239     return retval;
240   stop:
241     return 0;
242 }
243 
244 SPATIALITE_PRIVATE int
unregister_external_graphic(void * p_sqlite,const char * xlink_href)245 unregister_external_graphic (void *p_sqlite, const char *xlink_href)
246 {
247 /* auxiliary function: deletes an ExternalGraphic Resource */
248     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
249     int ret;
250     const char *sql;
251     sqlite3_stmt *stmt;
252     int exists = 0;
253     int retval = 0;
254 
255 /* checking if already exists */
256     if (xlink_href == NULL)
257 	return 0;
258     exists = check_external_graphic (sqlite, xlink_href);
259     if (!exists)
260 	return 0;
261 
262     sql = "DELETE FROM SE_external_graphics WHERE xlink_href = ?";
263     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
264     if (ret != SQLITE_OK)
265       {
266 	  spatialite_e ("unregisterExternalGraphic: \"%s\"\n",
267 			sqlite3_errmsg (sqlite));
268 	  goto stop;
269       }
270     sqlite3_reset (stmt);
271     sqlite3_clear_bindings (stmt);
272     sqlite3_bind_text (stmt, 1, xlink_href, strlen (xlink_href), SQLITE_STATIC);
273     ret = sqlite3_step (stmt);
274     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
275 	retval = 1;
276     else
277 	spatialite_e ("unregisterExternalGraphic() error: \"%s\"\n",
278 		      sqlite3_errmsg (sqlite));
279     sqlite3_finalize (stmt);
280     return retval;
281   stop:
282     return 0;
283 }
284 
285 static int
vector_style_causes_duplicate_name(sqlite3 * sqlite,sqlite3_int64 id,const unsigned char * p_blob,int n_bytes)286 vector_style_causes_duplicate_name (sqlite3 * sqlite, sqlite3_int64 id,
287 				    const unsigned char *p_blob, int n_bytes)
288 {
289 /* auxiliary function: checks for an eventual duplicate name */
290     int count = 0;
291     int ret;
292     const char *sql;
293     sqlite3_stmt *stmt;
294 
295     sql = "SELECT Count(*) FROM SE_vector_styles "
296 	"WHERE Lower(style_name) = Lower(XB_GetName(?)) AND style_id <> ?";
297     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
298     if (ret != SQLITE_OK)
299       {
300 	  spatialite_e ("VectorStyle duplicate Name: \"%s\"\n",
301 			sqlite3_errmsg (sqlite));
302 	  return 0;
303       }
304     sqlite3_reset (stmt);
305     sqlite3_clear_bindings (stmt);
306     sqlite3_bind_blob (stmt, 1, p_blob, n_bytes, SQLITE_STATIC);
307     sqlite3_bind_int64 (stmt, 2, id);
308     while (1)
309       {
310 	  /* scrolling the result set rows */
311 	  ret = sqlite3_step (stmt);
312 	  if (ret == SQLITE_DONE)
313 	      break;		/* end of result set */
314 	  if (ret == SQLITE_ROW)
315 	      count = sqlite3_column_int (stmt, 0);
316       }
317     sqlite3_finalize (stmt);
318     if (count != 0)
319 	return 1;
320     return 0;
321 }
322 
323 static int
map_configuration_causes_duplicate_name(sqlite3 * sqlite,sqlite3_int64 id,const unsigned char * p_blob,int n_bytes)324 map_configuration_causes_duplicate_name (sqlite3 * sqlite, sqlite3_int64 id,
325 					 const unsigned char *p_blob,
326 					 int n_bytes)
327 {
328 /* auxiliary function: checks for an eventual duplicate name */
329     int count = 0;
330     int ret;
331     const char *sql;
332     sqlite3_stmt *stmt;
333 
334     sql = "SELECT Count(*) FROM rl2map_configurations "
335 	"WHERE Lower(name) = Lower(XB_GetName(?)) AND id <> ?";
336     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
337     if (ret != SQLITE_OK)
338       {
339 	  spatialite_e ("MapConfigurations duplicate Name: \"%s\"\n",
340 			sqlite3_errmsg (sqlite));
341 	  return 0;
342       }
343     sqlite3_reset (stmt);
344     sqlite3_clear_bindings (stmt);
345     sqlite3_bind_blob (stmt, 1, p_blob, n_bytes, SQLITE_STATIC);
346     sqlite3_bind_int64 (stmt, 2, id);
347     while (1)
348       {
349 	  /* scrolling the result set rows */
350 	  ret = sqlite3_step (stmt);
351 	  if (ret == SQLITE_DONE)
352 	      break;		/* end of result set */
353 	  if (ret == SQLITE_ROW)
354 	      count = sqlite3_column_int (stmt, 0);
355       }
356     sqlite3_finalize (stmt);
357     if (count != 0)
358 	return 1;
359     return 0;
360 }
361 
362 SPATIALITE_PRIVATE int
register_map_configuration(void * p_sqlite,const unsigned char * p_blob,int n_bytes)363 register_map_configuration (void *p_sqlite, const unsigned char *p_blob,
364 			    int n_bytes)
365 {
366 /* auxiliary function: inserts a Map Configuration definition */
367     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
368     int ret;
369     const char *sql;
370     sqlite3_stmt *stmt;
371     char *name;
372 
373     if (p_blob != NULL && n_bytes > 0)
374       {
375 	  /* attempting to insert the Map Configuration */
376 	  if (map_configuration_causes_duplicate_name
377 	      (sqlite, -1, p_blob, n_bytes))
378 	      return 0;
379 	  sql = "INSERT INTO rl2map_configurations "
380 	      "(id, name, config) VALUES (NULL, ?, ?)";
381 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
382 	  if (ret != SQLITE_OK)
383 	    {
384 		spatialite_e ("registerMapConfigurations: \"%s\"\n",
385 			      sqlite3_errmsg (sqlite));
386 		return 0;
387 	    }
388 	  name = gaiaXmlBlobGetName (p_blob, n_bytes);
389 	  sqlite3_reset (stmt);
390 	  sqlite3_clear_bindings (stmt);
391 	  if (name == NULL)
392 	      sqlite3_bind_null (stmt, 1);
393 	  else
394 	      sqlite3_bind_text (stmt, 1, name, strlen (name), SQLITE_STATIC);
395 	  sqlite3_bind_blob (stmt, 2, p_blob, n_bytes, SQLITE_STATIC);
396 	  ret = sqlite3_step (stmt);
397 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
398 	      ;
399 	  else
400 	    {
401 		spatialite_e ("registerMapConfigurations() error: \"%s\"\n",
402 			      sqlite3_errmsg (sqlite));
403 		sqlite3_finalize (stmt);
404 		return 0;
405 	    }
406 	  sqlite3_finalize (stmt);
407 	  return 1;
408       }
409     else
410 	return 0;
411 }
412 
413 static int
check_map_configuration_by_id(sqlite3 * sqlite,int id)414 check_map_configuration_by_id (sqlite3 * sqlite, int id)
415 {
416 /* checks if a Map Configuration do actually exists - by ID */
417     int ret;
418     const char *sql;
419     sqlite3_stmt *stmt;
420     int count = 0;
421 
422     sql = "SELECT id FROM rl2map_configurations " "WHERE id = ?";
423     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
424     if (ret != SQLITE_OK)
425       {
426 	  spatialite_e ("check MapConfigurations by ID: \"%s\"\n",
427 			sqlite3_errmsg (sqlite));
428 	  goto stop;
429       }
430     sqlite3_reset (stmt);
431     sqlite3_clear_bindings (stmt);
432     sqlite3_bind_int (stmt, 1, id);
433     while (1)
434       {
435 	  /* scrolling the result set rows */
436 	  ret = sqlite3_step (stmt);
437 	  if (ret == SQLITE_DONE)
438 	      break;		/* end of result set */
439 	  if (ret == SQLITE_ROW)
440 	      count++;
441       }
442     sqlite3_finalize (stmt);
443     if (count == 1)
444 	return 1;
445     return 0;
446   stop:
447     return 0;
448 }
449 
450 static int
check_map_configuration_by_name(sqlite3 * sqlite,const char * name,sqlite3_int64 * id)451 check_map_configuration_by_name (sqlite3 * sqlite, const char *name,
452 				 sqlite3_int64 * id)
453 {
454 /* checks if a Map Configuration do actually exists - by name */
455     int ret;
456     const char *sql;
457     sqlite3_stmt *stmt;
458     int count = 0;
459     sqlite3_int64 xid = 0;
460 
461     sql = "SELECT id FROM rl2map_configurations "
462 	"WHERE Lower(name) = Lower(?)";
463     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
464     if (ret != SQLITE_OK)
465       {
466 	  spatialite_e ("check MapConfigurations by Name: \"%s\"\n",
467 			sqlite3_errmsg (sqlite));
468 	  goto stop;
469       }
470     sqlite3_reset (stmt);
471     sqlite3_clear_bindings (stmt);
472     sqlite3_bind_text (stmt, 1, name, strlen (name), SQLITE_STATIC);
473     while (1)
474       {
475 	  /* scrolling the result set rows */
476 	  ret = sqlite3_step (stmt);
477 	  if (ret == SQLITE_DONE)
478 	      break;		/* end of result set */
479 	  if (ret == SQLITE_ROW)
480 	    {
481 		xid = sqlite3_column_int64 (stmt, 0);
482 		count++;
483 	    }
484       }
485     sqlite3_finalize (stmt);
486     if (count == 1)
487       {
488 	  *id = xid;
489 	  return 1;
490       }
491     return 0;
492   stop:
493     return 0;
494 }
495 
496 static int
do_delete_map_configuration(sqlite3 * sqlite,sqlite3_int64 id)497 do_delete_map_configuration (sqlite3 * sqlite, sqlite3_int64 id)
498 {
499 /* auxiliary function: really deleting a Map Configuration */
500     int ret;
501     const char *sql;
502     sqlite3_stmt *stmt;
503     int retval = 0;
504     sql = "DELETE FROM rl2map_configurations WHERE id = ?";
505     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
506     if (ret != SQLITE_OK)
507       {
508 	  spatialite_e ("unregisterMapConfigurations: \"%s\"\n",
509 			sqlite3_errmsg (sqlite));
510 	  goto stop;
511       }
512     sqlite3_reset (stmt);
513     sqlite3_clear_bindings (stmt);
514     sqlite3_bind_int64 (stmt, 1, id);
515     ret = sqlite3_step (stmt);
516     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
517 	retval = 1;
518     else
519 	spatialite_e ("unregisterMapConfigurations() error: \"%s\"\n",
520 		      sqlite3_errmsg (sqlite));
521     sqlite3_finalize (stmt);
522     return retval;
523   stop:
524     return 0;
525 }
526 
527 SPATIALITE_PRIVATE int
unregister_map_configuration(void * p_sqlite,int xid,const char * name)528 unregister_map_configuration (void *p_sqlite, int xid, const char *name)
529 {
530 /* auxiliary function: deletes a Map Configuration definition */
531     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
532     sqlite3_int64 id;
533 
534     if (xid >= 0)
535       {
536 	  /* checking if the Map Configuration do actually exists */
537 	  if (check_map_configuration_by_id (sqlite, xid))
538 	      id = xid;
539 	  else
540 	      return 0;
541 	  /* deleting the Map Configuration */
542 	  return do_delete_map_configuration (sqlite, id);
543       }
544     else if (name != NULL)
545       {
546 	  /* checking if the Map Configuration do actually exists */
547 	  if (!check_map_configuration_by_name (sqlite, name, &id))
548 	      return 0;
549 	  /* deleting the Vector Style */
550 	  return do_delete_map_configuration (sqlite, id);
551       }
552     else
553 	return 0;
554 }
555 
556 static int
do_reload_map_configuration(sqlite3 * sqlite,sqlite3_int64 id,const unsigned char * p_blob,int n_bytes)557 do_reload_map_configuration (sqlite3 * sqlite, sqlite3_int64 id,
558 			     const unsigned char *p_blob, int n_bytes)
559 {
560 /* auxiliary function: reloads a Map Configurarion definition */
561     int ret;
562     const char *sql;
563     sqlite3_stmt *stmt;
564     char *name;
565 
566     if (p_blob != NULL && n_bytes > 0)
567       {
568 	  /* attempting to update the Vector Style */
569 	  sql =
570 	      "UPDATE rl2map_configurations SET name = ?, config = ? "
571 	      "WHERE id = ?";
572 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
573 	  if (ret != SQLITE_OK)
574 	    {
575 		spatialite_e ("reloadMapConfiguration: \"%s\"\n",
576 			      sqlite3_errmsg (sqlite));
577 		return 0;
578 	    }
579 	  name = gaiaXmlBlobGetName (p_blob, n_bytes);
580 	  sqlite3_reset (stmt);
581 	  sqlite3_clear_bindings (stmt);
582 	  if (name == NULL)
583 	      sqlite3_bind_null (stmt, 1);
584 	  else
585 	      sqlite3_bind_text (stmt, 1, name, strlen (name), SQLITE_STATIC);
586 	  sqlite3_bind_blob (stmt, 2, p_blob, n_bytes, SQLITE_STATIC);
587 	  sqlite3_bind_int64 (stmt, 3, id);
588 	  ret = sqlite3_step (stmt);
589 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
590 	      ;
591 	  else
592 	    {
593 		spatialite_e ("reloadMapConfiguration() error: \"%s\"\n",
594 			      sqlite3_errmsg (sqlite));
595 		sqlite3_finalize (stmt);
596 		return 0;
597 	    }
598 	  sqlite3_finalize (stmt);
599 	  return 1;
600       }
601     else
602 	return 0;
603 }
604 
605 SPATIALITE_PRIVATE int
reload_map_configuration(void * p_sqlite,int xid,const char * name,const unsigned char * p_blob,int n_bytes)606 reload_map_configuration (void *p_sqlite, int xid,
607 			  const char *name,
608 			  const unsigned char *p_blob, int n_bytes)
609 {
610 /* auxiliary function: reloads a Map Configuration definition */
611     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
612     sqlite3_int64 id;
613 
614     if (xid >= 0)
615       {
616 	  /* checking if the MapConfiguration do actually exists */
617 	  if (check_map_configuration_by_id (sqlite, xid))
618 	      id = xid;
619 	  else
620 	      return 0;
621 	  /* reloading the Map Configuration */
622 	  if (map_configuration_causes_duplicate_name
623 	      (sqlite, id, p_blob, n_bytes))
624 	      return 0;
625 	  return do_reload_map_configuration (sqlite, id, p_blob, n_bytes);
626       }
627     else if (name != NULL)
628       {
629 	  /* checking if the Map Configuration do actually exists */
630 	  if (!check_map_configuration_by_name (sqlite, name, &id))
631 	      return 0;
632 	  /* reloading the Map Configuration */
633 	  if (map_configuration_causes_duplicate_name
634 	      (sqlite, id, p_blob, n_bytes))
635 	      return 0;
636 	  return do_reload_map_configuration (sqlite, id, p_blob, n_bytes);
637       }
638     else
639 	return 0;
640 }
641 
642 SPATIALITE_PRIVATE int
count_map_configurations(void * p_sqlite)643 count_map_configurations (void *p_sqlite)
644 {
645 /* auxiliary function: counting how may registered Map Configurations are there */
646     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
647     char *errMsg = NULL;
648     int i;
649     char **results;
650     int rows;
651     int columns;
652     int ret;
653     int count = 0;
654     const char *sql = "SELECT Count(*) FROM rl2map_configurations_view";
655     ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
656     if (ret != SQLITE_OK)
657       {
658 	  spatialite_e ("NumMapConfigurations: \"%s\"\n", errMsg);
659 	  sqlite3_free (errMsg);
660 	  return -1;
661       }
662     for (i = 1; i <= rows; i++)
663 	count = atoi (results[(i * columns) + 0]);
664     sqlite3_free_table (results);
665     return count;
666 }
667 
668 SPATIALITE_PRIVATE char *
get_map_configuration_name(void * p_sqlite,int ind)669 get_map_configuration_name (void *p_sqlite, int ind)
670 {
671 /* auxiliary function: returning the Name of the Nth MapConfiguration */
672     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
673     char *errMsg = NULL;
674     int i;
675     char **results;
676     int rows;
677     int columns;
678     int ret;
679     int count = 0;
680     char *name = NULL;
681     const char *sql = "SELECT name FROM rl2map_configurations_view ORDER BY name";
682     ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
683     if (ret != SQLITE_OK)
684       {
685 	  spatialite_e ("GetMapConfigurationName: \"%s\"\n", errMsg);
686 	  sqlite3_free (errMsg);
687 	  return NULL;
688       }
689     for (i = 1; i <= rows; i++)
690       {
691 	  const char *str = results[(i * columns) + 0];
692 	  count++;
693 	  if (count == ind)
694 	    {
695 		if (str != NULL)
696 		  {
697 		      int len = strlen (str);
698 		      name = malloc (len + 1);
699 		      strcpy (name, str);
700 		  }
701 	    }
702       }
703     sqlite3_free_table (results);
704     return name;
705 }
706 
707 SPATIALITE_PRIVATE char *
get_map_configuration_title(void * p_sqlite,int ind)708 get_map_configuration_title (void *p_sqlite, int ind)
709 {
710 /* auxiliary function: returning the Title of the Nth MapConfiguration */
711     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
712     char *errMsg = NULL;
713     int i;
714     char **results;
715     int rows;
716     int columns;
717     int ret;
718     int count = 0;
719     char *title = NULL;
720     const char *sql =
721 	"SELECT title FROM rl2map_configurations_view ORDER BY name";
722     ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
723     if (ret != SQLITE_OK)
724       {
725 	  spatialite_e ("GetMapConfigurationTitle: \"%s\"\n", errMsg);
726 	  sqlite3_free (errMsg);
727 	  return NULL;
728       }
729     for (i = 1; i <= rows; i++)
730       {
731 	  const char *str = results[(i * columns) + 0];
732 	  count++;
733 	  if (count == ind)
734 	    {
735 		if (str != NULL)
736 		  {
737 		      int len = strlen (str);
738 		      title = malloc (len + 1);
739 		      strcpy (title, str);
740 		  }
741 	    }
742       }
743     sqlite3_free_table (results);
744     return title;
745 }
746 
747 SPATIALITE_PRIVATE char *
get_map_configuration_abstract(void * p_sqlite,int ind)748 get_map_configuration_abstract (void *p_sqlite, int ind)
749 {
750 /* auxiliary function: returning the Abstract of the Nth MapConfiguration */
751     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
752     char *errMsg = NULL;
753     int i;
754     char **results;
755     int rows;
756     int columns;
757     int ret;
758     int count = 0;
759     char *abstract = NULL;
760     const char *sql =
761 	"SELECT abstract FROM rl2map_configurations_view ORDER BY name";
762     ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
763     if (ret != SQLITE_OK)
764       {
765 	  spatialite_e ("GetMapConfigurationAbstract: \"%s\"\n", errMsg);
766 	  sqlite3_free (errMsg);
767 	  return NULL;
768       }
769     for (i = 1; i <= rows; i++)
770       {
771 	  const char *str = results[(i * columns) + 0];
772 	  count++;
773 	  if (count == ind)
774 	    {
775 		if (str != NULL)
776 		  {
777 		      int len = strlen (str);
778 		      abstract = malloc (len + 1);
779 		      strcpy (abstract, str);
780 		  }
781 	    }
782       }
783     sqlite3_free_table (results);
784     return abstract;
785 }
786 
787 SPATIALITE_PRIVATE int
register_vector_style(void * p_sqlite,const unsigned char * p_blob,int n_bytes)788 register_vector_style (void *p_sqlite, const unsigned char *p_blob, int n_bytes)
789 {
790 /* auxiliary function: inserts a Vector Style definition */
791     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
792     int ret;
793     const char *sql;
794     sqlite3_stmt *stmt;
795 
796     if (p_blob != NULL && n_bytes > 0)
797       {
798 	  /* attempting to insert the Vector Style */
799 	  if (vector_style_causes_duplicate_name (sqlite, -1, p_blob, n_bytes))
800 	      return 0;
801 	  sql = "INSERT INTO SE_vector_styles "
802 	      "(style_id, style) VALUES (NULL, ?)";
803 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
804 	  if (ret != SQLITE_OK)
805 	    {
806 		spatialite_e ("registerVectorStyle: \"%s\"\n",
807 			      sqlite3_errmsg (sqlite));
808 		return 0;
809 	    }
810 	  sqlite3_reset (stmt);
811 	  sqlite3_clear_bindings (stmt);
812 	  sqlite3_bind_blob (stmt, 1, p_blob, n_bytes, SQLITE_STATIC);
813 	  ret = sqlite3_step (stmt);
814 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
815 	      ;
816 	  else
817 	    {
818 		spatialite_e ("registerVectorStyle() error: \"%s\"\n",
819 			      sqlite3_errmsg (sqlite));
820 		sqlite3_finalize (stmt);
821 		return 0;
822 	    }
823 	  sqlite3_finalize (stmt);
824 	  return 1;
825       }
826     else
827 	return 0;
828 }
829 
830 static int
check_vector_style_by_id(sqlite3 * sqlite,int style_id)831 check_vector_style_by_id (sqlite3 * sqlite, int style_id)
832 {
833 /* checks if a Vector Style do actually exists - by ID */
834     int ret;
835     const char *sql;
836     sqlite3_stmt *stmt;
837     int count = 0;
838 
839     sql = "SELECT style_id FROM SE_vector_styles " "WHERE style_id = ?";
840     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
841     if (ret != SQLITE_OK)
842       {
843 	  spatialite_e ("check Vector Style by ID: \"%s\"\n",
844 			sqlite3_errmsg (sqlite));
845 	  goto stop;
846       }
847     sqlite3_reset (stmt);
848     sqlite3_clear_bindings (stmt);
849     sqlite3_bind_int (stmt, 1, style_id);
850     while (1)
851       {
852 	  /* scrolling the result set rows */
853 	  ret = sqlite3_step (stmt);
854 	  if (ret == SQLITE_DONE)
855 	      break;		/* end of result set */
856 	  if (ret == SQLITE_ROW)
857 	      count++;
858       }
859     sqlite3_finalize (stmt);
860     if (count == 1)
861 	return 1;
862     return 0;
863   stop:
864     return 0;
865 }
866 
867 static int
check_vector_style_by_name(sqlite3 * sqlite,const char * style_name,sqlite3_int64 * id)868 check_vector_style_by_name (sqlite3 * sqlite, const char *style_name,
869 			    sqlite3_int64 * id)
870 {
871 /* checks if a Vector Style do actually exists - by name */
872     int ret;
873     const char *sql;
874     sqlite3_stmt *stmt;
875     int count = 0;
876     sqlite3_int64 xid = 0;
877 
878     sql = "SELECT style_id FROM SE_vector_styles "
879 	"WHERE Lower(style_name) = Lower(?)";
880     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
881     if (ret != SQLITE_OK)
882       {
883 	  spatialite_e ("check Vector Style by Name: \"%s\"\n",
884 			sqlite3_errmsg (sqlite));
885 	  goto stop;
886       }
887     sqlite3_reset (stmt);
888     sqlite3_clear_bindings (stmt);
889     sqlite3_bind_text (stmt, 1, style_name, strlen (style_name), SQLITE_STATIC);
890     while (1)
891       {
892 	  /* scrolling the result set rows */
893 	  ret = sqlite3_step (stmt);
894 	  if (ret == SQLITE_DONE)
895 	      break;		/* end of result set */
896 	  if (ret == SQLITE_ROW)
897 	    {
898 		xid = sqlite3_column_int64 (stmt, 0);
899 		count++;
900 	    }
901       }
902     sqlite3_finalize (stmt);
903     if (count == 1)
904       {
905 	  *id = xid;
906 	  return 1;
907       }
908     return 0;
909   stop:
910     return 0;
911 }
912 
913 static int
check_vector_style_refs_by_id(sqlite3 * sqlite,int style_id,int * has_refs)914 check_vector_style_refs_by_id (sqlite3 * sqlite, int style_id, int *has_refs)
915 {
916 /* checks if a Vector Style do actually exists - by ID */
917     int ret;
918     const char *sql;
919     sqlite3_stmt *stmt;
920     int count = 0;
921     int ref_count = 0;
922 
923     sql = "SELECT s.style_id, l.style_id FROM SE_vector_styles AS s "
924 	"LEFT JOIN SE_vector_styled_layers AS l ON (l.style_id = s.style_id) "
925 	"WHERE s.style_id = ?";
926     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
927     if (ret != SQLITE_OK)
928       {
929 	  spatialite_e ("check Vector Style Refs by ID: \"%s\"\n",
930 			sqlite3_errmsg (sqlite));
931 	  goto stop;
932       }
933     sqlite3_reset (stmt);
934     sqlite3_clear_bindings (stmt);
935     sqlite3_bind_int (stmt, 1, style_id);
936     while (1)
937       {
938 	  /* scrolling the result set rows */
939 	  ret = sqlite3_step (stmt);
940 	  if (ret == SQLITE_DONE)
941 	      break;		/* end of result set */
942 	  if (ret == SQLITE_ROW)
943 	    {
944 		count++;
945 		if (sqlite3_column_type (stmt, 1) == SQLITE_INTEGER)
946 		    ref_count++;
947 	    }
948       }
949     sqlite3_finalize (stmt);
950     if (count >= 1)
951       {
952 	  if (ref_count > 0)
953 	      *has_refs = 1;
954 	  return 1;
955       }
956     return 0;
957   stop:
958     return 0;
959 }
960 
961 static int
check_vector_style_refs_by_name(sqlite3 * sqlite,const char * style_name,sqlite3_int64 * id,int * has_refs)962 check_vector_style_refs_by_name (sqlite3 * sqlite, const char *style_name,
963 				 sqlite3_int64 * id, int *has_refs)
964 {
965 /* checks if a Vector Style do actually exists - by name */
966     int ret;
967     const char *sql;
968     sqlite3_stmt *stmt;
969     int count = 0;
970     int ref_count = 0;
971     sqlite3_int64 xid = 0;
972 
973     sql = "SELECT style_id FROM SE_vector_styles "
974 	"WHERE Lower(style_name) = Lower(?)";
975     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
976     if (ret != SQLITE_OK)
977       {
978 	  spatialite_e ("check Vector Style Refs by Name: \"%s\"\n",
979 			sqlite3_errmsg (sqlite));
980 	  goto stop;
981       }
982     sqlite3_reset (stmt);
983     sqlite3_clear_bindings (stmt);
984     sqlite3_bind_text (stmt, 1, style_name, strlen (style_name), SQLITE_STATIC);
985     while (1)
986       {
987 	  /* scrolling the result set rows */
988 	  ret = sqlite3_step (stmt);
989 	  if (ret == SQLITE_DONE)
990 	      break;		/* end of result set */
991 	  if (ret == SQLITE_ROW)
992 	    {
993 		xid = sqlite3_column_int64 (stmt, 0);
994 		count++;
995 	    }
996       }
997     sqlite3_finalize (stmt);
998     if (count != 1)
999 	return 0;
1000     *id = xid;
1001     sql = "SELECT s.style_id, l.style_id FROM SE_vector_styles AS s "
1002 	"LEFT JOIN SE_vector_styled_layers AS l ON (l.style_id = s.style_id) "
1003 	"WHERE s.style_id = ?";
1004     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1005     if (ret != SQLITE_OK)
1006       {
1007 	  spatialite_e ("check Vector Style Refs by ID: \"%s\"\n",
1008 			sqlite3_errmsg (sqlite));
1009 	  goto stop;
1010       }
1011     sqlite3_reset (stmt);
1012     sqlite3_clear_bindings (stmt);
1013     sqlite3_bind_int64 (stmt, 1, *id);
1014     while (1)
1015       {
1016 	  /* scrolling the result set rows */
1017 	  ret = sqlite3_step (stmt);
1018 	  if (ret == SQLITE_DONE)
1019 	      break;		/* end of result set */
1020 	  if (ret == SQLITE_ROW)
1021 	    {
1022 		if (sqlite3_column_type (stmt, 1) == SQLITE_INTEGER)
1023 		    ref_count++;
1024 	    }
1025       }
1026     sqlite3_finalize (stmt);
1027     if (ref_count > 0)
1028 	*has_refs = 1;
1029     return 1;
1030   stop:
1031     return 0;
1032 }
1033 
1034 static int
do_insert_vector_style_layer(sqlite3 * sqlite,const char * coverage_name,sqlite3_int64 id)1035 do_insert_vector_style_layer (sqlite3 * sqlite, const char *coverage_name,
1036 			      sqlite3_int64 id)
1037 {
1038 /* auxiliary function: really inserting a Vector Styled Layer */
1039     int ret;
1040     const char *sql;
1041     sqlite3_stmt *stmt;
1042     int retval = 0;
1043     sql = "INSERT INTO SE_vector_styled_layers "
1044 	"(coverage_name, style_id) VALUES (?, ?)";
1045     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1046     if (ret != SQLITE_OK)
1047       {
1048 	  spatialite_e ("registerVectorStyledLayer: \"%s\"\n",
1049 			sqlite3_errmsg (sqlite));
1050 	  goto stop;
1051       }
1052     sqlite3_reset (stmt);
1053     sqlite3_clear_bindings (stmt);
1054     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
1055 		       SQLITE_STATIC);
1056     sqlite3_bind_int64 (stmt, 2, id);
1057     ret = sqlite3_step (stmt);
1058     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
1059 	retval = 1;
1060     else
1061 	spatialite_e ("registerVectorStyledLayer() error: \"%s\"\n",
1062 		      sqlite3_errmsg (sqlite));
1063     sqlite3_finalize (stmt);
1064     return retval;
1065   stop:
1066     return 0;
1067 }
1068 
1069 static int
do_delete_vector_style_refs(sqlite3 * sqlite,sqlite3_int64 id)1070 do_delete_vector_style_refs (sqlite3 * sqlite, sqlite3_int64 id)
1071 {
1072 /* auxiliary function: deleting all Vector Style references */
1073     int ret;
1074     const char *sql;
1075     sqlite3_stmt *stmt;
1076     int retval = 0;
1077     sql = "DELETE FROM SE_vector_styled_layers WHERE style_id = ?";
1078     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1079     if (ret != SQLITE_OK)
1080       {
1081 	  spatialite_e ("unregisterVectorStyle: \"%s\"\n",
1082 			sqlite3_errmsg (sqlite));
1083 	  goto stop;
1084       }
1085     sqlite3_reset (stmt);
1086     sqlite3_clear_bindings (stmt);
1087     sqlite3_bind_int64 (stmt, 1, id);
1088     ret = sqlite3_step (stmt);
1089     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
1090 	retval = 1;
1091     else
1092 	spatialite_e ("unregisterVectorStyle() error: \"%s\"\n",
1093 		      sqlite3_errmsg (sqlite));
1094     sqlite3_finalize (stmt);
1095     return retval;
1096   stop:
1097     return 0;
1098 }
1099 
1100 static int
do_delete_vector_style(sqlite3 * sqlite,sqlite3_int64 id)1101 do_delete_vector_style (sqlite3 * sqlite, sqlite3_int64 id)
1102 {
1103 /* auxiliary function: really deleting a Vector Style */
1104     int ret;
1105     const char *sql;
1106     sqlite3_stmt *stmt;
1107     int retval = 0;
1108     sql = "DELETE FROM SE_vector_styles WHERE style_id = ?";
1109     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1110     if (ret != SQLITE_OK)
1111       {
1112 	  spatialite_e ("unregisterVectorStyle: \"%s\"\n",
1113 			sqlite3_errmsg (sqlite));
1114 	  goto stop;
1115       }
1116     sqlite3_reset (stmt);
1117     sqlite3_clear_bindings (stmt);
1118     sqlite3_bind_int64 (stmt, 1, id);
1119     ret = sqlite3_step (stmt);
1120     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
1121 	retval = 1;
1122     else
1123 	spatialite_e ("unregisterVectorStyle() error: \"%s\"\n",
1124 		      sqlite3_errmsg (sqlite));
1125     sqlite3_finalize (stmt);
1126     return retval;
1127   stop:
1128     return 0;
1129 }
1130 
1131 SPATIALITE_PRIVATE int
unregister_vector_style(void * p_sqlite,int style_id,const char * style_name,int remove_all)1132 unregister_vector_style (void *p_sqlite, int style_id,
1133 			 const char *style_name, int remove_all)
1134 {
1135 /* auxiliary function: deletes a Vector Style definition */
1136     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
1137     sqlite3_int64 id;
1138     int has_refs = 0;
1139 
1140     if (style_id >= 0)
1141       {
1142 	  /* checking if the Vector Style do actually exists */
1143 	  if (check_vector_style_refs_by_id (sqlite, style_id, &has_refs))
1144 	      id = style_id;
1145 	  else
1146 	      return 0;
1147 	  if (has_refs)
1148 	    {
1149 		if (!remove_all)
1150 		    return 0;
1151 		/* deleting all references */
1152 		if (!do_delete_vector_style_refs (sqlite, id))
1153 		    return 0;
1154 	    }
1155 	  /* deleting the Vector Style */
1156 	  return do_delete_vector_style (sqlite, id);
1157       }
1158     else if (style_name != NULL)
1159       {
1160 	  /* checking if the Vector Style do actually exists */
1161 	  if (!check_vector_style_refs_by_name
1162 	      (sqlite, style_name, &id, &has_refs))
1163 	      return 0;
1164 	  if (has_refs)
1165 	    {
1166 		if (!remove_all)
1167 		    return 0;
1168 		/* deleting all references */
1169 		if (!do_delete_vector_style_refs (sqlite, id))
1170 		    return 0;
1171 	    }
1172 	  /* deleting the Vector Style */
1173 	  return do_delete_vector_style (sqlite, id);
1174       }
1175     else
1176 	return 0;
1177 }
1178 
1179 static int
do_reload_vector_style(sqlite3 * sqlite,sqlite3_int64 id,const unsigned char * p_blob,int n_bytes)1180 do_reload_vector_style (sqlite3 * sqlite, sqlite3_int64 id,
1181 			const unsigned char *p_blob, int n_bytes)
1182 {
1183 /* auxiliary function: reloads a Vector Style definition */
1184     int ret;
1185     const char *sql;
1186     sqlite3_stmt *stmt;
1187 
1188     if (p_blob != NULL && n_bytes > 0)
1189       {
1190 	  /* attempting to update the Vector Style */
1191 	  sql = "UPDATE SE_vector_styles SET style = ? " "WHERE style_id = ?";
1192 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1193 	  if (ret != SQLITE_OK)
1194 	    {
1195 		spatialite_e ("reloadVectorStyle: \"%s\"\n",
1196 			      sqlite3_errmsg (sqlite));
1197 		return 0;
1198 	    }
1199 	  sqlite3_reset (stmt);
1200 	  sqlite3_clear_bindings (stmt);
1201 	  sqlite3_bind_blob (stmt, 1, p_blob, n_bytes, SQLITE_STATIC);
1202 	  sqlite3_bind_int64 (stmt, 2, id);
1203 	  ret = sqlite3_step (stmt);
1204 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
1205 	      ;
1206 	  else
1207 	    {
1208 		spatialite_e ("reloadVectorStyle() error: \"%s\"\n",
1209 			      sqlite3_errmsg (sqlite));
1210 		sqlite3_finalize (stmt);
1211 		return 0;
1212 	    }
1213 	  sqlite3_finalize (stmt);
1214 	  return 1;
1215       }
1216     else
1217 	return 0;
1218 }
1219 
1220 SPATIALITE_PRIVATE int
reload_vector_style(void * p_sqlite,int style_id,const char * style_name,const unsigned char * p_blob,int n_bytes)1221 reload_vector_style (void *p_sqlite, int style_id,
1222 		     const char *style_name,
1223 		     const unsigned char *p_blob, int n_bytes)
1224 {
1225 /* auxiliary function: reloads a Vector Style definition */
1226     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
1227     sqlite3_int64 id;
1228 
1229     if (style_id >= 0)
1230       {
1231 	  /* checking if the Vector Style do actually exists */
1232 	  if (check_vector_style_by_id (sqlite, style_id))
1233 	      id = style_id;
1234 	  else
1235 	      return 0;
1236 	  /* reloading the Vector Style */
1237 	  if (vector_style_causes_duplicate_name (sqlite, id, p_blob, n_bytes))
1238 	      return 0;
1239 	  return do_reload_vector_style (sqlite, id, p_blob, n_bytes);
1240       }
1241     else if (style_name != NULL)
1242       {
1243 	  /* checking if the Vector Style do actually exists */
1244 	  if (!check_vector_style_by_name (sqlite, style_name, &id))
1245 	      return 0;
1246 	  /* reloading the Vector Style */
1247 	  if (vector_style_causes_duplicate_name (sqlite, id, p_blob, n_bytes))
1248 	      return 0;
1249 	  return do_reload_vector_style (sqlite, id, p_blob, n_bytes);
1250       }
1251     else
1252 	return 0;
1253 }
1254 
1255 SPATIALITE_PRIVATE int
register_vector_styled_layer_ex(void * p_sqlite,const char * coverage_name,int style_id,const char * style_name)1256 register_vector_styled_layer_ex (void *p_sqlite, const char *coverage_name,
1257 				 int style_id, const char *style_name)
1258 {
1259 /* auxiliary function: inserts a Vector Styled Layer definition */
1260     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
1261     sqlite3_int64 id;
1262 
1263     if (coverage_name == NULL)
1264 	return 0;
1265 
1266     if (style_id >= 0)
1267       {
1268 	  /* checking if the Vector Style do actually exists */
1269 	  if (check_vector_style_by_id (sqlite, style_id))
1270 	      id = style_id;
1271 	  else
1272 	      return 0;
1273 	  /* inserting the Vector Styled Layer */
1274 	  return do_insert_vector_style_layer (sqlite, coverage_name, id);
1275       }
1276     else if (style_name != NULL)
1277       {
1278 	  /* checking if the Vector Style do actually exists */
1279 	  if (!check_vector_style_by_name (sqlite, style_name, &id))
1280 	      return 0;
1281 	  /* inserting the Vector Styled Layer */
1282 	  return do_insert_vector_style_layer (sqlite, coverage_name, id);
1283       }
1284     else
1285 	return 0;
1286 }
1287 
1288 SPATIALITE_PRIVATE int
register_vector_styled_layer(void * p_sqlite,const char * f_table_name,const char * f_geometry_column,int style_id,const unsigned char * p_blob,int n_bytes)1289 register_vector_styled_layer (void *p_sqlite, const char *f_table_name,
1290 			      const char *f_geometry_column, int style_id,
1291 			      const unsigned char *p_blob, int n_bytes)
1292 {
1293 /* auxiliary function: inserts a Vector Styled Layer definition - DEPRECATED */
1294     if (p_blob != NULL && n_bytes <= 0 && f_geometry_column != NULL)
1295       {
1296 	  /* silencing compiler complaints */
1297 	  p_blob = NULL;
1298 	  n_bytes = 0;
1299 	  f_geometry_column = NULL;
1300       }
1301     return register_vector_styled_layer_ex (p_sqlite, f_table_name, style_id,
1302 					    NULL);
1303 }
1304 
1305 static int
check_vector_styled_layer_by_id(sqlite3 * sqlite,const char * coverage_name,int style_id)1306 check_vector_styled_layer_by_id (sqlite3 * sqlite, const char *coverage_name,
1307 				 int style_id)
1308 {
1309 /* checks if a Vector Styled Layer do actually exists - by ID */
1310     int ret;
1311     const char *sql;
1312     sqlite3_stmt *stmt;
1313     int count = 0;
1314 
1315     sql = "SELECT style_id FROM SE_vector_styled_layers "
1316 	"WHERE Lower(coverage_name) = Lower(?) AND style_id = ?";
1317     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1318     if (ret != SQLITE_OK)
1319       {
1320 	  spatialite_e ("check Vector Styled Layer by ID: \"%s\"\n",
1321 			sqlite3_errmsg (sqlite));
1322 	  goto stop;
1323       }
1324     sqlite3_reset (stmt);
1325     sqlite3_clear_bindings (stmt);
1326     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
1327 		       SQLITE_STATIC);
1328     sqlite3_bind_int64 (stmt, 2, style_id);
1329     while (1)
1330       {
1331 	  /* scrolling the result set rows */
1332 	  ret = sqlite3_step (stmt);
1333 	  if (ret == SQLITE_DONE)
1334 	      break;		/* end of result set */
1335 	  if (ret == SQLITE_ROW)
1336 	      count++;
1337       }
1338     sqlite3_finalize (stmt);
1339     if (count == 1)
1340 	return 1;
1341     return 0;
1342   stop:
1343     return 0;
1344 }
1345 
1346 static int
check_vector_styled_layer_by_name(sqlite3 * sqlite,const char * coverage_name,const char * style_name,sqlite3_int64 * id)1347 check_vector_styled_layer_by_name (sqlite3 * sqlite, const char *coverage_name,
1348 				   const char *style_name, sqlite3_int64 * id)
1349 {
1350 /* checks if a Vector Styled Layer do actually exists - by name */
1351     int ret;
1352     const char *sql;
1353     sqlite3_stmt *stmt;
1354     int count = 0;
1355     sqlite3_int64 xid = 0;
1356 
1357     sql = "SELECT l.style_id FROM SE_vector_styled_layers AS l "
1358 	"JOIN SE_vector_styles AS s ON (l.style_id = s.style_id) "
1359 	"WHERE Lower(l.coverage_name) = Lower(?) "
1360 	"AND Lower(s.style_name) = Lower(?)";
1361     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1362     if (ret != SQLITE_OK)
1363       {
1364 	  spatialite_e ("check Vector Styled Layer by Name: \"%s\"\n",
1365 			sqlite3_errmsg (sqlite));
1366 	  goto stop;
1367       }
1368     sqlite3_reset (stmt);
1369     sqlite3_clear_bindings (stmt);
1370     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
1371 		       SQLITE_STATIC);
1372     sqlite3_bind_text (stmt, 2, style_name, strlen (style_name), SQLITE_STATIC);
1373     while (1)
1374       {
1375 	  /* scrolling the result set rows */
1376 	  ret = sqlite3_step (stmt);
1377 	  if (ret == SQLITE_DONE)
1378 	      break;		/* end of result set */
1379 	  if (ret == SQLITE_ROW)
1380 	    {
1381 		xid = sqlite3_column_int64 (stmt, 0);
1382 		count++;
1383 	    }
1384       }
1385     sqlite3_finalize (stmt);
1386     if (count == 1)
1387       {
1388 	  *id = xid;
1389 	  return 1;
1390       }
1391     return 0;
1392   stop:
1393     return 0;
1394 }
1395 
1396 static int
do_delete_vector_style_layer(sqlite3 * sqlite,const char * coverage_name,sqlite3_int64 id)1397 do_delete_vector_style_layer (sqlite3 * sqlite, const char *coverage_name,
1398 			      sqlite3_int64 id)
1399 {
1400 /* auxiliary function: really deleting a Vector Styled Layer */
1401     int ret;
1402     const char *sql;
1403     sqlite3_stmt *stmt;
1404     int retval = 0;
1405     sql = "DELETE FROM SE_vector_styled_layers "
1406 	"WHERE Lower(coverage_name) = Lower(?) AND style_id = ?";
1407     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1408     if (ret != SQLITE_OK)
1409       {
1410 	  spatialite_e ("unregisterVectorStyledLayer: \"%s\"\n",
1411 			sqlite3_errmsg (sqlite));
1412 	  goto stop;
1413       }
1414     sqlite3_reset (stmt);
1415     sqlite3_clear_bindings (stmt);
1416     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
1417 		       SQLITE_STATIC);
1418     sqlite3_bind_int64 (stmt, 2, id);
1419     ret = sqlite3_step (stmt);
1420     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
1421 	retval = 1;
1422     else
1423 	spatialite_e ("unregisterVectorStyledLayer() error: \"%s\"\n",
1424 		      sqlite3_errmsg (sqlite));
1425     sqlite3_finalize (stmt);
1426     return retval;
1427   stop:
1428     return 0;
1429 }
1430 
1431 SPATIALITE_PRIVATE int
unregister_vector_styled_layer(void * p_sqlite,const char * coverage_name,int style_id,const char * style_name)1432 unregister_vector_styled_layer (void *p_sqlite, const char *coverage_name,
1433 				int style_id, const char *style_name)
1434 {
1435 /* auxiliary function: removes a Vector Styled Layer definition */
1436     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
1437     sqlite3_int64 id;
1438 
1439     if (coverage_name == NULL)
1440 	return 0;
1441 
1442     if (style_id >= 0)
1443       {
1444 	  /* checking if the Vector Styled Layer do actually exists */
1445 	  if (check_vector_styled_layer_by_id (sqlite, coverage_name, style_id))
1446 	      id = style_id;
1447 	  else
1448 	      return 0;
1449 	  /* removing the Vector Styled Layer */
1450 	  return do_delete_vector_style_layer (sqlite, coverage_name, id);
1451       }
1452     else if (style_name != NULL)
1453       {
1454 	  /* checking if the Vector Styled Layer do actually exists */
1455 	  if (!check_vector_styled_layer_by_name
1456 	      (sqlite, coverage_name, style_name, &id))
1457 	      return 0;
1458 	  /* removing the Vector Styled Layer */
1459 	  return do_delete_vector_style_layer (sqlite, coverage_name, id);
1460       }
1461     else
1462 	return 0;
1463 }
1464 
1465 static int
raster_style_causes_duplicate_name(sqlite3 * sqlite,sqlite3_int64 id,const unsigned char * p_blob,int n_bytes)1466 raster_style_causes_duplicate_name (sqlite3 * sqlite, sqlite3_int64 id,
1467 				    const unsigned char *p_blob, int n_bytes)
1468 {
1469 /* auxiliary function: checks for an eventual duplicate name */
1470     int count = 0;
1471     int ret;
1472     const char *sql;
1473     sqlite3_stmt *stmt;
1474 
1475     sql = "SELECT Count(*) FROM SE_raster_styles "
1476 	"WHERE Lower(style_name) = Lower(XB_GetName(?)) AND style_id <> ?";
1477     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1478     if (ret != SQLITE_OK)
1479       {
1480 	  spatialite_e ("RasterStyle duplicate Name: \"%s\"\n",
1481 			sqlite3_errmsg (sqlite));
1482 	  return 0;
1483       }
1484     sqlite3_reset (stmt);
1485     sqlite3_clear_bindings (stmt);
1486     sqlite3_bind_blob (stmt, 1, p_blob, n_bytes, SQLITE_STATIC);
1487     sqlite3_bind_int64 (stmt, 2, id);
1488     while (1)
1489       {
1490 	  /* scrolling the result set rows */
1491 	  ret = sqlite3_step (stmt);
1492 	  if (ret == SQLITE_DONE)
1493 	      break;		/* end of result set */
1494 	  if (ret == SQLITE_ROW)
1495 	      count = sqlite3_column_int (stmt, 0);
1496       }
1497     sqlite3_finalize (stmt);
1498     if (count != 0)
1499 	return 1;
1500     return 0;
1501 }
1502 
1503 SPATIALITE_PRIVATE int
register_raster_style(void * p_sqlite,const unsigned char * p_blob,int n_bytes)1504 register_raster_style (void *p_sqlite, const unsigned char *p_blob, int n_bytes)
1505 {
1506 /* auxiliary function: inserts a Raster Style definition */
1507     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
1508     int ret;
1509     const char *sql;
1510     sqlite3_stmt *stmt;
1511 
1512     if (p_blob != NULL && n_bytes > 0)
1513       {
1514 	  /* attempting to insert the Raster Style */
1515 	  if (raster_style_causes_duplicate_name (sqlite, -1, p_blob, n_bytes))
1516 	      return 0;
1517 	  sql = "INSERT INTO SE_raster_styles "
1518 	      "(style_id, style) VALUES (NULL, ?)";
1519 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1520 	  if (ret != SQLITE_OK)
1521 	    {
1522 		spatialite_e ("registerRasterStyle: \"%s\"\n",
1523 			      sqlite3_errmsg (sqlite));
1524 		return 0;
1525 	    }
1526 	  sqlite3_reset (stmt);
1527 	  sqlite3_clear_bindings (stmt);
1528 	  sqlite3_bind_blob (stmt, 1, p_blob, n_bytes, SQLITE_STATIC);
1529 	  ret = sqlite3_step (stmt);
1530 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
1531 	      ;
1532 	  else
1533 	    {
1534 		spatialite_e ("registerRasterStyle() error: \"%s\"\n",
1535 			      sqlite3_errmsg (sqlite));
1536 		sqlite3_finalize (stmt);
1537 		return 0;
1538 	    }
1539 	  sqlite3_finalize (stmt);
1540 	  return 1;
1541       }
1542     else
1543 	return 0;
1544 }
1545 
1546 static int
do_delete_raster_style_refs(sqlite3 * sqlite,sqlite3_int64 id)1547 do_delete_raster_style_refs (sqlite3 * sqlite, sqlite3_int64 id)
1548 {
1549 /* auxiliary function: deleting all Raster Style references */
1550     int ret;
1551     const char *sql;
1552     sqlite3_stmt *stmt;
1553     int retval = 0;
1554     sql = "DELETE FROM SE_raster_styled_layers WHERE style_id = ?";
1555     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1556     if (ret != SQLITE_OK)
1557       {
1558 	  spatialite_e ("unregisterRasterStyle: \"%s\"\n",
1559 			sqlite3_errmsg (sqlite));
1560 	  goto stop;
1561       }
1562     sqlite3_reset (stmt);
1563     sqlite3_clear_bindings (stmt);
1564     sqlite3_bind_int64 (stmt, 1, id);
1565     ret = sqlite3_step (stmt);
1566     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
1567 	retval = 1;
1568     else
1569 	spatialite_e ("unregisterRasterStyle() error: \"%s\"\n",
1570 		      sqlite3_errmsg (sqlite));
1571     sqlite3_finalize (stmt);
1572     return retval;
1573   stop:
1574     return 0;
1575 }
1576 
1577 static int
check_raster_style_refs_by_id(sqlite3 * sqlite,int style_id,int * has_refs)1578 check_raster_style_refs_by_id (sqlite3 * sqlite, int style_id, int *has_refs)
1579 {
1580 /* checks if a Raster Style do actually exists - by ID */
1581     int ret;
1582     const char *sql;
1583     sqlite3_stmt *stmt;
1584     int count = 0;
1585     int ref_count = 0;
1586 
1587     sql = "SELECT s.style_id, l.style_id FROM SE_raster_styles AS s "
1588 	"LEFT JOIN SE_raster_styled_layers AS l ON (l.style_id = s.style_id) "
1589 	"WHERE s.style_id = ?";
1590     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1591     if (ret != SQLITE_OK)
1592       {
1593 	  spatialite_e ("check Raster Style Refs by ID: \"%s\"\n",
1594 			sqlite3_errmsg (sqlite));
1595 	  goto stop;
1596       }
1597     sqlite3_reset (stmt);
1598     sqlite3_clear_bindings (stmt);
1599     sqlite3_bind_int (stmt, 1, style_id);
1600     while (1)
1601       {
1602 	  /* scrolling the result set rows */
1603 	  ret = sqlite3_step (stmt);
1604 	  if (ret == SQLITE_DONE)
1605 	      break;		/* end of result set */
1606 	  if (ret == SQLITE_ROW)
1607 	    {
1608 		count++;
1609 		if (sqlite3_column_type (stmt, 1) == SQLITE_INTEGER)
1610 		    ref_count++;
1611 	    }
1612       }
1613     sqlite3_finalize (stmt);
1614     if (count >= 1)
1615       {
1616 	  if (ref_count > 0)
1617 	      *has_refs = 1;
1618 	  return 1;
1619       }
1620     return 0;
1621   stop:
1622     return 0;
1623 }
1624 
1625 static int
check_raster_style_refs_by_name(sqlite3 * sqlite,const char * style_name,sqlite3_int64 * id,int * has_refs)1626 check_raster_style_refs_by_name (sqlite3 * sqlite, const char *style_name,
1627 				 sqlite3_int64 * id, int *has_refs)
1628 {
1629 /* checks if a Raster Style do actually exists - by name */
1630     int ret;
1631     const char *sql;
1632     sqlite3_stmt *stmt;
1633     int count = 0;
1634     int ref_count = 0;
1635     sqlite3_int64 xid = 0;
1636 
1637     sql = "SELECT style_id FROM SE_raster_styles "
1638 	"WHERE Lower(style_name) = Lower(?)";
1639     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1640     if (ret != SQLITE_OK)
1641       {
1642 	  spatialite_e ("check Raster Style Refs by Name: \"%s\"\n",
1643 			sqlite3_errmsg (sqlite));
1644 	  goto stop;
1645       }
1646     sqlite3_reset (stmt);
1647     sqlite3_clear_bindings (stmt);
1648     sqlite3_bind_text (stmt, 1, style_name, strlen (style_name), SQLITE_STATIC);
1649     while (1)
1650       {
1651 	  /* scrolling the result set rows */
1652 	  ret = sqlite3_step (stmt);
1653 	  if (ret == SQLITE_DONE)
1654 	      break;		/* end of result set */
1655 	  if (ret == SQLITE_ROW)
1656 	    {
1657 		xid = sqlite3_column_int64 (stmt, 0);
1658 		count++;
1659 	    }
1660       }
1661     sqlite3_finalize (stmt);
1662     if (count != 1)
1663 	return 0;
1664     *id = xid;
1665     sql = "SELECT s.style_id, l.style_id FROM SE_raster_styles AS s "
1666 	"LEFT JOIN SE_raster_styled_layers AS l ON (l.style_id = s.style_id) "
1667 	"WHERE s.style_id = ?";
1668     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1669     if (ret != SQLITE_OK)
1670       {
1671 	  spatialite_e ("check Raster Style Refs by ID: \"%s\"\n",
1672 			sqlite3_errmsg (sqlite));
1673 	  goto stop;
1674       }
1675     sqlite3_reset (stmt);
1676     sqlite3_clear_bindings (stmt);
1677     sqlite3_bind_int64 (stmt, 1, *id);
1678     while (1)
1679       {
1680 	  /* scrolling the result set rows */
1681 	  ret = sqlite3_step (stmt);
1682 	  if (ret == SQLITE_DONE)
1683 	      break;		/* end of result set */
1684 	  if (ret == SQLITE_ROW)
1685 	    {
1686 		if (sqlite3_column_type (stmt, 1) == SQLITE_INTEGER)
1687 		    ref_count++;
1688 	    }
1689       }
1690     sqlite3_finalize (stmt);
1691     if (ref_count > 0)
1692 	*has_refs = 1;
1693     return 1;
1694   stop:
1695     return 0;
1696 }
1697 
1698 static int
do_delete_raster_style(sqlite3 * sqlite,sqlite3_int64 id)1699 do_delete_raster_style (sqlite3 * sqlite, sqlite3_int64 id)
1700 {
1701 /* auxiliary function: really deleting a Raster Style */
1702     int ret;
1703     const char *sql;
1704     sqlite3_stmt *stmt;
1705     int retval = 0;
1706     sql = "DELETE FROM SE_raster_styles WHERE style_id = ?";
1707     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1708     if (ret != SQLITE_OK)
1709       {
1710 	  spatialite_e ("unregisterRasterStyle: \"%s\"\n",
1711 			sqlite3_errmsg (sqlite));
1712 	  goto stop;
1713       }
1714     sqlite3_reset (stmt);
1715     sqlite3_clear_bindings (stmt);
1716     sqlite3_bind_int64 (stmt, 1, id);
1717     ret = sqlite3_step (stmt);
1718     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
1719 	retval = 1;
1720     else
1721 	spatialite_e ("unregisterRasterStyle() error: \"%s\"\n",
1722 		      sqlite3_errmsg (sqlite));
1723     sqlite3_finalize (stmt);
1724     return retval;
1725   stop:
1726     return 0;
1727 }
1728 
1729 SPATIALITE_PRIVATE int
unregister_raster_style(void * p_sqlite,int style_id,const char * style_name,int remove_all)1730 unregister_raster_style (void *p_sqlite, int style_id,
1731 			 const char *style_name, int remove_all)
1732 {
1733 /* auxiliary function: deletes a Raster Style definition */
1734     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
1735     sqlite3_int64 id;
1736     int has_refs = 0;
1737 
1738     if (style_id >= 0)
1739       {
1740 	  /* checking if the Raster Style do actually exists */
1741 	  if (check_raster_style_refs_by_id (sqlite, style_id, &has_refs))
1742 	      id = style_id;
1743 	  else
1744 	      return 0;
1745 	  if (has_refs)
1746 	    {
1747 		if (!remove_all)
1748 		    return 0;
1749 		/* deleting all references */
1750 		if (!do_delete_raster_style_refs (sqlite, id))
1751 		    return 0;
1752 	    }
1753 	  /* deleting the Raster Style */
1754 	  return do_delete_raster_style (sqlite, id);
1755       }
1756     else if (style_name != NULL)
1757       {
1758 	  /* checking if the Raster Style do actually exists */
1759 	  if (!check_raster_style_refs_by_name
1760 	      (sqlite, style_name, &id, &has_refs))
1761 	      return 0;
1762 	  if (has_refs)
1763 	    {
1764 		if (!remove_all)
1765 		    return 0;
1766 		/* deleting all references */
1767 		if (!do_delete_raster_style_refs (sqlite, id))
1768 		    return 0;
1769 	    }
1770 	  /* deleting the Raster Style */
1771 	  return do_delete_raster_style (sqlite, id);
1772       }
1773     else
1774 	return 0;
1775 }
1776 
1777 static int
check_raster_style_by_id(sqlite3 * sqlite,int style_id)1778 check_raster_style_by_id (sqlite3 * sqlite, int style_id)
1779 {
1780 /* checks if a Raster Style do actually exists - by ID */
1781     int ret;
1782     const char *sql;
1783     sqlite3_stmt *stmt;
1784     int count = 0;
1785 
1786     sql = "SELECT style_id FROM SE_raster_styles " "WHERE style_id = ?";
1787     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1788     if (ret != SQLITE_OK)
1789       {
1790 	  spatialite_e ("check Raster Style by ID: \"%s\"\n",
1791 			sqlite3_errmsg (sqlite));
1792 	  goto stop;
1793       }
1794     sqlite3_reset (stmt);
1795     sqlite3_clear_bindings (stmt);
1796     sqlite3_bind_int (stmt, 1, style_id);
1797     while (1)
1798       {
1799 	  /* scrolling the result set rows */
1800 	  ret = sqlite3_step (stmt);
1801 	  if (ret == SQLITE_DONE)
1802 	      break;		/* end of result set */
1803 	  if (ret == SQLITE_ROW)
1804 	      count++;
1805       }
1806     sqlite3_finalize (stmt);
1807     if (count == 1)
1808 	return 1;
1809     return 0;
1810   stop:
1811     return 0;
1812 }
1813 
1814 static int
check_raster_style_by_name(sqlite3 * sqlite,const char * style_name,sqlite3_int64 * id)1815 check_raster_style_by_name (sqlite3 * sqlite, const char *style_name,
1816 			    sqlite3_int64 * id)
1817 {
1818 /* checks if a Raster Style do actually exists - by name */
1819     int ret;
1820     const char *sql;
1821     sqlite3_stmt *stmt;
1822     int count = 0;
1823     sqlite3_int64 xid = 0;
1824 
1825     sql = "SELECT style_id FROM SE_raster_styles "
1826 	"WHERE Lower(style_name) = Lower(?)";
1827     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1828     if (ret != SQLITE_OK)
1829       {
1830 	  spatialite_e ("check Raster Style by Name: \"%s\"\n",
1831 			sqlite3_errmsg (sqlite));
1832 	  goto stop;
1833       }
1834     sqlite3_reset (stmt);
1835     sqlite3_clear_bindings (stmt);
1836     sqlite3_bind_text (stmt, 1, style_name, strlen (style_name), SQLITE_STATIC);
1837     while (1)
1838       {
1839 	  /* scrolling the result set rows */
1840 	  ret = sqlite3_step (stmt);
1841 	  if (ret == SQLITE_DONE)
1842 	      break;		/* end of result set */
1843 	  if (ret == SQLITE_ROW)
1844 	    {
1845 		xid = sqlite3_column_int64 (stmt, 0);
1846 		count++;
1847 	    }
1848       }
1849     sqlite3_finalize (stmt);
1850     if (count == 1)
1851       {
1852 	  *id = xid;
1853 	  return 1;
1854       }
1855     return 0;
1856   stop:
1857     return 0;
1858 }
1859 
1860 static int
do_reload_raster_style(sqlite3 * sqlite,sqlite3_int64 id,const unsigned char * p_blob,int n_bytes)1861 do_reload_raster_style (sqlite3 * sqlite, sqlite3_int64 id,
1862 			const unsigned char *p_blob, int n_bytes)
1863 {
1864 /* auxiliary function: reloads a Raster Style definition */
1865     int ret;
1866     const char *sql;
1867     sqlite3_stmt *stmt;
1868 
1869     if (p_blob != NULL && n_bytes > 0)
1870       {
1871 	  /* attempting to update the Raster Style */
1872 	  sql = "UPDATE SE_raster_styles SET style = ? " "WHERE style_id = ?";
1873 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1874 	  if (ret != SQLITE_OK)
1875 	    {
1876 		spatialite_e ("reloadRasterStyle: \"%s\"\n",
1877 			      sqlite3_errmsg (sqlite));
1878 		return 0;
1879 	    }
1880 	  sqlite3_reset (stmt);
1881 	  sqlite3_clear_bindings (stmt);
1882 	  sqlite3_bind_blob (stmt, 1, p_blob, n_bytes, SQLITE_STATIC);
1883 	  sqlite3_bind_int64 (stmt, 2, id);
1884 	  ret = sqlite3_step (stmt);
1885 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
1886 	      ;
1887 	  else
1888 	    {
1889 		spatialite_e ("reloadRasterStyle() error: \"%s\"\n",
1890 			      sqlite3_errmsg (sqlite));
1891 		sqlite3_finalize (stmt);
1892 		return 0;
1893 	    }
1894 	  sqlite3_finalize (stmt);
1895 	  return 1;
1896       }
1897     else
1898 	return 0;
1899 }
1900 
1901 SPATIALITE_PRIVATE int
reload_raster_style(void * p_sqlite,int style_id,const char * style_name,const unsigned char * p_blob,int n_bytes)1902 reload_raster_style (void *p_sqlite, int style_id,
1903 		     const char *style_name,
1904 		     const unsigned char *p_blob, int n_bytes)
1905 {
1906 /* auxiliary function: reloads a Raster Style definition */
1907     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
1908     sqlite3_int64 id;
1909 
1910     if (style_id >= 0)
1911       {
1912 	  /* checking if the Raster Style do actually exists */
1913 	  if (check_raster_style_by_id (sqlite, style_id))
1914 	      id = style_id;
1915 	  else
1916 	      return 0;
1917 	  /* reloading the Raster Style */
1918 	  if (raster_style_causes_duplicate_name (sqlite, id, p_blob, n_bytes))
1919 	      return 0;
1920 	  return do_reload_raster_style (sqlite, id, p_blob, n_bytes);
1921       }
1922     else if (style_name != NULL)
1923       {
1924 	  /* checking if the Raster Style do actually exists */
1925 	  if (!check_raster_style_by_name (sqlite, style_name, &id))
1926 	      return 0;
1927 	  /* reloading the Raster Style */
1928 	  if (raster_style_causes_duplicate_name (sqlite, id, p_blob, n_bytes))
1929 	      return 0;
1930 	  return do_reload_raster_style (sqlite, id, p_blob, n_bytes);
1931       }
1932     else
1933 	return 0;
1934 }
1935 
1936 static int
do_insert_raster_style_layer(sqlite3 * sqlite,const char * coverage_name,sqlite3_int64 id)1937 do_insert_raster_style_layer (sqlite3 * sqlite, const char *coverage_name,
1938 			      sqlite3_int64 id)
1939 {
1940 /* auxiliary function: really inserting a Raster Styled Layer */
1941     int ret;
1942     const char *sql;
1943     sqlite3_stmt *stmt;
1944     int retval = 0;
1945     sql = "INSERT INTO SE_raster_styled_layers "
1946 	"(coverage_name, style_id) VALUES (?, ?)";
1947     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
1948     if (ret != SQLITE_OK)
1949       {
1950 	  spatialite_e ("registerRasterStyledLayer: \"%s\"\n",
1951 			sqlite3_errmsg (sqlite));
1952 	  goto stop;
1953       }
1954     sqlite3_reset (stmt);
1955     sqlite3_clear_bindings (stmt);
1956     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
1957 		       SQLITE_STATIC);
1958     sqlite3_bind_int64 (stmt, 2, id);
1959     ret = sqlite3_step (stmt);
1960     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
1961 	retval = 1;
1962     else
1963 	spatialite_e ("registerRasterStyledLayer() error: \"%s\"\n",
1964 		      sqlite3_errmsg (sqlite));
1965     sqlite3_finalize (stmt);
1966     return retval;
1967   stop:
1968     return 0;
1969 }
1970 
1971 SPATIALITE_PRIVATE int
register_raster_styled_layer_ex(void * p_sqlite,const char * coverage_name,int style_id,const char * style_name)1972 register_raster_styled_layer_ex (void *p_sqlite, const char *coverage_name,
1973 				 int style_id, const char *style_name)
1974 {
1975 /* auxiliary function: inserts a Raster Styled Layer definition */
1976     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
1977     sqlite3_int64 id;
1978 
1979     if (coverage_name == NULL)
1980 	return 0;
1981 
1982     if (style_id >= 0)
1983       {
1984 	  /* checking if the Raster Style do actually exists */
1985 	  if (check_raster_style_by_id (sqlite, style_id))
1986 	      id = style_id;
1987 	  else
1988 	      return 0;
1989 	  /* inserting the Raster Styled Layer */
1990 	  return do_insert_raster_style_layer (sqlite, coverage_name, id);
1991       }
1992     else if (style_name != NULL)
1993       {
1994 	  /* checking if the Raster Style do actually exists */
1995 	  if (!check_raster_style_by_name (sqlite, style_name, &id))
1996 	      return 0;
1997 	  /* inserting the Raster Styled Layer */
1998 	  return do_insert_raster_style_layer (sqlite, coverage_name, id);
1999       }
2000     else
2001 	return 0;
2002 }
2003 
2004 SPATIALITE_PRIVATE int
register_raster_styled_layer(void * p_sqlite,const char * coverage_name,int style_id,const unsigned char * p_blob,int n_bytes)2005 register_raster_styled_layer (void *p_sqlite, const char *coverage_name,
2006 			      int style_id, const unsigned char *p_blob,
2007 			      int n_bytes)
2008 {
2009 /* auxiliary function: inserts a Raster Styled Layer definition - DEPRECATED */
2010     if (p_blob != NULL && n_bytes <= 0)
2011       {
2012 	  /* silencing compiler complaints */
2013 	  p_blob = NULL;
2014 	  n_bytes = 0;
2015       }
2016     return register_raster_styled_layer_ex (p_sqlite, coverage_name, style_id,
2017 					    NULL);
2018 }
2019 
2020 static int
check_raster_styled_layer_by_id(sqlite3 * sqlite,const char * coverage_name,int style_id)2021 check_raster_styled_layer_by_id (sqlite3 * sqlite, const char *coverage_name,
2022 				 int style_id)
2023 {
2024 /* checks if a Raster Styled Layer do actually exists - by ID */
2025     int ret;
2026     const char *sql;
2027     sqlite3_stmt *stmt;
2028     int count = 0;
2029 
2030     sql = "SELECT style_id FROM SE_raster_styled_layers "
2031 	"WHERE Lower(coverage_name) = Lower(?) AND style_id = ?";
2032     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2033     if (ret != SQLITE_OK)
2034       {
2035 	  spatialite_e ("check Raster Styled Layer by ID: \"%s\"\n",
2036 			sqlite3_errmsg (sqlite));
2037 	  goto stop;
2038       }
2039     sqlite3_reset (stmt);
2040     sqlite3_clear_bindings (stmt);
2041     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2042 		       SQLITE_STATIC);
2043     sqlite3_bind_int64 (stmt, 2, style_id);
2044     while (1)
2045       {
2046 	  /* scrolling the result set rows */
2047 	  ret = sqlite3_step (stmt);
2048 	  if (ret == SQLITE_DONE)
2049 	      break;		/* end of result set */
2050 	  if (ret == SQLITE_ROW)
2051 	      count++;
2052       }
2053     sqlite3_finalize (stmt);
2054     if (count == 1)
2055 	return 1;
2056     return 0;
2057   stop:
2058     return 0;
2059 }
2060 
2061 static int
check_raster_styled_layer_by_name(sqlite3 * sqlite,const char * coverage_name,const char * style_name,sqlite3_int64 * id)2062 check_raster_styled_layer_by_name (sqlite3 * sqlite, const char *coverage_name,
2063 				   const char *style_name, sqlite3_int64 * id)
2064 {
2065 /* checks if a Raster Styled Layer do actually exists - by name */
2066     int ret;
2067     const char *sql;
2068     sqlite3_stmt *stmt;
2069     int count = 0;
2070     sqlite3_int64 xid = 0;
2071 
2072     sql = "SELECT l.style_id FROM SE_raster_styled_layers AS l "
2073 	"JOIN SE_raster_styles AS s ON (l.style_id = s.style_id) "
2074 	"WHERE Lower(l.coverage_name) = Lower(?) AND "
2075 	"Lower(s.style_name) = Lower(?)";
2076     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2077     if (ret != SQLITE_OK)
2078       {
2079 	  spatialite_e ("check Raster Styled Layer by Name: \"%s\"\n",
2080 			sqlite3_errmsg (sqlite));
2081 	  goto stop;
2082       }
2083     sqlite3_reset (stmt);
2084     sqlite3_clear_bindings (stmt);
2085     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2086 		       SQLITE_STATIC);
2087     sqlite3_bind_text (stmt, 2, style_name, strlen (style_name), SQLITE_STATIC);
2088     while (1)
2089       {
2090 	  /* scrolling the result set rows */
2091 	  ret = sqlite3_step (stmt);
2092 	  if (ret == SQLITE_DONE)
2093 	      break;		/* end of result set */
2094 	  if (ret == SQLITE_ROW)
2095 	    {
2096 		xid = sqlite3_column_int64 (stmt, 0);
2097 		count++;
2098 	    }
2099       }
2100     sqlite3_finalize (stmt);
2101     if (count == 1)
2102       {
2103 	  *id = xid;
2104 	  return 1;
2105       }
2106     return 0;
2107   stop:
2108     return 0;
2109 }
2110 
2111 static int
do_delete_raster_style_layer(sqlite3 * sqlite,const char * coverage_name,sqlite3_int64 id)2112 do_delete_raster_style_layer (sqlite3 * sqlite, const char *coverage_name,
2113 			      sqlite3_int64 id)
2114 {
2115 /* auxiliary function: really deleting a Raster Styled Layer */
2116     int ret;
2117     const char *sql;
2118     sqlite3_stmt *stmt;
2119     int retval = 0;
2120     sql = "DELETE FROM SE_raster_styled_layers "
2121 	"WHERE Lower(coverage_name) = Lower(?) AND " "style_id = ?";
2122     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2123     if (ret != SQLITE_OK)
2124       {
2125 	  spatialite_e ("unregisterRasterStyledLayer: \"%s\"\n",
2126 			sqlite3_errmsg (sqlite));
2127 	  goto stop;
2128       }
2129     sqlite3_reset (stmt);
2130     sqlite3_clear_bindings (stmt);
2131     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2132 		       SQLITE_STATIC);
2133     sqlite3_bind_int64 (stmt, 2, id);
2134     ret = sqlite3_step (stmt);
2135     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
2136 	retval = 1;
2137     else
2138 	spatialite_e ("unregisterRasterStyledLayer() error: \"%s\"\n",
2139 		      sqlite3_errmsg (sqlite));
2140     sqlite3_finalize (stmt);
2141     return retval;
2142   stop:
2143     return 0;
2144 }
2145 
2146 SPATIALITE_PRIVATE int
unregister_raster_styled_layer(void * p_sqlite,const char * coverage_name,int style_id,const char * style_name)2147 unregister_raster_styled_layer (void *p_sqlite, const char *coverage_name,
2148 				int style_id, const char *style_name)
2149 {
2150 /* auxiliary function: removes a Raster Styled Layer definition */
2151     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
2152     sqlite3_int64 id;
2153 
2154     if (coverage_name == NULL)
2155 	return 0;
2156 
2157     if (style_id >= 0)
2158       {
2159 	  /* checking if the Raster Styled Layer do actually exists */
2160 	  if (check_raster_styled_layer_by_id (sqlite, coverage_name, style_id))
2161 	      id = style_id;
2162 	  else
2163 	      return 0;
2164 	  /* removing the Raster Styled Layer */
2165 	  return do_delete_raster_style_layer (sqlite, coverage_name, id);
2166       }
2167     else if (style_name != NULL)
2168       {
2169 	  /* checking if the Raster Styled Layer do actually exists */
2170 	  if (!check_raster_styled_layer_by_name
2171 	      (sqlite, coverage_name, style_name, &id))
2172 	      return 0;
2173 	  /* removing the Raster Styled Layer */
2174 	  return do_delete_raster_style_layer (sqlite, coverage_name, id);
2175       }
2176     else
2177 	return 0;
2178 }
2179 
2180 SPATIALITE_PRIVATE int
register_vector_coverage(void * p_sqlite,const char * coverage_name,const char * f_table_name,const char * f_geometry_column,const char * title,const char * abstract,int is_queryable,int is_editable)2181 register_vector_coverage (void *p_sqlite, const char *coverage_name,
2182 			  const char *f_table_name,
2183 			  const char *f_geometry_column, const char *title,
2184 			  const char *abstract, int is_queryable,
2185 			  int is_editable)
2186 {
2187 /* auxiliary function: inserts a Vector Coverage definition */
2188     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
2189     int ret;
2190     const char *sql;
2191     sqlite3_stmt *stmt;
2192 
2193     if (coverage_name != NULL && f_table_name != NULL
2194 	&& f_geometry_column != NULL && title != NULL && abstract != NULL)
2195       {
2196 	  /* attempting to insert the Vector Coverage */
2197 	  sql = "INSERT INTO vector_coverages "
2198 	      "(coverage_name, f_table_name, f_geometry_column, title, "
2199 	      "abstract, is_queryable, is_editable) VALUES "
2200 	      "(Lower(?), Lower(?), Lower(?), ?, ?, ?, ?)";
2201 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2202 	  if (ret != SQLITE_OK)
2203 	    {
2204 		spatialite_e ("registerVectorCoverage: \"%s\"\n",
2205 			      sqlite3_errmsg (sqlite));
2206 		return 0;
2207 	    }
2208 	  sqlite3_reset (stmt);
2209 	  sqlite3_clear_bindings (stmt);
2210 	  sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2211 			     SQLITE_STATIC);
2212 	  sqlite3_bind_text (stmt, 2, f_table_name, strlen (f_table_name),
2213 			     SQLITE_STATIC);
2214 	  sqlite3_bind_text (stmt, 3, f_geometry_column,
2215 			     strlen (f_geometry_column), SQLITE_STATIC);
2216 	  sqlite3_bind_text (stmt, 4, title, strlen (title), SQLITE_STATIC);
2217 	  sqlite3_bind_text (stmt, 5, abstract, strlen (abstract),
2218 			     SQLITE_STATIC);
2219 	  if (is_queryable)
2220 	      is_queryable = 1;
2221 	  if (is_editable)
2222 	      is_editable = 1;
2223 	  sqlite3_bind_int (stmt, 6, is_queryable);
2224 	  sqlite3_bind_int (stmt, 7, is_editable);
2225 	  ret = sqlite3_step (stmt);
2226 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
2227 	      ;
2228 	  else
2229 	    {
2230 		spatialite_e ("registerVectorCoverage() error: \"%s\"\n",
2231 			      sqlite3_errmsg (sqlite));
2232 		sqlite3_finalize (stmt);
2233 		return 0;
2234 	    }
2235 	  sqlite3_finalize (stmt);
2236 	  return 1;
2237       }
2238     else if (coverage_name != NULL && f_table_name != NULL
2239 	     && f_geometry_column != NULL)
2240       {
2241 	  /* attempting to insert the Vector Coverage */
2242 	  sql = "INSERT INTO vector_coverages "
2243 	      "(coverage_name, f_table_name, f_geometry_column, "
2244 	      "is_queryable, is_editable) VALUES "
2245 	      "(Lower(?), Lower(?), Lower(?), ?, ?)";
2246 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2247 	  if (ret != SQLITE_OK)
2248 	    {
2249 		spatialite_e ("registerVectorCoverage: \"%s\"\n",
2250 			      sqlite3_errmsg (sqlite));
2251 		return 0;
2252 	    }
2253 	  sqlite3_reset (stmt);
2254 	  sqlite3_clear_bindings (stmt);
2255 	  sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2256 			     SQLITE_STATIC);
2257 	  sqlite3_bind_text (stmt, 2, f_table_name, strlen (f_table_name),
2258 			     SQLITE_STATIC);
2259 	  sqlite3_bind_text (stmt, 3, f_geometry_column,
2260 			     strlen (f_geometry_column), SQLITE_STATIC);
2261 	  if (is_queryable)
2262 	      is_queryable = 1;
2263 	  if (is_editable)
2264 	      is_editable = 1;
2265 	  sqlite3_bind_int (stmt, 4, is_queryable);
2266 	  sqlite3_bind_int (stmt, 5, is_editable);
2267 	  ret = sqlite3_step (stmt);
2268 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
2269 	      ;
2270 	  else
2271 	    {
2272 		spatialite_e ("registerVectorCoverage() error: \"%s\"\n",
2273 			      sqlite3_errmsg (sqlite));
2274 		sqlite3_finalize (stmt);
2275 		return 0;
2276 	    }
2277 	  sqlite3_finalize (stmt);
2278 	  return 1;
2279       }
2280     else
2281 	return 0;
2282 }
2283 
2284 SPATIALITE_PRIVATE int
register_spatial_view_coverage(void * p_sqlite,const char * coverage_name,const char * view_name,const char * view_geometry,const char * title,const char * abstract,int is_queryable,int is_editable)2285 register_spatial_view_coverage (void *p_sqlite, const char *coverage_name,
2286 				const char *view_name,
2287 				const char *view_geometry, const char *title,
2288 				const char *abstract, int is_queryable,
2289 				int is_editable)
2290 {
2291 /* auxiliary function: inserts a Spatial View Coverage definition */
2292     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
2293     int ret;
2294     const char *sql;
2295     sqlite3_stmt *stmt;
2296 
2297     if (coverage_name != NULL && view_name != NULL
2298 	&& view_geometry != NULL && title != NULL && abstract != NULL)
2299       {
2300 	  /* attempting to insert the Vector Coverage */
2301 	  sql = "INSERT INTO vector_coverages "
2302 	      "(coverage_name, view_name, view_geometry, title, "
2303 	      "abstract, is_queryable, is_editable) VALUES "
2304 	      "(Lower(?), Lower(?), Lower(?), ?, ?, ?, ?)";
2305 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2306 	  if (ret != SQLITE_OK)
2307 	    {
2308 		spatialite_e ("registerVectorCoverage: \"%s\"\n",
2309 			      sqlite3_errmsg (sqlite));
2310 		return 0;
2311 	    }
2312 	  sqlite3_reset (stmt);
2313 	  sqlite3_clear_bindings (stmt);
2314 	  sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2315 			     SQLITE_STATIC);
2316 	  sqlite3_bind_text (stmt, 2, view_name, strlen (view_name),
2317 			     SQLITE_STATIC);
2318 	  sqlite3_bind_text (stmt, 3, view_geometry,
2319 			     strlen (view_geometry), SQLITE_STATIC);
2320 	  sqlite3_bind_text (stmt, 4, title, strlen (title), SQLITE_STATIC);
2321 	  sqlite3_bind_text (stmt, 5, abstract, strlen (abstract),
2322 			     SQLITE_STATIC);
2323 	  if (is_queryable)
2324 	      is_queryable = 1;
2325 	  if (is_editable)
2326 	      is_editable = 1;
2327 	  sqlite3_bind_int (stmt, 6, is_queryable);
2328 	  sqlite3_bind_int (stmt, 7, is_editable);
2329 	  ret = sqlite3_step (stmt);
2330 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
2331 	      ;
2332 	  else
2333 	    {
2334 		spatialite_e ("registerVectorCoverage() error: \"%s\"\n",
2335 			      sqlite3_errmsg (sqlite));
2336 		sqlite3_finalize (stmt);
2337 		return 0;
2338 	    }
2339 	  sqlite3_finalize (stmt);
2340 	  return 1;
2341       }
2342     else if (coverage_name != NULL && view_name != NULL
2343 	     && view_geometry != NULL)
2344       {
2345 	  /* attempting to insert the Spatial View Coverage */
2346 	  sql = "INSERT INTO vector_coverages "
2347 	      "(coverage_name, view_name, view_geometry, "
2348 	      "is_queryable, is_editable) VALUES "
2349 	      "(Lower(?), Lower(?), Lower(?), ?, ?)";
2350 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2351 	  if (ret != SQLITE_OK)
2352 	    {
2353 		spatialite_e ("registerVectorCoverage: \"%s\"\n",
2354 			      sqlite3_errmsg (sqlite));
2355 		return 0;
2356 	    }
2357 	  sqlite3_reset (stmt);
2358 	  sqlite3_clear_bindings (stmt);
2359 	  sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2360 			     SQLITE_STATIC);
2361 	  sqlite3_bind_text (stmt, 2, view_name, strlen (view_name),
2362 			     SQLITE_STATIC);
2363 	  sqlite3_bind_text (stmt, 3, view_geometry,
2364 			     strlen (view_geometry), SQLITE_STATIC);
2365 	  if (is_queryable)
2366 	      is_queryable = 1;
2367 	  if (is_editable)
2368 	      is_editable = 1;
2369 	  sqlite3_bind_int (stmt, 4, is_queryable);
2370 	  sqlite3_bind_int (stmt, 5, is_editable);
2371 	  ret = sqlite3_step (stmt);
2372 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
2373 	      ;
2374 	  else
2375 	    {
2376 		spatialite_e ("registerVectorCoverage() error: \"%s\"\n",
2377 			      sqlite3_errmsg (sqlite));
2378 		sqlite3_finalize (stmt);
2379 		return 0;
2380 	    }
2381 	  sqlite3_finalize (stmt);
2382 	  return 1;
2383       }
2384     else
2385 	return 0;
2386 }
2387 
2388 SPATIALITE_PRIVATE int
register_virtual_table_coverage(void * p_sqlite,const char * coverage_name,const char * virt_name,const char * virt_geometry,const char * title,const char * abstract,int is_queryable)2389 register_virtual_table_coverage (void *p_sqlite, const char *coverage_name,
2390 				 const char *virt_name,
2391 				 const char *virt_geometry, const char *title,
2392 				 const char *abstract, int is_queryable)
2393 {
2394 /* auxiliary function: inserts a VirtualTable Coverage definition */
2395     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
2396     int ret;
2397     const char *sql;
2398     sqlite3_stmt *stmt;
2399 
2400     if (coverage_name != NULL && virt_name != NULL
2401 	&& virt_geometry != NULL && title != NULL && abstract != NULL)
2402       {
2403 	  /* attempting to insert the Vector Coverage */
2404 	  sql = "INSERT INTO vector_coverages "
2405 	      "(coverage_name, virt_name, virt_geometry, title, "
2406 	      "abstract, is_queryable, is_editable) VALUES "
2407 	      "(Lower(?), Lower(?), Lower(?), ?, ?, ?, ?)";
2408 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2409 	  if (ret != SQLITE_OK)
2410 	    {
2411 		spatialite_e ("registerVectorCoverage: \"%s\"\n",
2412 			      sqlite3_errmsg (sqlite));
2413 		return 0;
2414 	    }
2415 	  sqlite3_reset (stmt);
2416 	  sqlite3_clear_bindings (stmt);
2417 	  sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2418 			     SQLITE_STATIC);
2419 	  sqlite3_bind_text (stmt, 2, virt_name, strlen (virt_name),
2420 			     SQLITE_STATIC);
2421 	  sqlite3_bind_text (stmt, 3, virt_geometry,
2422 			     strlen (virt_geometry), SQLITE_STATIC);
2423 	  sqlite3_bind_text (stmt, 4, title, strlen (title), SQLITE_STATIC);
2424 	  sqlite3_bind_text (stmt, 5, abstract, strlen (abstract),
2425 			     SQLITE_STATIC);
2426 	  if (is_queryable)
2427 	      is_queryable = 1;
2428 	  sqlite3_bind_int (stmt, 6, is_queryable);
2429 	  sqlite3_bind_int (stmt, 7, 0);
2430 	  ret = sqlite3_step (stmt);
2431 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
2432 	      ;
2433 	  else
2434 	    {
2435 		spatialite_e ("registerVectorCoverage() error: \"%s\"\n",
2436 			      sqlite3_errmsg (sqlite));
2437 		sqlite3_finalize (stmt);
2438 		return 0;
2439 	    }
2440 	  sqlite3_finalize (stmt);
2441 	  return 1;
2442       }
2443     else if (coverage_name != NULL && virt_name != NULL
2444 	     && virt_geometry != NULL)
2445       {
2446 	  /* attempting to insert the VirtualTable Coverage */
2447 	  sql = "INSERT INTO vector_coverages "
2448 	      "(coverage_name, virt_name, virt_geometry, "
2449 	      "is_queryable, is_editable) VALUES "
2450 	      "(Lower(?), Lower(?), Lower(?), ?, ?)";
2451 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2452 	  if (ret != SQLITE_OK)
2453 	    {
2454 		spatialite_e ("registerVectorCoverage: \"%s\"\n",
2455 			      sqlite3_errmsg (sqlite));
2456 		return 0;
2457 	    }
2458 	  sqlite3_reset (stmt);
2459 	  sqlite3_clear_bindings (stmt);
2460 	  sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2461 			     SQLITE_STATIC);
2462 	  sqlite3_bind_text (stmt, 2, virt_name, strlen (virt_name),
2463 			     SQLITE_STATIC);
2464 	  sqlite3_bind_text (stmt, 3, virt_geometry,
2465 			     strlen (virt_geometry), SQLITE_STATIC);
2466 	  if (is_queryable)
2467 	      is_queryable = 1;
2468 	  sqlite3_bind_int (stmt, 4, is_queryable);
2469 	  sqlite3_bind_int (stmt, 5, 0);
2470 	  ret = sqlite3_step (stmt);
2471 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
2472 	      ;
2473 	  else
2474 	    {
2475 		spatialite_e ("registerVectorCoverage() error: \"%s\"\n",
2476 			      sqlite3_errmsg (sqlite));
2477 		sqlite3_finalize (stmt);
2478 		return 0;
2479 	    }
2480 	  sqlite3_finalize (stmt);
2481 	  return 1;
2482       }
2483     else
2484 	return 0;
2485 }
2486 
2487 SPATIALITE_PRIVATE int
register_topogeo_coverage(void * p_sqlite,const char * coverage_name,const char * topogeo_name,const char * title,const char * abstract,int is_queryable,int is_editable)2488 register_topogeo_coverage (void *p_sqlite, const char *coverage_name,
2489 			   const char *topogeo_name, const char *title,
2490 			   const char *abstract, int is_queryable,
2491 			   int is_editable)
2492 {
2493 /* auxiliary function: inserts a Vector Coverage definition
2494  * based on some Topology-Geometry */
2495     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
2496     int ret;
2497     const char *sql;
2498     char *xsql;
2499     int i;
2500     char **results;
2501     int rows;
2502     int columns;
2503     char *errMsg = NULL;
2504     char *f_table_name = NULL;
2505     char *f_geometry_column = NULL;
2506     sqlite3_stmt *stmt;
2507 
2508     if (topogeo_name == NULL)
2509 	return 0;
2510 
2511 /* testing if the Topology-Geometry do really exist */
2512     xsql = sqlite3_mprintf ("SELECT topology_name "
2513 			    "FROM topologies WHERE Lower(topology_name) = %Q",
2514 			    topogeo_name);
2515     ret = sqlite3_get_table (sqlite, xsql, &results, &rows, &columns, &errMsg);
2516     sqlite3_free (xsql);
2517     if (ret != SQLITE_OK)
2518       {
2519 	  sqlite3_free (errMsg);
2520 	  return 0;
2521       }
2522     for (i = 1; i <= rows; i++)
2523       {
2524 	  const char *value = results[(i * columns) + 0];
2525 	  if (f_table_name != NULL)
2526 	      sqlite3_free (f_table_name);
2527 	  if (f_geometry_column != NULL)
2528 	      sqlite3_free (f_geometry_column);
2529 	  f_table_name = sqlite3_mprintf ("%s_edge", value);
2530 	  f_geometry_column = sqlite3_mprintf ("geom");
2531       }
2532     sqlite3_free_table (results);
2533 
2534     if (coverage_name != NULL && f_table_name != NULL
2535 	&& f_geometry_column != NULL && title != NULL && abstract != NULL)
2536       {
2537 	  /* attempting to insert the Vector Coverage */
2538 	  sql = "INSERT INTO vector_coverages "
2539 	      "(coverage_name, f_table_name, f_geometry_column, "
2540 	      "topology_name, title, abstract, is_queryable, is_editable) VALUES "
2541 	      "(Lower(?), Lower(?), Lower(?), Lower(?), ?, ?, ?, ?)";
2542 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2543 	  if (ret != SQLITE_OK)
2544 	    {
2545 		spatialite_e ("registerTopoGeoCoverage: \"%s\"\n",
2546 			      sqlite3_errmsg (sqlite));
2547 		return 0;
2548 	    }
2549 	  sqlite3_reset (stmt);
2550 	  sqlite3_clear_bindings (stmt);
2551 	  sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2552 			     SQLITE_STATIC);
2553 	  sqlite3_bind_text (stmt, 2, f_table_name, strlen (f_table_name),
2554 			     sqlite3_free);
2555 	  sqlite3_bind_text (stmt, 3, f_geometry_column,
2556 			     strlen (f_geometry_column), sqlite3_free);
2557 	  sqlite3_bind_text (stmt, 4, topogeo_name, strlen (topogeo_name),
2558 			     SQLITE_STATIC);
2559 	  sqlite3_bind_text (stmt, 5, title, strlen (title), SQLITE_STATIC);
2560 	  sqlite3_bind_text (stmt, 6, abstract, strlen (abstract),
2561 			     SQLITE_STATIC);
2562 	  if (is_queryable)
2563 	      is_queryable = 1;
2564 	  if (is_editable)
2565 	      is_editable = 1;
2566 	  sqlite3_bind_int (stmt, 7, is_queryable);
2567 	  sqlite3_bind_int (stmt, 8, is_editable);
2568 	  ret = sqlite3_step (stmt);
2569 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
2570 	      ;
2571 	  else
2572 	    {
2573 		spatialite_e ("registerTopoGeoCoverage() error: \"%s\"\n",
2574 			      sqlite3_errmsg (sqlite));
2575 		sqlite3_finalize (stmt);
2576 		return 0;
2577 	    }
2578 	  sqlite3_finalize (stmt);
2579 	  return 1;
2580       }
2581     else if (coverage_name != NULL && f_table_name != NULL
2582 	     && f_geometry_column != NULL)
2583       {
2584 	  /* attempting to insert the Vector Coverage */
2585 	  sql = "INSERT INTO vector_coverages "
2586 	      "(coverage_name, f_table_name, f_geometry_column, "
2587 	      "topology_name, is_queryable, is_editable) VALUES "
2588 	      "(Lower(?), Lower(?), Lower(?), Lower(?), ?, ?)";
2589 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2590 	  if (ret != SQLITE_OK)
2591 	    {
2592 		spatialite_e ("registerTopoGeoCoverage: \"%s\"\n",
2593 			      sqlite3_errmsg (sqlite));
2594 		return 0;
2595 	    }
2596 	  sqlite3_reset (stmt);
2597 	  sqlite3_clear_bindings (stmt);
2598 	  sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2599 			     SQLITE_STATIC);
2600 	  sqlite3_bind_text (stmt, 2, f_table_name, strlen (f_table_name),
2601 			     sqlite3_free);
2602 	  sqlite3_bind_text (stmt, 3, f_geometry_column,
2603 			     strlen (f_geometry_column), sqlite3_free);
2604 	  sqlite3_bind_text (stmt, 4, topogeo_name, strlen (topogeo_name),
2605 			     SQLITE_STATIC);
2606 	  sqlite3_bind_int (stmt, 5, is_queryable);
2607 	  sqlite3_bind_int (stmt, 6, is_editable);
2608 	  ret = sqlite3_step (stmt);
2609 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
2610 	      ;
2611 	  else
2612 	    {
2613 		spatialite_e ("registerTopoGeoCoverage() error: \"%s\"\n",
2614 			      sqlite3_errmsg (sqlite));
2615 		sqlite3_finalize (stmt);
2616 		return 0;
2617 	    }
2618 	  sqlite3_finalize (stmt);
2619 	  return 1;
2620       }
2621     else
2622       {
2623 	  if (f_table_name != NULL)
2624 	      sqlite3_free (f_table_name);
2625 	  if (f_geometry_column != NULL)
2626 	      sqlite3_free (f_geometry_column);
2627 	  return 0;
2628       }
2629 }
2630 
2631 SPATIALITE_PRIVATE int
register_toponet_coverage(void * p_sqlite,const char * coverage_name,const char * toponet_name,const char * title,const char * abstract,int is_queryable,int is_editable)2632 register_toponet_coverage (void *p_sqlite, const char *coverage_name,
2633 			   const char *toponet_name, const char *title,
2634 			   const char *abstract, int is_queryable,
2635 			   int is_editable)
2636 {
2637 /* auxiliary function: inserts a Vector Coverage definition
2638  * based on some Topology-Network */
2639     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
2640     int ret;
2641     const char *sql;
2642     char *xsql;
2643     int i;
2644     char **results;
2645     int rows;
2646     int columns;
2647     char *errMsg = NULL;
2648     char *f_table_name = NULL;
2649     char *f_geometry_column = NULL;
2650     sqlite3_stmt *stmt;
2651 
2652     if (toponet_name == NULL)
2653 	return 0;
2654 
2655 /* testing if the Topology-Network do really exist */
2656     xsql = sqlite3_mprintf ("SELECT network_name "
2657 			    "FROM networks WHERE Lower(network_name) = %Q",
2658 			    toponet_name);
2659     ret = sqlite3_get_table (sqlite, xsql, &results, &rows, &columns, &errMsg);
2660     sqlite3_free (xsql);
2661     if (ret != SQLITE_OK)
2662       {
2663 	  sqlite3_free (errMsg);
2664 	  return 0;
2665       }
2666     for (i = 1; i <= rows; i++)
2667       {
2668 	  const char *value = results[(i * columns) + 0];
2669 	  if (f_table_name != NULL)
2670 	      sqlite3_free (f_table_name);
2671 	  if (f_geometry_column != NULL)
2672 	      sqlite3_free (f_geometry_column);
2673 	  f_table_name = sqlite3_mprintf ("%s_link", value);
2674 	  f_geometry_column = sqlite3_mprintf ("geometry");
2675       }
2676     sqlite3_free_table (results);
2677 
2678     if (coverage_name != NULL && f_table_name != NULL
2679 	&& f_geometry_column != NULL && title != NULL && abstract != NULL)
2680       {
2681 	  /* attempting to insert the Vector Coverage */
2682 	  sql = "INSERT INTO vector_coverages "
2683 	      "(coverage_name, f_table_name, f_geometry_column, "
2684 	      "network_name, title, abstract, is_queryable, is_editable) VALUES "
2685 	      "(Lower(?), Lower(?), Lower(?), Lower(?), ?, ?, ?, ?)";
2686 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2687 	  if (ret != SQLITE_OK)
2688 	    {
2689 		spatialite_e ("registerTopoNetCoverage: \"%s\"\n",
2690 			      sqlite3_errmsg (sqlite));
2691 		return 0;
2692 	    }
2693 	  sqlite3_reset (stmt);
2694 	  sqlite3_clear_bindings (stmt);
2695 	  sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2696 			     SQLITE_STATIC);
2697 	  sqlite3_bind_text (stmt, 2, f_table_name, strlen (f_table_name),
2698 			     sqlite3_free);
2699 	  sqlite3_bind_text (stmt, 3, f_geometry_column,
2700 			     strlen (f_geometry_column), sqlite3_free);
2701 	  sqlite3_bind_text (stmt, 4, toponet_name, strlen (toponet_name),
2702 			     SQLITE_STATIC);
2703 	  sqlite3_bind_text (stmt, 5, title, strlen (title), SQLITE_STATIC);
2704 	  sqlite3_bind_text (stmt, 6, abstract, strlen (abstract),
2705 			     SQLITE_STATIC);
2706 	  if (is_queryable)
2707 	      is_queryable = 1;
2708 	  if (is_editable)
2709 	      is_editable = 1;
2710 	  sqlite3_bind_int (stmt, 7, is_queryable);
2711 	  sqlite3_bind_int (stmt, 8, is_editable);
2712 	  ret = sqlite3_step (stmt);
2713 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
2714 	      ;
2715 	  else
2716 	    {
2717 		spatialite_e ("registerTopoNetCoverage() error: \"%s\"\n",
2718 			      sqlite3_errmsg (sqlite));
2719 		sqlite3_finalize (stmt);
2720 		return 0;
2721 	    }
2722 	  sqlite3_finalize (stmt);
2723 	  return 1;
2724       }
2725     else if (coverage_name != NULL && f_table_name != NULL
2726 	     && f_geometry_column != NULL)
2727       {
2728 	  /* attempting to insert the Vector Coverage */
2729 	  sql = "INSERT INTO vector_coverages "
2730 	      "(coverage_name, f_table_name, f_geometry_column, "
2731 	      "network_name, is_queryable, is_editable) VALUES "
2732 	      "(Lower(?), Lower(?), Lower(?), Lower(?), ?, ?)";
2733 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2734 	  if (ret != SQLITE_OK)
2735 	    {
2736 		spatialite_e ("registerTopoNetCoverage: \"%s\"\n",
2737 			      sqlite3_errmsg (sqlite));
2738 		return 0;
2739 	    }
2740 	  sqlite3_reset (stmt);
2741 	  sqlite3_clear_bindings (stmt);
2742 	  sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2743 			     SQLITE_STATIC);
2744 	  sqlite3_bind_text (stmt, 2, f_table_name, strlen (f_table_name),
2745 			     sqlite3_free);
2746 	  sqlite3_bind_text (stmt, 3, f_geometry_column,
2747 			     strlen (f_geometry_column), sqlite3_free);
2748 	  sqlite3_bind_text (stmt, 4, toponet_name, strlen (toponet_name),
2749 			     SQLITE_STATIC);
2750 	  sqlite3_bind_int (stmt, 5, is_queryable);
2751 	  sqlite3_bind_int (stmt, 6, is_editable);
2752 	  ret = sqlite3_step (stmt);
2753 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
2754 	      ;
2755 	  else
2756 	    {
2757 		spatialite_e ("registerTopoNetCoverage() error: \"%s\"\n",
2758 			      sqlite3_errmsg (sqlite));
2759 		sqlite3_finalize (stmt);
2760 		return 0;
2761 	    }
2762 	  sqlite3_finalize (stmt);
2763 	  return 1;
2764       }
2765     else
2766       {
2767 	  if (f_table_name != NULL)
2768 	      sqlite3_free (f_table_name);
2769 	  if (f_geometry_column != NULL)
2770 	      sqlite3_free (f_geometry_column);
2771 	  return 0;
2772       }
2773 }
2774 
2775 static int
check_vector_coverage(sqlite3 * sqlite,const char * coverage_name)2776 check_vector_coverage (sqlite3 * sqlite, const char *coverage_name)
2777 {
2778 /* checks if a Vector Coverage do actually exists */
2779     int ret;
2780     const char *sql;
2781     sqlite3_stmt *stmt;
2782     int count = 0;
2783 
2784     sql = "SELECT coverage_name FROM vector_coverages "
2785 	"WHERE Lower(coverage_name) = Lower(?)";
2786     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2787     if (ret != SQLITE_OK)
2788       {
2789 	  spatialite_e ("check Vector Coverage: \"%s\"\n",
2790 			sqlite3_errmsg (sqlite));
2791 	  goto stop;
2792       }
2793     sqlite3_reset (stmt);
2794     sqlite3_clear_bindings (stmt);
2795     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2796 		       SQLITE_STATIC);
2797     while (1)
2798       {
2799 	  /* scrolling the result set rows */
2800 	  ret = sqlite3_step (stmt);
2801 	  if (ret == SQLITE_DONE)
2802 	      break;		/* end of result set */
2803 	  if (ret == SQLITE_ROW)
2804 	      count++;
2805       }
2806     sqlite3_finalize (stmt);
2807     if (count == 1)
2808 	return 1;
2809     return 0;
2810   stop:
2811     return 0;
2812 }
2813 
2814 static void
do_delete_vector_coverage_srid(sqlite3 * sqlite,const char * coverage_name,int srid)2815 do_delete_vector_coverage_srid (sqlite3 * sqlite, const char *coverage_name,
2816 				int srid)
2817 {
2818 /* auxiliary function: deleting a Vector Coverage alternative SRID */
2819     int ret;
2820     const char *sql;
2821     sqlite3_stmt *stmt;
2822 
2823     if (srid < 0)
2824 	sql = "DELETE FROM vector_coverages_srid "
2825 	    "WHERE Lower(coverage_name) = Lower(?)";
2826     else
2827 	sql = "DELETE FROM vector_coverages_srid "
2828 	    "WHERE Lower(coverage_name) = Lower(?) AND srid = ?";
2829     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2830     if (ret != SQLITE_OK)
2831       {
2832 	  spatialite_e ("unregisterVectorCoverageSrid: \"%s\"\n",
2833 			sqlite3_errmsg (sqlite));
2834 	  return;
2835       }
2836     sqlite3_reset (stmt);
2837     sqlite3_clear_bindings (stmt);
2838     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2839 		       SQLITE_STATIC);
2840     if (srid >= 0)
2841 	sqlite3_bind_int (stmt, 2, srid);
2842     ret = sqlite3_step (stmt);
2843     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
2844 	;
2845     else
2846 	spatialite_e ("unregisterVectorCoverageSrid() error: \"%s\"\n",
2847 		      sqlite3_errmsg (sqlite));
2848     sqlite3_finalize (stmt);
2849 }
2850 
2851 static void
do_delete_vector_coverage_keyword(sqlite3 * sqlite,const char * coverage_name,const char * keyword)2852 do_delete_vector_coverage_keyword (sqlite3 * sqlite, const char *coverage_name,
2853 				   const char *keyword)
2854 {
2855 /* auxiliary function: deleting an Vector Coverage Keyword */
2856     int ret;
2857     const char *sql;
2858     sqlite3_stmt *stmt;
2859 
2860     if (keyword == NULL)
2861 	sql = "DELETE FROM vector_coverages_keyword "
2862 	    "WHERE Lower(coverage_name) = Lower(?)";
2863     else
2864 	sql = "DELETE FROM vector_coverages_keyword "
2865 	    "WHERE Lower(coverage_name) = Lower(?) AND Lower(keyword) = Lower(?)";
2866     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2867     if (ret != SQLITE_OK)
2868       {
2869 	  spatialite_e ("unregisterVectorCoverageKeyword: \"%s\"\n",
2870 			sqlite3_errmsg (sqlite));
2871 	  return;
2872       }
2873     sqlite3_reset (stmt);
2874     sqlite3_clear_bindings (stmt);
2875     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2876 		       SQLITE_STATIC);
2877     if (keyword != NULL)
2878 	sqlite3_bind_text (stmt, 2, keyword, strlen (keyword), SQLITE_STATIC);
2879     ret = sqlite3_step (stmt);
2880     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
2881 	;
2882     else
2883 	spatialite_e ("unregisterVectorCoverageKeyword() error: \"%s\"\n",
2884 		      sqlite3_errmsg (sqlite));
2885     sqlite3_finalize (stmt);
2886 }
2887 
2888 static void
do_delete_vector_coverage_styled_layers(sqlite3 * sqlite,const char * coverage_name)2889 do_delete_vector_coverage_styled_layers (sqlite3 * sqlite,
2890 					 const char *coverage_name)
2891 {
2892 /* auxiliary function: deleting all Vector Coverage Styled references */
2893     int ret;
2894     const char *sql;
2895     sqlite3_stmt *stmt;
2896     sql = "DELETE FROM SE_vector_styled_layers WHERE coverage_name = ?";
2897     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2898     if (ret != SQLITE_OK)
2899       {
2900 	  spatialite_e ("unregisterVectorCoverageStyles: \"%s\"\n",
2901 			sqlite3_errmsg (sqlite));
2902 	  return;
2903       }
2904     sqlite3_reset (stmt);
2905     sqlite3_clear_bindings (stmt);
2906     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2907 		       SQLITE_STATIC);
2908     ret = sqlite3_step (stmt);
2909     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
2910 	;
2911     else
2912 	spatialite_e ("unregisterVectorCoverageStyles() error: \"%s\"\n",
2913 		      sqlite3_errmsg (sqlite));
2914     sqlite3_finalize (stmt);
2915 }
2916 
2917 static int
do_delete_vector_coverage(sqlite3 * sqlite,const char * coverage_name)2918 do_delete_vector_coverage (sqlite3 * sqlite, const char *coverage_name)
2919 {
2920 /* auxiliary function: deleting a Vector Coverage */
2921     int ret;
2922     const char *sql;
2923     sqlite3_stmt *stmt;
2924     int retval = 0;
2925     sql = "DELETE FROM vector_coverages "
2926 	"WHERE Lower(coverage_name) = Lower(?)";
2927     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2928     if (ret != SQLITE_OK)
2929       {
2930 	  spatialite_e ("unregisterVectorCoverage: \"%s\"\n",
2931 			sqlite3_errmsg (sqlite));
2932 	  goto stop;
2933       }
2934     sqlite3_reset (stmt);
2935     sqlite3_clear_bindings (stmt);
2936     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
2937 		       SQLITE_STATIC);
2938     ret = sqlite3_step (stmt);
2939     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
2940 	retval = 1;
2941     else
2942 	spatialite_e ("unregisterVectorCoverage() error: \"%s\"\n",
2943 		      sqlite3_errmsg (sqlite));
2944     sqlite3_finalize (stmt);
2945     return retval;
2946   stop:
2947     return 0;
2948 }
2949 
2950 SPATIALITE_PRIVATE int
unregister_vector_coverage(void * p_sqlite,const char * coverage_name)2951 unregister_vector_coverage (void *p_sqlite, const char *coverage_name)
2952 {
2953 /* auxiliary function: deletes a Vector Coverage definition (and any related) */
2954     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
2955 
2956     if (coverage_name == NULL)
2957 	return 0;
2958 
2959     /* checking if the Vector Coverage do actually exists */
2960     if (!check_vector_coverage (sqlite, coverage_name))
2961 	return 0;
2962     /* deleting all alternative SRIDs */
2963     do_delete_vector_coverage_srid (sqlite, coverage_name, -1);
2964     /* deleting all Keywords */
2965     do_delete_vector_coverage_keyword (sqlite, coverage_name, NULL);
2966     /* deleting all Styled Layers */
2967     do_delete_vector_coverage_styled_layers (sqlite, coverage_name);
2968     /* deleting the Vector Coverage itself */
2969     return do_delete_vector_coverage (sqlite, coverage_name);
2970 }
2971 
2972 SPATIALITE_PRIVATE int
set_vector_coverage_infos(void * p_sqlite,const char * coverage_name,const char * title,const char * abstract,int is_queryable,int is_editable)2973 set_vector_coverage_infos (void *p_sqlite, const char *coverage_name,
2974 			   const char *title, const char *abstract,
2975 			   int is_queryable, int is_editable)
2976 {
2977 /* auxiliary function: updates the descriptive infos supporting a Vector Coverage */
2978     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
2979     int ret;
2980     const char *sql;
2981     sqlite3_stmt *stmt;
2982     int prev_changes;
2983     int curr_changes;
2984 
2985     if (coverage_name != NULL && title != NULL && abstract != NULL)
2986       {
2987 	  prev_changes = sqlite3_total_changes (sqlite);
2988 
2989 	  /* attempting to update the Vector Coverage */
2990 	  if (is_queryable < 0 || is_editable < 0)
2991 	    {
2992 		sql = "UPDATE vector_coverages SET title = ?, abstract = ? "
2993 		    "WHERE Lower(coverage_name) = Lower(?)";
2994 		ret =
2995 		    sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
2996 		if (ret != SQLITE_OK)
2997 		  {
2998 		      spatialite_e ("setVectorCoverageInfos: \"%s\"\n",
2999 				    sqlite3_errmsg (sqlite));
3000 		      return 0;
3001 		  }
3002 		sqlite3_reset (stmt);
3003 		sqlite3_clear_bindings (stmt);
3004 		sqlite3_bind_text (stmt, 1, title, strlen (title),
3005 				   SQLITE_STATIC);
3006 		sqlite3_bind_text (stmt, 2, abstract, strlen (abstract),
3007 				   SQLITE_STATIC);
3008 		sqlite3_bind_text (stmt, 3, coverage_name,
3009 				   strlen (coverage_name), SQLITE_STATIC);
3010 	    }
3011 	  else
3012 	    {
3013 		sql = "UPDATE vector_coverages SET title = ?, abstract = ?, "
3014 		    "is_queryable = ?, is_editable = ? WHERE Lower(coverage_name) = Lower(?)";
3015 		ret =
3016 		    sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
3017 		if (ret != SQLITE_OK)
3018 		  {
3019 		      spatialite_e ("setVectorCoverageInfos: \"%s\"\n",
3020 				    sqlite3_errmsg (sqlite));
3021 		      return 0;
3022 		  }
3023 		sqlite3_reset (stmt);
3024 		sqlite3_clear_bindings (stmt);
3025 		sqlite3_bind_text (stmt, 1, title, strlen (title),
3026 				   SQLITE_STATIC);
3027 		sqlite3_bind_text (stmt, 2, abstract, strlen (abstract),
3028 				   SQLITE_STATIC);
3029 		if (is_queryable)
3030 		    is_queryable = 1;
3031 		if (is_editable)
3032 		    is_editable = 1;
3033 		sqlite3_bind_int (stmt, 3, is_queryable);
3034 		sqlite3_bind_int (stmt, 4, is_editable);
3035 		sqlite3_bind_text (stmt, 5, coverage_name,
3036 				   strlen (coverage_name), SQLITE_STATIC);
3037 	    }
3038 	  ret = sqlite3_step (stmt);
3039 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
3040 	      ;
3041 	  else
3042 	    {
3043 		spatialite_e ("setVectorCoverageInfos() error: \"%s\"\n",
3044 			      sqlite3_errmsg (sqlite));
3045 		sqlite3_finalize (stmt);
3046 		return 0;
3047 	    }
3048 	  sqlite3_finalize (stmt);
3049 
3050 	  curr_changes = sqlite3_total_changes (sqlite);
3051 	  if (prev_changes == curr_changes)
3052 	      return 0;
3053 	  return 1;
3054       }
3055     else
3056 	return 0;
3057 }
3058 
3059 SPATIALITE_PRIVATE int
set_vector_coverage_copyright(void * p_sqlite,const char * coverage_name,const char * copyright,const char * license)3060 set_vector_coverage_copyright (void *p_sqlite, const char *coverage_name,
3061 			       const char *copyright, const char *license)
3062 {
3063 /* auxiliary function: updates the copyright infos supporting a Vector Coverage */
3064     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
3065     int ret;
3066     const char *sql;
3067     sqlite3_stmt *stmt;
3068 
3069     if (coverage_name == NULL)
3070 	return 0;
3071     if (copyright == NULL && license == NULL)
3072 	return 1;
3073 
3074     if (copyright == NULL)
3075       {
3076 	  /* just updating the License */
3077 	  sql = "UPDATE vector_coverages SET license = ("
3078 	      "SELECT id FROM data_licenses WHERE name = ?) "
3079 	      "WHERE Lower(coverage_name) = Lower(?)";
3080 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
3081 	  if (ret != SQLITE_OK)
3082 	    {
3083 		spatialite_e ("setVectorCoverageCopyright: \"%s\"\n",
3084 			      sqlite3_errmsg (sqlite));
3085 		return 0;
3086 	    }
3087 	  sqlite3_reset (stmt);
3088 	  sqlite3_clear_bindings (stmt);
3089 	  sqlite3_bind_text (stmt, 1, license, strlen (license), SQLITE_STATIC);
3090 	  sqlite3_bind_text (stmt, 2, coverage_name,
3091 			     strlen (coverage_name), SQLITE_STATIC);
3092       }
3093     else if (license == NULL)
3094       {
3095 	  /* just updating the Copyright */
3096 	  sql = "UPDATE vector_coverages SET copyright = ? "
3097 	      "WHERE Lower(coverage_name) = Lower(?)";
3098 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
3099 	  if (ret != SQLITE_OK)
3100 	    {
3101 		spatialite_e ("setVectorCoverageCopyright: \"%s\"\n",
3102 			      sqlite3_errmsg (sqlite));
3103 		return 0;
3104 	    }
3105 	  sqlite3_reset (stmt);
3106 	  sqlite3_clear_bindings (stmt);
3107 	  sqlite3_bind_text (stmt, 1, copyright, strlen (copyright),
3108 			     SQLITE_STATIC);
3109 	  sqlite3_bind_text (stmt, 2, coverage_name, strlen (coverage_name),
3110 			     SQLITE_STATIC);
3111       }
3112     else
3113       {
3114 	  /* updating both Copyright and License */
3115 	  sql = "UPDATE vector_coverages SET copyright = ?, license = ("
3116 	      "SELECT id FROM data_licenses WHERE name = ?) "
3117 	      "WHERE Lower(coverage_name) = Lower(?)";
3118 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
3119 	  if (ret != SQLITE_OK)
3120 	    {
3121 		spatialite_e ("setVectorCoverageCopyright: \"%s\"\n",
3122 			      sqlite3_errmsg (sqlite));
3123 		return 0;
3124 	    }
3125 	  sqlite3_reset (stmt);
3126 	  sqlite3_clear_bindings (stmt);
3127 	  sqlite3_bind_text (stmt, 1, copyright, strlen (copyright),
3128 			     SQLITE_STATIC);
3129 	  sqlite3_bind_text (stmt, 2, license, strlen (license), SQLITE_STATIC);
3130 	  sqlite3_bind_text (stmt, 3, coverage_name,
3131 			     strlen (coverage_name), SQLITE_STATIC);
3132       }
3133     ret = sqlite3_step (stmt);
3134     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
3135 	;
3136     else
3137       {
3138 	  spatialite_e ("setVectorCoverageCopyright() error: \"%s\"\n",
3139 			sqlite3_errmsg (sqlite));
3140 	  sqlite3_finalize (stmt);
3141 	  return 0;
3142       }
3143     sqlite3_finalize (stmt);
3144     return 1;
3145 }
3146 
3147 static int
check_vector_coverage_srid2(sqlite3 * sqlite,const char * coverage_name,int srid)3148 check_vector_coverage_srid2 (sqlite3 * sqlite, const char *coverage_name,
3149 			     int srid)
3150 {
3151 /* checks if a Vector Coverage SRID do actually exists */
3152     int ret;
3153     const char *sql;
3154     sqlite3_stmt *stmt;
3155     int count = 0;
3156 
3157     sql = "SELECT srid FROM vector_coverages_srid "
3158 	"WHERE Lower(coverage_name) = Lower(?) AND srid = ?";
3159     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
3160     if (ret != SQLITE_OK)
3161       {
3162 	  spatialite_e ("check Vector Coverage SRID: \"%s\"\n",
3163 			sqlite3_errmsg (sqlite));
3164 	  goto stop;
3165       }
3166     sqlite3_reset (stmt);
3167     sqlite3_clear_bindings (stmt);
3168     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
3169 		       SQLITE_STATIC);
3170     sqlite3_bind_int (stmt, 2, srid);
3171     while (1)
3172       {
3173 	  /* scrolling the result set rows */
3174 	  ret = sqlite3_step (stmt);
3175 	  if (ret == SQLITE_DONE)
3176 	      break;		/* end of result set */
3177 	  if (ret == SQLITE_ROW)
3178 	      count++;
3179       }
3180     sqlite3_finalize (stmt);
3181     if (count == 1)
3182 	return 1;
3183     return 0;
3184   stop:
3185     return 0;
3186 }
3187 
3188 static int
find_vector_coverage_type(sqlite3 * sqlite,const char * coverage_name)3189 find_vector_coverage_type (sqlite3 * sqlite, const char *coverage_name)
3190 {
3191 /* determining the Vector Coverage Type */
3192     int ret;
3193     int i;
3194     char **results;
3195     int rows;
3196     int columns;
3197     char *value1;
3198     char *value2;
3199     int type = VECTOR_UNKNOWN;
3200     char *sql;
3201 
3202     sql =
3203 	sqlite3_mprintf
3204 	("SELECT f_table_name, f_geometry_column, view_name, view_geometry, "
3205 	 "virt_name, virt_geometry, topology_name, network_name "
3206 	 "FROM vector_coverages WHERE coverage_name = %Q", coverage_name);
3207     ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, NULL);
3208     sqlite3_free (sql);
3209     if (ret != SQLITE_OK)
3210 	return VECTOR_UNKNOWN;
3211     if (rows < 1)
3212 	;
3213     else
3214       {
3215 	  for (i = 1; i <= rows; i++)
3216 	    {
3217 		value1 = results[(i * columns) + 0];
3218 		value2 = results[(i * columns) + 1];
3219 		if (value1 != NULL && value2 != NULL)
3220 		    type = VECTOR_GEOTABLE;
3221 		value1 = results[(i * columns) + 2];
3222 		value2 = results[(i * columns) + 3];
3223 		if (value1 != NULL && value2 != NULL)
3224 		    type = VECTOR_SPATIALVIEW;
3225 		value1 = results[(i * columns) + 4];
3226 		value2 = results[(i * columns) + 5];
3227 		if (value1 != NULL && value2 != NULL)
3228 		    type = VECTOR_VIRTUALSHP;
3229 		value1 = results[(i * columns) + 6];
3230 		if (value1 != NULL)
3231 		    type = VECTOR_TOPOGEO;
3232 		value1 = results[(i * columns) + 7];
3233 		if (value1 != NULL)
3234 		    type = VECTOR_TOPONET;
3235 	    }
3236       }
3237     sqlite3_free_table (results);
3238     return type;
3239 }
3240 
3241 static int
check_vector_coverage_srid1(sqlite3 * sqlite,const char * coverage_name,int srid)3242 check_vector_coverage_srid1 (sqlite3 * sqlite, const char *coverage_name,
3243 			     int srid)
3244 {
3245 /* checks if a Vector Coverage do actually exists and check its SRID */
3246     int ret;
3247     char *sql;
3248     sqlite3_stmt *stmt;
3249     int count = 0;
3250     int same_srid = 0;
3251     int type = find_vector_coverage_type (sqlite, coverage_name);
3252 
3253     switch (type)
3254       {
3255       case VECTOR_GEOTABLE:
3256 	  sql = sqlite3_mprintf ("SELECT c.srid FROM vector_coverages AS v "
3257 				 "JOIN geometry_columns AS c ON (v.f_table_name IS NOT NULL AND v.f_geometry_column IS NOT NULL "
3258 				 "AND v.topology_name IS NULL AND v.network_name IS NULL AND "
3259 				 "Lower(v.f_table_name) = Lower(c.f_table_name) "
3260 				 "AND Lower(v.f_geometry_column) = Lower(c.f_geometry_column)) "
3261 				 "WHERE Lower(v.coverage_name) = Lower(%Q)",
3262 				 coverage_name);
3263 	  break;
3264       case VECTOR_SPATIALVIEW:
3265 	  sql = sqlite3_mprintf ("SELECT c.srid FROM vector_coverages AS v "
3266 				 "JOIN views_geometry_columns AS x ON (v.view_name IS NOT NULL AND v.view_geometry IS NOT NULL "
3267 				 "AND Lower(v.view_name) = Lower(x.view_name) AND Lower(v.view_geometry) = Lower(x.view_geometry)) "
3268 				 "JOIN geometry_columns AS c ON (Lower(x.f_table_name) = Lower(c.f_table_name) "
3269 				 "AND Lower(x.f_geometry_column) = Lower(c.f_geometry_column)) "
3270 				 "WHERE Lower(v.coverage_name) = Lower(%Q)",
3271 				 coverage_name);
3272 	  break;
3273       case VECTOR_VIRTUALSHP:
3274 	  sql = sqlite3_mprintf ("SELECT c.srid FROM vector_coverages AS v "
3275 				 "JOIN virts_geometry_columns AS c ON (v.virt_name IS NOT NULL AND v.virt_geometry IS NOT NULL "
3276 				 "AND Lower(v.virt_name) = Lower(c.virt_name) AND Lower(v.virt_geometry) = Lower(c.virt_geometry)) "
3277 				 "WHERE Lower(v.coverage_name) = Lower(%Q)",
3278 				 coverage_name);
3279 	  break;
3280       case VECTOR_TOPOGEO:
3281 	  sql = sqlite3_mprintf ("SELECT c.srid FROM vector_coverages AS v "
3282 				 "JOIN topologies AS c ON (v.topology_name IS NOT NULL "
3283 				 "AND Lower(v.topology_name) = Lower(c.topology_name)) "
3284 				 "WHERE Lower(v.coverage_name) = Lower(%Q)",
3285 				 coverage_name);
3286 	  break;
3287       case VECTOR_TOPONET:
3288 	  sql = sqlite3_mprintf ("SELECT c.srid FROM vector_coverages AS v "
3289 				 "JOIN networks AS c ON (v.network_name IS NOT NULL "
3290 				 "AND Lower(v.network_name) = Lower(c.network_name)) "
3291 				 "WHERE Lower(v.coverage_name) = Lower(%Q)",
3292 				 coverage_name);
3293 	  break;
3294       case VECTOR_UNKNOWN:
3295       default:
3296 	  goto stop;
3297 	  break;
3298       };
3299 
3300     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
3301     sqlite3_free (sql);
3302     if (ret != SQLITE_OK)
3303 	goto stop;
3304     while (1)
3305       {
3306 	  /* scrolling the result set rows */
3307 	  ret = sqlite3_step (stmt);
3308 	  if (ret == SQLITE_DONE)
3309 	      break;		/* end of result set */
3310 	  if (ret == SQLITE_ROW)
3311 	    {
3312 		int natural_srid = sqlite3_column_int (stmt, 0);
3313 		if (srid == natural_srid)
3314 		    same_srid++;
3315 		count++;
3316 	    }
3317       }
3318     sqlite3_finalize (stmt);
3319     if (count == 1 && same_srid == 0)
3320       {
3321 	  if (check_vector_coverage_srid2 (sqlite, coverage_name, srid))
3322 	      return 0;
3323 	  else
3324 	      return 1;
3325       }
3326     return 0;
3327   stop:
3328     return 0;
3329 }
3330 
3331 SPATIALITE_PRIVATE int
register_vector_coverage_srid(void * p_sqlite,const char * coverage_name,int srid)3332 register_vector_coverage_srid (void *p_sqlite, const char *coverage_name,
3333 			       int srid)
3334 {
3335 /* auxiliary function: inserting a Vector Coverage alternative SRID */
3336     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
3337     int ret;
3338     const char *sql;
3339     sqlite3_stmt *stmt;
3340 
3341     if (coverage_name == NULL)
3342 	return 0;
3343     if (srid <= 0)
3344 	return 0;
3345 
3346     /* checking if the Vector Coverage do actually exists */
3347     if (!check_vector_coverage_srid1 (sqlite, coverage_name, srid))
3348 	return 0;
3349 
3350     /* attempting to insert the Vector Coverage alternative SRID */
3351     sql = "INSERT INTO vector_coverages_srid "
3352 	"(coverage_name, srid) VALUES (Lower(?), ?)";
3353     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
3354     if (ret != SQLITE_OK)
3355       {
3356 	  spatialite_e ("registerVectorCoverageSrid: \"%s\"\n",
3357 			sqlite3_errmsg (sqlite));
3358 	  return 0;
3359       }
3360     sqlite3_reset (stmt);
3361     sqlite3_clear_bindings (stmt);
3362     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
3363 		       SQLITE_STATIC);
3364     sqlite3_bind_int (stmt, 2, srid);
3365     ret = sqlite3_step (stmt);
3366     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
3367 	;
3368     else
3369       {
3370 	  spatialite_e ("registerVectorCoverageSrid() error: \"%s\"\n",
3371 			sqlite3_errmsg (sqlite));
3372 	  sqlite3_finalize (stmt);
3373 	  return 0;
3374       }
3375     sqlite3_finalize (stmt);
3376     return 1;
3377 }
3378 
3379 SPATIALITE_PRIVATE int
unregister_vector_coverage_srid(void * p_sqlite,const char * coverage_name,int srid)3380 unregister_vector_coverage_srid (void *p_sqlite, const char *coverage_name,
3381 				 int srid)
3382 {
3383 /* auxiliary function: deletes a Vector Coverage alternative SRID */
3384     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
3385 
3386     if (coverage_name == NULL)
3387 	return 0;
3388 
3389     /* checking if the Vector Coverage SRID do actually exists */
3390     if (!check_vector_coverage_srid2 (sqlite, coverage_name, srid))
3391 	return 0;
3392     /* deleting the alternative SRID */
3393     do_delete_vector_coverage_srid (sqlite, coverage_name, srid);
3394     return 1;
3395 }
3396 
3397 static int
check_vector_coverage_keyword0(sqlite3 * sqlite,const char * coverage_name)3398 check_vector_coverage_keyword0 (sqlite3 * sqlite, const char *coverage_name)
3399 {
3400 /* checks if a Vector Coverage do actually exists */
3401     int ret;
3402     const char *sql;
3403     sqlite3_stmt *stmt;
3404     int count = 0;
3405 
3406     sql =
3407 	"SELECT coverage_name FROM vector_coverages WHERE Lower(coverage_name) = Lower(?)";
3408     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
3409     if (ret != SQLITE_OK)
3410       {
3411 	  spatialite_e ("check Vector Coverage Keyword: \"%s\"\n",
3412 			sqlite3_errmsg (sqlite));
3413 	  goto stop;
3414       }
3415     sqlite3_reset (stmt);
3416     sqlite3_clear_bindings (stmt);
3417     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
3418 		       SQLITE_STATIC);
3419     while (1)
3420       {
3421 	  /* scrolling the result set rows */
3422 	  ret = sqlite3_step (stmt);
3423 	  if (ret == SQLITE_DONE)
3424 	      break;		/* end of result set */
3425 	  if (ret == SQLITE_ROW)
3426 	      count++;
3427       }
3428     sqlite3_finalize (stmt);
3429     if (count == 0)
3430 	return 0;
3431     return 1;
3432   stop:
3433     return 0;
3434 }
3435 
3436 static int
check_vector_coverage_keyword1(sqlite3 * sqlite,const char * coverage_name,const char * keyword)3437 check_vector_coverage_keyword1 (sqlite3 * sqlite, const char *coverage_name,
3438 				const char *keyword)
3439 {
3440 /* checks if a Vector Coverage do actually exists and check the Keyword */
3441     int ret;
3442     const char *sql;
3443     sqlite3_stmt *stmt;
3444     int same_kw = 0;
3445 
3446     sql =
3447 	"SELECT keyword FROM vector_coverages_keyword WHERE Lower(coverage_name) = Lower(?)";
3448     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
3449     if (ret != SQLITE_OK)
3450       {
3451 	  spatialite_e ("check Vector Coverage Keyword: \"%s\"\n",
3452 			sqlite3_errmsg (sqlite));
3453 	  goto stop;
3454       }
3455     sqlite3_reset (stmt);
3456     sqlite3_clear_bindings (stmt);
3457     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
3458 		       SQLITE_STATIC);
3459     while (1)
3460       {
3461 	  /* scrolling the result set rows */
3462 	  ret = sqlite3_step (stmt);
3463 	  if (ret == SQLITE_DONE)
3464 	      break;		/* end of result set */
3465 	  if (ret == SQLITE_ROW)
3466 	    {
3467 		const char *kw = (const char *) sqlite3_column_text (stmt, 0);
3468 		if (strcasecmp (kw, keyword) == 0)
3469 		    same_kw++;
3470 	    }
3471       }
3472     sqlite3_finalize (stmt);
3473     if (same_kw == 0)
3474       {
3475 	  if (!check_vector_coverage_keyword0 (sqlite, coverage_name))
3476 	      return 0;
3477 	  else
3478 	      return 1;
3479       }
3480     return 0;
3481   stop:
3482     return 0;
3483 }
3484 
3485 static int
check_vector_coverage_keyword2(sqlite3 * sqlite,const char * coverage_name,const char * keyword)3486 check_vector_coverage_keyword2 (sqlite3 * sqlite, const char *coverage_name,
3487 				const char *keyword)
3488 {
3489 /* checks if a Vector Coverage do actually exists and check the Keyword */
3490     int ret;
3491     const char *sql;
3492     sqlite3_stmt *stmt;
3493     int count = 0;
3494 
3495     sql = "SELECT keyword FROM vector_coverages_keyword "
3496 	"WHERE Lower(coverage_name) = Lower(?) AND Lower(keyword) = Lower(?)";
3497     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
3498     if (ret != SQLITE_OK)
3499       {
3500 	  spatialite_e ("check Vector Coverage Keyword: \"%s\"\n",
3501 			sqlite3_errmsg (sqlite));
3502 	  goto stop;
3503       }
3504     sqlite3_reset (stmt);
3505     sqlite3_clear_bindings (stmt);
3506     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
3507 		       SQLITE_STATIC);
3508     sqlite3_bind_text (stmt, 2, keyword, strlen (keyword), SQLITE_STATIC);
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 	      count++;
3517       }
3518     sqlite3_finalize (stmt);
3519     if (count == 0)
3520 	return 0;
3521     return 1;
3522   stop:
3523     return 0;
3524 }
3525 
3526 SPATIALITE_PRIVATE int
register_vector_coverage_keyword(void * p_sqlite,const char * coverage_name,const char * keyword)3527 register_vector_coverage_keyword (void *p_sqlite, const char *coverage_name,
3528 				  const char *keyword)
3529 {
3530 /* auxiliary function: inserting a Vector Coverage Keyword */
3531     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
3532     int ret;
3533     const char *sql;
3534     sqlite3_stmt *stmt;
3535 
3536     if (coverage_name == NULL)
3537 	return 0;
3538     if (keyword == NULL)
3539 	return 0;
3540 
3541     /* checking if the Vector Coverage do actually exists */
3542     if (!check_vector_coverage_keyword1 (sqlite, coverage_name, keyword))
3543 	return 0;
3544 
3545     /* attempting to insert the Vector Coverage Keyword */
3546     sql = "INSERT INTO vector_coverages_keyword "
3547 	"(coverage_name, keyword) VALUES (Lower(?), ?)";
3548     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
3549     if (ret != SQLITE_OK)
3550       {
3551 	  spatialite_e ("registerVectorCoverageKeyword: \"%s\"\n",
3552 			sqlite3_errmsg (sqlite));
3553 	  return 0;
3554       }
3555     sqlite3_reset (stmt);
3556     sqlite3_clear_bindings (stmt);
3557     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
3558 		       SQLITE_STATIC);
3559     sqlite3_bind_text (stmt, 2, keyword, strlen (keyword), SQLITE_STATIC);
3560     ret = sqlite3_step (stmt);
3561     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
3562 	;
3563     else
3564       {
3565 	  spatialite_e ("registerVectorCoverageKeyword() error: \"%s\"\n",
3566 			sqlite3_errmsg (sqlite));
3567 	  sqlite3_finalize (stmt);
3568 	  return 0;
3569       }
3570     sqlite3_finalize (stmt);
3571     return 1;
3572 }
3573 
3574 SPATIALITE_PRIVATE int
unregister_vector_coverage_keyword(void * p_sqlite,const char * coverage_name,const char * keyword)3575 unregister_vector_coverage_keyword (void *p_sqlite, const char *coverage_name,
3576 				    const char *keyword)
3577 {
3578 /* auxiliary function: deletes a Vector Coverage Keyword */
3579     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
3580 
3581     if (coverage_name == NULL)
3582 	return 0;
3583     if (keyword == NULL)
3584 	return 0;
3585 
3586     /* checking if the Vector Coverage Keyword do actually exists */
3587     if (!check_vector_coverage_keyword2 (sqlite, coverage_name, keyword))
3588 	return 0;
3589     /* deleting the Keyword */
3590     do_delete_vector_coverage_keyword (sqlite, coverage_name, keyword);
3591     return 1;
3592 }
3593 
3594 static int
do_null_vector_coverage_extents(sqlite3 * sqlite,sqlite3_stmt * stmt_upd_cvg,sqlite3_stmt * stmt_null_srid,const char * coverage_name)3595 do_null_vector_coverage_extents (sqlite3 * sqlite, sqlite3_stmt * stmt_upd_cvg,
3596 				 sqlite3_stmt * stmt_null_srid,
3597 				 const char *coverage_name)
3598 {
3599 /* setting the main Coverage Extent to NULL */
3600     int ret;
3601     sqlite3_reset (stmt_upd_cvg);
3602     sqlite3_clear_bindings (stmt_upd_cvg);
3603     sqlite3_bind_null (stmt_upd_cvg, 1);
3604     sqlite3_bind_null (stmt_upd_cvg, 2);
3605     sqlite3_bind_null (stmt_upd_cvg, 3);
3606     sqlite3_bind_null (stmt_upd_cvg, 4);
3607     sqlite3_bind_null (stmt_upd_cvg, 5);
3608     sqlite3_bind_null (stmt_upd_cvg, 6);
3609     sqlite3_bind_null (stmt_upd_cvg, 7);
3610     sqlite3_bind_null (stmt_upd_cvg, 8);
3611     sqlite3_bind_text (stmt_upd_cvg, 9, coverage_name, strlen (coverage_name),
3612 		       SQLITE_STATIC);
3613     ret = sqlite3_step (stmt_upd_cvg);
3614     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
3615 	;
3616     else
3617       {
3618 	  spatialite_e ("updateVectorCoverageExtent error: \"%s\"\n",
3619 			sqlite3_errmsg (sqlite));
3620 	  return 0;
3621       }
3622 /* setting all alternativ Coverage Extent to NULL */
3623     sqlite3_reset (stmt_null_srid);
3624     sqlite3_clear_bindings (stmt_null_srid);
3625     sqlite3_bind_text (stmt_null_srid, 1, coverage_name, strlen (coverage_name),
3626 		       SQLITE_STATIC);
3627     ret = sqlite3_step (stmt_null_srid);
3628     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
3629 	;
3630     else
3631       {
3632 	  spatialite_e ("updateVectorCoverageExtent error: \"%s\"\n",
3633 			sqlite3_errmsg (sqlite));
3634 	  return 0;
3635       }
3636     return 1;
3637 }
3638 
3639 static int
do_update_vector_coverage_extents(sqlite3 * sqlite,const void * cache,sqlite3_stmt * stmt_upd_cvg,sqlite3_stmt * stmt_srid,sqlite3_stmt * stmt_upd_srid,const char * coverage_name,int natural_srid,double minx,double miny,double maxx,double maxy)3640 do_update_vector_coverage_extents (sqlite3 * sqlite, const void *cache,
3641 				   sqlite3_stmt * stmt_upd_cvg,
3642 				   sqlite3_stmt * stmt_srid,
3643 				   sqlite3_stmt * stmt_upd_srid,
3644 				   const char *coverage_name, int natural_srid,
3645 				   double minx, double miny, double maxx,
3646 				   double maxy)
3647 {
3648 /* updating the Coverage Extents */
3649     int ret;
3650     int geographic = 0;
3651     double geo_minx = minx;
3652     double geo_miny = miny;
3653     double geo_maxx = maxx;
3654     double geo_maxy = maxy;
3655     char *proj_from = NULL;
3656     char *proj_to = NULL;
3657     gaiaGeomCollPtr in;
3658     gaiaGeomCollPtr out;
3659     gaiaPointPtr pt;
3660 
3661 #ifndef OMIT_PROJ		/* including PROJ.4 */
3662 
3663     getProjParams (sqlite, natural_srid, &proj_from);
3664     if (proj_from == NULL)
3665 	goto error;
3666 
3667     ret = srid_is_geographic (sqlite, natural_srid, &geographic);
3668     if (!ret)
3669 	return 0;
3670     if (!geographic)
3671       {
3672 	  /* computing the geographic extent */
3673 	  getProjParams (sqlite, 4326, &proj_to);
3674 	  if (proj_to == NULL)
3675 	      goto error;
3676 	  in = gaiaAllocGeomColl ();
3677 	  in->Srid = natural_srid;
3678 	  gaiaAddPointToGeomColl (in, minx, miny);
3679 	  if (cache != NULL)
3680 	      out = gaiaTransform_r (cache, in, proj_from, proj_to);
3681 	  else
3682 	      out = gaiaTransform (in, proj_from, proj_to);
3683 	  if (out == NULL)
3684 	    {
3685 		gaiaFreeGeomColl (in);
3686 		goto error;
3687 	    }
3688 	  pt = out->FirstPoint;
3689 	  if (pt == NULL)
3690 	    {
3691 		gaiaFreeGeomColl (in);
3692 		gaiaFreeGeomColl (out);
3693 		goto error;
3694 	    }
3695 	  geo_minx = pt->X;
3696 	  geo_miny = pt->Y;
3697 	  gaiaFreeGeomColl (in);
3698 	  gaiaFreeGeomColl (out);
3699 	  in = gaiaAllocGeomColl ();
3700 	  in->Srid = natural_srid;
3701 	  gaiaAddPointToGeomColl (in, maxx, maxy);
3702 	  if (cache != NULL)
3703 	      out = gaiaTransform_r (cache, in, proj_from, proj_to);
3704 	  else
3705 	      out = gaiaTransform (in, proj_from, proj_to);
3706 	  if (out == NULL)
3707 	    {
3708 		gaiaFreeGeomColl (in);
3709 		goto error;
3710 	    }
3711 	  pt = out->FirstPoint;
3712 	  if (pt == NULL)
3713 	    {
3714 		gaiaFreeGeomColl (in);
3715 		gaiaFreeGeomColl (out);
3716 		goto error;
3717 	    }
3718 	  geo_maxx = pt->X;
3719 	  geo_maxy = pt->Y;
3720 	  gaiaFreeGeomColl (in);
3721 	  gaiaFreeGeomColl (out);
3722 	  free (proj_to);
3723 	  proj_to = NULL;
3724       }
3725 
3726 /* setting the main Coverage Extent */
3727     sqlite3_reset (stmt_upd_cvg);
3728     sqlite3_clear_bindings (stmt_upd_cvg);
3729     sqlite3_bind_double (stmt_upd_cvg, 1, geo_minx);
3730     sqlite3_bind_double (stmt_upd_cvg, 2, geo_miny);
3731     sqlite3_bind_double (stmt_upd_cvg, 3, geo_maxx);
3732     sqlite3_bind_double (stmt_upd_cvg, 4, geo_maxy);
3733     sqlite3_bind_double (stmt_upd_cvg, 5, minx);
3734     sqlite3_bind_double (stmt_upd_cvg, 6, miny);
3735     sqlite3_bind_double (stmt_upd_cvg, 7, maxx);
3736     sqlite3_bind_double (stmt_upd_cvg, 8, maxy);
3737     sqlite3_bind_text (stmt_upd_cvg, 9, coverage_name, strlen (coverage_name),
3738 		       SQLITE_STATIC);
3739     ret = sqlite3_step (stmt_upd_cvg);
3740     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
3741 	;
3742     else
3743       {
3744 	  spatialite_e ("updateVectorCoverageExtent error: \"%s\"\n",
3745 			sqlite3_errmsg (sqlite));
3746 	  goto error;
3747       }
3748 
3749 /* updating any alternative SRID supporting this Vector Coverage */
3750     sqlite3_reset (stmt_srid);
3751     sqlite3_clear_bindings (stmt_srid);
3752     sqlite3_bind_text (stmt_srid, 1, coverage_name, strlen (coverage_name),
3753 		       SQLITE_STATIC);
3754     while (1)
3755       {
3756 	  /* scrolling the result set rows */
3757 	  ret = sqlite3_step (stmt_srid);
3758 	  if (ret == SQLITE_DONE)
3759 	      break;		/* end of result set */
3760 	  if (ret == SQLITE_ROW)
3761 	    {
3762 		/* processing a single alternative SRID Extent */
3763 		double alt_minx;
3764 		double alt_miny;
3765 		double alt_maxx;
3766 		double alt_maxy;
3767 		int srid = sqlite3_column_int (stmt_srid, 0);
3768 		getProjParams (sqlite, srid, &proj_to);
3769 		if (proj_to == NULL)
3770 		    goto error;
3771 		in = gaiaAllocGeomColl ();
3772 		in->Srid = natural_srid;
3773 		gaiaAddPointToGeomColl (in, minx, miny);
3774 		if (cache != NULL)
3775 		    out = gaiaTransform_r (cache, in, proj_from, proj_to);
3776 		else
3777 		    out = gaiaTransform (in, proj_from, proj_to);
3778 		if (out == NULL)
3779 		  {
3780 		      gaiaFreeGeomColl (in);
3781 		      goto error;
3782 		  }
3783 		pt = out->FirstPoint;
3784 		if (pt == NULL)
3785 		  {
3786 		      gaiaFreeGeomColl (in);
3787 		      gaiaFreeGeomColl (out);
3788 		      goto error;
3789 		  }
3790 		alt_minx = pt->X;
3791 		alt_miny = pt->Y;
3792 		gaiaFreeGeomColl (in);
3793 		gaiaFreeGeomColl (out);
3794 		in = gaiaAllocGeomColl ();
3795 		in->Srid = natural_srid;
3796 		gaiaAddPointToGeomColl (in, maxx, maxy);
3797 		if (cache != NULL)
3798 		    out = gaiaTransform_r (cache, in, proj_from, proj_to);
3799 		else
3800 		    out = gaiaTransform (in, proj_from, proj_to);
3801 		if (out == NULL)
3802 		  {
3803 		      gaiaFreeGeomColl (in);
3804 		      goto error;
3805 		  }
3806 		pt = out->FirstPoint;
3807 		if (pt == NULL)
3808 		  {
3809 		      gaiaFreeGeomColl (in);
3810 		      gaiaFreeGeomColl (out);
3811 		      goto error;
3812 		  }
3813 		alt_maxx = pt->X;
3814 		alt_maxy = pt->Y;
3815 		gaiaFreeGeomColl (in);
3816 		gaiaFreeGeomColl (out);
3817 		free (proj_to);
3818 		proj_to = NULL;
3819 
3820 /* setting the alternative Srid Extent */
3821 		sqlite3_reset (stmt_upd_srid);
3822 		sqlite3_clear_bindings (stmt_upd_srid);
3823 		sqlite3_bind_double (stmt_upd_srid, 1, alt_minx);
3824 		sqlite3_bind_double (stmt_upd_srid, 2, alt_miny);
3825 		sqlite3_bind_double (stmt_upd_srid, 3, alt_maxx);
3826 		sqlite3_bind_double (stmt_upd_srid, 4, alt_maxy);
3827 		sqlite3_bind_text (stmt_upd_srid, 5, coverage_name,
3828 				   strlen (coverage_name), SQLITE_STATIC);
3829 		sqlite3_bind_int (stmt_upd_srid, 6, srid);
3830 		ret = sqlite3_step (stmt_upd_srid);
3831 		if (ret == SQLITE_DONE || ret == SQLITE_ROW)
3832 		    ;
3833 		else
3834 		  {
3835 		      spatialite_e
3836 			  ("updateVectorCoverageExtent error: \"%s\"\n",
3837 			   sqlite3_errmsg (sqlite));
3838 		      goto error;
3839 		  }
3840 	    }
3841 	  else
3842 	    {
3843 		spatialite_e ("updateVectorCoverageExtent() error: \"%s\"\n",
3844 			      sqlite3_errmsg (sqlite));
3845 		goto error;
3846 	    }
3847       }
3848 
3849     free (proj_from);
3850     return 1;
3851 
3852   error:
3853     if (proj_from)
3854 	free (proj_from);
3855     if (proj_to)
3856 	free (proj_to);
3857 #endif /* end including PROJ.4 */
3858     return 0;
3859 }
3860 
3861 SPATIALITE_PRIVATE int
update_vector_coverage_extent(void * p_sqlite,const void * cache,const char * coverage_name,int transaction)3862 update_vector_coverage_extent (void *p_sqlite, const void *cache,
3863 			       const char *coverage_name, int transaction)
3864 {
3865 /* updates one (or all) Vector Coverage Extents */
3866     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
3867     int ret;
3868     char *sql;
3869     sqlite3_stmt *stmt = NULL;
3870     sqlite3_stmt *stmt_ext = NULL;
3871     sqlite3_stmt *stmt_upd_cvg = NULL;
3872     sqlite3_stmt *stmt_upd_srid = NULL;
3873     sqlite3_stmt *stmt_null_srid = NULL;
3874     sqlite3_stmt *stmt_srid = NULL;
3875     sqlite3_stmt *stmt_virt = NULL;
3876 
3877 /* preparing the ancillary SQL statements */
3878     sql = "SELECT srid FROM vector_coverages_srid "
3879 	"WHERE Lower(coverage_name) = Lower(?)";
3880     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_srid, NULL);
3881     if (ret != SQLITE_OK)
3882       {
3883 	  spatialite_e ("updateVectorCoverageExtent: \"%s\"\n",
3884 			sqlite3_errmsg (sqlite));
3885 	  goto error;
3886       }
3887 
3888     sql = "UPDATE vector_coverages SET geo_minx = ?, geo_miny = ?, "
3889 	"geo_maxx = ?, geo_maxy = ?, extent_minx = ?, extent_miny = ?, "
3890 	"extent_maxx = ?, extent_maxy = ? "
3891 	"WHERE Lower(coverage_name) = Lower(?)";
3892     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_upd_cvg, NULL);
3893     if (ret != SQLITE_OK)
3894       {
3895 	  spatialite_e ("updateVectorCoverageExtent: \"%s\"\n",
3896 			sqlite3_errmsg (sqlite));
3897 	  goto error;
3898       }
3899 
3900     sql = "UPDATE vector_coverages_srid SET extent_minx = NULL, "
3901 	"extent_miny = NULL, extent_maxx = NULL, extent_maxy = NULL "
3902 	"WHERE Lower(coverage_name) = Lower(?)";
3903     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_null_srid, NULL);
3904     if (ret != SQLITE_OK)
3905       {
3906 	  spatialite_e ("updateVectorCoverageExtent: \"%s\"\n",
3907 			sqlite3_errmsg (sqlite));
3908 	  goto error;
3909       }
3910 
3911     sql = "UPDATE vector_coverages_srid SET extent_minx = ?, "
3912 	"extent_miny = ?, extent_maxx = ?, extent_maxy = ? "
3913 	"WHERE Lower(coverage_name) = Lower(?) AND srid = ?";
3914     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_upd_srid, NULL);
3915     if (ret != SQLITE_OK)
3916       {
3917 	  spatialite_e ("updateVectorCoverageExtent: \"%s\"\n",
3918 			sqlite3_errmsg (sqlite));
3919 	  goto error;
3920       }
3921 
3922 /* preparing the main SQL statement */
3923     if (coverage_name == NULL)
3924       {
3925 	  sql = "SELECT v.coverage_name, v.f_table_name, v.f_geometry_column, "
3926 	      "c.srid FROM vector_coverages AS v "
3927 	      "JOIN geometry_columns AS c ON (Lower(v.f_table_name) = "
3928 	      "Lower(c.f_table_name) AND Lower(v.f_geometry_column) = "
3929 	      "Lower(c.f_geometry_column)) "
3930 	      "WHERE v.f_table_name IS NOT NULL AND v.f_geometry_column IS NOT NULL "
3931 	      "UNION "
3932 	      "SELECT v.coverage_name, v.view_name, w.view_geometry, c.srid "
3933 	      "FROM vector_coverages AS v "
3934 	      "JOIN views_geometry_columns AS w ON "
3935 	      "(Lower(v.view_name) = Lower(w.view_name) AND "
3936 	      "Lower(v.view_geometry) = Lower(w.view_geometry)) "
3937 	      "JOIN geometry_columns AS c ON "
3938 	      "(Lower(w.f_table_name) = Lower(c.f_table_name) AND "
3939 	      "Lower(w.f_geometry_column) = Lower(c.f_geometry_column)) "
3940 	      "WHERE v.view_name IS NOT NULL AND v.view_geometry IS NOT NULL";
3941       }
3942     else
3943       {
3944 	  sql = "SELECT v.coverage_name, v.f_table_name, v.f_geometry_column, "
3945 	      "c.srid FROM vector_coverages AS v "
3946 	      "JOIN geometry_columns AS c ON (Lower(v.f_table_name) = "
3947 	      "Lower(c.f_table_name) AND Lower(v.f_geometry_column) = "
3948 	      "Lower(c.f_geometry_column)) "
3949 	      "WHERE Lower(v.coverage_name) = Lower(?) AND "
3950 	      "v.f_table_name IS NOT NULL AND v.f_geometry_column IS NOT NULL "
3951 	      "UNION "
3952 	      "SELECT v.coverage_name, v.view_name, v.view_geometry, c.srid "
3953 	      "FROM vector_coverages AS v "
3954 	      "JOIN views_geometry_columns AS w ON "
3955 	      "(Lower(v.view_name) = Lower(w.view_name) AND "
3956 	      "Lower(v.view_geometry) = Lower(w.view_geometry)) "
3957 	      "JOIN geometry_columns AS c ON "
3958 	      "(Lower(w.f_table_name) = Lower(c.f_table_name) AND "
3959 	      "Lower(w.f_geometry_column) = Lower(c.f_geometry_column)) "
3960 	      "WHERE Lower(v.coverage_name) = Lower(?) AND "
3961 	      "v.view_name IS NOT NULL AND v.view_geometry IS NOT NULL";
3962       }
3963     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
3964     if (ret != SQLITE_OK)
3965       {
3966 	  spatialite_e ("updateVectorCoverageExtent: \"%s\"\n",
3967 			sqlite3_errmsg (sqlite));
3968 	  goto error;
3969       }
3970 
3971     if (transaction)
3972       {
3973 	  /* starting a Transaction */
3974 	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
3975 	  if (ret != SQLITE_OK)
3976 	      goto error;
3977       }
3978 
3979     sqlite3_reset (stmt);
3980     sqlite3_clear_bindings (stmt);
3981     if (coverage_name != NULL)
3982       {
3983 	  sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
3984 			     SQLITE_STATIC);
3985 	  sqlite3_bind_text (stmt, 2, coverage_name, strlen (coverage_name),
3986 			     SQLITE_STATIC);
3987       }
3988     while (1)
3989       {
3990 	  /* scrolling the result set rows */
3991 	  ret = sqlite3_step (stmt);
3992 	  if (ret == SQLITE_DONE)
3993 	      break;		/* end of result set */
3994 	  if (ret == SQLITE_ROW)
3995 	    {
3996 		/* processing a single Vector Coverage */
3997 		char *table;
3998 		char *geom;
3999 		const char *cvg = (const char *) sqlite3_column_text (stmt, 0);
4000 		const char *xtable =
4001 		    (const char *) sqlite3_column_text (stmt, 1);
4002 		const char *xgeom =
4003 		    (const char *) sqlite3_column_text (stmt, 2);
4004 		int natural_srid = sqlite3_column_int (stmt, 3);
4005 		table = gaiaDoubleQuotedSql (xtable);
4006 		geom = gaiaDoubleQuotedSql (xgeom);
4007 		sql =
4008 		    sqlite3_mprintf
4009 		    ("SELECT Min(MbrMinX(\"%s\")), Min(MbrMinY(\"%s\")), "
4010 		     "Max(MbrMaxX(\"%s\")), Max(MbrMaxY(\"%s\")) "
4011 		     "FROM \"%s\"", geom, geom, geom, geom, table);
4012 		free (table);
4013 		free (geom);
4014 		ret =
4015 		    sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_ext,
4016 					NULL);
4017 		sqlite3_free (sql);
4018 		if (ret != SQLITE_OK)
4019 		  {
4020 		      spatialite_e ("updateVectorCoverageExtent: \"%s\"\n",
4021 				    sqlite3_errmsg (sqlite));
4022 		      goto error;
4023 		  }
4024 		while (1)
4025 		  {
4026 		      /* scrolling the result set rows */
4027 		      ret = sqlite3_step (stmt_ext);
4028 		      if (ret == SQLITE_DONE)
4029 			  break;	/* end of result set */
4030 		      if (ret == SQLITE_ROW)
4031 			{
4032 			    int null_minx = 1;
4033 			    int null_miny = 1;
4034 			    int null_maxx = 1;
4035 			    int null_maxy = 1;
4036 			    double minx = 0.0;
4037 			    double miny = 0.0;
4038 			    double maxx = 0.0;
4039 			    double maxy = 0.0;
4040 			    if (sqlite3_column_type (stmt_ext, 0) ==
4041 				SQLITE_FLOAT)
4042 			      {
4043 				  minx = sqlite3_column_double (stmt_ext, 0);
4044 				  null_minx = 0;
4045 			      }
4046 			    if (sqlite3_column_type (stmt_ext, 1) ==
4047 				SQLITE_FLOAT)
4048 			      {
4049 				  miny = sqlite3_column_double (stmt_ext, 1);
4050 				  null_miny = 0;
4051 			      }
4052 			    if (sqlite3_column_type (stmt_ext, 2) ==
4053 				SQLITE_FLOAT)
4054 			      {
4055 				  maxx = sqlite3_column_double (stmt_ext, 2);
4056 				  null_maxx = 0;
4057 			      }
4058 			    if (sqlite3_column_type (stmt_ext, 3) ==
4059 				SQLITE_FLOAT)
4060 			      {
4061 				  maxy = sqlite3_column_double (stmt_ext, 3);
4062 				  null_maxy = 0;
4063 			      }
4064 			    if (null_minx || null_miny || null_maxx
4065 				|| null_maxy)
4066 				ret =
4067 				    do_null_vector_coverage_extents (sqlite,
4068 								     stmt_upd_cvg,
4069 								     stmt_null_srid,
4070 								     cvg);
4071 			    else
4072 				ret =
4073 				    do_update_vector_coverage_extents (sqlite,
4074 								       cache,
4075 								       stmt_upd_cvg,
4076 								       stmt_srid,
4077 								       stmt_upd_srid,
4078 								       cvg,
4079 								       natural_srid,
4080 								       minx,
4081 								       miny,
4082 								       maxx,
4083 								       maxy);
4084 			    if (!ret)
4085 				goto error;
4086 			}
4087 		      else
4088 			{
4089 			    spatialite_e
4090 				("updateVectorCoverageExtent() error: \"%s\"\n",
4091 				 sqlite3_errmsg (sqlite));
4092 			    goto error;
4093 			}
4094 		  }
4095 		sqlite3_finalize (stmt_ext);
4096 		stmt_ext = NULL;
4097 	    }
4098 	  else
4099 	    {
4100 		spatialite_e ("updateVectorCoverageExtent() error: \"%s\"\n",
4101 			      sqlite3_errmsg (sqlite));
4102 		goto error;
4103 	    }
4104       }
4105 
4106 /* updating VirtualShapes Extents */
4107     sql = "UPDATE vector_coverages SET "
4108 	"geo_minx = MbrMinX(ST_Transform(GetVirtualTableExtent(virt_name), 4326)), "
4109 	"geo_miny = MbrMinY(ST_Transform(GetVirtualTableExtent(virt_name), 4326)), "
4110 	"geo_maxx = MbrMaxX(ST_Transform(GetVirtualTableExtent(virt_name), 4326)), "
4111 	"geo_maxy = MbrMaxY(ST_Transform(GetVirtualTableExtent(virt_name), 4326)), "
4112 	"extent_minx = MbrMinX(GetVirtualTableExtent(virt_name)), "
4113 	"extent_miny = MbrMinY(GetVirtualTableExtent(virt_name)), "
4114 	"extent_maxx = MbrMaxX(GetVirtualTableExtent(virt_name)), "
4115 	"extent_maxy = MbrMaxY(GetVirtualTableExtent(virt_name)) "
4116 	"WHERE virt_name IS NOT NULL";
4117     ret = sqlite3_exec (sqlite, sql, NULL, NULL, NULL);
4118     if (ret != SQLITE_OK)
4119       {
4120 	  spatialite_e ("updateVectorCoverageExtent: \"%s\"\n",
4121 			sqlite3_errmsg (sqlite));
4122 	  goto error;
4123       }
4124 
4125     sql =
4126 	"SELECT coverage_name, virt_name FROM vector_coverages WHERE virt_name IS NOT NULL";
4127     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_virt, NULL);
4128     if (ret != SQLITE_OK)
4129       {
4130 	  spatialite_e ("updateVectorCoverageExtent: ERROR #1 !!! \"%s\"\n",
4131 			sqlite3_errmsg (sqlite));
4132 	  goto error;
4133       }
4134     while (1)
4135       {
4136 	  /* scrolling the result set rows */
4137 	  ret = sqlite3_step (stmt_virt);
4138 	  if (ret == SQLITE_DONE)
4139 	      break;		/* end of result set */
4140 	  if (ret == SQLITE_ROW)
4141 	    {
4142 		const char *coverage_name =
4143 		    (const char *) sqlite3_column_text (stmt_virt, 0);
4144 		const char *virt_name =
4145 		    (const char *) sqlite3_column_text (stmt_virt, 1);
4146 		sql =
4147 		    sqlite3_mprintf ("UPDATE vector_coverages_srid SET "
4148 				     "extent_minx = MbrMinX(ST_Transform(GetVirtualTableExtent(%Q), srid)), "
4149 				     "extent_miny = MbrMinY(ST_Transform(GetVirtualTableExtent(%Q), srid)), "
4150 				     "extent_maxx = MbrMaxX(ST_Transform(GetVirtualTableExtent(%Q), srid)), "
4151 				     "extent_maxy = MbrMaxY(ST_Transform(GetVirtualTableExtent(%Q), srid)) "
4152 				     "WHERE coverage_name = %Q", virt_name,
4153 				     virt_name, virt_name, virt_name,
4154 				     coverage_name);
4155 		ret = sqlite3_exec (sqlite, sql, NULL, NULL, NULL);
4156 		sqlite3_free (sql);
4157 		if (ret != SQLITE_OK)
4158 		  {
4159 		      spatialite_e
4160 			  ("updateVectorCoverageExtent:  ERROR #2 !!! %d \"%s\"\n",
4161 			   ret, sqlite3_errmsg (sqlite));
4162 		      goto error;
4163 		  }
4164 	    }
4165 	  else
4166 	    {
4167 		spatialite_e
4168 		    ("updateVectorCoverageExtent() error: \"%s\"\n",
4169 		     sqlite3_errmsg (sqlite));
4170 		goto error;
4171 	    }
4172       }
4173 
4174     if (transaction)
4175       {
4176 	  /* committing the still pending Transaction */
4177 	  ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
4178 	  if (ret != SQLITE_OK)
4179 	      goto error;
4180       }
4181 
4182     sqlite3_finalize (stmt);
4183     sqlite3_finalize (stmt_upd_cvg);
4184     sqlite3_finalize (stmt_upd_srid);
4185     sqlite3_finalize (stmt_null_srid);
4186     sqlite3_finalize (stmt_srid);
4187     sqlite3_finalize (stmt_virt);
4188     return 1;
4189 
4190   error:
4191     if (stmt != NULL)
4192 	sqlite3_finalize (stmt);
4193     if (stmt_ext != NULL)
4194 	sqlite3_finalize (stmt_ext);
4195     if (stmt_upd_cvg != NULL)
4196 	sqlite3_finalize (stmt_upd_cvg);
4197     if (stmt_upd_srid != NULL)
4198 	sqlite3_finalize (stmt_upd_srid);
4199     if (stmt_null_srid != NULL)
4200 	sqlite3_finalize (stmt_null_srid);
4201     if (stmt_srid != NULL)
4202 	sqlite3_finalize (stmt_srid);
4203     if (stmt_virt != NULL)
4204 	sqlite3_finalize (stmt_virt);
4205 
4206     return 0;
4207 }
4208 
4209 static int
check_raster_coverage_srid2(sqlite3 * sqlite,const char * coverage_name,int srid)4210 check_raster_coverage_srid2 (sqlite3 * sqlite, const char *coverage_name,
4211 			     int srid)
4212 {
4213 /* checks if a Raster Coverage SRID do actually exists */
4214     int ret;
4215     const char *sql;
4216     sqlite3_stmt *stmt;
4217     int count = 0;
4218 
4219     sql = "SELECT srid FROM raster_coverages_srid "
4220 	"WHERE Lower(coverage_name) = Lower(?) AND srid = ?";
4221     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
4222     if (ret != SQLITE_OK)
4223       {
4224 	  spatialite_e ("check Raster Coverage SRID: \"%s\"\n",
4225 			sqlite3_errmsg (sqlite));
4226 	  goto stop;
4227       }
4228     sqlite3_reset (stmt);
4229     sqlite3_clear_bindings (stmt);
4230     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
4231 		       SQLITE_STATIC);
4232     sqlite3_bind_int (stmt, 2, srid);
4233     while (1)
4234       {
4235 	  /* scrolling the result set rows */
4236 	  ret = sqlite3_step (stmt);
4237 	  if (ret == SQLITE_DONE)
4238 	      break;		/* end of result set */
4239 	  if (ret == SQLITE_ROW)
4240 	      count++;
4241       }
4242     sqlite3_finalize (stmt);
4243     if (count == 1)
4244 	return 1;
4245     return 0;
4246   stop:
4247     return 0;
4248 }
4249 
4250 static int
check_raster_coverage_srid1(sqlite3 * sqlite,const char * coverage_name,int srid)4251 check_raster_coverage_srid1 (sqlite3 * sqlite, const char *coverage_name,
4252 			     int srid)
4253 {
4254 /* checks if a Raster Coverage do actually exists and check its SRID */
4255     int ret;
4256     const char *sql;
4257     sqlite3_stmt *stmt;
4258     int count = 0;
4259     int same_srid = 0;
4260 
4261     sql = "SELECT srid FROM raster_coverages "
4262 	"WHERE Lower(coverage_name) = Lower(?)";
4263     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
4264     if (ret != SQLITE_OK)
4265       {
4266 	  spatialite_e ("check Raster Coverage SRID: \"%s\"\n",
4267 			sqlite3_errmsg (sqlite));
4268 	  goto stop;
4269       }
4270     sqlite3_reset (stmt);
4271     sqlite3_clear_bindings (stmt);
4272     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
4273 		       SQLITE_STATIC);
4274     while (1)
4275       {
4276 	  /* scrolling the result set rows */
4277 	  ret = sqlite3_step (stmt);
4278 	  if (ret == SQLITE_DONE)
4279 	      break;		/* end of result set */
4280 	  if (ret == SQLITE_ROW)
4281 	    {
4282 		int natural_srid = sqlite3_column_int (stmt, 0);
4283 		if (srid == natural_srid)
4284 		    same_srid++;
4285 		count++;
4286 	    }
4287       }
4288     sqlite3_finalize (stmt);
4289     if (count == 1 && same_srid == 0)
4290       {
4291 	  if (check_raster_coverage_srid2 (sqlite, coverage_name, srid))
4292 	      return 0;
4293 	  else
4294 	      return 1;
4295       }
4296     return 0;
4297   stop:
4298     return 0;
4299 }
4300 
4301 SPATIALITE_PRIVATE int
register_raster_coverage_srid(void * p_sqlite,const char * coverage_name,int srid)4302 register_raster_coverage_srid (void *p_sqlite, const char *coverage_name,
4303 			       int srid)
4304 {
4305 /* auxiliary function: inserting a Raster Coverage alternative SRID */
4306     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
4307     int ret;
4308     const char *sql;
4309     sqlite3_stmt *stmt;
4310 
4311     if (coverage_name == NULL)
4312 	return 0;
4313     if (srid <= 0)
4314 	return 0;
4315 
4316     /* checking if the Raster Coverage do actually exists */
4317     if (!check_raster_coverage_srid1 (sqlite, coverage_name, srid))
4318 	return 0;
4319 
4320     /* attempting to insert the Raster Coverage alternative SRID */
4321     sql = "INSERT INTO raster_coverages_srid "
4322 	"(coverage_name, srid) VALUES (Lower(?), ?)";
4323     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
4324     if (ret != SQLITE_OK)
4325       {
4326 	  spatialite_e ("registerRasterCoverageSrid: \"%s\"\n",
4327 			sqlite3_errmsg (sqlite));
4328 	  return 0;
4329       }
4330     sqlite3_reset (stmt);
4331     sqlite3_clear_bindings (stmt);
4332     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
4333 		       SQLITE_STATIC);
4334     sqlite3_bind_int (stmt, 2, srid);
4335     ret = sqlite3_step (stmt);
4336     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4337 	;
4338     else
4339       {
4340 	  spatialite_e ("registerRasterCoverageSrid() error: \"%s\"\n",
4341 			sqlite3_errmsg (sqlite));
4342 	  sqlite3_finalize (stmt);
4343 	  return 0;
4344       }
4345     sqlite3_finalize (stmt);
4346     return 1;
4347 }
4348 
4349 static void
do_delete_raster_coverage_srid(sqlite3 * sqlite,const char * coverage_name,int srid)4350 do_delete_raster_coverage_srid (sqlite3 * sqlite, const char *coverage_name,
4351 				int srid)
4352 {
4353 /* auxiliary function: deleting all Raster Coverage alternative SRIDs */
4354     int ret;
4355     const char *sql;
4356     sqlite3_stmt *stmt;
4357 
4358     sql = "DELETE FROM raster_coverages_srid "
4359 	"WHERE Lower(coverage_name) = Lower(?) AND srid = ?";
4360     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
4361     if (ret != SQLITE_OK)
4362       {
4363 	  spatialite_e ("unregisterRasterCoverageSrid: \"%s\"\n",
4364 			sqlite3_errmsg (sqlite));
4365 	  return;
4366       }
4367     sqlite3_reset (stmt);
4368     sqlite3_clear_bindings (stmt);
4369     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
4370 		       SQLITE_STATIC);
4371     sqlite3_bind_int (stmt, 2, srid);
4372     ret = sqlite3_step (stmt);
4373     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4374 	;
4375     else
4376 	spatialite_e ("unregisterRasterCoverageSrid() error: \"%s\"\n",
4377 		      sqlite3_errmsg (sqlite));
4378     sqlite3_finalize (stmt);
4379 }
4380 
4381 SPATIALITE_PRIVATE int
unregister_raster_coverage_srid(void * p_sqlite,const char * coverage_name,int srid)4382 unregister_raster_coverage_srid (void *p_sqlite, const char *coverage_name,
4383 				 int srid)
4384 {
4385 /* auxiliary function: deletes a Raster Coverage alternative SRID */
4386     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
4387 
4388     if (coverage_name == NULL)
4389 	return 0;
4390 
4391     /* checking if the Raster Coverage SRID do actually exists */
4392     if (!check_raster_coverage_srid2 (sqlite, coverage_name, srid))
4393 	return 0;
4394     /* deleting the alternative SRID */
4395     do_delete_raster_coverage_srid (sqlite, coverage_name, srid);
4396     return 1;
4397 }
4398 
4399 static int
check_raster_coverage_keyword0(sqlite3 * sqlite,const char * coverage_name)4400 check_raster_coverage_keyword0 (sqlite3 * sqlite, const char *coverage_name)
4401 {
4402 /* checks if a Raster Coverage do actually exists */
4403     int ret;
4404     const char *sql;
4405     sqlite3_stmt *stmt;
4406     int count = 0;
4407 
4408     sql =
4409 	"SELECT coverage_name FROM raster_coverages WHERE Lower(coverage_name) = Lower(?)";
4410     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
4411     if (ret != SQLITE_OK)
4412       {
4413 	  spatialite_e ("check Raster Coverage Keyword: \"%s\"\n",
4414 			sqlite3_errmsg (sqlite));
4415 	  goto stop;
4416       }
4417     sqlite3_reset (stmt);
4418     sqlite3_clear_bindings (stmt);
4419     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
4420 		       SQLITE_STATIC);
4421     while (1)
4422       {
4423 	  /* scrolling the result set rows */
4424 	  ret = sqlite3_step (stmt);
4425 	  if (ret == SQLITE_DONE)
4426 	      break;		/* end of result set */
4427 	  if (ret == SQLITE_ROW)
4428 	      count++;
4429       }
4430     sqlite3_finalize (stmt);
4431     if (count == 0)
4432 	return 0;
4433     return 1;
4434   stop:
4435     return 0;
4436 }
4437 
4438 static int
check_raster_coverage_keyword1(sqlite3 * sqlite,const char * coverage_name,const char * keyword)4439 check_raster_coverage_keyword1 (sqlite3 * sqlite, const char *coverage_name,
4440 				const char *keyword)
4441 {
4442 /* checks if a Raster Coverage do actually exists and check the Keyword */
4443     int ret;
4444     const char *sql;
4445     sqlite3_stmt *stmt;
4446     int same_kw = 0;
4447 
4448     sql =
4449 	"SELECT keyword FROM raster_coverages_keyword WHERE Lower(coverage_name) = Lower(?)";
4450     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
4451     if (ret != SQLITE_OK)
4452       {
4453 	  spatialite_e ("check Raster Coverage Keyword: \"%s\"\n",
4454 			sqlite3_errmsg (sqlite));
4455 	  goto stop;
4456       }
4457     sqlite3_reset (stmt);
4458     sqlite3_clear_bindings (stmt);
4459     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
4460 		       SQLITE_STATIC);
4461     while (1)
4462       {
4463 	  /* scrolling the result set rows */
4464 	  ret = sqlite3_step (stmt);
4465 	  if (ret == SQLITE_DONE)
4466 	      break;		/* end of result set */
4467 	  if (ret == SQLITE_ROW)
4468 	    {
4469 		const char *kw = (const char *) sqlite3_column_text (stmt, 0);
4470 		if (strcasecmp (kw, keyword) == 0)
4471 		    same_kw++;
4472 	    }
4473       }
4474     sqlite3_finalize (stmt);
4475     if (same_kw == 0)
4476       {
4477 	  if (!check_raster_coverage_keyword0 (sqlite, coverage_name))
4478 	      return 0;
4479 	  else
4480 	      return 1;
4481       }
4482     return 0;
4483   stop:
4484     return 0;
4485 }
4486 
4487 static int
check_raster_coverage_keyword2(sqlite3 * sqlite,const char * coverage_name,const char * keyword)4488 check_raster_coverage_keyword2 (sqlite3 * sqlite, const char *coverage_name,
4489 				const char *keyword)
4490 {
4491 /* checks if a Raster Coverage do actually exists and check the Keyword */
4492     int ret;
4493     const char *sql;
4494     sqlite3_stmt *stmt;
4495     int count = 0;
4496 
4497     sql = "SELECT keyword FROM raster_coverages_keyword "
4498 	"WHERE Lower(coverage_name) = Lower(?) AND Lower(keyword) = Lower(?)";
4499     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
4500     if (ret != SQLITE_OK)
4501       {
4502 	  spatialite_e ("check Raster Coverage Keyword: \"%s\"\n",
4503 			sqlite3_errmsg (sqlite));
4504 	  goto stop;
4505       }
4506     sqlite3_reset (stmt);
4507     sqlite3_clear_bindings (stmt);
4508     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
4509 		       SQLITE_STATIC);
4510     sqlite3_bind_text (stmt, 2, keyword, strlen (keyword), SQLITE_STATIC);
4511     while (1)
4512       {
4513 	  /* scrolling the result set rows */
4514 	  ret = sqlite3_step (stmt);
4515 	  if (ret == SQLITE_DONE)
4516 	      break;		/* end of result set */
4517 	  if (ret == SQLITE_ROW)
4518 	      count++;
4519       }
4520     sqlite3_finalize (stmt);
4521     if (count == 0)
4522 	return 0;
4523     return 1;
4524   stop:
4525     return 0;
4526 }
4527 
4528 SPATIALITE_PRIVATE int
register_raster_coverage_keyword(void * p_sqlite,const char * coverage_name,const char * keyword)4529 register_raster_coverage_keyword (void *p_sqlite, const char *coverage_name,
4530 				  const char *keyword)
4531 {
4532 /* auxiliary function: inserting a Raster Coverage Keyword */
4533     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
4534     int ret;
4535     const char *sql;
4536     sqlite3_stmt *stmt;
4537 
4538     if (coverage_name == NULL)
4539 	return 0;
4540     if (keyword == NULL)
4541 	return 0;
4542 
4543     /* checking if the Raster Coverage do actually exists */
4544     if (!check_raster_coverage_keyword1 (sqlite, coverage_name, keyword))
4545 	return 0;
4546 
4547     /* attempting to insert the Raster Coverage Keyword */
4548     sql = "INSERT INTO raster_coverages_keyword "
4549 	"(coverage_name, keyword) VALUES (Lower(?), ?)";
4550     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
4551     if (ret != SQLITE_OK)
4552       {
4553 	  spatialite_e ("registerRasterCoverageKeyword: \"%s\"\n",
4554 			sqlite3_errmsg (sqlite));
4555 	  return 0;
4556       }
4557     sqlite3_reset (stmt);
4558     sqlite3_clear_bindings (stmt);
4559     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
4560 		       SQLITE_STATIC);
4561     sqlite3_bind_text (stmt, 2, keyword, strlen (keyword), SQLITE_STATIC);
4562     ret = sqlite3_step (stmt);
4563     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4564 	;
4565     else
4566       {
4567 	  spatialite_e ("registerRasterCoverageKeyword() error: \"%s\"\n",
4568 			sqlite3_errmsg (sqlite));
4569 	  sqlite3_finalize (stmt);
4570 	  return 0;
4571       }
4572     sqlite3_finalize (stmt);
4573     return 1;
4574 }
4575 
4576 static void
do_delete_raster_coverage_keyword(sqlite3 * sqlite,const char * coverage_name,const char * keyword)4577 do_delete_raster_coverage_keyword (sqlite3 * sqlite, const char *coverage_name,
4578 				   const char *keyword)
4579 {
4580 /* auxiliary function: deleting all Raster Coverage Keyword */
4581     int ret;
4582     const char *sql;
4583     sqlite3_stmt *stmt;
4584 
4585     sql = "DELETE FROM raster_coverages_keyword "
4586 	"WHERE Lower(coverage_name) = Lower(?) AND Lower(keyword) = Lower(?)";
4587     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
4588     if (ret != SQLITE_OK)
4589       {
4590 	  spatialite_e ("unregisterRasterCoverageKeyword: \"%s\"\n",
4591 			sqlite3_errmsg (sqlite));
4592 	  return;
4593       }
4594     sqlite3_reset (stmt);
4595     sqlite3_clear_bindings (stmt);
4596     sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
4597 		       SQLITE_STATIC);
4598     sqlite3_bind_text (stmt, 2, keyword, strlen (keyword), SQLITE_STATIC);
4599     ret = sqlite3_step (stmt);
4600     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4601 	;
4602     else
4603 	spatialite_e ("unregisterRasterCoverageKeyword() error: \"%s\"\n",
4604 		      sqlite3_errmsg (sqlite));
4605     sqlite3_finalize (stmt);
4606 }
4607 
4608 SPATIALITE_PRIVATE int
unregister_raster_coverage_keyword(void * p_sqlite,const char * coverage_name,const char * keyword)4609 unregister_raster_coverage_keyword (void *p_sqlite, const char *coverage_name,
4610 				    const char *keyword)
4611 {
4612 /* auxiliary function: deletes a Raster Coverage Keyword */
4613     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
4614 
4615     if (coverage_name == NULL)
4616 	return 0;
4617     if (keyword == NULL)
4618 	return 0;
4619 
4620     /* checking if the Raster Coverage Keyword do actually exists */
4621     if (!check_raster_coverage_keyword2 (sqlite, coverage_name, keyword))
4622 	return 0;
4623     /* deleting the Keyword */
4624     do_delete_raster_coverage_keyword (sqlite, coverage_name, keyword);
4625     return 1;
4626 }
4627 
4628 static int
do_null_raster_coverage_extents(sqlite3 * sqlite,sqlite3_stmt * stmt_upd_cvg,sqlite3_stmt * stmt_null_srid,const char * coverage_name)4629 do_null_raster_coverage_extents (sqlite3 * sqlite, sqlite3_stmt * stmt_upd_cvg,
4630 				 sqlite3_stmt * stmt_null_srid,
4631 				 const char *coverage_name)
4632 {
4633 /* setting the main Coverage Extent to NULL */
4634     int ret;
4635     sqlite3_reset (stmt_upd_cvg);
4636     sqlite3_clear_bindings (stmt_upd_cvg);
4637     sqlite3_bind_null (stmt_upd_cvg, 1);
4638     sqlite3_bind_null (stmt_upd_cvg, 2);
4639     sqlite3_bind_null (stmt_upd_cvg, 3);
4640     sqlite3_bind_null (stmt_upd_cvg, 4);
4641     sqlite3_bind_null (stmt_upd_cvg, 5);
4642     sqlite3_bind_null (stmt_upd_cvg, 6);
4643     sqlite3_bind_null (stmt_upd_cvg, 7);
4644     sqlite3_bind_null (stmt_upd_cvg, 8);
4645     sqlite3_bind_text (stmt_upd_cvg, 9, coverage_name, strlen (coverage_name),
4646 		       SQLITE_STATIC);
4647     ret = sqlite3_step (stmt_upd_cvg);
4648     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4649 	;
4650     else
4651       {
4652 	  spatialite_e ("updateRasterCoverageExtent error: \"%s\"\n",
4653 			sqlite3_errmsg (sqlite));
4654 	  return 0;
4655       }
4656 /* setting all alternativ Coverage Extent to NULL */
4657     sqlite3_reset (stmt_null_srid);
4658     sqlite3_clear_bindings (stmt_null_srid);
4659     sqlite3_bind_text (stmt_null_srid, 1, coverage_name, strlen (coverage_name),
4660 		       SQLITE_STATIC);
4661     ret = sqlite3_step (stmt_null_srid);
4662     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4663 	;
4664     else
4665       {
4666 	  spatialite_e ("updateRasterCoverageExtent error: \"%s\"\n",
4667 			sqlite3_errmsg (sqlite));
4668 	  return 0;
4669       }
4670     return 1;
4671 }
4672 
4673 static int
do_update_raster_coverage_extents(sqlite3 * sqlite,const void * cache,sqlite3_stmt * stmt_upd_cvg,sqlite3_stmt * stmt_srid,sqlite3_stmt * stmt_upd_srid,const char * coverage_name,int natural_srid,double minx,double miny,double maxx,double maxy)4674 do_update_raster_coverage_extents (sqlite3 * sqlite, const void *cache,
4675 				   sqlite3_stmt * stmt_upd_cvg,
4676 				   sqlite3_stmt * stmt_srid,
4677 				   sqlite3_stmt * stmt_upd_srid,
4678 				   const char *coverage_name, int natural_srid,
4679 				   double minx, double miny, double maxx,
4680 				   double maxy)
4681 {
4682 /* updating the Coverage Extents */
4683     int ret;
4684     int geographic = 0;
4685     double geo_minx = minx;
4686     double geo_miny = miny;
4687     double geo_maxx = maxx;
4688     double geo_maxy = maxy;
4689     char *proj_from = NULL;
4690     char *proj_to = NULL;
4691     gaiaGeomCollPtr in;
4692     gaiaGeomCollPtr out;
4693     gaiaPointPtr pt;
4694 
4695 #ifndef OMIT_PROJ		/* including PROJ.4 */
4696 
4697     getProjParams (sqlite, natural_srid, &proj_from);
4698     if (proj_from == NULL)
4699 	goto error;
4700 
4701     ret = srid_is_geographic (sqlite, natural_srid, &geographic);
4702     if (!ret)
4703 	return 0;
4704     if (!geographic)
4705       {
4706 	  /* computing the geographic extent */
4707 	  getProjParams (sqlite, 4326, &proj_to);
4708 	  if (proj_to == NULL)
4709 	      goto error;
4710 	  in = gaiaAllocGeomColl ();
4711 	  in->Srid = natural_srid;
4712 	  gaiaAddPointToGeomColl (in, minx, miny);
4713 	  if (cache != NULL)
4714 	      out = gaiaTransform_r (cache, in, proj_from, proj_to);
4715 	  else
4716 	      out = gaiaTransform (in, proj_from, proj_to);
4717 	  if (out == NULL)
4718 	    {
4719 		gaiaFreeGeomColl (in);
4720 		goto error;
4721 	    }
4722 	  pt = out->FirstPoint;
4723 	  if (pt == NULL)
4724 	    {
4725 		gaiaFreeGeomColl (in);
4726 		gaiaFreeGeomColl (out);
4727 		goto error;
4728 	    }
4729 	  geo_minx = pt->X;
4730 	  geo_miny = pt->Y;
4731 	  gaiaFreeGeomColl (in);
4732 	  gaiaFreeGeomColl (out);
4733 	  in = gaiaAllocGeomColl ();
4734 	  in->Srid = natural_srid;
4735 	  gaiaAddPointToGeomColl (in, maxx, maxy);
4736 	  if (cache != NULL)
4737 	      out = gaiaTransform_r (cache, in, proj_from, proj_to);
4738 	  else
4739 	      out = gaiaTransform (in, proj_from, proj_to);
4740 	  if (out == NULL)
4741 	    {
4742 		gaiaFreeGeomColl (in);
4743 		goto error;
4744 	    }
4745 	  pt = out->FirstPoint;
4746 	  if (pt == NULL)
4747 	    {
4748 		gaiaFreeGeomColl (in);
4749 		gaiaFreeGeomColl (out);
4750 		goto error;
4751 	    }
4752 	  geo_maxx = pt->X;
4753 	  geo_maxy = pt->Y;
4754 	  gaiaFreeGeomColl (in);
4755 	  gaiaFreeGeomColl (out);
4756 	  free (proj_to);
4757 	  proj_to = NULL;
4758       }
4759 
4760 /* setting the main Coverage Extent */
4761     sqlite3_reset (stmt_upd_cvg);
4762     sqlite3_clear_bindings (stmt_upd_cvg);
4763     sqlite3_bind_double (stmt_upd_cvg, 1, geo_minx);
4764     sqlite3_bind_double (stmt_upd_cvg, 2, geo_miny);
4765     sqlite3_bind_double (stmt_upd_cvg, 3, geo_maxx);
4766     sqlite3_bind_double (stmt_upd_cvg, 4, geo_maxy);
4767     sqlite3_bind_double (stmt_upd_cvg, 5, minx);
4768     sqlite3_bind_double (stmt_upd_cvg, 6, miny);
4769     sqlite3_bind_double (stmt_upd_cvg, 7, maxx);
4770     sqlite3_bind_double (stmt_upd_cvg, 8, maxy);
4771     sqlite3_bind_text (stmt_upd_cvg, 9, coverage_name, strlen (coverage_name),
4772 		       SQLITE_STATIC);
4773     ret = sqlite3_step (stmt_upd_cvg);
4774     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4775 	;
4776     else
4777       {
4778 	  spatialite_e ("updateRasterCoverageExtent error: \"%s\"\n",
4779 			sqlite3_errmsg (sqlite));
4780 	  goto error;
4781       }
4782 
4783 /* updating any alternative SRID supporting this Raster Coverage */
4784     sqlite3_reset (stmt_srid);
4785     sqlite3_clear_bindings (stmt_srid);
4786     sqlite3_bind_text (stmt_srid, 1, coverage_name, strlen (coverage_name),
4787 		       SQLITE_STATIC);
4788     while (1)
4789       {
4790 	  /* scrolling the result set rows */
4791 	  ret = sqlite3_step (stmt_srid);
4792 	  if (ret == SQLITE_DONE)
4793 	      break;		/* end of result set */
4794 	  if (ret == SQLITE_ROW)
4795 	    {
4796 		/* processing a single alternative SRID Extent */
4797 		double alt_minx;
4798 		double alt_miny;
4799 		double alt_maxx;
4800 		double alt_maxy;
4801 		int srid = sqlite3_column_int (stmt_srid, 0);
4802 		getProjParams (sqlite, srid, &proj_to);
4803 		if (proj_to == NULL)
4804 		    goto error;
4805 		in = gaiaAllocGeomColl ();
4806 		in->Srid = natural_srid;
4807 		gaiaAddPointToGeomColl (in, minx, miny);
4808 		if (cache != NULL)
4809 		    out = gaiaTransform_r (cache, in, proj_from, proj_to);
4810 		else
4811 		    out = gaiaTransform (in, proj_from, proj_to);
4812 		if (out == NULL)
4813 		  {
4814 		      gaiaFreeGeomColl (in);
4815 		      goto error;
4816 		  }
4817 		pt = out->FirstPoint;
4818 		if (pt == NULL)
4819 		  {
4820 		      gaiaFreeGeomColl (in);
4821 		      gaiaFreeGeomColl (out);
4822 		      goto error;
4823 		  }
4824 		alt_minx = pt->X;
4825 		alt_miny = pt->Y;
4826 		gaiaFreeGeomColl (in);
4827 		gaiaFreeGeomColl (out);
4828 		in = gaiaAllocGeomColl ();
4829 		in->Srid = natural_srid;
4830 		gaiaAddPointToGeomColl (in, maxx, maxy);
4831 		if (cache != NULL)
4832 		    out = gaiaTransform_r (cache, in, proj_from, proj_to);
4833 		else
4834 		    out = gaiaTransform (in, proj_from, proj_to);
4835 		if (out == NULL)
4836 		  {
4837 		      gaiaFreeGeomColl (in);
4838 		      goto error;
4839 		  }
4840 		pt = out->FirstPoint;
4841 		if (pt == NULL)
4842 		  {
4843 		      gaiaFreeGeomColl (in);
4844 		      gaiaFreeGeomColl (out);
4845 		      goto error;
4846 		  }
4847 		alt_maxx = pt->X;
4848 		alt_maxy = pt->Y;
4849 		gaiaFreeGeomColl (in);
4850 		gaiaFreeGeomColl (out);
4851 		free (proj_to);
4852 		proj_to = NULL;
4853 
4854 /* setting the alternative Srid Extent */
4855 		sqlite3_reset (stmt_upd_srid);
4856 		sqlite3_clear_bindings (stmt_upd_srid);
4857 		sqlite3_bind_double (stmt_upd_srid, 1, alt_minx);
4858 		sqlite3_bind_double (stmt_upd_srid, 2, alt_miny);
4859 		sqlite3_bind_double (stmt_upd_srid, 3, alt_maxx);
4860 		sqlite3_bind_double (stmt_upd_srid, 4, alt_maxy);
4861 		sqlite3_bind_text (stmt_upd_srid, 5, coverage_name,
4862 				   strlen (coverage_name), SQLITE_STATIC);
4863 		sqlite3_bind_int (stmt_upd_srid, 6, srid);
4864 		ret = sqlite3_step (stmt_upd_srid);
4865 		if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4866 		    ;
4867 		else
4868 		  {
4869 		      spatialite_e
4870 			  ("updateRasterCoverageExtent error: \"%s\"\n",
4871 			   sqlite3_errmsg (sqlite));
4872 		      goto error;
4873 		  }
4874 	    }
4875 	  else
4876 	    {
4877 		spatialite_e ("updateRasterCoverageExtent() error: \"%s\"\n",
4878 			      sqlite3_errmsg (sqlite));
4879 		goto error;
4880 	    }
4881       }
4882 
4883     free (proj_from);
4884     return 1;
4885 
4886   error:
4887     if (proj_from)
4888 	free (proj_from);
4889     if (proj_to)
4890 	free (proj_to);
4891 #endif /* end including PROJ.4 */
4892     return 0;
4893 }
4894 
4895 SPATIALITE_PRIVATE int
update_raster_coverage_extent(void * p_sqlite,const void * cache,const char * coverage_name,int transaction)4896 update_raster_coverage_extent (void *p_sqlite, const void *cache,
4897 			       const char *coverage_name, int transaction)
4898 {
4899 /* updates one (or all) Raster Coverage Extents */
4900     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
4901     int ret;
4902     char *sql;
4903     sqlite3_stmt *stmt = NULL;
4904     sqlite3_stmt *stmt_ext = NULL;
4905     sqlite3_stmt *stmt_upd_cvg = NULL;
4906     sqlite3_stmt *stmt_upd_srid = NULL;
4907     sqlite3_stmt *stmt_null_srid = NULL;
4908     sqlite3_stmt *stmt_srid = NULL;
4909 
4910 /* preparing the ancillary SQL statements */
4911     sql = "SELECT srid FROM raster_coverages_srid "
4912 	"WHERE Lower(coverage_name) = Lower(?)";
4913     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_srid, NULL);
4914     if (ret != SQLITE_OK)
4915       {
4916 	  spatialite_e ("updateRasterCoverageExtent: \"%s\"\n",
4917 			sqlite3_errmsg (sqlite));
4918 	  goto error;
4919       }
4920 
4921     sql = "UPDATE raster_coverages SET geo_minx = ?, geo_miny = ?, "
4922 	"geo_maxx = ?, geo_maxy = ?, extent_minx = ?, extent_miny = ?, "
4923 	"extent_maxx = ?, extent_maxy = ? "
4924 	"WHERE Lower(coverage_name) = Lower(?)";
4925     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_upd_cvg, NULL);
4926     if (ret != SQLITE_OK)
4927       {
4928 	  spatialite_e ("updateRasterCoverageExtent: \"%s\"\n",
4929 			sqlite3_errmsg (sqlite));
4930 	  goto error;
4931       }
4932 
4933     sql = "UPDATE raster_coverages_srid SET extent_minx = NULL, "
4934 	"extent_miny = NULL, extent_maxx = NULL, extent_maxy = NULL "
4935 	"WHERE Lower(coverage_name) = Lower(?)";
4936     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_null_srid, NULL);
4937     if (ret != SQLITE_OK)
4938       {
4939 	  spatialite_e ("updateRasterCoverageExtent: \"%s\"\n",
4940 			sqlite3_errmsg (sqlite));
4941 	  goto error;
4942       }
4943 
4944     sql = "UPDATE raster_coverages_srid SET extent_minx = ?, "
4945 	"extent_miny = ?, extent_maxx = ?, extent_maxy = ? "
4946 	"WHERE Lower(coverage_name) = Lower(?) AND srid = ?";
4947     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_upd_srid, NULL);
4948     if (ret != SQLITE_OK)
4949       {
4950 	  spatialite_e ("updateRasterCoverageExtent: \"%s\"\n",
4951 			sqlite3_errmsg (sqlite));
4952 	  goto error;
4953       }
4954 
4955 /* preparing the main SQL statement */
4956     if (coverage_name == NULL)
4957       {
4958 	  sql = "SELECT coverage_name, srid FROM raster_coverages";
4959       }
4960     else
4961       {
4962 
4963 	  sql = "SELECT coverage_name, srid FROM raster_coverages "
4964 	      "WHERE Lower(coverage_name) = Lower(?)";
4965       }
4966     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
4967     if (ret != SQLITE_OK)
4968       {
4969 	  spatialite_e ("updateRasterCoverageExtent: \"%s\"\n",
4970 			sqlite3_errmsg (sqlite));
4971 	  goto error;
4972       }
4973 
4974     if (transaction)
4975       {
4976 	  /* starting a Transaction */
4977 	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
4978 	  if (ret != SQLITE_OK)
4979 	      goto error;
4980       }
4981 
4982     sqlite3_reset (stmt);
4983     sqlite3_clear_bindings (stmt);
4984     if (coverage_name != NULL)
4985 	sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
4986 			   SQLITE_STATIC);
4987     while (1)
4988       {
4989 	  /* scrolling the result set rows */
4990 	  ret = sqlite3_step (stmt);
4991 	  if (ret == SQLITE_DONE)
4992 	      break;		/* end of result set */
4993 	  if (ret == SQLITE_ROW)
4994 	    {
4995 		/* processing a single Raster Coverage */
4996 		char *xtile_table;
4997 		char *tile_table;
4998 		const char *cvg = (const char *) sqlite3_column_text (stmt, 0);
4999 		int natural_srid = sqlite3_column_int (stmt, 1);
5000 		xtile_table = sqlite3_mprintf ("%s_tiles", cvg);
5001 		tile_table = gaiaDoubleQuotedSql (xtile_table);
5002 		sqlite3_free (xtile_table);
5003 		sql =
5004 		    sqlite3_mprintf
5005 		    ("SELECT Min(MbrMinX(geometry)), Min(MbrMinY(geometry)), "
5006 		     "Max(MbrMaxX(geometry)), Max(MbrMaxY(geometry)) FROM \"%s\"",
5007 		     tile_table);
5008 		free (tile_table);
5009 		ret =
5010 		    sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_ext,
5011 					NULL);
5012 		sqlite3_free (sql);
5013 		if (ret != SQLITE_OK)
5014 		  {
5015 		      spatialite_e ("updateRasterCoverageExtent: \"%s\"\n",
5016 				    sqlite3_errmsg (sqlite));
5017 		      goto error;
5018 		  }
5019 		while (1)
5020 		  {
5021 		      /* scrolling the result set rows */
5022 		      ret = sqlite3_step (stmt_ext);
5023 		      if (ret == SQLITE_DONE)
5024 			  break;	/* end of result set */
5025 		      if (ret == SQLITE_ROW)
5026 			{
5027 			    int null_minx = 1;
5028 			    int null_miny = 1;
5029 			    int null_maxx = 1;
5030 			    int null_maxy = 1;
5031 			    double minx = 0.0;
5032 			    double miny = 0.0;
5033 			    double maxx = 0.0;
5034 			    double maxy = 0.0;
5035 			    if (sqlite3_column_type (stmt_ext, 0) ==
5036 				SQLITE_FLOAT)
5037 			      {
5038 				  minx = sqlite3_column_double (stmt_ext, 0);
5039 				  null_minx = 0;
5040 			      }
5041 			    if (sqlite3_column_type (stmt_ext, 1) ==
5042 				SQLITE_FLOAT)
5043 			      {
5044 				  miny = sqlite3_column_double (stmt_ext, 1);
5045 				  null_miny = 0;
5046 			      }
5047 			    if (sqlite3_column_type (stmt_ext, 2) ==
5048 				SQLITE_FLOAT)
5049 			      {
5050 				  maxx = sqlite3_column_double (stmt_ext, 2);
5051 				  null_maxx = 0;
5052 			      }
5053 			    if (sqlite3_column_type (stmt_ext, 3) ==
5054 				SQLITE_FLOAT)
5055 			      {
5056 				  maxy = sqlite3_column_double (stmt_ext, 3);
5057 				  null_maxy = 0;
5058 			      }
5059 			    if (null_minx || null_miny || null_maxx
5060 				|| null_maxy)
5061 				ret =
5062 				    do_null_raster_coverage_extents (sqlite,
5063 								     stmt_upd_cvg,
5064 								     stmt_null_srid,
5065 								     cvg);
5066 			    else
5067 				ret =
5068 				    do_update_raster_coverage_extents (sqlite,
5069 								       cache,
5070 								       stmt_upd_cvg,
5071 								       stmt_srid,
5072 								       stmt_upd_srid,
5073 								       cvg,
5074 								       natural_srid,
5075 								       minx,
5076 								       miny,
5077 								       maxx,
5078 								       maxy);
5079 			    if (!ret)
5080 				goto error;
5081 			}
5082 		      else
5083 			{
5084 			    spatialite_e
5085 				("updateRasterCoverageExtent() error: \"%s\"\n",
5086 				 sqlite3_errmsg (sqlite));
5087 			    goto error;
5088 			}
5089 		  }
5090 		sqlite3_finalize (stmt_ext);
5091 		stmt_ext = NULL;
5092 	    }
5093 	  else
5094 	    {
5095 		spatialite_e ("updateRasterCoverageExtent() error: \"%s\"\n",
5096 			      sqlite3_errmsg (sqlite));
5097 		goto error;
5098 	    }
5099       }
5100 
5101     if (transaction)
5102       {
5103 	  /* committing the still pending Transaction */
5104 	  ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
5105 	  if (ret != SQLITE_OK)
5106 	      goto error;
5107       }
5108 
5109     sqlite3_finalize (stmt);
5110     sqlite3_finalize (stmt_upd_cvg);
5111     sqlite3_finalize (stmt_upd_srid);
5112     sqlite3_finalize (stmt_null_srid);
5113     sqlite3_finalize (stmt_srid);
5114     return 1;
5115 
5116   error:
5117     if (stmt != NULL)
5118 	sqlite3_finalize (stmt);
5119     if (stmt_ext != NULL)
5120 	sqlite3_finalize (stmt_ext);
5121     if (stmt_upd_cvg != NULL)
5122 	sqlite3_finalize (stmt_upd_cvg);
5123     if (stmt_upd_srid != NULL)
5124 	sqlite3_finalize (stmt_upd_srid);
5125     if (stmt_null_srid != NULL)
5126 	sqlite3_finalize (stmt_null_srid);
5127     if (stmt_srid != NULL)
5128 	sqlite3_finalize (stmt_srid);
5129     return 0;
5130 }
5131 
5132 SPATIALITE_PRIVATE int
get_iso_metadata_id(void * p_sqlite,const char * fileIdentifier,void * p_id)5133 get_iso_metadata_id (void *p_sqlite, const char *fileIdentifier, void *p_id)
5134 {
5135 /* auxiliary function: return the ID of the row corresponding to "fileIdentifier" */
5136     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
5137     sqlite3_int64 *p64 = (sqlite3_int64 *) p_id;
5138     sqlite3_int64 id = 0;
5139     int ret;
5140     const char *sql;
5141     sqlite3_stmt *stmt;
5142     int ok = 0;
5143 
5144     sql = "SELECT id FROM ISO_metadata WHERE fileId = ?";
5145     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5146     if (ret != SQLITE_OK)
5147       {
5148 	  spatialite_e ("getIsoMetadataId: \"%s\"\n", sqlite3_errmsg (sqlite));
5149 	  goto stop;
5150       }
5151     sqlite3_reset (stmt);
5152     sqlite3_clear_bindings (stmt);
5153     sqlite3_bind_text (stmt, 1, fileIdentifier, strlen (fileIdentifier),
5154 		       SQLITE_STATIC);
5155     while (1)
5156       {
5157 	  /* scrolling the result set rows */
5158 	  ret = sqlite3_step (stmt);
5159 	  if (ret == SQLITE_DONE)
5160 	      break;		/* end of result set */
5161 	  if (ret == SQLITE_ROW)
5162 	    {
5163 		ok++;
5164 		id = sqlite3_column_int64 (stmt, 0);
5165 	    }
5166       }
5167     sqlite3_finalize (stmt);
5168 
5169     if (ok == 1)
5170       {
5171 	  *p64 = id;
5172 	  return 1;
5173       }
5174   stop:
5175     return 0;
5176 }
5177 
5178 SPATIALITE_PRIVATE int
register_iso_metadata(void * p_sqlite,const char * scope,const unsigned char * p_blob,int n_bytes,void * p_id,const char * fileIdentifier)5179 register_iso_metadata (void *p_sqlite, const char *scope,
5180 		       const unsigned char *p_blob, int n_bytes, void *p_id,
5181 		       const char *fileIdentifier)
5182 {
5183 /* auxiliary function: inserts or updates an ISO Metadata */
5184     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
5185     sqlite3_int64 *p64 = (sqlite3_int64 *) p_id;
5186     sqlite3_int64 id = *p64;
5187     int ret;
5188     const char *sql;
5189     sqlite3_stmt *stmt;
5190     int exists = 0;
5191     int retval = 0;
5192 
5193     if (id >= 0)
5194       {
5195 	  /* checking if already exists - by ID */
5196 	  sql = "SELECT id FROM ISO_metadata WHERE id = ?";
5197 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5198 	  if (ret != SQLITE_OK)
5199 	    {
5200 		spatialite_e ("registerIsoMetadata: \"%s\"\n",
5201 			      sqlite3_errmsg (sqlite));
5202 		goto stop;
5203 	    }
5204 	  sqlite3_reset (stmt);
5205 	  sqlite3_clear_bindings (stmt);
5206 	  sqlite3_bind_int64 (stmt, 1, id);
5207 	  while (1)
5208 	    {
5209 		/* scrolling the result set rows */
5210 		ret = sqlite3_step (stmt);
5211 		if (ret == SQLITE_DONE)
5212 		    break;	/* end of result set */
5213 		if (ret == SQLITE_ROW)
5214 		    exists = 1;
5215 	    }
5216 	  sqlite3_finalize (stmt);
5217       }
5218     if (fileIdentifier != NULL)
5219       {
5220 	  /* checking if already exists - by fileIdentifier */
5221 	  sql = "SELECT id FROM ISO_metadata WHERE fileId = ?";
5222 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5223 	  if (ret != SQLITE_OK)
5224 	    {
5225 		spatialite_e ("registerIsoMetadata: \"%s\"\n",
5226 			      sqlite3_errmsg (sqlite));
5227 		goto stop;
5228 	    }
5229 	  sqlite3_reset (stmt);
5230 	  sqlite3_clear_bindings (stmt);
5231 	  sqlite3_bind_text (stmt, 1, fileIdentifier, strlen (fileIdentifier),
5232 			     SQLITE_STATIC);
5233 	  while (1)
5234 	    {
5235 		/* scrolling the result set rows */
5236 		ret = sqlite3_step (stmt);
5237 		if (ret == SQLITE_DONE)
5238 		    break;	/* end of result set */
5239 		if (ret == SQLITE_ROW)
5240 		  {
5241 		      exists = 1;
5242 		      id = sqlite3_column_int64 (stmt, 0);
5243 		  }
5244 	    }
5245 	  sqlite3_finalize (stmt);
5246       }
5247 
5248     if (exists)
5249       {
5250 	  /* update */
5251 	  sql = "UPDATE ISO_metadata SET md_scope = ?, metadata = ? "
5252 	      "WHERE id = ?";
5253       }
5254     else
5255       {
5256 	  /* insert */
5257 	  sql = "INSERT INTO ISO_metadata "
5258 	      "(id, md_scope, metadata) VALUES (?, ?, ?)";
5259       }
5260     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5261     if (ret != SQLITE_OK)
5262       {
5263 	  spatialite_e ("registerIsoMetadata: \"%s\"\n",
5264 			sqlite3_errmsg (sqlite));
5265 	  goto stop;
5266       }
5267     sqlite3_reset (stmt);
5268     sqlite3_clear_bindings (stmt);
5269     if (exists)
5270       {
5271 	  /* update */
5272 	  sqlite3_bind_text (stmt, 1, scope, strlen (scope), SQLITE_STATIC);
5273 	  sqlite3_bind_blob (stmt, 2, p_blob, n_bytes, SQLITE_STATIC);
5274 	  sqlite3_bind_int64 (stmt, 3, id);
5275       }
5276     else
5277       {
5278 	  /* insert */
5279 	  if (id < 0)
5280 	      sqlite3_bind_null (stmt, 1);
5281 	  else
5282 	      sqlite3_bind_int64 (stmt, 1, id);
5283 	  sqlite3_bind_text (stmt, 2, scope, strlen (scope), SQLITE_STATIC);
5284 	  sqlite3_bind_blob (stmt, 3, p_blob, n_bytes, SQLITE_STATIC);
5285       }
5286     ret = sqlite3_step (stmt);
5287     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
5288 	retval = 1;
5289     else
5290 	spatialite_e ("registerIsoMetadata() error: \"%s\"\n",
5291 		      sqlite3_errmsg (sqlite));
5292     sqlite3_finalize (stmt);
5293     return retval;
5294   stop:
5295     return 0;
5296 }
5297 
5298 #endif /* end including LIBXML2 */
5299 
5300 SPATIALITE_PRIVATE int
register_wms_getcapabilities(void * p_sqlite,const char * url,const char * title,const char * abstract)5301 register_wms_getcapabilities (void *p_sqlite, const char *url,
5302 			      const char *title, const char *abstract)
5303 {
5304 /* auxiliary function: inserts a WMS GetCapabilities */
5305     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
5306     int ret;
5307     const char *sql;
5308     sqlite3_stmt *stmt;
5309 
5310     if (url != NULL && title != NULL && abstract != NULL)
5311       {
5312 	  /* attempting to insert the WMS GetCapabilities */
5313 	  sql = "INSERT INTO wms_getcapabilities (url, title, abstract) "
5314 	      "VALUES (?, ?, ?)";
5315 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5316 	  if (ret != SQLITE_OK)
5317 	    {
5318 		spatialite_e ("WMS_RegisterGetCapabilities: \"%s\"\n",
5319 			      sqlite3_errmsg (sqlite));
5320 		return 0;
5321 	    }
5322 	  sqlite3_reset (stmt);
5323 	  sqlite3_clear_bindings (stmt);
5324 	  sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
5325 	  sqlite3_bind_text (stmt, 2, title, strlen (title), SQLITE_STATIC);
5326 	  sqlite3_bind_text (stmt, 3, abstract, strlen (abstract),
5327 			     SQLITE_STATIC);
5328 	  ret = sqlite3_step (stmt);
5329 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
5330 	      ;
5331 	  else
5332 	    {
5333 		spatialite_e ("WMS_RegisterGetCapabilities() error: \"%s\"\n",
5334 			      sqlite3_errmsg (sqlite));
5335 		sqlite3_finalize (stmt);
5336 		return 0;
5337 	    }
5338 	  sqlite3_finalize (stmt);
5339 	  return 1;
5340       }
5341     else if (url != NULL)
5342       {
5343 	  /* attempting to insert the WMS GetCapabilities */
5344 	  sql = "INSERT INTO wms_getcapabilities (url) VALUES (?)";
5345 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5346 	  if (ret != SQLITE_OK)
5347 	    {
5348 		spatialite_e ("WMS_RegisterGetCapabilities: \"%s\"\n",
5349 			      sqlite3_errmsg (sqlite));
5350 		return 0;
5351 	    }
5352 	  sqlite3_reset (stmt);
5353 	  sqlite3_clear_bindings (stmt);
5354 	  sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
5355 	  ret = sqlite3_step (stmt);
5356 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
5357 	      ;
5358 	  else
5359 	    {
5360 		spatialite_e ("WMS_RegisterGetCapabilities() error: \"%s\"\n",
5361 			      sqlite3_errmsg (sqlite));
5362 		sqlite3_finalize (stmt);
5363 		return 0;
5364 	    }
5365 	  sqlite3_finalize (stmt);
5366 	  return 1;
5367       }
5368     else
5369 	return 0;
5370 }
5371 
5372 static int
check_wms_getcapabilities(sqlite3 * sqlite,const char * url)5373 check_wms_getcapabilities (sqlite3 * sqlite, const char *url)
5374 {
5375 /* checks if a WMS GetCapabilities do actually exists */
5376     int ret;
5377     const char *sql;
5378     sqlite3_stmt *stmt;
5379     int count = 0;
5380 
5381     sql = "SELECT url FROM wms_getcapabilities WHERE url = ?";
5382     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5383     if (ret != SQLITE_OK)
5384       {
5385 	  spatialite_e ("check WMS GetCapabilities: \"%s\"\n",
5386 			sqlite3_errmsg (sqlite));
5387 	  goto stop;
5388       }
5389     sqlite3_reset (stmt);
5390     sqlite3_clear_bindings (stmt);
5391     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
5392     while (1)
5393       {
5394 	  /* scrolling the result set rows */
5395 	  ret = sqlite3_step (stmt);
5396 	  if (ret == SQLITE_DONE)
5397 	      break;		/* end of result set */
5398 	  if (ret == SQLITE_ROW)
5399 	      count++;
5400       }
5401     sqlite3_finalize (stmt);
5402     if (count == 1)
5403 	return 1;
5404     return 0;
5405   stop:
5406     return 0;
5407 }
5408 
5409 static int
do_delete_wms_getcapabilities(sqlite3 * sqlite,const char * url)5410 do_delete_wms_getcapabilities (sqlite3 * sqlite, const char *url)
5411 {
5412 /* auxiliary function: deleting a WMS GetCapabilities */
5413     int ret;
5414     int result = 0;
5415     const char *sql;
5416     sqlite3_stmt *stmt;
5417 
5418     sql = "DELETE FROM wms_getcapabilities WHERE url = ?";
5419     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5420     if (ret != SQLITE_OK)
5421       {
5422 	  spatialite_e ("WMS_UnRegisterGetCapabilities: \"%s\"\n",
5423 			sqlite3_errmsg (sqlite));
5424 	  return 0;
5425       }
5426     sqlite3_reset (stmt);
5427     sqlite3_clear_bindings (stmt);
5428     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
5429     ret = sqlite3_step (stmt);
5430     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
5431 	result = 1;
5432     else
5433 	spatialite_e ("WMS_UnRegisterGetCapabilities() error: \"%s\"\n",
5434 		      sqlite3_errmsg (sqlite));
5435     sqlite3_finalize (stmt);
5436     return result;
5437 }
5438 
5439 static void
do_delete_wms_settings_0(sqlite3 * sqlite,const char * url)5440 do_delete_wms_settings_0 (sqlite3 * sqlite, const char *url)
5441 {
5442 /* auxiliary function: deleting WMS settings (from GetCapabilities) */
5443     int ret;
5444     const char *sql;
5445     sqlite3_stmt *stmt;
5446 
5447     sql = "DELETE FROM wms_settings WHERE id IN ("
5448 	"SELECT s.id FROM wms_getcapabilities AS c "
5449 	"JOIN wms_getmap AS m ON (c.id = m.parent_id) "
5450 	"JOIN wms_settings AS s ON (m.id = s.parent_id) " "WHERE c.url = ?)";
5451     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5452     if (ret != SQLITE_OK)
5453       {
5454 	  spatialite_e ("WMS_UnRegisterGetCapabilities: \"%s\"\n",
5455 			sqlite3_errmsg (sqlite));
5456 	  return;
5457       }
5458     sqlite3_reset (stmt);
5459     sqlite3_clear_bindings (stmt);
5460     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
5461     ret = sqlite3_step (stmt);
5462     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
5463 	;
5464     else
5465 	spatialite_e ("WMS_UnRegisterGetCapabilities() error: \"%s\"\n",
5466 		      sqlite3_errmsg (sqlite));
5467     sqlite3_finalize (stmt);
5468 }
5469 
5470 static void
do_delete_wms_getmap_0(sqlite3 * sqlite,const char * url)5471 do_delete_wms_getmap_0 (sqlite3 * sqlite, const char *url)
5472 {
5473 /* auxiliary function: deleting WMS GetMap (from GetCapabilities) */
5474     int ret;
5475     const char *sql;
5476     sqlite3_stmt *stmt;
5477 
5478     sql = "DELETE FROM wms_getmap WHERE id IN ("
5479 	"SELECT m.id FROM wms_getcapabilities AS c "
5480 	"JOIN wms_getmap AS m ON (c.id = m.parent_id) " "WHERE c.url = ?)";
5481     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5482     if (ret != SQLITE_OK)
5483       {
5484 	  spatialite_e ("WMS_UnRegisterGetCapabilities: \"%s\"\n",
5485 			sqlite3_errmsg (sqlite));
5486 	  return;
5487       }
5488     sqlite3_reset (stmt);
5489     sqlite3_clear_bindings (stmt);
5490     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
5491     ret = sqlite3_step (stmt);
5492     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
5493 	;
5494     else
5495 	spatialite_e ("WMS_UnRegisterGetCapabilities() error: \"%s\"\n",
5496 		      sqlite3_errmsg (sqlite));
5497     sqlite3_finalize (stmt);
5498 }
5499 
5500 SPATIALITE_PRIVATE int
unregister_wms_getcapabilities(void * p_sqlite,const char * url)5501 unregister_wms_getcapabilities (void *p_sqlite, const char *url)
5502 {
5503 /* auxiliary function: deletes a WMS GetCapabilities definition (and any related) */
5504     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
5505 
5506     if (url == NULL)
5507 	return 0;
5508 
5509     /* checking if the WMS GetCapabilities do actually exists */
5510     if (!check_wms_getcapabilities (sqlite, url))
5511 	return 0;
5512     /* deleting all WMS settings */
5513     do_delete_wms_settings_0 (sqlite, url);
5514     /* deleting all WMS GetMap */
5515     do_delete_wms_getmap_0 (sqlite, url);
5516     /* deleting the WMS GetCapability itself */
5517     return do_delete_wms_getcapabilities (sqlite, url);
5518 }
5519 
5520 SPATIALITE_PRIVATE int
set_wms_getcapabilities_infos(void * p_sqlite,const char * url,const char * title,const char * abstract)5521 set_wms_getcapabilities_infos (void *p_sqlite, const char *url,
5522 			       const char *title, const char *abstract)
5523 {
5524 /* auxiliary function: updates the descriptive infos supporting a WMS GetCapabilities */
5525     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
5526     int ret;
5527     const char *sql;
5528     sqlite3_stmt *stmt;
5529 
5530     if (url != NULL && title != NULL && abstract != NULL)
5531       {
5532 	  /* checking if the WMS GetCapabilities do actually exists */
5533 	  if (!check_wms_getcapabilities (sqlite, url))
5534 	      return 0;
5535 
5536 	  /* attempting to update the WMS GetCapabilities */
5537 	  sql =
5538 	      "UPDATE wms_getcapabilities SET title = ?, abstract = ? WHERE url = ?";
5539 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5540 	  if (ret != SQLITE_OK)
5541 	    {
5542 		spatialite_e ("WMS_SetGetCapabilitiesInfos: \"%s\"\n",
5543 			      sqlite3_errmsg (sqlite));
5544 		return 0;
5545 	    }
5546 	  sqlite3_reset (stmt);
5547 	  sqlite3_clear_bindings (stmt);
5548 	  sqlite3_bind_text (stmt, 1, title, strlen (title), SQLITE_STATIC);
5549 	  sqlite3_bind_text (stmt, 2, abstract, strlen (abstract),
5550 			     SQLITE_STATIC);
5551 	  sqlite3_bind_text (stmt, 3, url, strlen (url), SQLITE_STATIC);
5552 	  ret = sqlite3_step (stmt);
5553 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
5554 	      ;
5555 	  else
5556 	    {
5557 		spatialite_e ("WMS_SetGetCapabilitiesInfos() error: \"%s\"\n",
5558 			      sqlite3_errmsg (sqlite));
5559 		sqlite3_finalize (stmt);
5560 		return 0;
5561 	    }
5562 	  sqlite3_finalize (stmt);
5563 	  return 1;
5564       }
5565     else
5566 	return 0;
5567 }
5568 
5569 static int
wms_getmap_parentid(sqlite3 * sqlite,const char * url,sqlite3_int64 * id)5570 wms_getmap_parentid (sqlite3 * sqlite, const char *url, sqlite3_int64 * id)
5571 {
5572 /* retieving the WMS GetCapabilities ID value */
5573     int ret;
5574     const char *sql;
5575     sqlite3_stmt *stmt;
5576     int count = 0;
5577 
5578     sql = "SELECT id FROM wms_getcapabilities WHERE url = ?";
5579     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5580     if (ret != SQLITE_OK)
5581       {
5582 	  spatialite_e ("GetMap parent_id: \"%s\"\n", sqlite3_errmsg (sqlite));
5583 	  goto stop;
5584       }
5585     sqlite3_reset (stmt);
5586     sqlite3_clear_bindings (stmt);
5587     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
5588     while (1)
5589       {
5590 	  /* scrolling the result set rows */
5591 	  ret = sqlite3_step (stmt);
5592 	  if (ret == SQLITE_DONE)
5593 	      break;		/* end of result set */
5594 	  if (ret == SQLITE_ROW)
5595 	    {
5596 		*id = sqlite3_column_int64 (stmt, 0);
5597 		count++;
5598 	    }
5599       }
5600     sqlite3_finalize (stmt);
5601     if (count == 1)
5602 	return 1;
5603     return 0;
5604   stop:
5605     return 0;
5606 }
5607 
5608 SPATIALITE_PRIVATE int
register_wms_getmap(void * p_sqlite,const char * getcapabilities_url,const char * getmap_url,const char * layer_name,const char * title,const char * abstract,const char * version,const char * ref_sys,const char * image_format,const char * style,int transparent,int flip_axes,int tiled,int cached,int tile_width,int tile_height,const char * bgcolor,int is_queryable,const char * getfeatureinfo_url)5609 register_wms_getmap (void *p_sqlite, const char *getcapabilities_url,
5610 		     const char *getmap_url, const char *layer_name,
5611 		     const char *title, const char *abstract,
5612 		     const char *version, const char *ref_sys,
5613 		     const char *image_format, const char *style,
5614 		     int transparent, int flip_axes, int tiled, int cached,
5615 		     int tile_width, int tile_height, const char *bgcolor,
5616 		     int is_queryable, const char *getfeatureinfo_url)
5617 {
5618 /* auxiliary function: inserts a WMS GetMap */
5619     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
5620     int ret;
5621     sqlite3_int64 parent_id;
5622     const char *sql;
5623     sqlite3_stmt *stmt;
5624 
5625     if (getcapabilities_url == NULL)
5626 	return 0;
5627 
5628     if (!wms_getmap_parentid (sqlite, getcapabilities_url, &parent_id))
5629       {
5630 	  spatialite_e ("WMS_RegisterGetMap: missing parent GetCapabilities\n");
5631 	  return 0;
5632       }
5633 
5634     if (getmap_url != NULL && layer_name != NULL && title != NULL
5635 	&& abstract != NULL)
5636       {
5637 	  /* attempting to insert the WMS GetMap */
5638 	  sql =
5639 	      "INSERT INTO wms_getmap (parent_id, url, layer_name, title, abstract, "
5640 	      "version, srs, format, style, transparent, flip_axes, tiled, "
5641 	      "is_cached, tile_width, tile_height, bgcolor, is_queryable, "
5642 	      "getfeatureinfo_url) VALUES "
5643 	      "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
5644 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5645 	  if (ret != SQLITE_OK)
5646 	    {
5647 		spatialite_e ("WMS_RegisterGetMap: \"%s\"\n",
5648 			      sqlite3_errmsg (sqlite));
5649 		return 0;
5650 	    }
5651 	  sqlite3_reset (stmt);
5652 	  sqlite3_clear_bindings (stmt);
5653 	  sqlite3_bind_int64 (stmt, 1, parent_id);
5654 	  sqlite3_bind_text (stmt, 2, getmap_url, strlen (getmap_url),
5655 			     SQLITE_STATIC);
5656 	  sqlite3_bind_text (stmt, 3, layer_name, strlen (layer_name),
5657 			     SQLITE_STATIC);
5658 	  sqlite3_bind_text (stmt, 4, title, strlen (title), SQLITE_STATIC);
5659 	  sqlite3_bind_text (stmt, 5, abstract, strlen (abstract),
5660 			     SQLITE_STATIC);
5661 	  sqlite3_bind_text (stmt, 6, version, strlen (version), SQLITE_STATIC);
5662 	  sqlite3_bind_text (stmt, 7, ref_sys, strlen (ref_sys), SQLITE_STATIC);
5663 	  sqlite3_bind_text (stmt, 8, image_format, strlen (image_format),
5664 			     SQLITE_STATIC);
5665 	  sqlite3_bind_text (stmt, 9, style, strlen (style), SQLITE_STATIC);
5666 	  if (transparent != 0)
5667 	      transparent = 1;
5668 	  sqlite3_bind_int (stmt, 10, transparent);
5669 	  if (flip_axes != 0)
5670 	      flip_axes = 1;
5671 	  sqlite3_bind_int (stmt, 11, flip_axes);
5672 	  if (tiled != 0)
5673 	      tiled = 1;
5674 	  sqlite3_bind_int (stmt, 12, tiled);
5675 	  if (cached != 0)
5676 	      cached = 1;
5677 	  sqlite3_bind_int (stmt, 13, cached);
5678 	  if (tile_width < 256)
5679 	      tile_width = 256;
5680 	  if (tile_height > 5000)
5681 	      tile_width = 5000;
5682 	  sqlite3_bind_int (stmt, 14, tile_width);
5683 	  if (tile_height < 256)
5684 	      tile_height = 256;
5685 	  if (tile_height > 5000)
5686 	      tile_height = 5000;
5687 	  sqlite3_bind_int (stmt, 15, tile_height);
5688 	  if (bgcolor == NULL)
5689 	      sqlite3_bind_null (stmt, 16);
5690 	  else
5691 	      sqlite3_bind_text (stmt, 16, bgcolor, strlen (bgcolor),
5692 				 SQLITE_STATIC);
5693 	  if (is_queryable != 0)
5694 	      is_queryable = 1;
5695 	  sqlite3_bind_int (stmt, 17, is_queryable);
5696 	  if (getfeatureinfo_url == NULL)
5697 	      sqlite3_bind_null (stmt, 18);
5698 	  else
5699 	      sqlite3_bind_text (stmt, 18, getfeatureinfo_url,
5700 				 strlen (getfeatureinfo_url), SQLITE_STATIC);
5701 	  ret = sqlite3_step (stmt);
5702 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
5703 	      ;
5704 	  else
5705 	    {
5706 		spatialite_e ("WMS_RegisterGetMap() error: \"%s\"\n",
5707 			      sqlite3_errmsg (sqlite));
5708 		sqlite3_finalize (stmt);
5709 		return 0;
5710 	    }
5711 	  sqlite3_finalize (stmt);
5712       }
5713     else if (getmap_url != NULL && layer_name != NULL)
5714       {
5715 	  /* attempting to insert the WMS GetMap */
5716 	  sql =
5717 	      "INSERT INTO wms_getmap (parent_id, url, layer_name, version, srs, "
5718 	      "format, style, transparent, flip_axes, tiled, is_cached, "
5719 	      "tile_width, tile_height, is_queryable) VALUES "
5720 	      "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)";
5721 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5722 	  if (ret != SQLITE_OK)
5723 	    {
5724 		spatialite_e ("WMS_RegisterGetMap: \"%s\"\n",
5725 			      sqlite3_errmsg (sqlite));
5726 		return 0;
5727 	    }
5728 	  sqlite3_reset (stmt);
5729 	  sqlite3_clear_bindings (stmt);
5730 	  sqlite3_bind_int64 (stmt, 1, parent_id);
5731 	  sqlite3_bind_text (stmt, 2, getmap_url, strlen (getmap_url),
5732 			     SQLITE_STATIC);
5733 	  sqlite3_bind_text (stmt, 3, layer_name, strlen (layer_name),
5734 			     SQLITE_STATIC);
5735 	  sqlite3_bind_text (stmt, 4, version, strlen (version), SQLITE_STATIC);
5736 	  sqlite3_bind_text (stmt, 5, ref_sys, strlen (ref_sys), SQLITE_STATIC);
5737 	  sqlite3_bind_text (stmt, 6, image_format, strlen (image_format),
5738 			     SQLITE_STATIC);
5739 	  sqlite3_bind_text (stmt, 7, style, strlen (style), SQLITE_STATIC);
5740 	  if (transparent != 0)
5741 	      transparent = 1;
5742 	  sqlite3_bind_int (stmt, 8, transparent);
5743 	  if (flip_axes != 0)
5744 	      flip_axes = 1;
5745 	  sqlite3_bind_int (stmt, 9, flip_axes);
5746 	  if (tiled != 0)
5747 	      tiled = 1;
5748 	  sqlite3_bind_int (stmt, 10, tiled);
5749 	  if (cached != 0)
5750 	      cached = 1;
5751 	  sqlite3_bind_int (stmt, 11, cached);
5752 	  if (tile_width < 256)
5753 	      tile_width = 256;
5754 	  if (tile_height > 5000)
5755 	      tile_width = 5000;
5756 	  sqlite3_bind_int (stmt, 12, tile_width);
5757 	  if (tile_height < 256)
5758 	      tile_height = 256;
5759 	  if (tile_height > 5000)
5760 	      tile_height = 5000;
5761 	  sqlite3_bind_int (stmt, 13, tile_height);
5762 	  ret = sqlite3_step (stmt);
5763 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
5764 	      ;
5765 	  else
5766 	    {
5767 		spatialite_e ("WMS_RegisterGetMap() error: \"%s\"\n",
5768 			      sqlite3_errmsg (sqlite));
5769 		sqlite3_finalize (stmt);
5770 		return 0;
5771 	    }
5772 	  sqlite3_finalize (stmt);
5773       }
5774     return 1;
5775 }
5776 
5777 static int
check_wms_getmap(sqlite3 * sqlite,const char * url,const char * layer_name)5778 check_wms_getmap (sqlite3 * sqlite, const char *url, const char *layer_name)
5779 {
5780 /* checks if a WMS GetMap do actually exists */
5781     int ret;
5782     const char *sql;
5783     sqlite3_stmt *stmt;
5784     int count = 0;
5785 
5786     sql = "SELECT url FROM wms_getmap WHERE url = ? AND layer_name = ?";
5787     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5788     if (ret != SQLITE_OK)
5789       {
5790 	  spatialite_e ("check WMS GetMap: \"%s\"\n", sqlite3_errmsg (sqlite));
5791 	  goto stop;
5792       }
5793     sqlite3_reset (stmt);
5794     sqlite3_clear_bindings (stmt);
5795     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
5796     sqlite3_bind_text (stmt, 2, layer_name, strlen (layer_name), SQLITE_STATIC);
5797     while (1)
5798       {
5799 	  /* scrolling the result set rows */
5800 	  ret = sqlite3_step (stmt);
5801 	  if (ret == SQLITE_DONE)
5802 	      break;		/* end of result set */
5803 	  if (ret == SQLITE_ROW)
5804 	      count++;
5805       }
5806     sqlite3_finalize (stmt);
5807     if (count == 1)
5808 	return 1;
5809     return 0;
5810   stop:
5811     return 0;
5812 }
5813 
5814 static int
do_delete_wms_getmap(sqlite3 * sqlite,const char * url,const char * layer_name)5815 do_delete_wms_getmap (sqlite3 * sqlite, const char *url, const char *layer_name)
5816 {
5817 /* auxiliary function: deleting a WMS GetMap */
5818     int ret;
5819     int result = 0;
5820     const char *sql;
5821     sqlite3_stmt *stmt;
5822 
5823     sql = "DELETE FROM wms_getmap WHERE url = ? AND layer_name = ?";
5824     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5825     if (ret != SQLITE_OK)
5826       {
5827 	  spatialite_e ("WMS_UnRegisterGetMap: \"%s\"\n",
5828 			sqlite3_errmsg (sqlite));
5829 	  return 0;
5830       }
5831     sqlite3_reset (stmt);
5832     sqlite3_clear_bindings (stmt);
5833     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
5834     sqlite3_bind_text (stmt, 2, layer_name, strlen (layer_name), SQLITE_STATIC);
5835     ret = sqlite3_step (stmt);
5836     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
5837 	result = 1;
5838     else
5839 	spatialite_e ("WMS_UnRegisterGetMap() error: \"%s\"\n",
5840 		      sqlite3_errmsg (sqlite));
5841     sqlite3_finalize (stmt);
5842     return result;
5843 }
5844 
5845 static void
do_delete_wms_settings_1(sqlite3 * sqlite,const char * url,const char * layer_name)5846 do_delete_wms_settings_1 (sqlite3 * sqlite, const char *url,
5847 			  const char *layer_name)
5848 {
5849 /* auxiliary function: deleting WMS settings (from GetMap) */
5850     int ret;
5851     const char *sql;
5852     sqlite3_stmt *stmt;
5853 
5854     sql = "DELETE FROM wms_settings WHERE id IN ("
5855 	"SELECT s.id FROM wms_getmap AS m "
5856 	"JOIN wms_settings AS s ON (m.id = s.parent_id) "
5857 	"WHERE m.url = ? AND m.layer_name = ?)";
5858     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5859     if (ret != SQLITE_OK)
5860       {
5861 	  spatialite_e ("WMS_UnRegisterGetMap: \"%s\"\n",
5862 			sqlite3_errmsg (sqlite));
5863 	  return;
5864       }
5865     sqlite3_reset (stmt);
5866     sqlite3_clear_bindings (stmt);
5867     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
5868     sqlite3_bind_text (stmt, 2, layer_name, strlen (layer_name), SQLITE_STATIC);
5869     ret = sqlite3_step (stmt);
5870     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
5871 	;
5872     else
5873 	spatialite_e ("WMS_UnRegisterGetMap() error: \"%s\"\n",
5874 		      sqlite3_errmsg (sqlite));
5875     sqlite3_finalize (stmt);
5876 }
5877 
5878 SPATIALITE_PRIVATE int
unregister_wms_getmap(void * p_sqlite,const char * url,const char * layer_name)5879 unregister_wms_getmap (void *p_sqlite, const char *url, const char *layer_name)
5880 {
5881 /* auxiliary function: deletes a WMS GetMap definition (and related settings) */
5882     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
5883 
5884     if (url == NULL || layer_name == NULL)
5885 	return 0;
5886 
5887     /* checking if the WMS GetMap do actually exists */
5888     if (!check_wms_getmap (sqlite, url, layer_name))
5889 	return 0;
5890     /* deleting all WMS settings */
5891     do_delete_wms_settings_1 (sqlite, url, layer_name);
5892     /* deleting the WMS GetMap itself */
5893     return do_delete_wms_getmap (sqlite, url, layer_name);
5894 }
5895 
5896 SPATIALITE_PRIVATE int
set_wms_getmap_infos(void * p_sqlite,const char * url,const char * layer_name,const char * title,const char * abstract)5897 set_wms_getmap_infos (void *p_sqlite, const char *url, const char *layer_name,
5898 		      const char *title, const char *abstract)
5899 {
5900 /* auxiliary function: updates the descriptive infos supporting a WMS GetMap */
5901     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
5902     int ret;
5903     const char *sql;
5904     sqlite3_stmt *stmt;
5905 
5906     if (url != NULL && title != NULL && abstract != NULL)
5907       {
5908 	  /* checking if the WMS GetMap do actually exists */
5909 	  if (!check_wms_getmap (sqlite, url, layer_name))
5910 	      return 0;
5911 
5912 	  /* attempting to update the WMS GetGetMap */
5913 	  sql = "UPDATE wms_getmap SET title = ?, abstract = ? "
5914 	      "WHERE url = ? AND layer_name = ?";
5915 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5916 	  if (ret != SQLITE_OK)
5917 	    {
5918 		spatialite_e ("WMS_SetGetMapInfos: \"%s\"\n",
5919 			      sqlite3_errmsg (sqlite));
5920 		return 0;
5921 	    }
5922 	  sqlite3_reset (stmt);
5923 	  sqlite3_clear_bindings (stmt);
5924 	  sqlite3_bind_text (stmt, 1, title, strlen (title), SQLITE_STATIC);
5925 	  sqlite3_bind_text (stmt, 2, abstract, strlen (abstract),
5926 			     SQLITE_STATIC);
5927 	  sqlite3_bind_text (stmt, 3, url, strlen (url), SQLITE_STATIC);
5928 	  sqlite3_bind_text (stmt, 4, layer_name, strlen (layer_name),
5929 			     SQLITE_STATIC);
5930 	  ret = sqlite3_step (stmt);
5931 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
5932 	      ;
5933 	  else
5934 	    {
5935 		spatialite_e ("WMS_SetGetMapInfos() error: \"%s\"\n",
5936 			      sqlite3_errmsg (sqlite));
5937 		sqlite3_finalize (stmt);
5938 		return 0;
5939 	    }
5940 	  sqlite3_finalize (stmt);
5941 	  return 1;
5942       }
5943     else
5944 	return 0;
5945 }
5946 
5947 SPATIALITE_PRIVATE int
set_wms_getmap_copyright(void * p_sqlite,const char * url,const char * layer_name,const char * copyright,const char * license)5948 set_wms_getmap_copyright (void *p_sqlite, const char *url,
5949 			  const char *layer_name, const char *copyright,
5950 			  const char *license)
5951 {
5952 /* auxiliary function: updates the copyright infos supporting a WMS layer */
5953     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
5954     int ret;
5955     const char *sql;
5956     sqlite3_stmt *stmt;
5957 
5958     if (url == NULL || layer_name == NULL)
5959 	return 0;
5960     if (copyright == NULL && license == NULL)
5961 	return 1;
5962 
5963     if (copyright == NULL)
5964       {
5965 	  /* just updating the License */
5966 	  sql = "UPDATE wms_getmap SET license = ("
5967 	      "SELECT id FROM data_licenses WHERE name = ?) "
5968 	      "WHERE url = ? AND layer_name = ?";
5969 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5970 	  if (ret != SQLITE_OK)
5971 	    {
5972 		spatialite_e ("setWMSLayerCopyright: \"%s\"\n",
5973 			      sqlite3_errmsg (sqlite));
5974 		return 0;
5975 	    }
5976 	  sqlite3_reset (stmt);
5977 	  sqlite3_clear_bindings (stmt);
5978 	  sqlite3_bind_text (stmt, 1, license, strlen (license), SQLITE_STATIC);
5979 	  sqlite3_bind_text (stmt, 2, url, strlen (url), SQLITE_STATIC);
5980 	  sqlite3_bind_text (stmt, 3, layer_name,
5981 			     strlen (layer_name), SQLITE_STATIC);
5982       }
5983     else if (license == NULL)
5984       {
5985 	  /* just updating the Copyright */
5986 	  sql = "UPDATE wms_getmap SET copyright = ? "
5987 	      "WHERE url = ? AND layer_name = ?";
5988 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
5989 	  if (ret != SQLITE_OK)
5990 	    {
5991 		spatialite_e ("setWMSLayerCopyright: \"%s\"\n",
5992 			      sqlite3_errmsg (sqlite));
5993 		return 0;
5994 	    }
5995 	  sqlite3_reset (stmt);
5996 	  sqlite3_clear_bindings (stmt);
5997 	  sqlite3_bind_text (stmt, 1, copyright, strlen (copyright),
5998 			     SQLITE_STATIC);
5999 	  sqlite3_bind_text (stmt, 2, url, strlen (url), SQLITE_STATIC);
6000 	  sqlite3_bind_text (stmt, 3, layer_name,
6001 			     strlen (layer_name), SQLITE_STATIC);
6002       }
6003     else
6004       {
6005 	  /* updating both Copyright and License */
6006 	  sql = "UPDATE wms_getmap SET copyright = ?, license = ("
6007 	      "SELECT id FROM data_licenses WHERE name = ?) "
6008 	      "WHERE url = ? AND layer_name = ?";
6009 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6010 	  if (ret != SQLITE_OK)
6011 	    {
6012 		spatialite_e ("setWMSLayerCopyright: \"%s\"\n",
6013 			      sqlite3_errmsg (sqlite));
6014 		return 0;
6015 	    }
6016 	  sqlite3_reset (stmt);
6017 	  sqlite3_clear_bindings (stmt);
6018 	  sqlite3_bind_text (stmt, 1, copyright, strlen (copyright),
6019 			     SQLITE_STATIC);
6020 	  sqlite3_bind_text (stmt, 2, license, strlen (license), SQLITE_STATIC);
6021 	  sqlite3_bind_text (stmt, 3, url, strlen (url), SQLITE_STATIC);
6022 	  sqlite3_bind_text (stmt, 4, layer_name,
6023 			     strlen (layer_name), SQLITE_STATIC);
6024       }
6025     ret = sqlite3_step (stmt);
6026     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6027 	;
6028     else
6029       {
6030 	  spatialite_e ("setWMSLayerCopyright() error: \"%s\"\n",
6031 			sqlite3_errmsg (sqlite));
6032 	  sqlite3_finalize (stmt);
6033 	  return 0;
6034       }
6035     sqlite3_finalize (stmt);
6036     return 1;
6037 }
6038 
6039 SPATIALITE_PRIVATE int
set_wms_getmap_bgcolor(void * p_sqlite,const char * url,const char * layer_name,const char * bgcolor)6040 set_wms_getmap_bgcolor (void *p_sqlite,
6041 			const char *url, const char *layer_name,
6042 			const char *bgcolor)
6043 {
6044 /* updating WMS GetMap Options - BgColor */
6045     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
6046     int ret;
6047     const char *sql;
6048     sqlite3_stmt *stmt;
6049 
6050     if (url != NULL)
6051       {
6052 	  /* checking if the WMS GetMap do actually exists */
6053 	  if (!check_wms_getmap (sqlite, url, layer_name))
6054 	      return 0;
6055 
6056 	  /* attempting to update the WMS GetMap */
6057 	  sql =
6058 	      "UPDATE wms_getmap SET bgcolor = ? WHERE url = ? AND layer_name = ?";
6059 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6060 	  if (ret != SQLITE_OK)
6061 	    {
6062 		spatialite_e ("WMS_SetGetMapOptions (BGCOLOR): \"%s\"\n",
6063 			      sqlite3_errmsg (sqlite));
6064 		return 0;
6065 	    }
6066 	  sqlite3_reset (stmt);
6067 	  sqlite3_clear_bindings (stmt);
6068 	  if (bgcolor == NULL)
6069 	      sqlite3_bind_null (stmt, 1);
6070 	  else
6071 	      sqlite3_bind_text (stmt, 1, bgcolor, strlen (bgcolor),
6072 				 SQLITE_STATIC);
6073 	  sqlite3_bind_text (stmt, 2, url, strlen (url), SQLITE_STATIC);
6074 	  sqlite3_bind_text (stmt, 3, layer_name, strlen (layer_name),
6075 			     SQLITE_STATIC);
6076 	  ret = sqlite3_step (stmt);
6077 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6078 	      ;
6079 	  else
6080 	    {
6081 		spatialite_e ("WMS_SetGetMapOptions (BGCOLOR) error: \"%s\"\n",
6082 			      sqlite3_errmsg (sqlite));
6083 		sqlite3_finalize (stmt);
6084 		return 0;
6085 	    }
6086 	  sqlite3_finalize (stmt);
6087 	  return 1;
6088       }
6089     else
6090 	return 0;
6091 }
6092 
6093 SPATIALITE_PRIVATE int
set_wms_getmap_queryable(void * p_sqlite,const char * url,const char * layer_name,int is_queryable,const char * getfeatureinfo_url)6094 set_wms_getmap_queryable (void *p_sqlite,
6095 			  const char *url, const char *layer_name,
6096 			  int is_queryable, const char *getfeatureinfo_url)
6097 {
6098 /* updating WMS GetMap Options - IsQueryable */
6099     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
6100     int ret;
6101     const char *sql;
6102     sqlite3_stmt *stmt;
6103 
6104     if (url != NULL)
6105       {
6106 	  /* checking if the WMS GetMap do actually exists */
6107 	  if (!check_wms_getmap (sqlite, url, layer_name))
6108 	      return 0;
6109 
6110 	  /* attempting to update the WMS GetMap */
6111 	  sql =
6112 	      "UPDATE wms_getmap SET is_queryable = ?, getfeatureinfo_url = ? WHERE url = ? AND layer_name = ?";
6113 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6114 	  if (ret != SQLITE_OK)
6115 	    {
6116 		spatialite_e ("WMS_SetGetMapOptions (IsQueryable): \"%s\"\n",
6117 			      sqlite3_errmsg (sqlite));
6118 		return 0;
6119 	    }
6120 	  sqlite3_reset (stmt);
6121 	  sqlite3_clear_bindings (stmt);
6122 	  if (is_queryable != 0)
6123 	      is_queryable = 1;
6124 	  sqlite3_bind_int (stmt, 1, is_queryable);
6125 	  if (getfeatureinfo_url == NULL)
6126 	      sqlite3_bind_null (stmt, 2);
6127 	  else
6128 	      sqlite3_bind_text (stmt, 2, getfeatureinfo_url,
6129 				 strlen (getfeatureinfo_url), SQLITE_STATIC);
6130 	  sqlite3_bind_text (stmt, 3, url, strlen (url), SQLITE_STATIC);
6131 	  sqlite3_bind_text (stmt, 4, layer_name, strlen (layer_name),
6132 			     SQLITE_STATIC);
6133 	  ret = sqlite3_step (stmt);
6134 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6135 	      ;
6136 	  else
6137 	    {
6138 		spatialite_e
6139 		    ("WMS_SetGetMapOptions (IsQueryable) error: \"%s\"\n",
6140 		     sqlite3_errmsg (sqlite));
6141 		sqlite3_finalize (stmt);
6142 		return 0;
6143 	    }
6144 	  sqlite3_finalize (stmt);
6145 	  return 1;
6146       }
6147     else
6148 	return 0;
6149 }
6150 
6151 SPATIALITE_PRIVATE int
set_wms_getmap_options(void * p_sqlite,const char * url,const char * layer_name,int transparent,int flip_axes)6152 set_wms_getmap_options (void *p_sqlite,
6153 			const char *url, const char *layer_name,
6154 			int transparent, int flip_axes)
6155 {
6156 /* updating WMS GetMap Options - Flags */
6157     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
6158     int ret;
6159     const char *sql;
6160     sqlite3_stmt *stmt;
6161 
6162     if (url != NULL)
6163       {
6164 	  /* checking if the WMS GetMap do actually exists */
6165 	  if (!check_wms_getmap (sqlite, url, layer_name))
6166 	      return 0;
6167 
6168 	  /* attempting to update the WMS GetMap */
6169 	  sql =
6170 	      "UPDATE wms_getmap SET transparent = ?, flip_axes = ? WHERE url = ? AND layer_name = ?";
6171 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6172 	  if (ret != SQLITE_OK)
6173 	    {
6174 		spatialite_e ("WMS_SetGetMapOptions (Flags): \"%s\"\n",
6175 			      sqlite3_errmsg (sqlite));
6176 		return 0;
6177 	    }
6178 	  sqlite3_reset (stmt);
6179 	  sqlite3_clear_bindings (stmt);
6180 	  if (transparent != 0)
6181 	      transparent = 1;
6182 	  sqlite3_bind_int (stmt, 1, transparent);
6183 	  if (flip_axes != 0)
6184 	      flip_axes = 1;
6185 	  sqlite3_bind_int (stmt, 2, flip_axes);
6186 	  sqlite3_bind_text (stmt, 3, url, strlen (url), SQLITE_STATIC);
6187 	  sqlite3_bind_text (stmt, 4, layer_name, strlen (layer_name),
6188 			     SQLITE_STATIC);
6189 	  ret = sqlite3_step (stmt);
6190 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6191 	      ;
6192 	  else
6193 	    {
6194 		spatialite_e ("WMS_SetGetMapOptions (Flags) error: \"%s\"\n",
6195 			      sqlite3_errmsg (sqlite));
6196 		sqlite3_finalize (stmt);
6197 		return 0;
6198 	    }
6199 	  sqlite3_finalize (stmt);
6200 	  return 1;
6201       }
6202     else
6203 	return 0;
6204 }
6205 
6206 SPATIALITE_PRIVATE int
set_wms_getmap_tiled(void * p_sqlite,const char * url,const char * layer_name,int tiled,int cached,int tile_width,int tile_height)6207 set_wms_getmap_tiled (void *p_sqlite,
6208 		      const char *url, const char *layer_name,
6209 		      int tiled, int cached, int tile_width, int tile_height)
6210 {
6211 /* updating WMS GetMap Options - Tiled */
6212     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
6213     int ret;
6214     const char *sql;
6215     sqlite3_stmt *stmt;
6216 
6217     if (url != NULL)
6218       {
6219 	  /* checking if the WMS GetMap do actually exists */
6220 	  if (!check_wms_getmap (sqlite, url, layer_name))
6221 	      return 0;
6222 
6223 	  /* attempting to update the WMS GetMap */
6224 	  sql =
6225 	      "UPDATE wms_getmap SET tiled = ?, is_cached = ?, tile_width = ?, tile_height = ? "
6226 	      "WHERE url = ? AND layer_name = ?";
6227 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6228 	  if (ret != SQLITE_OK)
6229 	    {
6230 		spatialite_e ("WMS_SetGetMapOptions (Tiled): \"%s\"\n",
6231 			      sqlite3_errmsg (sqlite));
6232 		return 0;
6233 	    }
6234 	  sqlite3_reset (stmt);
6235 	  sqlite3_clear_bindings (stmt);
6236 	  if (tiled != 0)
6237 	      tiled = 1;
6238 	  sqlite3_bind_int (stmt, 1, tiled);
6239 	  if (cached != 0)
6240 	      cached = 1;
6241 	  sqlite3_bind_int (stmt, 2, cached);
6242 	  if (tile_width < 256)
6243 	      tile_width = 256;
6244 	  if (tile_height > 5000)
6245 	      tile_width = 5000;
6246 	  sqlite3_bind_int (stmt, 3, tile_width);
6247 	  if (tile_height < 256)
6248 	      tile_height = 256;
6249 	  if (tile_height > 5000)
6250 	      tile_height = 5000;
6251 	  sqlite3_bind_int (stmt, 4, tile_height);
6252 	  sqlite3_bind_text (stmt, 5, url, strlen (url), SQLITE_STATIC);
6253 	  sqlite3_bind_text (stmt, 6, layer_name, strlen (layer_name),
6254 			     SQLITE_STATIC);
6255 	  ret = sqlite3_step (stmt);
6256 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6257 	      ;
6258 	  else
6259 	    {
6260 		spatialite_e ("WMS_SetGetMapOptions (Tiled) error: \"%s\"\n",
6261 			      sqlite3_errmsg (sqlite));
6262 		sqlite3_finalize (stmt);
6263 		return 0;
6264 	    }
6265 	  sqlite3_finalize (stmt);
6266 	  return 1;
6267       }
6268     else
6269 	return 0;
6270 }
6271 
6272 static int
wms_setting_parentid(sqlite3 * sqlite,const char * url,const char * layer_name,sqlite3_int64 * id)6273 wms_setting_parentid (sqlite3 * sqlite, const char *url, const char *layer_name,
6274 		      sqlite3_int64 * id)
6275 {
6276 /* retieving the WMS GetMap ID value */
6277     int ret;
6278     const char *sql;
6279     sqlite3_stmt *stmt;
6280     int count = 0;
6281 
6282     sql = "SELECT id FROM wms_getmap WHERE url = ? AND layer_name = ?";
6283     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6284     if (ret != SQLITE_OK)
6285       {
6286 	  spatialite_e ("WMS Setting parent_id: \"%s\"\n",
6287 			sqlite3_errmsg (sqlite));
6288 	  goto stop;
6289       }
6290     sqlite3_reset (stmt);
6291     sqlite3_clear_bindings (stmt);
6292     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
6293     sqlite3_bind_text (stmt, 2, layer_name, strlen (layer_name), SQLITE_STATIC);
6294     while (1)
6295       {
6296 	  /* scrolling the result set rows */
6297 	  ret = sqlite3_step (stmt);
6298 	  if (ret == SQLITE_DONE)
6299 	      break;		/* end of result set */
6300 	  if (ret == SQLITE_ROW)
6301 	    {
6302 		*id = sqlite3_column_int64 (stmt, 0);
6303 		count++;
6304 	    }
6305       }
6306     sqlite3_finalize (stmt);
6307     if (count == 1)
6308 	return 1;
6309     return 0;
6310   stop:
6311     return 0;
6312 }
6313 
6314 static int
do_wms_set_default(sqlite3 * sqlite,const char * url,const char * layer_name,const char * key,const char * value)6315 do_wms_set_default (sqlite3 * sqlite, const char *url, const char *layer_name,
6316 		    const char *key, const char *value)
6317 {
6318 /* auxiliary function: updating a WMS GetMap default setting */
6319     int ret;
6320     const char *sql;
6321     sqlite3_stmt *stmt;
6322     int result = 0;
6323 
6324 /* resetting an eventual previous default */
6325     sql = "UPDATE wms_settings SET is_default = 0 WHERE id IN ("
6326 	"SELECT s.id FROM wms_getmap AS m "
6327 	"JOIN wms_settings AS s ON (m.id = s.parent_id) "
6328 	"WHERE m.url = ? AND m.layer_name = ? AND s.key = Lower(?) AND s.value <> ?)";
6329     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6330     if (ret != SQLITE_OK)
6331       {
6332 	  spatialite_e ("WMS_DefaultSetting: \"%s\"\n",
6333 			sqlite3_errmsg (sqlite));
6334 	  return 0;
6335       }
6336     sqlite3_reset (stmt);
6337     sqlite3_clear_bindings (stmt);
6338     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
6339     sqlite3_bind_text (stmt, 2, layer_name, strlen (layer_name), SQLITE_STATIC);
6340     sqlite3_bind_text (stmt, 3, key, strlen (key), SQLITE_STATIC);
6341     sqlite3_bind_text (stmt, 4, value, strlen (value), SQLITE_STATIC);
6342     ret = sqlite3_step (stmt);
6343     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6344 	result = 1;
6345     else
6346 	spatialite_e ("WMS_DefaultSetting() error: \"%s\"\n",
6347 		      sqlite3_errmsg (sqlite));
6348     sqlite3_finalize (stmt);
6349     if (!result)
6350 	return 0;
6351 
6352 /* setting the current default */
6353     sql = "UPDATE wms_settings SET is_default = 1 WHERE id IN ("
6354 	"SELECT s.id FROM wms_getmap AS m "
6355 	"JOIN wms_settings AS s ON (m.id = s.parent_id) "
6356 	"WHERE m.url = ? AND m.layer_name = ? AND s.key = Lower(?) AND s.value = ?)";
6357     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6358     if (ret != SQLITE_OK)
6359       {
6360 	  spatialite_e ("WMS_DefaultSetting: \"%s\"\n",
6361 			sqlite3_errmsg (sqlite));
6362 	  return 0;
6363       }
6364     sqlite3_reset (stmt);
6365     sqlite3_clear_bindings (stmt);
6366     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
6367     sqlite3_bind_text (stmt, 2, layer_name, strlen (layer_name), SQLITE_STATIC);
6368     sqlite3_bind_text (stmt, 3, key, strlen (key), SQLITE_STATIC);
6369     sqlite3_bind_text (stmt, 4, value, strlen (value), SQLITE_STATIC);
6370     ret = sqlite3_step (stmt);
6371     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6372 	result = 1;
6373     else
6374 	spatialite_e ("WMS_DefaultSetting() error: \"%s\"\n",
6375 		      sqlite3_errmsg (sqlite));
6376     sqlite3_finalize (stmt);
6377 
6378     if (result)
6379       {
6380 	  /* updating the WMS GetMap */
6381 	  sql = NULL;
6382 	  if (strcasecmp (key, "version") == 0)
6383 	      sql =
6384 		  "UPDATE wms_getmap SET version = ? WHERE url = ? AND layer_name = ?";
6385 	  if (strcasecmp (key, "format") == 0)
6386 	      sql =
6387 		  "UPDATE wms_getmap SET format = ? WHERE url = ? AND layer_name = ?";
6388 	  if (strcasecmp (key, "style") == 0)
6389 	      sql =
6390 		  "UPDATE wms_getmap SET style = ? WHERE url = ? AND layer_name = ?";
6391 	  if (sql == NULL)
6392 	      return 0;
6393 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6394 	  if (ret != SQLITE_OK)
6395 	    {
6396 		spatialite_e ("WMS_DefaultSetting: \"%s\"\n",
6397 			      sqlite3_errmsg (sqlite));
6398 		return 0;
6399 	    }
6400 	  result = 0;
6401 	  sqlite3_reset (stmt);
6402 	  sqlite3_clear_bindings (stmt);
6403 	  sqlite3_bind_text (stmt, 1, value, strlen (value), SQLITE_STATIC);
6404 	  sqlite3_bind_text (stmt, 2, url, strlen (url), SQLITE_STATIC);
6405 	  sqlite3_bind_text (stmt, 3, layer_name, strlen (layer_name),
6406 			     SQLITE_STATIC);
6407 	  ret = sqlite3_step (stmt);
6408 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6409 	      result = 1;
6410 	  else
6411 	      spatialite_e ("WMS_DefaultSetting() error: \"%s\"\n",
6412 			    sqlite3_errmsg (sqlite));
6413 	  sqlite3_finalize (stmt);
6414       }
6415     return result;
6416 }
6417 
6418 static int
do_wms_srs_default(sqlite3 * sqlite,const char * url,const char * layer_name,const char * ref_sys)6419 do_wms_srs_default (sqlite3 * sqlite, const char *url, const char *layer_name,
6420 		    const char *ref_sys)
6421 {
6422 /* auxiliary function: updating a WMS GetMap default SRS */
6423     int ret;
6424     const char *sql;
6425     sqlite3_stmt *stmt;
6426     int result = 0;
6427 
6428 /* resetting an eventual previous default */
6429     sql = "UPDATE wms_ref_sys SET is_default = 0 WHERE id IN ("
6430 	"SELECT s.id FROM wms_getmap AS m "
6431 	"JOIN wms_ref_sys AS s ON (m.id = s.parent_id) "
6432 	"WHERE m.url = ? AND m.layer_name = ? AND s.srs <> Upper(?))";
6433     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6434     if (ret != SQLITE_OK)
6435       {
6436 	  spatialite_e ("WMS_DefaultSetting: \"%s\"\n",
6437 			sqlite3_errmsg (sqlite));
6438 	  return 0;
6439       }
6440     sqlite3_reset (stmt);
6441     sqlite3_clear_bindings (stmt);
6442     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
6443     sqlite3_bind_text (stmt, 2, layer_name, strlen (layer_name), SQLITE_STATIC);
6444     sqlite3_bind_text (stmt, 3, ref_sys, strlen (ref_sys), SQLITE_STATIC);
6445     ret = sqlite3_step (stmt);
6446     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6447 	result = 1;
6448     else
6449 	spatialite_e ("WMS_DefaultSRS() error: \"%s\"\n",
6450 		      sqlite3_errmsg (sqlite));
6451     sqlite3_finalize (stmt);
6452     if (!result)
6453 	return 0;
6454 
6455 /* setting the current default */
6456     sql = "UPDATE wms_ref_sys SET is_default = 1 WHERE id IN ("
6457 	"SELECT s.id FROM wms_getmap AS m "
6458 	"JOIN wms_ref_sys AS s ON (m.id = s.parent_id) "
6459 	"WHERE m.url = ? AND m.layer_name = ? AND s.srs = Lower(?))";
6460     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6461     if (ret != SQLITE_OK)
6462       {
6463 	  spatialite_e ("WMS_DefaultSetting: \"%s\"\n",
6464 			sqlite3_errmsg (sqlite));
6465 	  return 0;
6466       }
6467     sqlite3_reset (stmt);
6468     sqlite3_clear_bindings (stmt);
6469     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
6470     sqlite3_bind_text (stmt, 2, layer_name, strlen (layer_name), SQLITE_STATIC);
6471     sqlite3_bind_text (stmt, 3, ref_sys, strlen (ref_sys), SQLITE_STATIC);
6472     ret = sqlite3_step (stmt);
6473     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6474 	result = 1;
6475     else
6476 	spatialite_e ("WMS_DefaultSRS() error: \"%s\"\n",
6477 		      sqlite3_errmsg (sqlite));
6478     sqlite3_finalize (stmt);
6479 
6480     if (result)
6481       {
6482 	  /* updating the WMS GetMap */
6483 	  sql = NULL;
6484 	  sql =
6485 	      "UPDATE wms_getmap SET srs = ? WHERE url = ? AND layer_name = ?";
6486 	  if (sql == NULL)
6487 	      return 0;
6488 	  ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6489 	  if (ret != SQLITE_OK)
6490 	    {
6491 		spatialite_e ("WMS_DefaultSRS: \"%s\"\n",
6492 			      sqlite3_errmsg (sqlite));
6493 		return 0;
6494 	    }
6495 	  result = 0;
6496 	  sqlite3_reset (stmt);
6497 	  sqlite3_clear_bindings (stmt);
6498 	  sqlite3_bind_text (stmt, 1, ref_sys, strlen (ref_sys), SQLITE_STATIC);
6499 	  sqlite3_bind_text (stmt, 2, url, strlen (url), SQLITE_STATIC);
6500 	  sqlite3_bind_text (stmt, 3, layer_name, strlen (layer_name),
6501 			     SQLITE_STATIC);
6502 	  ret = sqlite3_step (stmt);
6503 	  if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6504 	      result = 1;
6505 	  else
6506 	      spatialite_e ("WMS_DefaultSRS() error: \"%s\"\n",
6507 			    sqlite3_errmsg (sqlite));
6508 	  sqlite3_finalize (stmt);
6509       }
6510     return result;
6511 }
6512 
6513 SPATIALITE_PRIVATE int
register_wms_setting(void * p_sqlite,const char * url,const char * layer_name,const char * key,const char * value,int is_default)6514 register_wms_setting (void *p_sqlite, const char *url, const char *layer_name,
6515 		      const char *key, const char *value, int is_default)
6516 {
6517 /* auxiliary function: inserts a WMS GetMap Setting */
6518     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
6519     int ret;
6520     sqlite3_int64 parent_id;
6521     const char *sql;
6522     sqlite3_stmt *stmt;
6523 
6524     if (!wms_setting_parentid (sqlite, url, layer_name, &parent_id))
6525       {
6526 	  spatialite_e ("WMS_RegisterSetting: missing parent GetMap\n");
6527 	  return 0;
6528       }
6529 
6530     /* attempting to insert the WMS Setting */
6531     sql = "INSERT INTO wms_settings (parent_id, key, value, is_default) "
6532 	"VALUES (?, Lower(?), ?, ?)";
6533     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6534     if (ret != SQLITE_OK)
6535       {
6536 	  spatialite_e ("WMS_RegisterSetting: \"%s\"\n",
6537 			sqlite3_errmsg (sqlite));
6538 	  return 0;
6539       }
6540     sqlite3_reset (stmt);
6541     sqlite3_clear_bindings (stmt);
6542     sqlite3_bind_int64 (stmt, 1, parent_id);
6543     sqlite3_bind_text (stmt, 2, key, strlen (key), SQLITE_STATIC);
6544     sqlite3_bind_text (stmt, 3, value, strlen (value), SQLITE_STATIC);
6545     if (is_default != 0)
6546 	is_default = 1;
6547     sqlite3_bind_int (stmt, 4, 0);
6548     ret = sqlite3_step (stmt);
6549     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6550 	;
6551     else
6552       {
6553 	  spatialite_e ("WMS_RegisterSetting() error: \"%s\"\n",
6554 			sqlite3_errmsg (sqlite));
6555 	  sqlite3_finalize (stmt);
6556 	  return 0;
6557       }
6558     sqlite3_finalize (stmt);
6559 
6560     if (is_default)
6561 	return do_wms_set_default (sqlite, url, layer_name, key, value);
6562     return 1;
6563 }
6564 
6565 static int
check_wms_setting(sqlite3 * sqlite,const char * url,const char * layer_name,const char * key,const char * value,int mode_delete)6566 check_wms_setting (sqlite3 * sqlite, const char *url, const char *layer_name,
6567 		   const char *key, const char *value, int mode_delete)
6568 {
6569 /* checks if a WMS GetMap Setting do actually exists */
6570     int ret;
6571     const char *sql;
6572     sqlite3_stmt *stmt;
6573     int count = 0;
6574 
6575     sql = "SELECT s.is_default FROM wms_getmap AS m "
6576 	"LEFT JOIN wms_settings AS s ON (m.id = s.parent_id) "
6577 	"WHERE m.url = ? AND m.layer_name = ? AND s.key = Lower(?) AND s.value = ?";
6578     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6579     if (ret != SQLITE_OK)
6580       {
6581 	  spatialite_e ("check WMS GetMap: \"%s\"\n", sqlite3_errmsg (sqlite));
6582 	  goto stop;
6583       }
6584     sqlite3_reset (stmt);
6585     sqlite3_clear_bindings (stmt);
6586     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
6587     sqlite3_bind_text (stmt, 2, layer_name, strlen (layer_name), SQLITE_STATIC);
6588     sqlite3_bind_text (stmt, 3, key, strlen (key), SQLITE_STATIC);
6589     sqlite3_bind_text (stmt, 4, value, strlen (value), SQLITE_STATIC);
6590     while (1)
6591       {
6592 	  /* scrolling the result set rows */
6593 	  ret = sqlite3_step (stmt);
6594 	  if (ret == SQLITE_DONE)
6595 	      break;		/* end of result set */
6596 	  if (ret == SQLITE_ROW)
6597 	    {
6598 		int is_default = sqlite3_column_int (stmt, 0);
6599 		if (mode_delete && is_default)
6600 		    ;
6601 		else
6602 		    count++;
6603 	    }
6604       }
6605     sqlite3_finalize (stmt);
6606     if (count == 1)
6607 	return 1;
6608   stop:
6609     return 0;
6610 }
6611 
6612 static int
do_delete_wms_setting(sqlite3 * sqlite,const char * url,const char * layer_name,const char * key,const char * value)6613 do_delete_wms_setting (sqlite3 * sqlite, const char *url,
6614 		       const char *layer_name, const char *key,
6615 		       const char *value)
6616 {
6617 /* auxiliary function: deleting a WMS GetMap setting */
6618     int ret;
6619     const char *sql;
6620     sqlite3_stmt *stmt;
6621     int result = 0;
6622 
6623     sql = "DELETE FROM wms_settings WHERE id IN ("
6624 	"SELECT s.id FROM wms_getmap AS m "
6625 	"JOIN wms_settings AS s ON (m.id = s.parent_id) "
6626 	"WHERE m.url = ? AND m.layer_name = ? AND s.key = Lower(?) AND s.value = ?)";
6627     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6628     if (ret != SQLITE_OK)
6629       {
6630 	  spatialite_e ("WMS_UnRegisterSetting: \"%s\"\n",
6631 			sqlite3_errmsg (sqlite));
6632 	  return 0;
6633       }
6634     sqlite3_reset (stmt);
6635     sqlite3_clear_bindings (stmt);
6636     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
6637     sqlite3_bind_text (stmt, 2, layer_name, strlen (layer_name), SQLITE_STATIC);
6638     sqlite3_bind_text (stmt, 3, key, strlen (key), SQLITE_STATIC);
6639     sqlite3_bind_text (stmt, 4, value, strlen (value), SQLITE_STATIC);
6640     ret = sqlite3_step (stmt);
6641     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6642 	result = 1;
6643     else
6644 	spatialite_e ("WMS_UnRegisterSetting() error: \"%s\"\n",
6645 		      sqlite3_errmsg (sqlite));
6646     sqlite3_finalize (stmt);
6647     return result;
6648 }
6649 
6650 SPATIALITE_PRIVATE int
unregister_wms_setting(void * p_sqlite,const char * url,const char * layer_name,const char * key,const char * value)6651 unregister_wms_setting (void *p_sqlite, const char *url, const char *layer_name,
6652 			const char *key, const char *value)
6653 {
6654 /* auxiliary function: deletes a WMS GetMap Setting */
6655     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
6656 
6657     if (url == NULL)
6658 	return 0;
6659 
6660     /* checking if the WMS GetMap do actually exists */
6661     if (!check_wms_setting (sqlite, url, layer_name, key, value, 1))
6662 	return 0;
6663     /* deleting the WMS GetMap Setting itself */
6664     return do_delete_wms_setting (sqlite, url, layer_name, key, value);
6665 }
6666 
6667 SPATIALITE_PRIVATE int
set_wms_default_setting(void * p_sqlite,const char * url,const char * layer_name,const char * key,const char * value)6668 set_wms_default_setting (void *p_sqlite, const char *url,
6669 			 const char *layer_name, const char *key,
6670 			 const char *value)
6671 {
6672 /* auxiliary function: updating a WMS GetMap Default Setting */
6673     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
6674 
6675     if (url == NULL)
6676 	return 0;
6677 
6678     /* checking if the WMS GetMap do actually exists */
6679     if (!check_wms_setting (sqlite, url, layer_name, key, value, 0))
6680 	return 0;
6681     /* updating the WMS GetMap Default Setting */
6682     return do_wms_set_default (sqlite, url, layer_name, key, value);
6683 }
6684 
6685 SPATIALITE_PRIVATE int
register_wms_srs(void * p_sqlite,const char * url,const char * layer_name,const char * ref_sys,double minx,double miny,double maxx,double maxy,int is_default)6686 register_wms_srs (void *p_sqlite, const char *url, const char *layer_name,
6687 		  const char *ref_sys, double minx, double miny, double maxx,
6688 		  double maxy, int is_default)
6689 {
6690 /* auxiliary function: inserts a WMS GetMap SRS */
6691     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
6692     int ret;
6693     sqlite3_int64 parent_id;
6694     const char *sql;
6695     sqlite3_stmt *stmt;
6696 
6697     if (!wms_setting_parentid (sqlite, url, layer_name, &parent_id))
6698       {
6699 	  spatialite_e ("WMS_RegisterSRS: missing parent GetMap\n");
6700 	  return 0;
6701       }
6702 
6703     /* attempting to insert the WMS Setting */
6704     sql =
6705 	"INSERT INTO wms_ref_sys (parent_id, srs, minx, miny, maxx, maxy, is_default) "
6706 	"VALUES (?, Upper(?), ?, ?, ?, ?, ?)";
6707     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6708     if (ret != SQLITE_OK)
6709       {
6710 	  spatialite_e ("WMS_RegisterSRS: \"%s\"\n", sqlite3_errmsg (sqlite));
6711 	  return 0;
6712       }
6713     sqlite3_reset (stmt);
6714     sqlite3_clear_bindings (stmt);
6715     sqlite3_bind_int64 (stmt, 1, parent_id);
6716     sqlite3_bind_text (stmt, 2, ref_sys, strlen (ref_sys), SQLITE_STATIC);
6717     sqlite3_bind_double (stmt, 3, minx);
6718     sqlite3_bind_double (stmt, 4, miny);
6719     sqlite3_bind_double (stmt, 5, maxx);
6720     sqlite3_bind_double (stmt, 6, maxy);
6721     if (is_default != 0)
6722 	is_default = 1;
6723     sqlite3_bind_int (stmt, 7, is_default);
6724     ret = sqlite3_step (stmt);
6725     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6726 	;
6727     else
6728       {
6729 	  spatialite_e ("WMS_RegisterSRS() error: \"%s\"\n",
6730 			sqlite3_errmsg (sqlite));
6731 	  sqlite3_finalize (stmt);
6732 	  return 0;
6733       }
6734     sqlite3_finalize (stmt);
6735 
6736     if (is_default)
6737 	return do_wms_srs_default (sqlite, url, layer_name, ref_sys);
6738     return 1;
6739 }
6740 
6741 static int
check_wms_srs(sqlite3 * sqlite,const char * url,const char * layer_name,const char * ref_sys,int mode_delete)6742 check_wms_srs (sqlite3 * sqlite, const char *url, const char *layer_name,
6743 	       const char *ref_sys, int mode_delete)
6744 {
6745 /* checks if a WMS GetMap SRS do actually exists */
6746     int ret;
6747     const char *sql;
6748     sqlite3_stmt *stmt;
6749     int count = 0;
6750 
6751     sql = "SELECT s.is_default FROM wms_getmap AS m "
6752 	"LEFT JOIN wms_ref_sys AS s ON (m.id = s.parent_id) "
6753 	"WHERE m.url = ? AND m.layer_name = ? AND s.srs = Upper(?)";
6754     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6755     if (ret != SQLITE_OK)
6756       {
6757 	  spatialite_e ("check WMS GetMap: \"%s\"\n", sqlite3_errmsg (sqlite));
6758 	  goto stop;
6759       }
6760     sqlite3_reset (stmt);
6761     sqlite3_clear_bindings (stmt);
6762     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
6763     sqlite3_bind_text (stmt, 2, layer_name, strlen (layer_name), SQLITE_STATIC);
6764     sqlite3_bind_text (stmt, 3, ref_sys, strlen (ref_sys), SQLITE_STATIC);
6765     while (1)
6766       {
6767 	  /* scrolling the result set rows */
6768 	  ret = sqlite3_step (stmt);
6769 	  if (ret == SQLITE_DONE)
6770 	      break;		/* end of result set */
6771 	  if (ret == SQLITE_ROW)
6772 	    {
6773 		int is_default = sqlite3_column_int (stmt, 0);
6774 		if (mode_delete && is_default)
6775 		    ;
6776 		else
6777 		    count++;
6778 	    }
6779       }
6780     sqlite3_finalize (stmt);
6781     if (count == 1)
6782 	return 1;
6783   stop:
6784     return 0;
6785 }
6786 
6787 static int
do_delete_wms_srs(sqlite3 * sqlite,const char * url,const char * layer_name,const char * ref_sys)6788 do_delete_wms_srs (sqlite3 * sqlite, const char *url,
6789 		   const char *layer_name, const char *ref_sys)
6790 {
6791 /* auxiliary function: deleting a WMS GetMap SRS */
6792     int ret;
6793     const char *sql;
6794     sqlite3_stmt *stmt;
6795     int result = 0;
6796 
6797     sql = "DELETE FROM wms_ref_sys WHERE id IN ("
6798 	"SELECT s.id FROM wms_getmap AS m "
6799 	"JOIN wms_ref_sys AS s ON (m.id = s.parent_id) "
6800 	"WHERE m.url = ? AND m.layer_name = ? AND s.srs = Upper(?))";
6801     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6802     if (ret != SQLITE_OK)
6803       {
6804 	  spatialite_e ("WMS_UnRegisterSRS: \"%s\"\n", sqlite3_errmsg (sqlite));
6805 	  return 0;
6806       }
6807     sqlite3_reset (stmt);
6808     sqlite3_clear_bindings (stmt);
6809     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
6810     sqlite3_bind_text (stmt, 2, layer_name, strlen (layer_name), SQLITE_STATIC);
6811     sqlite3_bind_text (stmt, 3, ref_sys, strlen (ref_sys), SQLITE_STATIC);
6812     ret = sqlite3_step (stmt);
6813     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6814 	result = 1;
6815     else
6816 	spatialite_e ("WMS_UnRegisterSRSg() error: \"%s\"\n",
6817 		      sqlite3_errmsg (sqlite));
6818     sqlite3_finalize (stmt);
6819     return result;
6820 }
6821 
6822 SPATIALITE_PRIVATE int
unregister_wms_srs(void * p_sqlite,const char * url,const char * layer_name,const char * ref_sys)6823 unregister_wms_srs (void *p_sqlite, const char *url, const char *layer_name,
6824 		    const char *ref_sys)
6825 {
6826 /* auxiliary function: deletes a WMS GetMap SRS */
6827     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
6828 
6829     if (url == NULL)
6830 	return 0;
6831 
6832     /* checking if the WMS GetMap do actually exists */
6833     if (!check_wms_srs (sqlite, url, layer_name, ref_sys, 1))
6834 	return 0;
6835     /* deleting the WMS GetMap SRS itself */
6836     return do_delete_wms_srs (sqlite, url, layer_name, ref_sys);
6837 }
6838 
6839 SPATIALITE_PRIVATE int
set_wms_default_srs(void * p_sqlite,const char * url,const char * layer_name,const char * ref_sys)6840 set_wms_default_srs (void *p_sqlite, const char *url,
6841 		     const char *layer_name, const char *ref_sys)
6842 {
6843 /* auxiliary function: updating a WMS GetMap Default SRS */
6844     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
6845 
6846     if (url == NULL)
6847 	return 0;
6848 
6849     /* checking if the WMS GetMap do actually exists */
6850     if (!check_wms_srs (sqlite, url, layer_name, ref_sys, 0))
6851 	return 0;
6852     /* updating the WMS GetMap Default SRS */
6853     return do_wms_srs_default (sqlite, url, layer_name, ref_sys);
6854 }
6855 
6856 SPATIALITE_PRIVATE char *
wms_getmap_request_url(void * p_sqlite,const char * getmap_url,const char * layer_name,int width,int height,double minx,double miny,double maxx,double maxy)6857 wms_getmap_request_url (void *p_sqlite, const char *getmap_url,
6858 			const char *layer_name, int width, int height,
6859 			double minx, double miny, double maxx, double maxy)
6860 {
6861 /* return a WMS GetMap request URL */
6862     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
6863     int ret;
6864     const char *sql;
6865     sqlite3_stmt *stmt;
6866     char *request_url = NULL;
6867 
6868     if (getmap_url == NULL)
6869 	return NULL;
6870 
6871     sql = "SELECT version, srs, format, style, transparent, flip_axes, "
6872 	"bgcolor FROM wms_getmap WHERE url = ? AND layer_name = ?";
6873     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6874     if (ret != SQLITE_OK)
6875       {
6876 	  spatialite_e ("WMS_GetMapRequestURL: \"%s\"\n",
6877 			sqlite3_errmsg (sqlite));
6878 	  return NULL;
6879       }
6880     sqlite3_reset (stmt);
6881     sqlite3_clear_bindings (stmt);
6882     sqlite3_bind_text (stmt, 1, getmap_url, strlen (getmap_url), SQLITE_STATIC);
6883     sqlite3_bind_text (stmt, 2, layer_name, strlen (layer_name), SQLITE_STATIC);
6884     while (1)
6885       {
6886 	  /* scrolling the result set rows */
6887 	  ret = sqlite3_step (stmt);
6888 	  if (ret == SQLITE_DONE)
6889 	      break;		/* end of result set */
6890 	  if (ret == SQLITE_ROW)
6891 	    {
6892 		const char *ref_sys_prefix = "CRS";
6893 		const char *bgcolor = NULL;
6894 		const char *version =
6895 		    (const char *) sqlite3_column_text (stmt, 0);
6896 		const char *ref_sys =
6897 		    (const char *) sqlite3_column_text (stmt, 1);
6898 		const char *format =
6899 		    (const char *) sqlite3_column_text (stmt, 2);
6900 		const char *style =
6901 		    (const char *) sqlite3_column_text (stmt, 3);
6902 		int transparent = sqlite3_column_int (stmt, 4);
6903 		int flip_axes = sqlite3_column_int (stmt, 5);
6904 		if (sqlite3_column_type (stmt, 6) == SQLITE_TEXT)
6905 		    bgcolor = (const char *) sqlite3_column_text (stmt, 6);
6906 		/* preparing the request URL */
6907 		if (strcmp (version, "1.3.0") < 0)
6908 		  {
6909 		      /* earlier versions of the protocol require SRS instead of CRS */
6910 		      ref_sys_prefix = "SRS";
6911 		  }
6912 		if (flip_axes)
6913 		  {
6914 		      request_url =
6915 			  sqlite3_mprintf
6916 			  ("%s?SERVICE=WMS&REQUEST=GetMap&VERSION=%s"
6917 			   "&LAYERS=%s&%s=%s&BBOX=%1.6f,%1.6f,%1.6f,%1.6f"
6918 			   "&WIDTH=%d&HEIGHT=%d&STYLES=%s&FORMAT=%s"
6919 			   "&TRANSPARENT=%s", getmap_url, version, layer_name,
6920 			   ref_sys_prefix, ref_sys, miny, minx, maxy, maxx,
6921 			   width, height, style, format,
6922 			   (transparent == 0) ? "FALSE" : "TRUE");
6923 		  }
6924 		else
6925 		  {
6926 		      request_url =
6927 			  sqlite3_mprintf
6928 			  ("%s?SERVICE=WMS&REQUEST=GetMap&VERSION=%s"
6929 			   "&LAYERS=%s&%s=%s&BBOX=%1.6f,%1.6f,%1.6f,%1.6f"
6930 			   "&WIDTH=%d&HEIGHT=%d&STYLES=%s&FORMAT=%s"
6931 			   "&TRANSPARENT=%s", getmap_url, version, layer_name,
6932 			   ref_sys_prefix, ref_sys, minx, miny, maxx, maxy,
6933 			   width, height, style, format,
6934 			   (transparent == 0) ? "FALSE" : "TRUE");
6935 		  }
6936 		if (bgcolor != NULL)
6937 		  {
6938 		      char *prev = request_url;
6939 		      request_url =
6940 			  sqlite3_mprintf ("%s&BGCOLOR=0x%s", prev, bgcolor);
6941 		      sqlite3_free (prev);
6942 		  }
6943 	    }
6944       }
6945     sqlite3_finalize (stmt);
6946     return request_url;
6947 }
6948 
6949 SPATIALITE_PRIVATE char *
wms_getfeatureinfo_request_url(void * p_sqlite,const char * getmap_url,const char * layer_name,int width,int height,int x,int y,double minx,double miny,double maxx,double maxy,int feature_count)6950 wms_getfeatureinfo_request_url (void *p_sqlite, const char *getmap_url,
6951 				const char *layer_name, int width, int height,
6952 				int x, int y, double minx, double miny,
6953 				double maxx, double maxy, int feature_count)
6954 {
6955 /* return a WMS GetFeatureInfo request URL */
6956     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
6957     int ret;
6958     const char *sql;
6959     sqlite3_stmt *stmt;
6960     char *request_url = NULL;
6961 
6962     if (getmap_url == NULL)
6963 	return NULL;
6964 
6965     sql = "SELECT version, srs, flip_axes, is_queryable, getfeatureinfo_url "
6966 	"FROM wms_getmap WHERE url = ? AND layer_name = ?";
6967     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
6968     if (ret != SQLITE_OK)
6969       {
6970 	  spatialite_e ("WMS_GetFeatureInfoRequestURL: \"%s\"\n",
6971 			sqlite3_errmsg (sqlite));
6972 	  return NULL;
6973       }
6974     sqlite3_reset (stmt);
6975     sqlite3_clear_bindings (stmt);
6976     sqlite3_bind_text (stmt, 1, getmap_url, strlen (getmap_url), SQLITE_STATIC);
6977     sqlite3_bind_text (stmt, 2, layer_name, strlen (layer_name), SQLITE_STATIC);
6978     while (1)
6979       {
6980 	  /* scrolling the result set rows */
6981 	  ret = sqlite3_step (stmt);
6982 	  if (ret == SQLITE_DONE)
6983 	      break;		/* end of result set */
6984 	  if (ret == SQLITE_ROW)
6985 	    {
6986 		const char *ref_sys_prefix = "CRS";
6987 		const char *getfeatureinfo_url = NULL;
6988 		const char *version =
6989 		    (const char *) sqlite3_column_text (stmt, 0);
6990 		const char *ref_sys =
6991 		    (const char *) sqlite3_column_text (stmt, 1);
6992 		int flip_axes = sqlite3_column_int (stmt, 2);
6993 		int is_queryable = sqlite3_column_int (stmt, 3);
6994 		if (sqlite3_column_type (stmt, 4) == SQLITE_TEXT)
6995 		    getfeatureinfo_url =
6996 			(const char *) sqlite3_column_text (stmt, 4);
6997 		if (!is_queryable || getfeatureinfo_url == NULL)
6998 		    return NULL;
6999 
7000 		/* preparing the request URL */
7001 		if (feature_count < 1)
7002 		    feature_count = 1;
7003 		if (strcmp (version, "1.3.0") < 0)
7004 		  {
7005 		      /* earlier versions of the protocol require SRS instead of CRS */
7006 		      ref_sys_prefix = "SRS";
7007 		  }
7008 		if (flip_axes)
7009 		  {
7010 		      request_url =
7011 			  sqlite3_mprintf
7012 			  ("%s?SERVICE=WMS&REQUEST=GetFeatureInfo&VERSION=%s"
7013 			   "&QUERY_LAYERS=%s&%s=%s&BBOX=%1.6f,%1.6f,%1.6f,%1.6f"
7014 			   "&WIDTH=%d&HEIGHT=%d&X=%d&Y=%d&FEATURE_COUNT=%d",
7015 			   getfeatureinfo_url, version, layer_name,
7016 			   ref_sys_prefix, ref_sys, miny, minx, maxy, maxx,
7017 			   width, height, x, y, feature_count);
7018 		  }
7019 		else
7020 		  {
7021 		      request_url =
7022 			  sqlite3_mprintf
7023 			  ("%s?SERVICE=WMS&REQUEST=GetFeatureInfo&VERSION=%s"
7024 			   "&QUERY_LAYERS=%s&%s=%s&BBOX=%1.6f,%1.6f,%1.6f,%1.6f"
7025 			   "&WIDTH=%d&HEIGHT=%d&X=%d&Y=%d&FEATURE_COUNT=%d",
7026 			   getfeatureinfo_url, version, layer_name,
7027 			   ref_sys_prefix, ref_sys, minx, miny, maxx, maxy,
7028 			   width, height, x, y, feature_count);
7029 		  }
7030 	    }
7031       }
7032     sqlite3_finalize (stmt);
7033     return request_url;
7034 }
7035 
7036 SPATIALITE_PRIVATE int
register_data_license(void * p_sqlite,const char * license_name,const char * url)7037 register_data_license (void *p_sqlite, const char *license_name,
7038 		       const char *url)
7039 {
7040 /* auxiliary function: inserts a Data License */
7041     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
7042     int ret;
7043     const char *sql;
7044     sqlite3_stmt *stmt;
7045 
7046     if (license_name == NULL)
7047 	return 0;
7048 
7049     sql = "INSERT INTO data_licenses (name, url) VALUES (?, ?)";
7050     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
7051     if (ret != SQLITE_OK)
7052       {
7053 	  spatialite_e ("registerDataLicense: \"%s\"\n",
7054 			sqlite3_errmsg (sqlite));
7055 	  return 0;
7056       }
7057     sqlite3_reset (stmt);
7058     sqlite3_clear_bindings (stmt);
7059     sqlite3_bind_text (stmt, 1, license_name,
7060 		       strlen (license_name), SQLITE_STATIC);
7061     if (url == NULL)
7062 	sqlite3_bind_null (stmt, 2);
7063     else
7064 	sqlite3_bind_text (stmt, 2, url, strlen (url), SQLITE_STATIC);
7065 
7066     ret = sqlite3_step (stmt);
7067     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
7068 	;
7069     else
7070       {
7071 	  spatialite_e ("registerDataLicense() error: \"%s\"\n",
7072 			sqlite3_errmsg (sqlite));
7073 	  sqlite3_finalize (stmt);
7074 	  return 0;
7075       }
7076     sqlite3_finalize (stmt);
7077     return 1;
7078 }
7079 
7080 SPATIALITE_PRIVATE int
unregister_data_license(void * p_sqlite,const char * license_name)7081 unregister_data_license (void *p_sqlite, const char *license_name)
7082 {
7083 /* auxiliary function: deletes a Data License */
7084     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
7085     int ret;
7086     const char *sql;
7087     sqlite3_stmt *stmt;
7088 
7089     if (license_name == NULL)
7090 	return 0;
7091 
7092     sql = "DELETE FROM data_licenses WHERE name = ?";
7093     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
7094     if (ret != SQLITE_OK)
7095       {
7096 	  spatialite_e ("unregisterDataLicense: \"%s\"\n",
7097 			sqlite3_errmsg (sqlite));
7098 	  return 0;
7099       }
7100     sqlite3_reset (stmt);
7101     sqlite3_clear_bindings (stmt);
7102     sqlite3_bind_text (stmt, 1, license_name,
7103 		       strlen (license_name), SQLITE_STATIC);
7104 
7105     ret = sqlite3_step (stmt);
7106     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
7107 	;
7108     else
7109       {
7110 	  spatialite_e ("unregisterDataLicense() error: \"%s\"\n",
7111 			sqlite3_errmsg (sqlite));
7112 	  sqlite3_finalize (stmt);
7113 	  return 0;
7114       }
7115     sqlite3_finalize (stmt);
7116     return 1;
7117 }
7118 
7119 SPATIALITE_PRIVATE int
rename_data_license(void * p_sqlite,const char * old_name,const char * new_name)7120 rename_data_license (void *p_sqlite, const char *old_name, const char *new_name)
7121 {
7122 /* auxiliary function: renames a Data License */
7123     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
7124     int ret;
7125     const char *sql;
7126     sqlite3_stmt *stmt;
7127     int prev_changes;
7128     int curr_changes;
7129 
7130     if (old_name == NULL || new_name == NULL)
7131 	return 0;
7132 
7133     prev_changes = sqlite3_total_changes (sqlite);
7134 
7135     sql = "UPDATE data_licenses SET name = ? WHERE name = ?";
7136     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
7137     if (ret != SQLITE_OK)
7138       {
7139 	  spatialite_e ("renameDataLicense: \"%s\"\n", sqlite3_errmsg (sqlite));
7140 	  return 0;
7141       }
7142     sqlite3_reset (stmt);
7143     sqlite3_clear_bindings (stmt);
7144     sqlite3_bind_text (stmt, 1, new_name, strlen (new_name), SQLITE_STATIC);
7145     sqlite3_bind_text (stmt, 2, old_name, strlen (old_name), SQLITE_STATIC);
7146 
7147     ret = sqlite3_step (stmt);
7148     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
7149 	;
7150     else
7151       {
7152 	  spatialite_e ("renameDataLicense() error: \"%s\"\n",
7153 			sqlite3_errmsg (sqlite));
7154 	  sqlite3_finalize (stmt);
7155 	  return 0;
7156       }
7157     sqlite3_finalize (stmt);
7158 
7159     curr_changes = sqlite3_total_changes (sqlite);
7160     if (prev_changes == curr_changes)
7161 	return 0;
7162     return 1;
7163 }
7164 
7165 SPATIALITE_PRIVATE int
set_data_license_url(void * p_sqlite,const char * license_name,const char * url)7166 set_data_license_url (void *p_sqlite, const char *license_name, const char *url)
7167 {
7168 /* auxiliary function: updates a Data License URL */
7169     sqlite3 *sqlite = (sqlite3 *) p_sqlite;
7170     int ret;
7171     const char *sql;
7172     sqlite3_stmt *stmt;
7173     int prev_changes;
7174     int curr_changes;
7175 
7176     if (license_name == NULL || url == NULL)
7177 	return 0;
7178 
7179     prev_changes = sqlite3_total_changes (sqlite);
7180 
7181     sql = "UPDATE data_licenses SET url = ? WHERE name = ?";
7182     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
7183     if (ret != SQLITE_OK)
7184       {
7185 	  spatialite_e ("setDataLicenseUrl: \"%s\"\n", sqlite3_errmsg (sqlite));
7186 	  return 0;
7187       }
7188     sqlite3_reset (stmt);
7189     sqlite3_clear_bindings (stmt);
7190     sqlite3_bind_text (stmt, 1, url, strlen (url), SQLITE_STATIC);
7191     sqlite3_bind_text (stmt, 2, license_name,
7192 		       strlen (license_name), SQLITE_STATIC);
7193 
7194     ret = sqlite3_step (stmt);
7195     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
7196 	;
7197     else
7198       {
7199 	  spatialite_e ("setDataLicenseUrl() error: \"%s\"\n",
7200 			sqlite3_errmsg (sqlite));
7201 	  sqlite3_finalize (stmt);
7202 	  return 0;
7203       }
7204     sqlite3_finalize (stmt);
7205 
7206     curr_changes = sqlite3_total_changes (sqlite);
7207     if (prev_changes == curr_changes)
7208 	return 0;
7209     return 1;
7210 }
7211