/**************************************************************************** * * MODULE: db.execute * AUTHOR(S): Radim Blazek (original contributor) * Huidae Cho * Glynn Clements * Hamish Bowman * Markus Neteler * Stephan Holl * Martin Landa * PURPOSE: process one non-select sql statement * COPYRIGHT: (C) 2002-2011 by the GRASS Development Team * * This program is free software under the GNU General * Public License (>=v2). Read the file COPYING that * comes with GRASS for details. * *****************************************************************************/ #include #include #include #include #include #include struct { const char *driver, *database, *schema, *sql, *input; int i; } parms; /* function prototypes */ static void parse_command_line(int, char **); static int get_stmt(FILE *, dbString *); static int stmt_is_empty(dbString *); static void error_handler(void *); int main(int argc, char **argv) { dbString stmt; dbDriver *driver; dbHandle handle; int ret; FILE *fd; int error; error = 0; parse_command_line(argc, argv); /* read from file or stdin ? */ if (parms.input && strcmp(parms.input, "-") != 0) { fd = fopen(parms.input, "r"); if (fd == NULL) { G_fatal_error(_("Unable to open file <%s>: %s"), parms.input, strerror(errno)); } } else { fd = stdin; } /* open DB connection */ db_init_string(&stmt); driver = db_start_driver(parms.driver); if (driver == NULL) { G_fatal_error(_("Unable to start driver <%s>"), parms.driver); } db_init_handle(&handle); db_set_handle(&handle, parms.database, parms.schema); if (db_open_database(driver, &handle) != DB_OK) G_fatal_error(_("Unable to open database <%s>"), parms.database); G_add_error_handler(error_handler, driver); if (parms.sql) { /* parms.sql */ db_set_string(&stmt, parms.sql); ret = db_execute_immediate(driver, &stmt); } else { /* parms.input */ while (get_stmt(fd, &stmt)) { if (stmt_is_empty(&stmt)) continue; G_debug(3, "sql: %s", db_get_string(&stmt)); ret = db_execute_immediate(driver, &stmt); if (ret != DB_OK) { if (parms.i) { /* ignore SQL errors */ G_warning(_("Error while executing: '%s'"), db_get_string(&stmt)); error++; } else { G_fatal_error(_("Error while executing: '%s'"), db_get_string(&stmt)); } } } } db_close_database(driver); db_shutdown_driver(driver); exit(error ? EXIT_FAILURE : EXIT_SUCCESS); } static void parse_command_line(int argc, char **argv) { struct Option *driver, *database, *schema, *sql, *input; struct Flag *i; struct GModule *module; const char *drv, *db, *schema_name; /* Initialize the GIS calls */ G_gisinit(argv[0]); /* Set description */ module = G_define_module(); G_add_keyword(_("database")); G_add_keyword(_("attribute table")); G_add_keyword(_("SQL")); module->label = _("Executes any SQL statement."); module->description = _("For SELECT statements use 'db.select'."); sql = G_define_standard_option(G_OPT_DB_SQL); sql->label = _("SQL statement"); sql->description = _("Example: update rybniky set kapri = 'hodne' where kapri = 'malo'"); sql->guisection = _("SQL"); input = G_define_standard_option(G_OPT_F_INPUT); input->required = NO; input->label = _("Name of file containing SQL statement(s)"); input->description = _("'-' for standard input"); input->guisection = _("SQL"); driver = G_define_standard_option(G_OPT_DB_DRIVER); driver->options = db_list_drivers(); driver->guisection = _("Connection"); if ((drv = db_get_default_driver_name())) driver->answer = (char *) drv; database = G_define_standard_option(G_OPT_DB_DATABASE); database->guisection = _("Connection"); if ((db = db_get_default_database_name())) database->answer = (char *) db; schema = G_define_standard_option(G_OPT_DB_SCHEMA); schema->guisection = _("Connection"); if ((schema_name = db_get_default_schema_name())) schema->answer = (char *) schema_name; i = G_define_flag(); i->key = 'i'; i->description = _("Ignore SQL errors and continue"); i->guisection = _("Errors"); if (G_parser(argc, argv)) exit(EXIT_SUCCESS); if (!sql->answer && !input->answer) { G_fatal_error(_("You must provide <%s> or <%s> option"), sql->key, input->key); } parms.driver = driver->answer; parms.database = database->answer; parms.schema = schema->answer; parms.sql = sql->answer; parms.input = input->answer; parms.i = i->answer ? TRUE : FALSE; } int get_stmt(FILE * fd, dbString * stmt) { char buf[DB_SQL_MAX], buf2[DB_SQL_MAX]; size_t len; db_zero_string(stmt); if (G_getl2(buf, sizeof(buf), fd) == 0) return 0; strcpy(buf2, buf); G_chop(buf2); len = strlen(buf2); if (buf2[len - 1] == ';') { /* end of statement */ buf2[len - 1] = 0; /* truncate ';' */ } db_set_string(stmt, buf2); return 1; } int stmt_is_empty(dbString * stmt) { char dummy[2]; return (sscanf(db_get_string(stmt), "%1s", dummy) != 1); } void error_handler(void *p) { dbDriver *driver = (dbDriver *) p; db_close_database(driver); db_shutdown_driver(driver); }