1 /*!
2 \file lib/db/dbmi_base/cursor.c
3
4 \brief DBMI Library (base) - cursors management
5
6 (C) 1999-2009 by the GRASS Development Team
7
8 This program is free software under the GNU General Public
9 License (>=v2). Read the file COPYING that comes with GRASS
10 for details.
11
12 \author Joel Jones (CERL/UIUC), Radim Blazek
13 */
14
15 #include <stdlib.h>
16 #include <grass/dbmi.h>
17
18 /*!
19 \brief Initialize dbCursor
20
21 \param cursor pointer to dbCursor to be initialized
22 */
db_init_cursor(dbCursor * cursor)23 void db_init_cursor(dbCursor *cursor)
24 {
25 G_zero(cursor, sizeof(dbCursor));
26 cursor->token = -1;
27 }
28
29 /*!
30 \brief Allocate table for cursor
31
32 \param cursor pointer to dbCursor
33 \param ncols number of column in table
34
35 \return DB_OK on success
36 \return error code on error
37 */
db_alloc_cursor_table(dbCursor * cursor,int ncols)38 int db_alloc_cursor_table(dbCursor *cursor, int ncols)
39 {
40 cursor->table = db_alloc_table(ncols);
41 if (cursor->table == NULL)
42 return db_get_error_code();
43 return DB_OK;
44 }
45
46 /*!
47 \brief Free allocated dbCursor
48
49 \param cursor pointer to dbCursor
50 */
db_free_cursor(dbCursor * cursor)51 void db_free_cursor(dbCursor *cursor)
52 {
53 if (cursor->table)
54 db_free_table(cursor->table);
55 if (cursor->column_flags)
56 db_free_cursor_column_flags(cursor);
57 db_init_cursor(cursor);
58 }
59
60 /*!
61 \brief Get table allocated by cursor
62
63 \param cursor pointer to dbCursor
64
65 \return pointer to dbTable
66 */
db_get_cursor_table(dbCursor * cursor)67 dbTable *db_get_cursor_table(dbCursor *cursor)
68 {
69 return cursor->table;
70 }
71
72 /*!
73 \brief Set table for given cursor
74
75 \param cursor pointer to dbCursor
76 \param table pointer to dbTable
77 */
db_set_cursor_table(dbCursor * cursor,dbTable * table)78 void db_set_cursor_table(dbCursor *cursor, dbTable *table)
79 {
80 cursor->table = table;
81 }
82
83 /*!
84 \brief Get cursor token
85
86 \param cursor pointer to dbCursor
87
88 \return pointer to dbToken
89 */
db_get_cursor_token(dbCursor * cursor)90 dbToken db_get_cursor_token(dbCursor *cursor)
91 {
92 return cursor->token;
93 }
94
95 /*!
96 \brief Set cursor token
97
98 \param cursor pointer to dbCursor
99 \param token pointer to dbToken
100 */
db_set_cursor_token(dbCursor * cursor,dbToken token)101 void db_set_cursor_token(dbCursor *cursor, dbToken token)
102 {
103 cursor->token = token;
104 }
105
106 /*!
107 \brief Set cursor to be read-only (select)
108
109 \param cursor pointer to dbCursor
110 */
db_set_cursor_type_readonly(dbCursor * cursor)111 void db_set_cursor_type_readonly(dbCursor *cursor)
112 {
113 cursor->type = DB_READONLY;
114 }
115
116 /*!
117 \brief Set cursor to be writable (update)
118
119 \param cursor pointer to dbCursor
120 */
db_set_cursor_type_update(dbCursor * cursor)121 void db_set_cursor_type_update(dbCursor *cursor)
122 {
123 cursor->type = DB_UPDATE;
124 }
125
126 /*!
127 \brief Set cursor to be writable (insert)
128
129 \param cursor pointer to dbCursor
130 */
db_set_cursor_type_insert(dbCursor * cursor)131 void db_set_cursor_type_insert(dbCursor *cursor)
132 {
133 cursor->type = DB_INSERT;
134 }
135
136 /*!
137 \brief Check cursor type
138
139 \param cursor pointer to dbCursor
140
141 \return 1 for known cursor type
142 \return 0 for unknown cursor type
143 */
db_test_cursor_type_fetch(dbCursor * cursor)144 int db_test_cursor_type_fetch(dbCursor *cursor)
145 {
146 return (cursor->type == DB_READONLY ||
147 cursor->type == DB_UPDATE ||
148 cursor->type == DB_INSERT);
149 }
150
151 /*!
152 \brief Check if cursor type is 'update'
153
154 \param cursor pointer to dbCursor
155
156 \return 1 if cursor type is 'update'
157 \return 0 otherwise
158 */
db_test_cursor_type_update(dbCursor * cursor)159 int db_test_cursor_type_update(dbCursor *cursor)
160 {
161 return (cursor->type == DB_UPDATE);
162 }
163
164 /*!
165 \brief Check if cursor type is 'insert'
166
167 \param cursor pointer to dbCursor
168
169 \return 1 if cursor type is 'insert'
170 \return 0 otherwise
171 */
db_test_cursor_type_insert(dbCursor * cursor)172 int db_test_cursor_type_insert(dbCursor *cursor)
173 {
174 return (cursor->type == DB_INSERT);
175 }
176
177 /*!
178 \brief Set cursor mode
179
180 Modes:
181 - DB_SCROLL
182 - DB_INSENSITIVE
183
184 \param cursor pointer to dbCursor
185 \param mode cursor mode
186 */
db_set_cursor_mode(dbCursor * cursor,int mode)187 void db_set_cursor_mode(dbCursor *cursor, int mode)
188 {
189 cursor->mode = mode;
190 }
191
192 /*!
193 \brief Set 'scroll' cursor mode
194
195 \param cursor pointer to dbCursor
196 */
db_set_cursor_mode_scroll(dbCursor * cursor)197 void db_set_cursor_mode_scroll(dbCursor *cursor)
198 {
199 cursor->mode |= DB_SCROLL;
200 }
201
202 /*!
203 \brief Unset 'scroll' cursor mode
204
205 \param cursor pointer to dbCursor
206 */
db_unset_cursor_mode_scroll(dbCursor * cursor)207 void db_unset_cursor_mode_scroll(dbCursor *cursor)
208 {
209 cursor->mode &= ~DB_SCROLL;
210 }
211
212 /*!
213 \brief Unset cursor mode
214
215 \param cursor pointer to dbCursor
216 */
db_unset_cursor_mode(dbCursor * cursor)217 void db_unset_cursor_mode(dbCursor *cursor)
218 {
219 cursor->mode = 0;
220 }
221
222 /*!
223 \brief Set 'intensive' cursor mode
224
225 \param cursor pointer to dbCursor
226 */
db_set_cursor_mode_insensitive(dbCursor * cursor)227 void db_set_cursor_mode_insensitive(dbCursor *cursor)
228 {
229 cursor->mode |= DB_INSENSITIVE;
230 }
231
232 /*!
233 \brief Unset 'intensive' cursor mode
234
235 \param cursor pointer to dbCursor
236 */
db_unset_cursor_mode_insensitive(dbCursor * cursor)237 void db_unset_cursor_mode_insensitive(dbCursor *cursor)
238 {
239 cursor->mode &= ~DB_INSENSITIVE;
240 }
241
242 /*!
243 \brief Check if cursor mode is 'scroll'
244
245 \param cursor pointer to dbCursor
246
247 \return 1 if true
248 \return 0 if false
249 */
db_test_cursor_mode_scroll(dbCursor * cursor)250 int db_test_cursor_mode_scroll(dbCursor *cursor)
251 {
252 return (cursor->mode & DB_SCROLL);
253 }
254
255 /*!
256 \brief Check if cursor mode is 'intensive'
257
258 \param cursor pointer to dbCursor
259
260 \return 1 if true
261 \return 0 if false
262 */
db_test_cursor_mode_insensitive(dbCursor * cursor)263 int db_test_cursor_mode_insensitive(dbCursor *cursor)
264 {
265 return (cursor->mode & DB_INSENSITIVE);
266 }
267
268 /*!
269 \brief Allocate columns' flags for cursor
270
271 \param cursor pointer to dbCursor
272
273 \return DB_OK on success
274 \return error code on failure
275 */
db_alloc_cursor_column_flags(dbCursor * cursor)276 int db_alloc_cursor_column_flags(dbCursor *cursor)
277 {
278 int ncols;
279 int col;
280
281 ncols = db_get_cursor_number_of_columns(cursor);
282 cursor->column_flags = (short *)db_calloc(ncols, sizeof(short));
283 if (cursor->column_flags == NULL)
284 return db_get_error_code();
285 for (col = 0; col < ncols; col++)
286 db_unset_cursor_column_flag(cursor, col);
287 return DB_OK;
288 }
289
290 /*!
291 \brief Free columns' flags of cursor
292
293 \param cursor pointer to dbCursor
294 */
db_free_cursor_column_flags(dbCursor * cursor)295 void db_free_cursor_column_flags(dbCursor *cursor)
296 {
297 if (cursor->column_flags)
298 db_free(cursor->column_flags);
299 cursor->column_flags = NULL;
300 }
301
302 /*!
303 \brief Set Column flag to 'update'
304
305 \param cursor pointer to dbCursor
306 \param col column index (starting with '0')
307 */
db_set_cursor_column_for_update(dbCursor * cursor,int col)308 void db_set_cursor_column_for_update(dbCursor *cursor, int col)
309 {
310 db_set_cursor_column_flag(cursor, col);
311 }
312
313 /*!
314 \brief Unset 'update' column flag
315
316 \param cursor pointer to dbCursor
317 \param col column index (starting with '0')
318 */
db_unset_cursor_column_for_update(dbCursor * cursor,int col)319 void db_unset_cursor_column_for_update(dbCursor *cursor, int col)
320 {
321 db_unset_cursor_column_flag(cursor, col);
322 }
323
324 /*!
325 \brief Check if column flag is 'update'
326
327 \param cursor pointer to dbCursor
328 \param col column index (starting with '0')
329
330 \return 1 if true
331 \return 0 if false
332 */
db_test_cursor_column_for_update(dbCursor * cursor,int col)333 int db_test_cursor_column_for_update(dbCursor *cursor, int col)
334 {
335 return db_test_cursor_column_flag(cursor, col);
336 }
337
338 /*!
339 \brief Check if columns' flag is 'update'
340
341 \param cursor pointer to dbCursor
342
343 \return 1 if true
344 \return 0 if false
345 */
db_test_cursor_any_column_for_update(dbCursor * cursor)346 int db_test_cursor_any_column_for_update(dbCursor *cursor)
347 {
348 return db_test_cursor_any_column_flag(cursor);
349 }
350
351 /*!
352 \brief Set column's flag
353
354 \param cursor pointer to dbCursor
355 \param col column index (starting with '0')
356 */
db_set_cursor_column_flag(dbCursor * cursor,int col)357 void db_set_cursor_column_flag(dbCursor *cursor, int col)
358 {
359 if (cursor->column_flags)
360 cursor->column_flags[col] = 1;
361 }
362
363 /*!
364 \brief Unset column's flag
365
366 \param cursor pointer to dbCursor
367 \param col column index (starting with '0')
368 */
db_unset_cursor_column_flag(dbCursor * cursor,int col)369 void db_unset_cursor_column_flag(dbCursor *cursor, int col)
370 {
371 if (cursor->column_flags)
372 cursor->column_flags[col] = 0;
373 }
374
375 /*!
376 \brief Checks column's flag
377
378 \param cursor pointer to dbCursor
379 \param col column index (starting with '0')
380
381 \return 1 if flag is defined
382 \return 0 otherwise
383 */
db_test_cursor_column_flag(dbCursor * cursor,int col)384 int db_test_cursor_column_flag(dbCursor *cursor, int col)
385 {
386 return cursor->column_flags && cursor->column_flags[col] ? 1 : 0;
387 }
388
389 /*!
390 \brief Get number of columns
391
392 \param cursor pointer to dbCursor
393 */
db_get_cursor_number_of_columns(dbCursor * cursor)394 int db_get_cursor_number_of_columns(dbCursor *cursor)
395 {
396 dbTable *table;
397
398 table = db_get_cursor_table(cursor);
399 if (table)
400 return db_get_table_number_of_columns(table);
401 return 0;
402 }
403
404 /*!
405 \brief Checks columns' flag
406
407 Is any cursor column flag set?
408
409 \param cursor pointer to dbCursor
410
411 \return 1 if true
412 \return 0 if false
413 */
db_test_cursor_any_column_flag(dbCursor * cursor)414 int db_test_cursor_any_column_flag(dbCursor *cursor)
415 {
416 int ncols, col;
417
418 ncols = db_get_cursor_number_of_columns(cursor);
419 for (col = 0; col < ncols; col++)
420 if (db_test_cursor_column_flag(cursor, col))
421 return 1;
422 return 0;
423 }
424