static grpc_error *fd_become_pollable_locked(grpc_fd *fd) { grpc_error *error = GRPC_ERROR_NONE; static const char *err_desc = "fd_become_pollable"; if (append_error(&error, pollable_materialize(&fd->pollable), err_desc)) { append_error(&error, pollable_add_fd(&fd->pollable, fd), err_desc); } return error; }
/* pollset->po.mu lock must be held by the caller before calling this. The function pollset_work() may temporarily release the lock (pollset->po.mu) during the course of its execution but it will always re-acquire the lock and ensure that it is held by the time the function returns */ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_pollset_worker **worker_hdl, gpr_timespec now, gpr_timespec deadline) { grpc_pollset_worker worker; if (0 && GRPC_TRACER_ON(grpc_polling_trace)) { gpr_log(GPR_DEBUG, "PS:%p work hdl=%p worker=%p now=%" PRId64 ".%09d deadline=%" PRId64 ".%09d kwp=%d root_worker=%p", pollset, worker_hdl, &worker, now.tv_sec, now.tv_nsec, deadline.tv_sec, deadline.tv_nsec, pollset->kicked_without_poller, pollset->root_worker); } grpc_error *error = GRPC_ERROR_NONE; static const char *err_desc = "pollset_work"; if (pollset->kicked_without_poller) { pollset->kicked_without_poller = false; return GRPC_ERROR_NONE; } if (pollset->current_pollable != &pollset->pollable) { gpr_mu_lock(&pollset->current_pollable->po.mu); } if (begin_worker(pollset, &worker, worker_hdl, &now, deadline)) { gpr_tls_set(&g_current_thread_pollset, (intptr_t)pollset); gpr_tls_set(&g_current_thread_worker, (intptr_t)&worker); GPR_ASSERT(!pollset->shutdown_closure); append_error(&error, pollable_materialize(worker.pollable), err_desc); if (worker.pollable != &pollset->pollable) { gpr_mu_unlock(&worker.pollable->po.mu); } gpr_mu_unlock(&pollset->pollable.po.mu); if (pollset->event_cursor == pollset->event_count) { append_error(&error, pollset_epoll(exec_ctx, pollset, worker.pollable, now, deadline), err_desc); } append_error(&error, pollset_process_events(exec_ctx, pollset, false), err_desc); gpr_mu_lock(&pollset->pollable.po.mu); if (worker.pollable != &pollset->pollable) { gpr_mu_lock(&worker.pollable->po.mu); } gpr_tls_set(&g_current_thread_pollset, 0); gpr_tls_set(&g_current_thread_worker, 0); pollset_maybe_finish_shutdown(exec_ctx, pollset); } end_worker(exec_ctx, pollset, &worker, worker_hdl); if (worker.pollable != &pollset->pollable) { gpr_mu_unlock(&worker.pollable->po.mu); } if (grpc_exec_ctx_has_work(exec_ctx)) { gpr_mu_unlock(&pollset->pollable.po.mu); grpc_exec_ctx_flush(exec_ctx); gpr_mu_lock(&pollset->pollable.po.mu); } return error; }
int db__driver_begin_transaction(void) { G_debug(2, "mysql: START TRANSACTION"); init_error(); if (mysql_query(connection, "START TRANSACTION") != 0) { append_error("Cannot start transaction: \n"); append_error(mysql_error(connection)); report_error(); return DB_FAILED; } return DB_OK; }
int db__driver_commit_transaction(void) { G_debug(2, "mysql: COMMIT"); init_error(); if (mysql_query(connection, "COMMIT") != 0) { append_error("Cannot commit transaction: \n"); append_error(mysql_error(connection)); report_error(); return DB_FAILED; } return DB_OK; }
static void do_kick_all(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error_unused) { grpc_error *error = GRPC_ERROR_NONE; grpc_pollset *pollset = arg; gpr_mu_lock(&pollset->pollable.po.mu); if (pollset->root_worker != NULL) { grpc_pollset_worker *worker = pollset->root_worker; do { if (worker->pollable != &pollset->pollable) { gpr_mu_lock(&worker->pollable->po.mu); } if (worker->initialized_cv) { worker->kicked = true; gpr_cv_signal(&worker->cv); } else { append_error(&error, grpc_wakeup_fd_wakeup(&worker->pollable->wakeup), "pollset_shutdown"); } if (worker->pollable != &pollset->pollable) { gpr_mu_unlock(&worker->pollable->po.mu); } worker = worker->links[PWL_POLLSET].next; } while (worker != pollset->root_worker); } pollset->kick_alls_pending--; pollset_maybe_finish_shutdown(exec_ctx, pollset); gpr_mu_unlock(&pollset->pollable.po.mu); GRPC_LOG_IF_ERROR("kick_all", error); }
static DBusHandlerResult send_error (DBusConnection *connection, DBusMessage *request, gint error_type, const char *message) { DBusMessage *reply = dbus_message_new_method_return (request); DBusMessageIter iter; if (!message) { message = ""; rb_debug ("attempting to return error with no message"); } else { rb_debug ("attempting to return error: %s", message); } dbus_message_iter_init_append (reply, &iter); if (append_error (&iter, error_type, message) == FALSE) { return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } dbus_connection_send (connection, reply, NULL); dbus_message_unref (reply); return DBUS_HANDLER_RESULT_HANDLED; }
parse_result_t parse(alternation_list_t *result) { parse_result_t status = parsed_ok; bool first = true; // We expect only one alternation, but need to reserve one more for try_parse_appending result->alternations.reserve(2); while (status == parsed_ok) { // Scan a vert bar if we're not first rstring_t bar; if (! first && ! this->scan('|', &bar)) { status = parsed_done; break; } status = try_parse_appending(&result->alternations); if (status == parsed_done) { if (! first) { append_error(&this->errors, bar.start(), error_trailing_vertical_bar, "Trailing vertical bar"); status = parsed_error; } break; } first = false; } if (status == parsed_done) { /* We may get an empty alternation list if we are just the program name. In that case, ensure we have at least one. */ if (result->alternations.empty()) { result->alternations.resize(1); } /* Hackish place to do this */ collapse_corresponding_options(result); status = parsed_ok; } return status; }
void MainError::show_error_local(const char *string) { SET_TRACE // assume user won't get to closing the GUI here lock_window("MainError::show_error_local"); SET_TRACE if(get_gui()) { SET_TRACE MainErrorGUI *gui = (MainErrorGUI*)get_gui(); gui->lock_window("MainError::show_error_local"); SET_TRACE append_error(string); SET_TRACE gui->list->update(&errors, 0, 0, 1, gui->list->get_xposition(), gui->list->get_yposition(), gui->list->get_highlighted_item(), // Flat index of item cursor is over 0, // set all autoplace flags to 1 1); SET_TRACE gui->unlock_window(); unlock_window(); SET_TRACE start(); SET_TRACE } else {
/*! \brief Open database (OGR datasource) \param handle pointer to dbHandle (db name and schema) \return DB_OK on success \return DB_FAILED on failure */ int db__driver_open_database(dbHandle * handle) { const char *name; dbConnection connection; init_error(); db_get_connection(&connection); name = db_get_handle_dbname(handle); /* if name is empty use connection.databaseName */ if (strlen(name) == 0) name = connection.databaseName; G_debug(3, "db_driver_open_database() name = '%s'", name); OGRRegisterAll(); hDs = OGROpen(name, TRUE, NULL); if (hDs == NULL) { append_error(_("Unable to open OGR data source")); report_error(); return DB_FAILED; } G_debug(3, "Datasource opened"); return DB_OK; }
// Parse a general expression parse_result_t parse(expression_t *result) { if (this->is_at_end()) { return parsed_done; } parse_result_t status; // should be set in every branch rstring_t token; // Note that options must come before trying to parse it as a list, because "[options]" itself looks like a list if (this->scan("[options]", &token)) { result->production = 3; status = this->parse(&result->options_shortcut); } else if (this->scan('(', &token) || this->scan('[', &token)) { status = this->try_parse_auto(&result->alternation_list); if (status != parsed_error) { assert(token[0] == '(' || token[0] == '['); bool is_paren = (token[0] == '('); rstring_t close_token; if (this->scan(is_paren ? ')' : ']', &close_token)) { result->production = is_paren ? 1 : 2; parse(&result->opt_ellipsis); // never fails } else { // No closing bracket or paren if (is_paren) { append_error(&this->errors, token.start(), error_missing_close_paren, "Missing ')' to match opening '('"); } else { append_error(&this->errors, token.start(), error_missing_close_bracket, "Missing ']' to match opening '['"); } status = parsed_error; } } } else if (this->scan("...", &token)) { append_error(&this->errors, token.start(), error_leading_ellipsis, "Ellipsis may only follow an expression"); status = parsed_error; } else if (this->peek("|")) { // End of an alternation list status = parsed_done; } else { // Simple clause status = try_parse_auto(&result->simple_clause); if (status != parsed_error) { result->production = 0; parse(&result->opt_ellipsis); // never fails } } return status; }
/* expects pollsets locked, flag whether fd is locked or not */ static grpc_error *pollset_add_fd_locked(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_fd *fd, bool fd_locked) { static const char *err_desc = "pollset_add_fd"; grpc_error *error = GRPC_ERROR_NONE; if (pollset->current_pollable == &g_empty_pollable) { if (GRPC_TRACER_ON(grpc_polling_trace)) gpr_log(GPR_DEBUG, "PS:%p add fd %p; transition pollable from empty to fd", pollset, fd); /* empty pollable --> single fd pollable */ pollset_kick_all(exec_ctx, pollset); pollset->current_pollable = &fd->pollable; if (!fd_locked) gpr_mu_lock(&fd->pollable.po.mu); append_error(&error, fd_become_pollable_locked(fd), err_desc); if (!fd_locked) gpr_mu_unlock(&fd->pollable.po.mu); REF_BY(fd, 2, "pollset_pollable"); } else if (pollset->current_pollable == &pollset->pollable) { if (GRPC_TRACER_ON(grpc_polling_trace)) gpr_log(GPR_DEBUG, "PS:%p add fd %p; already multipolling", pollset, fd); append_error(&error, pollable_add_fd(pollset->current_pollable, fd), err_desc); } else if (pollset->current_pollable != &fd->pollable) { grpc_fd *had_fd = (grpc_fd *)pollset->current_pollable; if (GRPC_TRACER_ON(grpc_polling_trace)) gpr_log(GPR_DEBUG, "PS:%p add fd %p; transition pollable from fd %p to multipoller", pollset, fd, had_fd); pollset_kick_all(exec_ctx, pollset); pollset->current_pollable = &pollset->pollable; if (append_error(&error, pollable_materialize(&pollset->pollable), err_desc)) { pollable_add_fd(&pollset->pollable, had_fd); pollable_add_fd(&pollset->pollable, fd); } GRPC_CLOSURE_SCHED(exec_ctx, GRPC_CLOSURE_CREATE(unref_fd_no_longer_poller, had_fd, grpc_schedule_on_exec_ctx), GRPC_ERROR_NONE); } return error; }
/*! \brief Open select cursor \param sel select statement (given as dbString) \param[out] dbc pointer to dbCursor \param mode open mode \return DB_OK on success \return DB_FAILED on failure */ int db__driver_open_select_cursor(dbString * sel, dbCursor * dbc, int mode) { cursor *c; dbTable *table; init_error(); /* allocate cursor */ c = alloc_cursor(); if (c == NULL) return DB_FAILED; db_set_cursor_mode(dbc, mode); db_set_cursor_type_readonly(dbc); G_debug(3, "SQL: '%s'", db_get_string(sel)); c->hLayer = OGR_DS_ExecuteSQL(hDs, db_get_string(sel), NULL, NULL); if (c->hLayer == NULL) { append_error(_("Unable to select: \n")); append_error(db_get_string(sel)); append_error("\n"); report_error(); return DB_FAILED; } if (describe_table(c->hLayer, &table, c) == DB_FAILED) { append_error(_("Unable to describe table\n")); report_error(); OGR_DS_ReleaseResultSet(hDs, c->hLayer); return DB_FAILED; } /* record table with dbCursor */ db_set_cursor_table(dbc, table); /* set dbCursor's token for my cursor */ db_set_cursor_token(dbc, c->token); return DB_OK; }
cursor *alloc_cursor() { cursor *c; /* allocate the cursor */ c = (cursor *) db_malloc(sizeof(cursor)); if (c == NULL) { append_error("cannot alloc new cursor"); return c; } c->st = NULL; c->cols = NULL; /* tokenize it */ c->token = db_new_token(c); if (c->token < 0) { free_cursor(c); c = NULL; append_error("cannot tokenize new cursor\n"); } return c; }
int db__driver_describe_table(dbString * table_name, dbTable ** table) { int i, nlayers; OGRLayerH hLayer = NULL; OGRFeatureDefnH hFeatureDefn; /* Find data source */ nlayers = OGR_DS_GetLayerCount(hDs); for (i = 0; i < nlayers; i++) { hLayer = OGR_DS_GetLayer(hDs, i); hFeatureDefn = OGR_L_GetLayerDefn(hLayer); if (G_strcasecmp ((char *)OGR_FD_GetName(hFeatureDefn), db_get_string(table_name)) == 0) { break; } hLayer = NULL; } if (hLayer == NULL) { append_error("Table '%s' does not exist\n", db_get_string(table_name)); report_error(); return DB_FAILED; } G_debug(3, "->>"); if (describe_table(hLayer, table, NULL) == DB_FAILED) { append_error("Cannot describe table\n"); report_error(); return DB_FAILED; } return DB_OK; }
int db__driver_execute_immediate(dbString * sql) { char *str; init_error(); /* In addition to standard escape character ' (apostrophe) * MySQL supports also \ (backslash). Because this is not SQL * standard, GRASS modules cannot escape all \ in the text * because other drivers do not support this feature. * For example, if a text contains string \' GRASS modules * escape ' by another ' and the string passed to the driver is \'' * MySQL converts \' to ' but second ' remains not escaped and * result is error. * Because of this, all occurencies of \ in sql must be * escaped by \ */ str = G_str_replace(db_get_string(sql), "\\", "\\\\"); G_debug(3, "Escaped SQL: %s", str); if (mysql_query(connection, str) != 0) { append_error("Cannot execute: \n"); append_error(str); append_error("\n"); append_error(mysql_error(connection)); report_error(); if (str) G_free(str); return DB_FAILED; } if (str) G_free(str); return DB_OK; }
int db__driver_execute_immediate(dbString * sql) { char *s; int ret; s = db_get_string(sql); ret = execute(s, NULL); if (ret == DB_FAILED) { append_error("Error in db_execute_immediate()"); report_error(); return DB_FAILED; } return DB_OK; }
/* pollable must be materialized */ static grpc_error *pollable_add_fd(pollable *p, grpc_fd *fd) { grpc_error *error = GRPC_ERROR_NONE; static const char *err_desc = "pollable_add_fd"; const int epfd = p->epfd; GPR_ASSERT(epfd != -1); if (GRPC_TRACER_ON(grpc_polling_trace)) { gpr_log(GPR_DEBUG, "add fd %p to pollable %p", fd, p); } gpr_mu_lock(&fd->orphaned_mu); if (fd->orphaned) { gpr_mu_unlock(&fd->orphaned_mu); return GRPC_ERROR_NONE; } struct epoll_event ev_fd = { .events = (uint32_t)(EPOLLET | EPOLLIN | EPOLLOUT | EPOLLEXCLUSIVE), .data.ptr = fd}; if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd->fd, &ev_fd) != 0) { switch (errno) { case EEXIST: break; default: append_error(&error, GRPC_OS_ERROR(errno, "epoll_ctl"), err_desc); } } gpr_mu_unlock(&fd->orphaned_mu); return error; } /******************************************************************************* * Pollset Definitions */ GPR_TLS_DECL(g_current_thread_pollset); GPR_TLS_DECL(g_current_thread_worker); /* Global state management */ static grpc_error *pollset_global_init(void) { gpr_tls_init(&g_current_thread_pollset); gpr_tls_init(&g_current_thread_worker); pollable_init(&g_empty_pollable, PO_EMPTY_POLLABLE); return GRPC_ERROR_NONE; }
/* \brief Get number of rows (i.e. features) in open cursor \param cn pointer to dbCursor \return number of rows \return DB_FAILED on error */ int db__driver_get_num_rows(dbCursor * cn) { cursor *c; dbToken token; G_debug(3, "db_driver_get_num_rows()"); /* get cursor token */ token = db_get_cursor_token(cn); /* get the cursor by its token */ if (!(c = (cursor *) db_find_token(token))) { append_error(_("Cursor not found")); report_error(); return DB_FAILED; } return (OGR_L_GetFeatureCount(c->hLayer, 1)); }
int db__driver_describe_table(dbString * table_name, dbTable ** table) { dbString sql; MYSQL_RES *res; db_init_string(&sql); db_set_string(&sql, "select * from "); db_append_string(&sql, db_get_string(table_name)); db_append_string(&sql, " where 1 = 0"); if (mysql_query(connection, db_get_string(&sql)) != 0) { append_error(db_get_string(&sql)); append_error("\n"); append_error(mysql_error(connection)); report_error(); return DB_FAILED; } res = mysql_store_result(connection); if (res == NULL) { append_error(db_get_string(&sql)); append_error("\n"); append_error(mysql_error(connection)); report_error(); return DB_FAILED; } if (describe_table(res, table, NULL) == DB_FAILED) { append_error("Cannot describe table\n"); report_error(); mysql_free_result(res); return DB_FAILED; } mysql_free_result(res); db_set_table_name(*table, db_get_string(table_name)); return DB_OK; }
static grpc_error *pollset_process_events(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, bool drain) { static const char *err_desc = "pollset_process_events"; grpc_error *error = GRPC_ERROR_NONE; for (int i = 0; (drain || i < MAX_EPOLL_EVENTS_HANDLED_EACH_POLL_CALL) && pollset->event_cursor != pollset->event_count; i++) { int n = pollset->event_cursor++; struct epoll_event *ev = &pollset->events[n]; void *data_ptr = ev->data.ptr; if (1 & (intptr_t)data_ptr) { if (GRPC_TRACER_ON(grpc_polling_trace)) { gpr_log(GPR_DEBUG, "PS:%p got pollset_wakeup %p", pollset, data_ptr); } append_error(&error, grpc_wakeup_fd_consume_wakeup( (void *)((~(intptr_t)1) & (intptr_t)data_ptr)), err_desc); } else { grpc_fd *fd = (grpc_fd *)data_ptr; bool cancel = (ev->events & (EPOLLERR | EPOLLHUP)) != 0; bool read_ev = (ev->events & (EPOLLIN | EPOLLPRI)) != 0; bool write_ev = (ev->events & EPOLLOUT) != 0; if (GRPC_TRACER_ON(grpc_polling_trace)) { gpr_log(GPR_DEBUG, "PS:%p got fd %p: cancel=%d read=%d " "write=%d", pollset, fd, cancel, read_ev, write_ev); } if (read_ev || cancel) { fd_become_readable(exec_ctx, fd, pollset); } if (write_ev || cancel) { fd_become_writable(exec_ctx, fd); } } } return error; }
/* Evaluate node recursively. * * Returns: * NODE_NULL result/value is unknown * NODE_TRUE * NODE_FALSE * NODE_VALUE result is a value stored in 'value' * (if value is not NULL otherwise NODE_NULL is returned and value is not set) * NODE_ERROR e.g. division by 0 * * If results is NODE_VALUE, the 'value' is set, if value is type SQLP_S the string is not duplicated * and only pointer is set -> do not free value->s */ double eval_node(SQLPNODE * nptr, int tab, int row, SQLPVALUE * value) { int left, right; SQLPVALUE left_value, right_value; int ccol; COLUMN *col; VALUE *val; double left_dval, right_dval, dval; char *rightbuf; /* Note: node types were previously checked by eval_node_type */ G_debug(4, "eval_node node_type = %d", nptr->node_type); switch (nptr->node_type) { case SQLP_NODE_VALUE: if (nptr->value.type == SQLP_NULL) return NODE_NULL; value->type = nptr->value.type; value->s = nptr->value.s; value->i = nptr->value.i; value->d = nptr->value.d; return NODE_VALUE; break; case SQLP_NODE_COLUMN: ccol = find_column(tab, nptr->column_name); col = &(db.tables[tab].cols[ccol]); val = &(db.tables[tab].rows[row].values[ccol]); if (val->is_null) return NODE_NULL; switch (col->type) { case DBF_CHAR: value->s = val->c; value->type = SQLP_S; break; case DBF_INT: value->i = val->i; value->type = SQLP_I; break; case DBF_DOUBLE: value->d = val->d; value->type = SQLP_D; break; } return NODE_VALUE; break; case SQLP_NODE_EXPRESSION: /* Note: Some expressions (e.g. NOT) have only one side */ if (nptr->left) { left = eval_node(nptr->left, tab, row, &left_value); G_debug(4, " left = %d", left); if (left == NODE_ERROR) return NODE_ERROR; if (left != NODE_NULL) { if (left_value.type == SQLP_I) left_dval = left_value.i; else left_dval = left_value.d; G_debug(4, " left_dval = %f", left_dval); } } if (nptr->right) { right = eval_node(nptr->right, tab, row, &right_value); G_debug(4, " right = %d", right); if (right == NODE_ERROR) return NODE_ERROR; if (right != NODE_NULL) { if (right_value.type == SQLP_I) right_dval = right_value.i; else right_dval = right_value.d; G_debug(4, " right_dval = %f", right_dval); } } G_debug(4, " operator = %d", nptr->oper); switch (nptr->oper) { /* Arithmetical */ case SQLP_ADD: case SQLP_SUBTR: case SQLP_MLTP: case SQLP_DIV: if (left == NODE_NULL || right == NODE_NULL) return NODE_NULL; switch (nptr->oper) { case SQLP_ADD: dval = left_dval + right_dval; break; case SQLP_SUBTR: dval = left_dval - right_dval; break; case SQLP_MLTP: dval = left_dval * right_dval; break; case SQLP_DIV: if (right_dval != 0.0) { dval = left_dval / right_dval; } else { append_error("Division by zero\n"); return NODE_ERROR; } break; } if (left_value.type == SQLP_I && right_value.type == SQLP_I && (nptr->oper == SQLP_ADD || nptr->oper == SQLP_SUBTR || nptr->oper == SQLP_MLTP)) { value->type = SQLP_I; value->i = (int)dval; } else { value->type = SQLP_D; value->d = dval; } return NODE_VALUE; break; /* Comparison */ /* Operators valid for all type */ case SQLP_EQ: if (left == NODE_NULL || right == NODE_NULL) { return NODE_NULL; } else if (left_value.type == SQLP_S) { /* we checked before if right is also string */ if (left_value.s && right_value.s && strcmp(left_value.s, right_value.s) == 0) return NODE_TRUE; else return NODE_FALSE; } else { /* numbers */ if (left_dval == right_dval) return NODE_TRUE; else return NODE_FALSE; } break; case SQLP_NE: if (left == NODE_NULL || right == NODE_NULL) { return NODE_NULL; } else if (left_value.type == SQLP_S) { /* we checked before if right is also string */ if (left_value.s && right_value.s && strcmp(left_value.s, right_value.s) != 0) return NODE_TRUE; else return NODE_FALSE; } else { /* numbers */ if (left_dval != right_dval) return NODE_TRUE; else return NODE_FALSE; } /* Operators valid for numbers */ case SQLP_LT: if (left == NODE_NULL || right == NODE_NULL) { return NODE_NULL; } else { if (left_dval < right_dval) return NODE_TRUE; else return NODE_FALSE; } case SQLP_LE: if (left == NODE_NULL || right == NODE_NULL) { return NODE_NULL; } else { if (left_dval <= right_dval) return NODE_TRUE; else return NODE_FALSE; } case SQLP_GT: if (left == NODE_NULL || right == NODE_NULL) { return NODE_NULL; } else { if (left_dval > right_dval) return NODE_TRUE; else return NODE_FALSE; } case SQLP_GE: if (left == NODE_NULL || right == NODE_NULL) { return NODE_NULL; } else { if (left_dval >= right_dval) return NODE_TRUE; else return NODE_FALSE; } /* Operator valid for string */ case SQLP_MTCH: if (left == NODE_NULL || right == NODE_NULL) { return NODE_NULL; } else { /* hack to get '%substring' and 'substring%' working */ rightbuf = G_str_replace(right_value.s, "%", ""); G_chop(rightbuf); if (left_value.s && right_value.s && strstr(left_value.s, rightbuf) != NULL) { G_free(rightbuf); return NODE_TRUE; } else { G_free(rightbuf); return NODE_FALSE; } } case SQLP_ISNULL: return right == NODE_NULL ? NODE_TRUE : NODE_FALSE; case SQLP_NOTNULL: return right != NODE_NULL ? NODE_TRUE : NODE_FALSE; /* Logical */ case SQLP_AND: if (left == NODE_NULL || right == NODE_NULL) { return NODE_NULL; } else if (left == NODE_TRUE && right == NODE_TRUE) { return NODE_TRUE; } else if (left == NODE_VALUE || right == NODE_VALUE) { /* Should not happen */ append_error("Value operand for AND\n"); return NODE_ERROR; } else { return NODE_FALSE; } case SQLP_OR: if (left == NODE_NULL && right == NODE_NULL) { return NODE_NULL; } else if (left == NODE_TRUE || right == NODE_TRUE) { return NODE_TRUE; } else if (left == NODE_VALUE || right == NODE_VALUE) { /* Should not happen */ append_error("Value operand for OR\n"); return NODE_ERROR; } else { return NODE_FALSE; } case SQLP_NOT: /* sub node stored on the right side */ if (right == NODE_NULL) { return NODE_NULL; } else if (right == NODE_TRUE) { return NODE_FALSE; } else if (right == NODE_VALUE) { /* Should not happen */ append_error("Value operand for NOT\n"); return NODE_ERROR; } else { return NODE_TRUE; } default: append_error("Unknown operator %d\n", nptr->oper); return NODE_FALSE; } } return NODE_ERROR; /* Not reached */ }
int load_table_head(int t) { int i, ncol, dtype, type, width, decimals; DBFHandle dbf; char fname[20]; G_debug(2, "load_table_head(): tab = %d, %s", t, db.tables[t].file); if (db.tables[t].described == TRUE) /*already described */ return DB_OK; if (access(db.tables[t].file, R_OK) == 0) db.tables[t].read = TRUE; else db.tables[t].read = FALSE; if (access(db.tables[t].file, W_OK) == 0) db.tables[t].write = TRUE; else db.tables[t].write = FALSE; /* load */ dbf = DBFOpen(db.tables[t].file, "r"); if (dbf == NULL) { append_error("Cannot open dbf file.\n"); return DB_FAILED; } ncol = DBFGetFieldCount(dbf); G_debug(2, " ncols = %d", ncol); for (i = 0; i < ncol; i++) { dtype = DBFGetFieldInfo(dbf, i, fname, &width, &decimals); G_debug(2, " DBFFieldType %d", dtype); switch (dtype) { case FTString: type = DBF_CHAR; break; case FTInteger: type = DBF_INT; break; case FTDouble: type = DBF_DOUBLE; break; case FTInvalid: G_warning("invalid/unsupported DBFFieldType"); break; default: G_warning("unknown DBFFieldType"); break; } add_column(t, type, fname, width, decimals); } DBFClose(dbf); db.tables[t].described = TRUE; return DB_OK; }
int save_table(int t) { int i, j, ncols, nrows, ret, field, rec; char name[2000], fname[20], element[100]; DBFHandle dbf; ROW *rows; VALUE *val; int dbftype, width, decimals; G_debug(2, "save_table %d", t); /* Note: because if driver is killed during the time the table is written, the process * is not completed and DATA ARE LOST. To minimize this, data are first written * to temporary file and then this file is renamed to 'database/table.dbf'. * Hopefully both file are on the same disk/partition */ if (!(db.tables[t].alive) || !(db.tables[t].updated)) return DB_OK; /* Construct our temp name because shapelib doesn't like '.' in name */ G__temp_element(element); sprintf(fname, "%d.dbf", getpid()); G_file_name(name, element, fname, G_mapset()); G_debug(2, "Write table to tempfile: '%s'", name); dbf = DBFCreate(name); if (dbf == NULL) return DB_FAILED; ncols = db.tables[t].ncols; rows = db.tables[t].rows; nrows = db.tables[t].nrows; for (i = 0; i < ncols; i++) { switch (db.tables[t].cols[i].type) { case DBF_INT: dbftype = FTInteger; break; case DBF_CHAR: dbftype = FTString; break; case DBF_DOUBLE: dbftype = FTDouble; break; } width = db.tables[t].cols[i].width; decimals = db.tables[t].cols[i].decimals; DBFAddField(dbf, db.tables[t].cols[i].name, dbftype, width, decimals); } G_debug(2, "Write %d rows", nrows); rec = 0; for (i = 0; i < nrows; i++) { if (rows[i].alive == FALSE) continue; for (j = 0; j < ncols; j++) { field = j; val = &(rows[i].values[j]); if (val->is_null) { DBFWriteNULLAttribute(dbf, rec, field); } else { switch (db.tables[t].cols[j].type) { case DBF_INT: ret = DBFWriteIntegerAttribute(dbf, rec, field, val->i); break; case DBF_CHAR: if (val->c != NULL) ret = DBFWriteStringAttribute(dbf, rec, field, val->c); else ret = DBFWriteStringAttribute(dbf, rec, field, ""); break; case DBF_DOUBLE: ret = DBFWriteDoubleAttribute(dbf, rec, field, val->d); break; } } } rec++; } G_debug(2, "Written %d records", rec); DBFClose(dbf); /* Copy */ if (G_rename_file(name, db.tables[t].file)) { append_error("Cannot move %s\nto %s\n", name, db.tables[t].file); return DB_FAILED; }; return DB_OK; }
int load_table(int t) { int i, j, ncols, nrows, dbfcol; DBFHandle dbf; char *buf; ROW *rows; VALUE *val; G_debug(2, "load_table(): tab = %d", t); if (db.tables[t].loaded == TRUE) /*already loaded */ return DB_OK; dbf = DBFOpen(db.tables[t].file, "r"); if (dbf == NULL) { append_error("Cannot open dbf file.\n"); return DB_FAILED; } ncols = db.tables[t].ncols; nrows = DBFGetRecordCount(dbf); rows = db.tables[t].rows; rows = (ROW *) G_malloc(nrows * sizeof(ROW)); db.tables[t].arows = nrows; G_debug(2, " ncols = %d nrows = %d", ncols, nrows); for (i = 0; i < nrows; i++) { rows[i].alive = TRUE; rows[i].values = (VALUE *) G_calloc(ncols, sizeof(VALUE)); for (j = 0; j < ncols; j++) { val = &(rows[i].values[j]); dbfcol = j; val->is_null = DBFIsAttributeNULL(dbf, i, dbfcol); if (!(val->is_null)) { switch (db.tables[t].cols[j].type) { case DBF_INT: val->i = DBFReadIntegerAttribute(dbf, i, dbfcol); break; case DBF_CHAR: buf = (char *)DBFReadStringAttribute(dbf, i, dbfcol); save_string(val, buf); break; case DBF_DOUBLE: val->d = DBFReadDoubleAttribute(dbf, i, dbfcol); break; } } } } DBFClose(dbf); db.tables[t].rows = rows; db.tables[t].nrows = nrows; db.tables[t].loaded = TRUE; return DB_OK; }
/* * \brief Parse connection string in form: * 1) 'database_name' * 2) 'host=xx,port=xx,dbname=xx' * \return DB_OK Success * \return DB_FAILED Failed to parse database */ int parse_conn(char *str, CONNPAR * conn) { int i; char **tokens, delm[2]; G_debug(3, "parse_conn : %s", str); /* reset */ conn->host = NULL; conn->port = 0; conn->dbname = NULL; conn->user = NULL; conn->password = NULL; if (strchr(str, '=') == NULL) { /*db name only */ conn->dbname = G_store(str); } else { delm[0] = ','; delm[1] = '\0'; tokens = G_tokenize(str, delm); i = 0; while (tokens[i]) { G_debug(3, "token %d : %s", i, tokens[i]); if (strncmp(tokens[i], "host", 4) == 0) { conn->host = G_store(tokens[i] + 5); } else if (strncmp(tokens[i], "port", 4) == 0) { long port = atol(tokens[i] + 5); if (port <= 0) { append_error(_("Wrong port number in MySQL database " "definition: ")); append_error(tokens[i] + 5); return DB_FAILED; } conn->port = (unsigned int)port; } else if (strncmp(tokens[i], "dbname", 6) == 0) { conn->dbname = G_store(tokens[i] + 7); } else if (strncmp(tokens[i], "user", 4) == 0) { G_warning(_("'user' in database definition " "is not supported, use db.login")); } else if (strncmp(tokens[i], "password", 8) == 0) { G_warning(_("'password' in database definition " "is not supported, use db.login")); } else { append_error(_("Unknown option in database definition for ")); append_error("MySQL: "); append_error(tokens[i]); return DB_FAILED; } i++; } G_free_tokens(tokens); } return DB_OK; }
int db__driver_open_database(dbHandle * handle) { const char *name; int len; dbConnection connection; char buf[1024]; DIR *dir; struct dirent *ent; char **tokens; int no_tokens, n; G_debug(2, "DBF: db__driver_open_database() name = '%s'", db_get_handle_dbname(handle)); db.name[0] = '\0'; db.tables = NULL; db.atables = 0; db.ntables = 0; db_get_connection(&connection); name = db_get_handle_dbname(handle); /* if name is empty use connection.databaseName */ if (strlen(name) == 0) { name = connection.databaseName; } strcpy(db.name, name); /* open database dir and read table ( *.dbf files ) names * to structure */ /* parse variables in db.name if present */ if (db.name[0] == '$') { tokens = G_tokenize(db.name, "/"); no_tokens = G_number_of_tokens(tokens); db.name[0] = '\0'; /* re-init */ for (n = 0; n < no_tokens; n++) { G_debug(3, "tokens[%d] = %s", n, tokens[n]); if (tokens[n][0] == '$') { G_strchg(tokens[n], '$', ' '); G_chop(tokens[n]); strcat(db.name, G__getenv(tokens[n])); G_debug(3, " -> %s", G__getenv(tokens[n])); } else strcat(db.name, tokens[n]); strcat(db.name, "/"); } G_free_tokens(tokens); } G_debug(2, "db.name = %s", db.name); errno = 0; dir = opendir(db.name); if (dir == NULL) { if (errno == ENOENT) { int status; status = G_mkdir(db.name); if (status != 0) { /* mkdir failed */ append_error("Cannot create dbf database: %s\n", name); report_error(); return DB_FAILED; } } else { /* some other problem */ append_error("Cannot open dbf database: %s\n", name); report_error(); return DB_FAILED; } } while ((ent = readdir(dir))) { len = strlen(ent->d_name) - 4; if ((len > 0) && (G_strcasecmp(ent->d_name + len, ".dbf") == 0)) { strcpy(buf, ent->d_name); buf[len] = '\0'; add_table(buf, ent->d_name); } } closedir(dir); return DB_OK; }
/*! \brief Fetch record \param cn pointer to dbCursor \param position position indicator (DB_NEXT, DB_FIRST, DB_LAST, etc) \param[out] more 0 for no record fetched otherwise 1 \return DB_OK on success \return DB_FAILED on error */ int db__driver_fetch(dbCursor * cn, int position, int *more) { int i, col; int ogrType, sqlType; dbToken token; dbTable *table; dbColumn *column; dbValue *value; cursor *c; G_debug(3, "db_driver_fetch()"); /* get cursor token */ token = db_get_cursor_token(cn); /* get the cursor by its token */ if (!(c = (cursor *) db_find_token(token))) { append_error(_("Cursor not found")); report_error(); return DB_FAILED; } /* fetch on position */ switch (position) { case DB_NEXT: G_debug(4, "DB_NEXT:"); if (c->hFeature) OGR_F_Destroy(c->hFeature); c->hFeature = OGR_L_GetNextFeature(c->hLayer); break; case DB_CURRENT: break; case DB_PREVIOUS: append_error(_("DB_PREVIOUS not supported")); report_error(); return DB_FAILED; break; case DB_FIRST: OGR_L_ResetReading(c->hLayer); if (c->hFeature) OGR_F_Destroy(c->hFeature); c->hFeature = OGR_L_GetNextFeature(c->hLayer); break; case DB_LAST: append_error(_("DB_LAST not supported")); report_error(); return DB_FAILED; break; }; if (c->hFeature == NULL) { *more = 0; return DB_OK; } *more = 1; /* get the data out of the descriptor into the table */ table = db_get_cursor_table(cn); /* check fid column */ if (strlen(OGR_L_GetFIDColumn(c->hLayer)) > 0) { column = db_get_table_column(table, 0); ogrType = db_get_column_host_type(column); sqlType = db_get_column_sqltype(column); value = db_get_column_value(column); value->i = OGR_F_GetFID(c->hFeature); G_debug(3, "fidcol '%s': ogrType %d, sqlType %d: val = %d", db_get_column_name(column), ogrType, sqlType, value->i); col = 0; } else { col = -1; } /* loop attributes */ for (i = 0; i < c->ncols; i++) { if (!(c->cols[i])) { continue; } /* unknown type */ col++; column = db_get_table_column(table, col); ogrType = db_get_column_host_type(column); sqlType = db_get_column_sqltype(column); value = db_get_column_value(column); db_zero_string(&value->s); /* Is null? */ if (OGR_F_IsFieldSet(c->hFeature, i)) { value->isNull = 0; } else { value->isNull = 1; continue; } G_debug(3, "col %d, ogrType %d, sqlType %d: val = '%s'", col, ogrType, sqlType, OGR_F_GetFieldAsString(c->hFeature, i)); switch (ogrType) { case OFTInteger: value->i = OGR_F_GetFieldAsInteger(c->hFeature, i); break; case OFTReal: value->d = OGR_F_GetFieldAsDouble(c->hFeature, i); break; case OFTString: case OFTDate: case OFTTime: case OFTDateTime: db_set_string(&(value->s), (char *)OGR_F_GetFieldAsString(c->hFeature, i)); break; default: G_warning(_("Unknown type")); break; } } G_debug(4, "Row fetched"); return DB_OK; }
int db__driver_create_table(dbTable * table) { int col, ncols; dbColumn *column; const char *colname; int sqltype; char buf[500]; PGresult *res; dbString sql; dbConnection connection; G_debug(3, "db__driver_create_table()"); init_error(); db_init_string(&sql); /* db_table_to_sql ( table, &sql ); */ db_set_string(&sql, "create table "); db_append_string(&sql, db_get_table_name(table)); db_append_string(&sql, " ( "); ncols = db_get_table_number_of_columns(table); for (col = 0; col < ncols; col++) { column = db_get_table_column(table, col); colname = db_get_column_name(column); sqltype = db_get_column_sqltype(column); G_debug(3, "%s (%s)", colname, db_sqltype_name(sqltype)); if (col > 0) db_append_string(&sql, ", "); db_append_string(&sql, colname); db_append_string(&sql, " "); switch (sqltype) { case DB_SQL_TYPE_CHARACTER: sprintf(buf, "varchar(%d)", db_get_column_length(column)); db_append_string(&sql, buf); break; case DB_SQL_TYPE_TEXT: db_append_string(&sql, "text"); break; case DB_SQL_TYPE_SMALLINT: db_append_string(&sql, "smallint"); break; case DB_SQL_TYPE_INTEGER: db_append_string(&sql, "integer"); break; case DB_SQL_TYPE_REAL: db_append_string(&sql, "real"); break; /* TODO: better numeric types */ case DB_SQL_TYPE_DOUBLE_PRECISION: case DB_SQL_TYPE_DECIMAL: case DB_SQL_TYPE_NUMERIC: case DB_SQL_TYPE_INTERVAL: db_append_string(&sql, "double precision"); break; case DB_SQL_TYPE_DATE: db_append_string(&sql, "date"); break; case DB_SQL_TYPE_TIME: db_append_string(&sql, "time"); break; case DB_SQL_TYPE_TIMESTAMP: db_append_string(&sql, "timestamp"); break; default: G_warning("Unknown column type (%s)", colname); return DB_FAILED; } } db_append_string(&sql, " )"); G_debug(3, " SQL: %s", db_get_string(&sql)); res = PQexec(pg_conn, db_get_string(&sql)); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { append_error("Cannot create table:\n"); append_error(db_get_string(&sql)); append_error("\n"); append_error(PQerrorMessage(pg_conn)); report_error(); PQclear(res); db_free_string(&sql); return DB_FAILED; } PQclear(res); /* Grant privileges */ db_get_connection(&connection); db_set_string(&sql, "grant select on "); db_append_string(&sql, db_get_table_name(table)); db_append_string(&sql, " to public"); if (connection.group) { db_append_string(&sql, ", group "); db_append_string(&sql, connection.group); } G_debug(3, " SQL: %s", db_get_string(&sql)); res = PQexec(pg_conn, db_get_string(&sql)); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { append_error("Cannot grant select on table:\n"); append_error(db_get_string(&sql)); append_error("\n"); append_error(PQerrorMessage(pg_conn)); report_error(); PQclear(res); db_free_string(&sql); return DB_FAILED; } PQclear(res); db_free_string(&sql); return DB_OK; }
int db__driver_open_select_cursor(dbString * sel, dbCursor * dbc, int mode) { PGresult *res; cursor *c; dbTable *table; char *str; init_error(); /* Set datetime style */ res = PQexec(pg_conn, "SET DATESTYLE TO ISO"); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { append_error("Cannot set DATESTYLE\n"); report_error(); PQclear(res); return DB_FAILED; } PQclear(res); /* allocate cursor */ c = alloc_cursor(); if (c == NULL) return DB_FAILED; db_set_cursor_mode(dbc, mode); db_set_cursor_type_readonly(dbc); /* \ must be escaped, see explanation in db_driver_execute_immediate() */ str = G_str_replace(db_get_string(sel), "\\", "\\\\"); G_debug(3, "Escaped SQL: %s", str); c->res = PQexec(pg_conn, str); if (!c->res || PQresultStatus(c->res) != PGRES_TUPLES_OK) { append_error("Cannot select: \n"); append_error(db_get_string(sel)); append_error("\n"); append_error(PQerrorMessage(pg_conn)); report_error(); PQclear(c->res); if (str) G_free(str); return DB_FAILED; } if (str) G_free(str); if (describe_table(c->res, &table, c) == DB_FAILED) { append_error("Cannot describe table\n"); report_error(); PQclear(res); return DB_FAILED; } c->nrows = PQntuples(c->res); c->row = -1; /* record table with dbCursor */ db_set_cursor_table(dbc, table); /* set dbCursor's token for my cursor */ db_set_cursor_token(dbc, c->token); return DB_OK; }
int db__driver_create_table(dbTable * table) { int col, ncols; dbColumn *column; const char *colname; int sqltype; char buf[500]; dbString sql; /* dbConnection conn_par; */ G_debug(3, "db__driver_create_table()"); init_error(); db_init_string(&sql); db_set_string(&sql, "CREATE TABLE "); db_append_string(&sql, db_get_table_name(table)); db_append_string(&sql, " ( "); ncols = db_get_table_number_of_columns(table); for (col = 0; col < ncols; col++) { column = db_get_table_column(table, col); colname = db_get_column_name(column); sqltype = db_get_column_sqltype(column); G_debug(3, "%s (%s)", colname, db_sqltype_name(sqltype)); if (col > 0) db_append_string(&sql, ", "); db_append_string(&sql, colname); db_append_string(&sql, " "); switch (sqltype) { case DB_SQL_TYPE_SMALLINT: db_append_string(&sql, "SMALLINT"); break; case DB_SQL_TYPE_INTEGER: db_append_string(&sql, "INT"); break; case DB_SQL_TYPE_REAL: db_append_string(&sql, "FLOAT"); break; /* TODO: better numeric types */ case DB_SQL_TYPE_DOUBLE_PRECISION: case DB_SQL_TYPE_DECIMAL: case DB_SQL_TYPE_NUMERIC: case DB_SQL_TYPE_INTERVAL: db_append_string(&sql, "DOUBLE"); break; /* GRASS does not distinguish TIMESTAMP and DATETIME */ /* case DB_SQL_TYPE_DATETIME|DB_DATETIME_MASK: db_append_string ( &sql, "DATETIME"); break; */ case DB_SQL_TYPE_TIMESTAMP: /* db_append_string ( &sql, "TIMESTAMP"); */ db_append_string(&sql, "DATETIME"); break; case DB_SQL_TYPE_DATE: db_append_string(&sql, "DATE"); break; case DB_SQL_TYPE_TIME: db_append_string(&sql, "TIME"); break; case DB_SQL_TYPE_CHARACTER: sprintf(buf, "VARCHAR(%d)", db_get_column_length(column)); db_append_string(&sql, buf); break; case DB_SQL_TYPE_TEXT: db_append_string(&sql, "TEXT"); break; default: G_warning("Unknown column type (%s)", colname); return DB_FAILED; } } db_append_string(&sql, " )"); G_debug(3, " SQL: %s", db_get_string(&sql)); if (mysql_query(connection, db_get_string(&sql)) != 0) { append_error("Cannot create table:\n"); append_error(db_get_string(&sql)); append_error("\n"); append_error(mysql_error(connection)); report_error(); db_free_string(&sql); return DB_FAILED; } /* Grant privileges */ /* * 1) MySQL does not support user groups but it is possible * to specify list of users. * 2) Only root can grant privileges. */ /* db_get_connection(&conn_par); if ( conn_par.group ) { db_set_string ( &sql, "GRANT SELECT ON on " ); db_append_string ( &sql, db_get_table_name ( table ) ); db_append_string ( &sql, " TO " ); db_append_string ( &sql, conn_par.group ); G_debug (3, " SQL: %s", db_get_string(&sql) ); if ( mysql_query ( connection, db_get_string(&sql) ) != 0 ) { G_warning ( "Cannot grant select on table: \n%s\n%s", db_get_string(&sql), mysql_error(connection) ); } } */ db_free_string(&sql); return DB_OK; }