GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
copy_tab.c
Go to the documentation of this file.
1 
15 #include <stdlib.h>
16 #include <string.h>
17 #include <grass/dbmi.h>
18 #include <grass/glocale.h>
19 #include "macros.h"
20 
21 static int cmp(const void *pa, const void *pb)
22 {
23  int *p1 = (int *)pa;
24  int *p2 = (int *)pb;
25 
26  if (*p1 < *p2)
27  return -1;
28  if (*p1 > *p2)
29  return 1;
30  return 0;
31 }
32 
58 int db__copy_table(const char *from_drvname, const char *from_dbname,
59  const char *from_tblname, const char *to_drvname,
60  const char *to_dbname, const char *to_tblname,
61  const char *where, const char *select, const char *selcol,
62  int *ivals, int nvals)
63 {
64  int col, ncols, sqltype, ctype, more, selcol_found;
65  char buf[1000];
66  int *ivalues;
67  dbHandle from_handle, to_handle;
68  dbString tblname, sql;
69  dbString value_string;
70  dbString *tblnames;
71  dbTable *table, *out_table;
72  dbCursor cursor;
73  dbColumn *column;
74  dbValue *value;
75  const char *colname;
76  dbDriver *from_driver, *to_driver;
77  int count, i;
78 
79  G_debug(3, "db_copy_table():\n from driver = %s, db = %s, table = %s\n"
80  " to driver = %s, db = %s, table = %s, where = %s, select = %s",
81  from_drvname, from_dbname, from_tblname, to_drvname, to_dbname,
82  to_tblname, where, select);
83 
84  db_init_handle(&from_handle);
85  db_init_handle(&to_handle);
86  db_init_string(&tblname);
87  db_init_string(&sql);
88  db_init_string(&value_string);
89 
90  /* Make a copy of input values and sort it */
91  if (ivals) {
92  ivalues = (int *)G_malloc(nvals * sizeof(int));
93  memcpy(ivalues, ivals, nvals * sizeof(int));
94  qsort((void *)ivalues, nvals, sizeof(int), cmp);
95  }
96 
97  /* Open input driver and database */
98  from_driver = db_start_driver(from_drvname);
99  if (from_driver == NULL) {
100  G_warning(_("Unable to start driver <%s>"), from_drvname);
101  return DB_FAILED;
102  }
103  db_set_handle(&from_handle, from_dbname, NULL);
104  if (db_open_database(from_driver, &from_handle) != DB_OK) {
105  G_warning(_("Unable to open database <%s> by driver <%s>"),
106  from_dbname, from_drvname);
108  return DB_FAILED;
109  }
110 
111  /* Open output driver and database */
112  if (strcmp(from_drvname, to_drvname) == 0
113  && strcmp(from_dbname, to_dbname) == 0) {
114  G_debug(3, "Use the same driver");
115  to_driver = from_driver;
116  }
117  else {
118  to_driver = db_start_driver(to_drvname);
119  if (to_driver == NULL) {
120  G_warning(_("Unable to start driver <%s>"), to_drvname);
122  return DB_FAILED;
123  }
124  db_set_handle(&to_handle, to_dbname, NULL);
125  if (db_open_database(to_driver, &to_handle) != DB_OK) {
126  G_warning(_("Unable to open database <%s> by driver <%s>"),
127  to_dbname, to_drvname);
129  if (from_driver != to_driver) {
131  }
132  return DB_FAILED;
133  }
134  }
135 
136  db_begin_transaction(to_driver);
137 
138  /* Because in SQLite3 an opened cursor is no more valid
139  if 'schema' is modified (create table), we have to open
140  cursor twice */
141 
142  /* test if the table exists */
143  if (db_list_tables(to_driver, &tblnames, &count, 0) != DB_OK) {
144  G_warning(_("Unable to get list tables in database <%s>"),
145  to_dbname);
147  if (from_driver != to_driver)
149 
150  return DB_FAILED;
151  }
152 
153  for (i = 0; i < count; i++) {
154  const char *tblname = db_get_string(&tblnames[i]);
155 
156  if (strcmp(to_tblname, tblname) == 0) {
157  G_warning(_("Table <%s> already exists in database <%s>"),
158  to_tblname, to_dbname);
160  if (from_driver != to_driver)
162 
163  return DB_FAILED;
164  }
165  }
166 
167  /* Create new table */
168  /* Open cursor for data structure */
169  if (select) {
170  db_set_string(&sql, select);
171 
172  /* TODO!: cannot use this because it will not work if a query
173  * ends with 'group by' for example */
174  /*
175  tmp = strdup ( select );
176  G_tolcase ( tmp );
177 
178  if ( !strstr( tmp,"where") )
179  {
180  db_append_string ( &sql, " where 0 = 1");
181  }
182  else
183  {
184  db_append_string ( &sql, " and 0 = 1");
185  }
186 
187  free (tmp);
188  */
189  }
190  else {
191  db_set_string(&sql, "select * from ");
192  db_append_string(&sql, from_tblname);
193  db_append_string(&sql, " where 0 = 1"); /* to get no data */
194  }
195 
196  G_debug(3, "db__copy_table: %s", db_get_string(&sql));
197  if (db_open_select_cursor(from_driver, &sql, &cursor, DB_SEQUENTIAL) !=
198  DB_OK) {
199  G_warning(_("Unable to open select cursor: '%s'"),
200  db_get_string(&sql));
202  if (from_driver != to_driver) {
204  }
205  return DB_FAILED;
206  }
207  G_debug(3, "Select cursor opened");
208 
209  table = db_get_cursor_table(&cursor);
210  ncols = db_get_table_number_of_columns(table);
211  G_debug(3, "ncols = %d", ncols);
212 
213  out_table = db_alloc_table(ncols);
214  db_set_table_name(out_table, to_tblname);
215 
216  selcol_found = 0;
217  for (col = 0; col < ncols; col++) {
218  dbColumn *out_column;
219 
220  column = db_get_table_column(table, col);
221  colname = db_get_column_name(column);
222  sqltype = db_get_column_sqltype(column);
223  ctype = db_sqltype_to_Ctype(sqltype);
224 
225  G_debug(3, "%s (%s)", colname, db_sqltype_name(sqltype));
226 
227  out_column = db_get_table_column(out_table, col);
228 
229  if (selcol && G_strcasecmp(colname, selcol) == 0) {
230  if (ctype != DB_C_TYPE_INT)
231  G_fatal_error(_("Column <%s> is not integer"),
232  colname);
233  selcol_found = 1;
234  }
235 
236  db_set_column_name(out_column, db_get_column_name(column));
237  db_set_column_description(out_column,
238  db_get_column_description(column));
239  db_set_column_sqltype(out_column, db_get_column_sqltype(column));
240  db_set_column_length(out_column, db_get_column_length(column));
242  db_set_column_scale(out_column, db_get_column_scale(column));
243  }
244 
245  db_close_cursor(&cursor);
246 
247  if (selcol && !selcol_found)
248  G_fatal_error(_("Column <%s> not found"), selcol);
249 
250  if (db_create_table(to_driver, out_table) != DB_OK) {
251  G_warning(_("Unable to create table <%s>"),
252  to_tblname);
254  if (from_driver != to_driver) {
256  }
257  return DB_FAILED;
258  }
259 
260  /* Open cursor with data */
261  if (select) {
262  db_set_string(&sql, select);
263  }
264  else {
265  db_set_string(&sql, "select * from ");
266  db_append_string(&sql, from_tblname);
267  if (where) {
268  db_append_string(&sql, " where ");
269  db_append_string(&sql, where);
270  }
271  }
272 
273  G_debug(3, "db__copy_table: %s", db_get_string(&sql));
274  if (db_open_select_cursor(from_driver, &sql, &cursor, DB_SEQUENTIAL) !=
275  DB_OK) {
276  G_warning(_("Unable to open select cursor: '%s'"),
277  db_get_string(&sql));
279  if (from_driver != to_driver) {
281  }
282  return DB_FAILED;
283  }
284  G_debug(3, "Select cursor opened");
285 
286  table = db_get_cursor_table(&cursor);
287  ncols = db_get_table_number_of_columns(table);
288  G_debug(3, "ncols = %d", ncols);
289 
290  /* Copy all rows */
291  while (1) {
292  int select;
293 
294  if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
295  G_warning(_("Unable to fetch data from table <%s>"),
296  from_tblname);
297  db_close_cursor(&cursor);
299  if (from_driver != to_driver) {
301  }
302  return DB_FAILED;
303  }
304  if (!more)
305  break;
306 
307  sprintf(buf, "insert into %s values ( ", to_tblname);
308  db_set_string(&sql, buf);
309  select = 1;
310  for (col = 0; col < ncols; col++) {
311  column = db_get_table_column(table, col);
312  colname = db_get_column_name(column);
313  sqltype = db_get_column_sqltype(column);
314  ctype = db_sqltype_to_Ctype(sqltype);
315  value = db_get_column_value(column);
316 
317  if (selcol && G_strcasecmp(colname, selcol) == 0) {
318  if (db_test_value_isnull(value))
319  continue;
320  if (!bsearch(&(value->i), ivalues, nvals, sizeof(int), cmp)) {
321  select = 0;
322  break;
323  }
324  }
325  if (col > 0)
326  db_append_string(&sql, ", ");
327  db_convert_value_to_string(value, sqltype, &value_string);
328  switch (ctype) {
329  case DB_C_TYPE_STRING:
330  case DB_C_TYPE_DATETIME:
331  if (db_test_value_isnull(value)) {
332  db_append_string(&sql, "null");
333  }
334  else {
335  db_double_quote_string(&value_string);
336  db_append_string(&sql, "'");
337  db_append_string(&sql, db_get_string(&value_string));
338  db_append_string(&sql, "'");
339  }
340  break;
341  case DB_C_TYPE_INT:
342  case DB_C_TYPE_DOUBLE:
343  if (db_test_value_isnull(value)) {
344  db_append_string(&sql, "null");
345  }
346  else {
347  db_append_string(&sql, db_get_string(&value_string));
348  }
349  break;
350  default:
351  G_warning(_("Unknown column type (column <%s>)"),
352  colname);
353  db_close_cursor(&cursor);
355  if (from_driver != to_driver) {
357  }
358  return DB_FAILED;
359  }
360  }
361  if (!select)
362  continue;
363  db_append_string(&sql, ")");
364  G_debug(3, "db__copy_table: %s", db_get_string(&sql));
365  if (db_execute_immediate(to_driver, &sql) != DB_OK) {
366  G_warning("Unable to insert new record: '%s'",
367  db_get_string(&sql));
368  db_close_cursor(&cursor);
370  if (from_driver != to_driver) {
372  }
373  return DB_FAILED;
374  }
375  }
376  if (selcol)
377  G_free(ivalues);
378  G_debug(3, "Table copy OK");
379 
380  db_close_cursor(&cursor);
381  db_commit_transaction(to_driver);
383  if (from_driver != to_driver) {
385  }
386 
387  return DB_OK;
388 }
389 
403 int db_copy_table(const char *from_drvname, const char *from_dbname,
404  const char *from_tblname, const char *to_drvname,
405  const char *to_dbname, const char *to_tblname)
406 {
407  return db__copy_table(from_drvname, from_dbname, from_tblname,
408  to_drvname, to_dbname, to_tblname,
409  NULL, NULL, NULL, NULL, 0);
410 }
411 
426 int db_copy_table_where(const char *from_drvname, const char *from_dbname,
427  const char *from_tblname, const char *to_drvname,
428  const char *to_dbname, const char *to_tblname,
429  const char *where)
430 {
431  return db__copy_table(from_drvname, from_dbname, from_tblname,
432  to_drvname, to_dbname, to_tblname,
433  where, NULL, NULL, NULL, 0);
434 }
435 
450 int db_copy_table_select(const char *from_drvname, const char *from_dbname,
451  const char *from_tblname, const char *to_drvname,
452  const char *to_dbname, const char *to_tblname,
453  const char *select)
454 {
455  return db__copy_table(from_drvname, from_dbname, from_tblname,
456  to_drvname, to_dbname, to_tblname,
457  NULL, select, NULL, NULL, 0);
458 }
459 
476 int db_copy_table_by_ints(const char *from_drvname, const char *from_dbname,
477  const char *from_tblname, const char *to_drvname,
478  const char *to_dbname, const char *to_tblname,
479  const char *selcol, int *ivals, int nvals)
480 {
481  return db__copy_table(from_drvname, from_dbname, from_tblname,
482  to_drvname, to_dbname, to_tblname,
483  NULL, NULL, selcol, ivals, nvals);
484 }
dbColumn * db_get_table_column(dbTable *table, int n)
returns column structure for given table and column number
void db_set_column_sqltype(dbColumn *column, int sqltype)
define column sqltype for column (the function db_sqltype_name() returns sqltype description) ...
int db_test_value_isnull(dbValue *value)
Definition: value.c:10
int G_strcasecmp(const char *x, const char *y)
String compare ignoring case (upper or lower)
Definition: strings.c:192
sprintf(buf2,"%s", G3D_CATS_ELEMENT)
const char * db_sqltype_name(int sqltype)
returns sqltype description
Definition: sqltype.c:9
int db_close_cursor(dbCursor *cursor)
Close cursor.
Definition: c_close_cur.c:27
const char * db_get_column_description(dbColumn *column)
returns column description for given column
int db_copy_table(const char *from_drvname, const char *from_dbname, const char *from_tblname, const char *to_drvname, const char *to_dbname, const char *to_tblname)
Copy a table.
Definition: copy_tab.c:403
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
int db__copy_table(const char *from_drvname, const char *from_dbname, const char *from_tblname, const char *to_drvname, const char *to_dbname, const char *to_tblname, const char *where, const char *select, const char *selcol, int *ivals, int nvals)
Copy table, used by various db_copy_table*.
Definition: copy_tab.c:58
void db_set_column_precision(dbColumn *column, int precision)
const char * db_get_column_name(dbColumn *column)
returns column name for given column
dbTable * db_alloc_table(int ncols)
int db_set_table_name(dbTable *table, const char *name)
int db_close_database_shutdown_driver(dbDriver *driver)
Close driver/database connection.
Definition: db.c:62
int db_get_column_precision(dbColumn *column)
int db_begin_transaction(dbDriver *driver)
Begin transaction.
Definition: c_execute.c:56
int count
int db_get_column_length(dbColumn *column)
int db_convert_value_to_string(dbValue *value, int sqltype, dbString *string)
Definition: valuefmt.c:47
int db_execute_immediate(dbDriver *driver, dbString *SQLstatement)
Execute SQL statements.
Definition: c_execute.c:27
int db_get_column_scale(dbColumn *column)
int db_set_column_name(dbColumn *column, const char *name)
int db_set_column_description(dbColumn *column, const char *description)
int db_append_string(dbString *x, const char *s)
Definition: string.c:193
int db_sqltype_to_Ctype(int sqltype)
Definition: sqlCtype.c:9
int db_fetch(dbCursor *cursor, int position, int *more)
Fetch data.
Definition: c_fetch.c:28
dbTable * db_get_cursor_table(dbCursor *cursor)
Definition: cursor.c:55
int db_copy_table_where(const char *from_drvname, const char *from_dbname, const char *from_tblname, const char *to_drvname, const char *to_dbname, const char *to_tblname, const char *where)
Copy a table (by where statement)
Definition: copy_tab.c:426
int db_get_column_sqltype(dbColumn *column)
returns column sqltype for column (the function db_sqltype_name() returns sqltype description) ...
int db_copy_table_by_ints(const char *from_drvname, const char *from_dbname, const char *from_tblname, const char *to_drvname, const char *to_dbname, const char *to_tblname, const char *selcol, int *ivals, int nvals)
Copy a table (by keys)
Definition: copy_tab.c:476
int db_get_table_number_of_columns(dbTable *table)
void db_set_column_length(dbColumn *column, int length)
dbValue * db_get_column_value(dbColumn *column)
returns column value for given column structure
void db_double_quote_string(dbString *src)
Definition: string.c:223
char * value
Definition: env.c:30
int db_copy_table_select(const char *from_drvname, const char *from_dbname, const char *from_tblname, const char *to_drvname, const char *to_dbname, const char *to_tblname, const char *select)
Copy a table (by select statement)
Definition: copy_tab.c:450
int db_set_handle(dbHandle *handle, const char *dbName, const char *dbSchema)
Definition: handle.c:22
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
Definition: g3drange.c:62
int db_create_table(dbDriver *driver, dbTable *table)
Create table.
Definition: c_create_tab.c:27
return NULL
Definition: dbfopen.c:1394
void db_set_column_scale(dbColumn *column, int scale)
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
char * db_get_string(dbString *x)
Definition: string.c:131
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
void db_init_handle(dbHandle *handle)
Definition: handle.c:10
int db_set_string(dbString *x, const char *s)
Definition: string.c:33
int db_open_database(dbDriver *driver, dbHandle *handle)
Open database connection.
Definition: c_opendb.c:27
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
int db_list_tables(dbDriver *driver, dbString **names, int *count, int system)
List available tables for given connection.
Definition: c_list_tabs.c:39
dbDriver * db_start_driver(const char *name)
Initialize a new dbDriver for db transaction.
Definition: start.c:43
int db_commit_transaction(dbDriver *driver)
Commit transaction.
Definition: c_execute.c:82
int db_open_select_cursor(dbDriver *driver, dbString *select, dbCursor *cursor, int mode)
Open select cursor.
Definition: c_openselect.c:29
void db_init_string(dbString *x)
Definition: string.c:11