GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-112dd97adf
dbmi_base/table.c
Go to the documentation of this file.
1 /*!
2  \file lib/db/dbmi_base/table.c
3 
4  \brief DBMI Library (base) - table management
5 
6  (C) 1999-2009, 2011 by the GRASS Development Team
7 
8  This program is free software under the GNU General Public License
9  (>=v2). Read the file COPYING that comes with GRASS for details.
10 
11  \author Joel Jones (CERL/UIUC), Radim Blazek
12  \author Doxygenized by Martin Landa <landa.martin gmail.com> (2011)
13  */
14 
15 #include <stdlib.h>
16 #include <string.h>
17 #include <grass/gis.h>
18 #include <grass/dbmi.h>
19 
20 /*!
21  \brief Allocate a table with a specific number of columns
22 
23  \param ncols number of columns which should be allocated
24 
25  \return allocated dbTable
26  \return NULL in case of an error
27  */
29 {
30  dbTable *table;
31  int i;
32 
33  table = (dbTable *)db_malloc(sizeof(dbTable));
34  if (table == NULL)
35  return (table = NULL);
36 
37  db_init_table(table);
38 
39  table->columns = (dbColumn *)db_calloc(sizeof(dbColumn), ncols);
40  if (table->columns == NULL) {
41  db_free(table);
42  return (table = NULL);
43  }
44  table->numColumns = ncols;
45  for (i = 0; i < ncols; i++)
46  db_init_column(&table->columns[i]);
47 
48  return table;
49 }
50 
51 /*!
52  \brief Initialize the table to zero
53 
54  \param table pointer to dbTable
55  */
56 void db_init_table(dbTable *table)
57 {
58  db_zero((void *)table, sizeof(dbTable));
59  db_init_string(&table->tableName);
60  db_init_string(&table->description);
61 }
62 
63 /*!
64  \brief Free the table
65 
66  \param table pointer to dbTable
67  */
68 void db_free_table(dbTable *table)
69 {
70  int i;
71 
72  db_free_string(&table->tableName);
73  db_free_string(&table->description);
74  for (i = 0; i < table->numColumns; i++)
75  db_free_column(&table->columns[i]);
76  if (table->columns)
77  db_free(table->columns);
78  db_free(table);
79 }
80 
81 /*!
82  \brief Set the name of the table
83 
84  \param table pointer to dbTable
85  \param name The name of the table
86 
87  \return DB_OK on success
88  */
89 int db_set_table_name(dbTable *table, const char *name)
90 {
91  return db_set_string(&table->tableName, name);
92 }
93 
94 /*!
95  \brief Get the name of the table
96 
97  \param table pointer to dbTable
98 
99  \return name of the table
100  */
101 const char *db_get_table_name(dbTable *table)
102 {
103  return db_get_string(&table->tableName);
104 }
105 
106 /*!
107  \brief Set the description of the table
108 
109  \param table pointer to dbTable
110  \param name description of the table
111 
112  \return DB_OK
113  */
114 int db_set_table_description(dbTable *table, const char *description)
115 {
116  return db_set_string(&table->description, description);
117 }
118 
119 /*!
120  \brief Get the description of the table
121 
122  \param table pointer to dbTable
123 
124  \return description of the table
125  */
127 {
128  return db_get_string(&table->description);
129 }
130 
131 /*!
132  \brief Return the number of columns of the table
133 
134  \param table pointer to dbTable
135 
136  \return number of columns
137  */
139 {
140  return table->numColumns;
141 }
142 
143 static void set_all_column_privs(dbTable *table,
144  void (*set_column_priv)(dbColumn *))
145 {
146  int col, ncols;
147  dbColumn *column;
148 
149  ncols = db_get_table_number_of_columns(table);
150  for (col = 0; col < ncols; col++) {
151  column = db_get_table_column(table, col);
152  set_column_priv(column);
153  }
154 }
155 
156 static int get_all_column_privs(dbTable *table,
157  int (*get_column_priv)(dbColumn *))
158 {
159  int priv, col, ncols;
160  dbColumn *column;
161 
162  ncols = db_get_table_number_of_columns(table);
163  for (col = 0; col < ncols; col++) {
164  column = db_get_table_column(table, col);
165  priv = get_column_priv(column);
166  if (priv != DB_GRANTED)
167  return priv;
168  }
169  return DB_GRANTED;
170 }
171 
172 /*!
173  \brief Grant selection privileges for all columns
174 
175  \param table pointer to dbTable
176  */
178 {
179  set_all_column_privs(table, db_set_column_select_priv_granted);
180 }
181 
182 /*!
183  \brief Set selection privileges not granted for all columns
184 
185  \param table pointer to dbTable
186  */
188 {
189  set_all_column_privs(table, db_set_column_select_priv_not_granted);
190 }
191 
192 /*!
193  \brief Get table select privileges
194 
195  \param table pointer to dbTable
196 
197  \return privileges
198  */
200 {
201  return get_all_column_privs(table, db_get_column_select_priv);
202 }
203 
204 /*!
205  \brief Grant update privileges for all columns
206 
207  \param table pointer to dbTable
208  */
210 {
211  set_all_column_privs(table, db_set_column_update_priv_granted);
212 }
213 
214 /*!
215  \brief Set update privileges not granted for all columns
216 
217  \param table pointer to dbTable
218  */
220 {
221  set_all_column_privs(table, db_set_column_update_priv_not_granted);
222 }
223 
224 /*!
225  \brief Get table update privileges
226 
227  \param table pointer to dbTable
228 
229  \return privileges
230  */
232 {
233  return get_all_column_privs(table, db_get_column_update_priv);
234 }
235 
236 /*!
237  \brief Grant insert privileges for table
238 
239  \param table pointer to dbTable
240  */
242 {
243  table->priv_insert = DB_GRANTED;
244 }
245 
246 /*!
247  \brief Set insert privileges not granted for table
248 
249  \param table pointer to dbTable
250  */
252 {
253  table->priv_insert = DB_NOT_GRANTED;
254 }
255 
256 /*!
257  \brief Get table insert privileges
258 
259  \param table pointer to dbTable
260 
261  \return prilileges
262  */
264 {
265  return table->priv_insert;
266 }
267 
268 /*!
269  \brief Grant delete privileges for table
270 
271  \param table pointer to dbTable
272  */
274 {
275  table->priv_delete = DB_GRANTED;
276 }
277 
278 /*!
279  \brief Set delete privileges not granted for table
280 
281  \param table pointer to dbTable
282  */
284 {
285  table->priv_delete = DB_NOT_GRANTED;
286 }
287 
288 /*!
289  \brief Get table delete privileges
290 
291  \param table pointer to dbTable
292 
293  \return privileges
294  */
296 {
297  return table->priv_delete;
298 }
299 
300 /*!
301  \brief Returns column structure for given table and column number
302 
303  \param table pointer to dbTable
304  \param idx column index (starting with '0')
305 
306  \return pointer to dbColumn
307  \return NULL if not found
308  */
310 {
311  if (idx < 0 || idx >= table->numColumns)
312  return ((dbColumn *)NULL);
313  return &table->columns[idx];
314 }
315 
316 /*!
317  \brief Returns column structure for given table and column name
318 
319  \param table pointer to dbTable
320  \param name the name of the column
321 
322  \return pointer to dbColumn
323  \return NULL if not found
324  */
326 {
327  dbColumn *c = NULL;
328  int i, columns = table->numColumns;
329 
330  for (i = 0; i < columns; i++) {
331  c = db_get_table_column(table, i);
332 
333  if (c == NULL)
334  return c;
335 
336  if (strcmp(name, db_get_string(&c->columnName)) == 0)
337  break;
338 
339  c = NULL;
340  }
341 
342  return c;
343 }
344 
345 /*!
346  \brief Set a specific column for given table and column number
347 
348  \param table Pointer to dbTable
349  \param idx Column index (starting with '0'). The index must be in range.
350  \param column Pointer to a dbColumn to insert.
351  A copy of the column stored, so the original column can be deleted.
352 
353  \return DB_OK on success
354  \return DB_FAILURE on error
355  */
356 int db_set_table_column(dbTable *table, int idx, dbColumn *column)
357 {
358  if (idx < 0 || idx >= table->numColumns)
359  return DB_FAILED;
360  db_copy_column(&table->columns[idx], column);
361  return DB_OK;
362 }
363 
364 /*!
365  \brief Append a specific column to given table
366 
367  \param table Pointer to dbTable
368  \param column Pointer to a dbColumn to append.
369  A copy of the column is stored, so the original column can be deleted.
370 
371  \return DB_OK on success
372  \return DB_FAILURE on error
373  */
375 {
376  table->columns = (dbColumn *)db_realloc(
377  (void *)table->columns, sizeof(dbColumn) * (table->numColumns + 1));
378  if (table->columns == NULL)
379  return DB_FAILED;
380  db_copy_column(&table->columns[table->numColumns], column);
381  table->numColumns++;
382  return DB_OK;
383 }
384 
385 /*!
386  \brief Make a new exact copy of an existing table
387 
388  New memory is allocated for the clone, the columns-content will be copied
389  too.
390 
391  \param src Pointer to dbTable
392 
393  \return A new alloacted clone of the given table on success
394  \return NULL on error
395  */
397 {
398  int i, n = db_get_table_number_of_columns(src);
399  dbTable *new = db_alloc_table(n);
400 
401  if (new == NULL)
402  return (new = NULL);
403 
404  db_copy_string(&new->description, &src->description);
405  db_copy_string(&new->tableName, &src->tableName);
406 
407  /* Deep copy the columns */
408  for (i = 0; i < n; i++) {
409  db_copy_column(&new->columns[i], &src->columns[i]);
410  }
411 
412  new->numColumns = n;
413  new->priv_delete = src->priv_delete;
414  new->priv_insert = src->priv_insert;
415 
416  return new;
417 }
418 
419 /*!
420  \brief Create SQL CREATE string from table definition
421 
422  \param table pointer to dbTable
423  \param sql dbString to store the SQL CREATE string
424 
425  \return DB_OK on success
426  \return DB_FAILED on error
427  */
429 {
430  int col, ncols;
431  dbColumn *column;
432  const char *colname;
433  int sqltype;
434  char buf[500];
435 
436  db_set_string(sql, "create table ");
437  db_append_string(sql, db_get_table_name(table));
438  db_append_string(sql, " ( ");
439 
440  ncols = db_get_table_number_of_columns(table);
441 
442  for (col = 0; col < ncols; col++) {
443  column = db_get_table_column(table, col);
444  colname = db_get_column_name(column);
445  sqltype = db_get_column_sqltype(column);
446 
447  G_debug(3, "%s (%s)", colname, db_sqltype_name(sqltype));
448 
449  if (col > 0)
450  db_append_string(sql, ", ");
451  db_append_string(sql, colname);
452  db_append_string(sql, " ");
453  /* Note: I found on Web:
454  * These are the ANSI data types: BIT, CHARACTER, DATE, DECIMAL, DOUBLE
455  * PRECISION, FLOAT, INTEGER, INTERVAL, NUMERIC, REAL, SMALLINT,
456  * TIMESTAMP, TIME, VARBIT, VARCHAR, CHAR
457  * ...
458  * Thus, the only data types you can use with the assurance that they
459  * will work everywhere are as follows: DOUBLE PRECISION, FLOAT,
460  * INTEGER, NUMERIC, REAL, SMALLINT, VARCHAR, CHAR */
461  switch (sqltype) {
463  sprintf(buf, "varchar(%d)", db_get_column_length(column));
464  db_append_string(sql, buf);
465  break;
466  case DB_SQL_TYPE_TEXT:
467  G_warning("Type TEXT converted to 'VARCHAR(250)'");
468  db_append_string(sql, "varchar(250)");
469  break;
471  case DB_SQL_TYPE_INTEGER:
472  db_append_string(sql, "integer");
473  break;
474  case DB_SQL_TYPE_REAL:
476  case DB_SQL_TYPE_DECIMAL:
477  case DB_SQL_TYPE_NUMERIC:
479  db_append_string(sql, "double precision");
480  break;
481  case DB_SQL_TYPE_DATE:
482  db_append_string(sql, "date");
483  break;
484  case DB_SQL_TYPE_TIME:
485  db_append_string(sql, "time");
486  break;
488  db_append_string(sql, "datetime");
489  break;
490  default:
491  G_warning("Unknown column type (%s)", colname);
492  return DB_FAILED;
493  }
494  }
495  db_append_string(sql, " )");
496  G_debug(3, "sql statement: %s", db_get_string(sql));
497 
498  return DB_OK;
499 }
int columns
Definition: calc.c:11
#define NULL
Definition: ccmath.h:32
#define DB_SQL_TYPE_TIME
Definition: dbmi.h:89
#define DB_SQL_TYPE_TEXT
Definition: dbmi.h:92
#define DB_SQL_TYPE_INTEGER
Definition: dbmi.h:83
struct _db_column dbColumn
#define DB_NOT_GRANTED
Definition: dbmi.h:129
#define DB_SQL_TYPE_SMALLINT
Definition: dbmi.h:82
#define DB_SQL_TYPE_NUMERIC
Definition: dbmi.h:87
#define DB_SQL_TYPE_INTERVAL
Definition: dbmi.h:91
#define DB_GRANTED
Definition: dbmi.h:128
#define DB_SQL_TYPE_REAL
Definition: dbmi.h:84
#define DB_FAILED
Definition: dbmi.h:72
#define DB_SQL_TYPE_DOUBLE_PRECISION
Definition: dbmi.h:85
#define DB_SQL_TYPE_DECIMAL
Definition: dbmi.h:86
#define DB_SQL_TYPE_DATE
Definition: dbmi.h:88
#define DB_OK
Definition: dbmi.h:71
#define DB_SQL_TYPE_CHARACTER
Definition: dbmi.h:81
#define DB_SQL_TYPE_TIMESTAMP
Definition: dbmi.h:90
void db_set_table_update_priv_not_granted(dbTable *table)
Set update privileges not granted for all columns.
int db_table_to_sql(dbTable *table, dbString *sql)
Create SQL CREATE string from table definition.
int db_get_table_number_of_columns(dbTable *table)
Return the number of columns of the table.
int db_set_table_name(dbTable *table, const char *name)
Set the name of the table.
int db_get_table_insert_priv(dbTable *table)
Get table insert privileges.
dbTable * db_alloc_table(int ncols)
Allocate a table with a specific number of columns.
int db_get_table_select_priv(dbTable *table)
Get table select privileges.
int db_get_table_update_priv(dbTable *table)
Get table update privileges.
dbTable * db_clone_table(dbTable *src)
Make a new exact copy of an existing table.
void db_set_table_update_priv_granted(dbTable *table)
Grant update privileges for all columns.
void db_set_table_delete_priv_not_granted(dbTable *table)
Set delete privileges not granted for table.
void db_set_table_delete_priv_granted(dbTable *table)
Grant delete privileges for table.
void db_set_table_insert_priv_not_granted(dbTable *table)
Set insert privileges not granted for table.
const char * db_get_table_name(dbTable *table)
Get the name of the table.
void db_free_table(dbTable *table)
Free the table.
int db_set_table_description(dbTable *table, const char *description)
Set the description of the table.
void db_set_table_insert_priv_granted(dbTable *table)
Grant insert privileges for table.
dbColumn * db_get_table_column_by_name(dbTable *table, const char *name)
Returns column structure for given table and column name.
int db_get_table_delete_priv(dbTable *table)
Get table delete privileges.
const char * db_get_table_description(dbTable *table)
Get the description of the table.
void db_set_table_select_priv_not_granted(dbTable *table)
Set selection privileges not granted for all columns.
void db_set_table_select_priv_granted(dbTable *table)
Grant selection privileges for all columns.
int db_set_table_column(dbTable *table, int idx, dbColumn *column)
Set a specific column for given table and column number.
dbColumn * db_get_table_column(dbTable *table, int idx)
Returns column structure for given table and column number.
void db_init_table(dbTable *table)
Initialize the table to zero.
int db_append_table_column(dbTable *table, dbColumn *column)
Append a specific column to given table.
const char * db_sqltype_name(int)
Get SQL data type description.
Definition: sqltype.c:25
int db_get_column_select_priv(dbColumn *)
Get select privileges.
void db_set_column_update_priv_not_granted(dbColumn *)
Unset update privileges.
int db_copy_string(dbString *, const dbString *)
Copy dbString.
Definition: string.c:230
int db_get_column_length(dbColumn *)
Get column's length.
dbColumn * db_copy_column(dbColumn *, dbColumn *)
Copy a db column from source to destination.
void db_set_column_select_priv_not_granted(dbColumn *)
Unset select privileges.
void * db_calloc(int, int)
Allocate memory.
int db_get_column_sqltype(dbColumn *)
Returns column sqltype for column.
void db_free_string(dbString *)
Free allocated space for dbString.
Definition: string.c:150
void db_set_column_select_priv_granted(dbColumn *)
Set select privileges to be granted.
void db_set_column_update_priv_granted(dbColumn *)
Set update privileges to be granted.
int db_set_string(dbString *, const char *)
Inserts string to dbString (enlarge string)
Definition: string.c:41
void db_init_column(dbColumn *)
Initialize dbColumn.
void db_free(void *)
Free allocated memory.
void db_free_column(dbColumn *)
Frees column structure.
void db_zero(void *, int)
Zero allocated space.
void db_init_string(dbString *)
Initialize dbString.
Definition: string.c:25
const char * db_get_column_name(dbColumn *)
Returns column name for given column.
int db_append_string(dbString *, const char *)
Append string to dbString.
Definition: string.c:205
int db_get_column_update_priv(dbColumn *)
Get update privileges.
char * db_get_string(const dbString *)
Get string.
Definition: string.c:140
void * db_realloc(void *, int)
Reallocate memory.
void * db_malloc(int)
Allocate memory.
void G_warning(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
const char * name
Definition: named_colr.c:6
dbString columnName
Definition: dbmi.h:196
dbString tableName
Definition: dbmi.h:213
int priv_insert
Definition: dbmi.h:217
int priv_delete
Definition: dbmi.h:218
int numColumns
Definition: dbmi.h:215
dbString description
Definition: dbmi.h:214
dbColumn * columns
Definition: dbmi.h:216