1 /*
2  gg_sequence.c -- Gaia support for Spatialite's own Sequence
3 
4  version 5.0, 2020 August 1
5 
6  Author: Sandro Furieri a.furieri@lqt.it
7 
8  ------------------------------------------------------------------------------
9 
10  Version: MPL 1.1/GPL 2.0/LGPL 2.1
11 
12  The contents of this file are subject to the Mozilla Public License Version
13  1.1 (the "License"); you may not use this file except in compliance with
14  the License. You may obtain a copy of the License at
15  http://www.mozilla.org/MPL/
16 
17 Software distributed under the License is distributed on an "AS IS" basis,
18 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
19 for the specific language governing rights and limitations under the
20 License.
21 
22 The Original Code is the SpatiaLite library
23 
24 The Initial Developer of the Original Code is Alessandro Furieri
25 
26 Portions created by the Initial Developer are Copyright (C) 2013-2021
27 the Initial Developer. All Rights Reserved.
28 
29 Contributor(s):
30 
31 Alternatively, the contents of this file may be used under the terms of
32 either the GNU General Public License Version 2 or later (the "GPL"), or
33 the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
34 in which case the provisions of the GPL or the LGPL are applicable instead
35 of those above. If you wish to allow use of your version of this file only
36 under the terms of either the GPL or the LGPL, and not to allow others to
37 use your version of this file under the terms of the MPL, indicate your
38 decision by deleting the provisions above and replace them with the notice
39 and other provisions required by the GPL or the LGPL. If you do not delete
40 the provisions above, a recipient may use your version of this file under
41 the terms of any one of the MPL, the GPL or the LGPL.
42 
43 */
44 
45 #include <stdlib.h>
46 #include <string.h>
47 
48 #if defined(_WIN32) && !defined(__MINGW32__)
49 #include "config-msvc.h"
50 #else
51 #include "config.h"
52 #endif
53 
54 #include <spatialite_private.h>
55 
56 #ifdef _WIN32
57 #define strcasecmp	_stricmp
58 #endif /* not WIN32 */
59 
60 GAIASEQ_DECLARE gaiaSequencePtr
gaiaCreateSequence(const void * p_cache,const char * seq_name)61 gaiaCreateSequence (const void *p_cache, const char *seq_name)
62 {
63 /* creating a new Sequence or retrieving an already existing Sequence */
64     struct splite_internal_cache *cache =
65 	(struct splite_internal_cache *) p_cache;
66     gaiaSequencePtr seq;
67 
68     if (cache == NULL)
69 	return NULL;
70     seq = cache->first_seq;
71     while (seq != NULL)
72       {
73 	  /* testing for an existing Sequence */
74 	  if (seq_name == NULL && seq->seq_name == NULL)
75 	      return seq;
76 	  if (seq_name != NULL && seq->seq_name != NULL)
77 	    {
78 		if (strcasecmp (seq_name, seq->seq_name) == 0)
79 		    return seq;
80 	    }
81 	  seq = seq->next;
82       }
83 
84 /* not already existsting; creating a new Sequence */
85     seq = malloc (sizeof (gaiaSequence));
86     if (seq_name == NULL)
87 	seq->seq_name = NULL;
88     else
89       {
90 	  int len = strlen (seq_name);
91 	  seq->seq_name = malloc (len + 1);
92 	  strcpy (seq->seq_name, seq_name);
93       }
94     seq->value = 0;
95     seq->next = NULL;
96 
97 /* inserting into the linked list */
98     if (cache->first_seq == NULL)
99 	cache->first_seq = seq;
100     if (cache->last_seq != NULL)
101 	cache->last_seq->next = seq;
102     cache->last_seq = seq;
103 
104     return seq;
105 }
106 
107 GAIASEQ_DECLARE gaiaSequencePtr
gaiaFindSequence(const void * p_cache,const char * seq_name)108 gaiaFindSequence (const void *p_cache, const char *seq_name)
109 {
110 /* retrieving an existing Sequence */
111     struct splite_internal_cache *cache =
112 	(struct splite_internal_cache *) p_cache;
113     gaiaSequencePtr seq;
114 
115     if (cache == NULL)
116 	return NULL;
117     seq = cache->first_seq;
118     while (seq != NULL)
119       {
120 	  /* testing for an existing Sequence */
121 	  if (seq_name == NULL && seq->seq_name == NULL)
122 	      return seq;
123 	  if (seq_name != NULL && seq->seq_name != NULL)
124 	    {
125 		if (strcasecmp (seq_name, seq->seq_name) == 0)
126 		    return seq;
127 	    }
128 	  seq = seq->next;
129       }
130 
131     return NULL;
132 }
133 
134 GAIASEQ_DECLARE int
gaiaLastUsedSequence(const void * p_cache,int * value)135 gaiaLastUsedSequence (const void *p_cache, int *value)
136 {
137 /* return the most recently used Sequence (if any) */
138     struct splite_internal_cache *cache =
139 	(struct splite_internal_cache *) p_cache;
140 
141     if (cache == NULL)
142 	return 0;
143     if (cache->ok_last_used_sequence == 0)
144 	return 0;
145     *value = cache->last_used_sequence_val;
146     return 1;
147 }
148 
149 GAIASEQ_DECLARE int
gaiaSequenceNext(const void * p_cache,gaiaSequencePtr seq)150 gaiaSequenceNext (const void *p_cache, gaiaSequencePtr seq)
151 {
152 /* inreases the Sequence value */
153     struct splite_internal_cache *cache =
154 	(struct splite_internal_cache *) p_cache;
155 
156     if (cache == NULL)
157 	return 0;
158     if (seq == NULL)
159 	return 0;
160 
161     seq->value += 1;
162     cache->ok_last_used_sequence = 1;
163     cache->last_used_sequence_val = seq->value;
164     return 1;
165 }
166 
167 GAIASEQ_DECLARE int
gaiaResetSequence(gaiaSequencePtr seq,int value)168 gaiaResetSequence (gaiaSequencePtr seq, int value)
169 {
170 /* resetting a Sequence */
171     if (seq == NULL)
172 	return 0;
173 
174     seq->value = abs (value);
175     return 1;
176 }
177