Beispiel #1
0
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;
}
Beispiel #2
0
/* 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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
 }
Beispiel #8
0
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
	{
Beispiel #9
0
/*!
  \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;
 }
Beispiel #11
0
/* 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;
}
Beispiel #12
0
/*!
  \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;
}
Beispiel #13
0
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;
}
Beispiel #14
0
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;
}
Beispiel #15
0
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;
}
Beispiel #16
0
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;
}
Beispiel #17
0
/* 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;
}
Beispiel #18
0
/*
  \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));
}
Beispiel #19
0
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;
}
Beispiel #20
0
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;
}
Beispiel #21
0
/* 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 */
}
Beispiel #22
0
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;
}
Beispiel #23
0
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;
}
Beispiel #24
0
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;
}
Beispiel #25
0
/*
 * \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;
}
Beispiel #26
0
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;
}
Beispiel #27
0
/*!
  \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;
}
Beispiel #28
0
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;
}
Beispiel #29
0
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;
}
Beispiel #30
0
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;
}