Пример #1
0
void
test_mongo_sync_cmd_kill_cursors_net (void)
{
  mongo_packet *p;
  mongo_sync_connection *conn;
  bson *b;
  gint i;
  mongo_reply_packet_header rh;
  gint64 cid;

  begin_network_tests (3);

  conn = mongo_sync_connect (config.primary_host, config.primary_port, TRUE);
  mongo_sync_conn_set_auto_reconnect (conn, TRUE);

  b = bson_new ();
  for (i = 0; i < 40; i++)
    {
      bson_reset (b);
      bson_append_string (b, "test-name", __FILE__, -1);
      bson_append_int32 (b, "seq", i);
      bson_finish (b);

      mongo_sync_cmd_insert (conn, config.ns, b, NULL);
    }
  bson_free (b);

  b = bson_new ();
  bson_append_string (b, "test-name", __FILE__, -1);
  bson_finish (b);

  p = mongo_sync_cmd_query (conn, config.ns,
			    MONGO_WIRE_FLAG_QUERY_NO_CURSOR_TIMEOUT,
			    0, 2, b, NULL);
  mongo_wire_reply_packet_get_header (p, &rh);
  cid = rh.cursor_id;
  mongo_wire_packet_free (p);

  ok (mongo_sync_cmd_kill_cursors (conn, 1, cid) == TRUE,
      "mongo_sync_kill_cursors() works");

  p = mongo_sync_cmd_query (conn, config.ns,
			    MONGO_WIRE_FLAG_QUERY_NO_CURSOR_TIMEOUT,
			    0, 2, b, NULL);
  bson_free (b);
  mongo_wire_reply_packet_get_header (p, &rh);
  cid = rh.cursor_id;
  mongo_wire_packet_free (p);
  shutdown (conn->super.fd, SHUT_RDWR);
  sleep (3);

  ok (mongo_sync_cmd_kill_cursors (conn, 1, cid) == TRUE,
      "mongo_sync_cmd_kill_cursors() automatically reconnects");

  mongo_sync_disconnect (conn);

  test_mongo_sync_cmd_kill_cursors_net_secondary ();

  end_network_tests ();
}
Пример #2
0
void
test_func_mongo_sync_auto_reconnect (void)
{
  mongo_sync_connection *conn;
  bson *b;
  mongo_packet *p;

  b = bson_new ();
  bson_append_int32 (b, "f_sync_auto_reconnect", 1);
  bson_finish (b);

  conn = mongo_sync_connect (config.primary_host, config.primary_port,
			     TRUE);
  ok (mongo_sync_cmd_insert (conn, config.ns, b, NULL) == TRUE);

  shutdown (conn->super.fd, SHUT_RDWR);
  sleep (1);

  ok (mongo_sync_cmd_insert (conn, config.ns, b, NULL) == FALSE,
      "Inserting fails with auto-reconnect turned off, and a broken "
      "connection");

  mongo_sync_conn_set_auto_reconnect (conn, TRUE);

  ok (mongo_sync_cmd_insert (conn, config.ns, b, NULL) == TRUE,
      "Inserting works with auto-reconnect turned on, and a broken "
      "connection");

  mongo_sync_conn_set_auto_reconnect (conn, FALSE);

  shutdown (conn->super.fd, SHUT_RDWR);
  sleep (1);

  ok (mongo_sync_cmd_insert (conn, config.ns, b, NULL) == FALSE,
      "Turning off auto-reconnect works");

  shutdown (conn->super.fd, SHUT_RDWR);
  sleep (1);

  p = mongo_sync_cmd_query (conn, config.ns, 0, 0, 1, b, NULL);
  ok (p == NULL,
      "Query fails with auto-reconnect turned off");

  mongo_sync_conn_set_auto_reconnect (conn, TRUE);
  p = mongo_sync_cmd_query (conn, config.ns, 0, 0, 1, b, NULL);
  ok (p != NULL,
      "Query does reconnect with auto-reconnect turned on");
  mongo_wire_packet_free (p);

  mongo_sync_disconnect (conn);
}
Пример #3
0
void
test_mongo_sync_cmd_kill_cursors_net_secondary (void)
{
  mongo_packet *p;
  mongo_sync_connection *conn;
  bson *b;

  mongo_reply_packet_header rh;
  gint64 cid;

  skip (!config.secondary_host, 1,
	"Secondary server not configured");

  conn = mongo_sync_connect (config.secondary_host, config.secondary_port,
			     TRUE);
  b = bson_new ();
  bson_append_string (b, "test-name", __FILE__, -1);
  bson_finish (b);

  p = mongo_sync_cmd_query (conn, config.ns,
			    MONGO_WIRE_FLAG_QUERY_NO_CURSOR_TIMEOUT,
			    0, 2, b, NULL);
  bson_free (b);
  mongo_wire_reply_packet_get_header (p, &rh);
  cid = rh.cursor_id;
  mongo_wire_packet_free (p);

  ok (mongo_sync_cmd_kill_cursors (conn, 1, cid) == TRUE,
      "mongo_sync_cmd_kill_cursors() works on secondary too");

  mongo_sync_disconnect (conn);

  endskip;
}
Пример #4
0
void
tut_sync_query_simple (void)
{
  mongo_sync_connection *conn;
  mongo_packet *p;
  mongo_sync_cursor *cursor;
  bson *query;
  gint i = 0;

  conn = mongo_sync_connect ("localhost", 27017, FALSE);
  if (!conn)
    {
      perror ("mongo_sync_connect()");
      exit (1);
    }

  query = bson_new ();
  bson_finish (query);

  p = mongo_sync_cmd_query (conn, "tutorial.docs", 0,
			    0, 10, query, NULL);
  if (!p)
    {
      perror ("mongo_sync_cmd_query()");
      exit (1);
    }
  bson_free (query);

  cursor = mongo_sync_cursor_new (conn, "tutorial.docs", p);
  if (!cursor)
    {
      perror ("mongo_sync_cursor_new()");
      exit (1);
    }

  while (mongo_sync_cursor_next (cursor))
    {
      bson *result = mongo_sync_cursor_get_data (cursor);
      bson_cursor *c;

      if (!result)
	{
	  perror ("mongo_sync_cursor_get_data()");
	  exit (1);
	}

      printf ("Keys in document #%d:\n", i);
      c = bson_cursor_new (result);
      while (bson_cursor_next (c))
	printf ("\t%s\n", bson_cursor_key (c));

      i++;
      bson_cursor_free (c);
      bson_free (result);
    }

  mongo_sync_cursor_free (cursor);
  mongo_sync_disconnect (conn);
}
	static void
do_query (mongo_sync_connection *conn)
{
	mongo_sync_cursor *c;
	bson *query;
	gchar *error = NULL;

	query = bson_build
		(BSON_TYPE_TIMESTAMP, "processed", 1294860709000,
		 BSON_TYPE_NONE);
	bson_finish (query);

	c = mongo_sync_cursor_new (conn, "blahblah.plurals",
			mongo_sync_cmd_query (conn, "blahblah.plurals", 0,
				0, 10, query, NULL));
	if (!c)
	{
		fprintf (stderr, "Error creating the query cursor: %s\n",
				strerror (errno));
		exit (1);
	}
	bson_free (query);

	while (mongo_sync_cursor_next (c))
	{
		bson *b = mongo_sync_cursor_get_data (c);
		bson_cursor *bc;
		gint32 w_t;
		gint64 w_i;

		if (!b)
		{
			int e = errno;

			mongo_sync_cmd_get_last_error (conn, "blahblah.plurals", &error);
			fprintf (stderr, "Error retrieving cursor data: %s\n",
					(error) ? error : strerror (e));
			exit (1);
		}

		bc = bson_find (b, "word_type");
		bson_cursor_get_int32 (bc, &w_t);
		printf ("\rWord type: %d\n", w_t);

		bc = bson_find (b, "word_id");
		bson_cursor_get_int64 (bc, &w_i);
		printf ("\rWord id: %d\n", (int)w_i);

		bson_cursor_free (bc);
		bson_free (b);
	}
	printf ("\n");

	mongo_sync_cursor_free (c);
}
Пример #6
0
static void
do_query (mongo_sync_connection *conn)
{
  mongo_sync_cursor *c;
  bson *query;
  gchar *error = NULL;

  query = bson_build
    (BSON_TYPE_STRING, "tutorial-program", "tut_hl_client.c", -1,
     BSON_TYPE_NONE);
  bson_finish (query);

  c = mongo_sync_cursor_new (conn, "lmc.tutorial",
			     mongo_sync_cmd_query (conn, "lmc.tutorial", 0,
						   0, 10, query, NULL));
  if (!c)
    {
      fprintf (stderr, "Error creating the query cursor: %s\n",
	       strerror (errno));
      exit (1);
    }
  bson_free (query);

  while (mongo_sync_cursor_next (c))
    {
      bson *b = mongo_sync_cursor_get_data (c);
      bson_cursor *bc;
      gint32 cnt;

      if (!b)
	{
	  int e = errno;

	  mongo_sync_cmd_get_last_error (conn, "lmc", &error);
	  fprintf (stderr, "Error retrieving cursor data: %s\n",
		   (error) ? error : strerror (e));
	  exit (1);
	}

      bc = bson_find (b, "counter");
      bson_cursor_get_int32 (bc, &cnt);
      printf ("\rCounter: %d", cnt);

      bson_cursor_free (bc);
      bson_free (b);
    }
  printf ("\n");

  mongo_sync_cursor_free (c);
}
Пример #7
0
struct output* launch_query(struct queryopt *opt, struct select_doc *s_doc,
				struct query_doc *qu_doc,
				struct db_connect *db_conn)
{
	struct output *out;
	out = malloc(sizeof(struct output));
	out->p = mongo_sync_cmd_query (db_conn->conn, "syslog.log", 0,
			    opt->e_skip, opt->e_ret, qu_doc->query, s_doc->select); 
	if (!out->p)
	{
	 	perror ("mongo_sync_cmd_query()");
     	  	printf("no records found\n");
	    	exit (1);
	}
	return out;
} 
Пример #8
0
gpointer
ssl_query_thread (gpointer _c)
{
  mongo_ssl_ctx *c = (mongo_ssl_ctx*) _c;
  guint tries;
  bson *test_doc = NULL;
  gchar *test_string;
  GThread *writer = g_thread_new ("insert", ssl_insert_thread, c);
  GThread *deleter;
  mongo_sync_connection *conn = mongo_sync_ssl_connect (config.primary_host, config.primary_port, TRUE, c);
  gboolean success = FALSE;
  g_thread_join (writer);
  sleep (1); 
  
  for(tries = 1; tries <= THREAD_POOL_SIZE; ++tries) 
    {
      test_doc = bson_new ();
      test_string = g_strdup_printf ("%s:%d", "ssl_insert_thread", tries);
      bson_append_string (test_doc, test_string, "ok", -1);
      bson_finish (test_doc);
      if (mongo_sync_cmd_query (conn, config.ns, 0, 0, 1, test_doc, NULL) != NULL) 
        {
          success = TRUE;
          break;
        }
      bson_free (test_doc);
      g_free (test_string);
      sleep (1);
    }

  ok (success, "mongo_sync_cmd_query () works with writer threads over SSL");
 
  deleter = g_thread_new ("delete", ssl_delete_thread, conn); 
 
  g_thread_join (deleter);
  g_thread_unref (deleter);
  mongo_sync_disconnect (conn);
  g_thread_unref (writer);

  return NULL;
}
Пример #9
0
void
test_func_mongo_sync_ssl_insert_query (void)
{
  mongo_sync_connection *conn = NULL;
  bson *test_doc = bson_new ();
  mongo_packet *p = NULL;
  //gchar *test_string =  g_strdup_printf ("%s:%s:%d", __FILE__, __func__, __LINE__);
  gchar *test_string = g_strdup ("test_func_mongo_sync_ssl_insert_query");
  bson_append_string (test_doc, test_string, "ok", -1);
  bson_finish (test_doc);
  
  conn = mongo_sync_ssl_connect (config.primary_host, config.primary_port, TRUE, config.ssl_settings);
  //conn = mongo_sync_connect (config.primary_host, config.primary_port, TRUE);
  mongo_sync_conn_set_auto_reconnect (conn, TRUE);
  
  ok (conn != NULL, "connection works without whitelists");

  ok (mongo_sync_cmd_insert (conn, config.ns, test_doc, NULL) == TRUE, "inserting a document works via SSL");

  p = mongo_sync_cmd_query (conn, config.ns, 0, 0, 1, test_doc, NULL);

  ok (p != NULL, 
       "querying the recently inserted document works via SSL");

  mongo_wire_packet_free (p);

  shutdown (conn->super.fd, SHUT_RDWR);
  sleep (3);

  ok (mongo_sync_cmd_delete (conn, config.ns, 0, test_doc) == TRUE, "automatic reconnection over SSL should work (at this time: attempting delete command)");

  /* ok (mongo_sync_cmd_query (conn, config.ns, 0, 0, 1, test_doc, NULL) == NULL, "test document should not exist after delete");
    */
    
  mongo_sync_disconnect (conn);
  bson_free (test_doc);
  g_free (test_string);
}
void
test_func_mongo_sync_auto_reconnect_cache (void)
{
  mongo_sync_conn_recovery_cache *cache;
  mongo_sync_connection *conn;
  bson *b;
  mongo_packet *p;
  GList *hosts;
  gchar *primary_addr;
  const gchar *error_msg;

  primary_addr = g_strdup_printf ("%s:%d", config.primary_host, config.primary_port);

  b = bson_new ();
  bson_append_int32 (b, "f_sync_auto_reconnect", 1);
  bson_finish (b);

  cache = mongo_sync_conn_recovery_cache_new ();

  mongo_sync_conn_recovery_cache_seed_add (cache,
                                           config.primary_host,
                                           config.primary_port);

  conn = mongo_sync_connect_recovery_cache (cache,
                                            TRUE);

  ok (mongo_sync_cmd_insert (conn, config.ns, b, NULL) == TRUE);

  shutdown (conn->super.fd, SHUT_RDWR);
  sleep (1);

  ok (mongo_sync_cmd_insert (conn, config.ns, b, NULL) == FALSE,
      "Inserting fails with auto-reconnect turned off, and a broken "
      "connection");

  error_msg = mongo_sync_conn_get_last_error (conn);

  ok (error_msg != NULL, "We have an error msg when insert fails.");

  mongo_sync_conn_set_auto_reconnect (conn, TRUE);

  ok (mongo_sync_cmd_insert (conn, config.ns, b, NULL) == TRUE,
      "Inserting works with auto-reconnect turned on, and a broken "
      "connection");

  error_msg = mongo_sync_conn_get_last_error (conn);

  ok (error_msg == NULL,
      "After a succesful insert we shouldn't have an error msg.");

  mongo_sync_conn_set_auto_reconnect (conn, FALSE);

  shutdown (conn->super.fd, SHUT_RDWR);
  sleep (1);

  ok (mongo_sync_cmd_insert (conn, config.ns, b, NULL) == FALSE,
      "Turning off auto-reconnect works");

  skip (!config.secondary_host, 7,
        "Secondary host not set up");

  shutdown (conn->super.fd, SHUT_RDWR);
  sleep (1);

  p = mongo_sync_cmd_query (conn, config.ns, 0, 0, 1, b, NULL);
  ok (p == NULL,
      "Query fails with auto-reconnect turned off");

  error_msg = mongo_sync_conn_get_last_error(conn);
  ok (error_msg != NULL, "We have an error msg after a failure query.");

  mongo_sync_conn_set_auto_reconnect (conn, TRUE);
  p = mongo_sync_cmd_query (conn, config.ns, 0, 0, 1, b, NULL);
  ok (p != NULL,
      "Query does reconnect with auto-reconnect turned on");

  ok (mongo_sync_conn_get_last_error(conn) == NULL,
      "We shouldn't have any error messages after a successful operation.");

  mongo_wire_packet_free (p);

  hosts = conn->rs.hosts;

  ok (cache->rs.hosts == NULL,
      "cache is discarded due to connect replace during auto-reconnect");

  ok ((conn->rs.hosts != NULL) &&
      (g_list_length (conn->rs.hosts) > 0),
      "hosts is filled in mongo_sync_connection");

  mongo_sync_disconnect (conn);

  ok ((cache->rs.hosts != NULL) &&
      (cache->rs.hosts == hosts) &&
      (g_list_length (cache->rs.hosts) > 0),
      "cache is filled by disconnect()");

  mongo_sync_conn_recovery_cache_free (cache);

  endskip;

  g_free (primary_addr);
}
Пример #11
0
void
mongo_dump (config_t *config)
{
  mongo_sync_connection *conn;
  mongo_sync_cursor *cursor;
  bson *b;
  int fd;

  glong cnt, pos = 0;

  gchar *error = NULL;
  int e;

  if (config->port == MONGO_CONN_LOCAL)
    {
      VLOG ("Connecting to %s/%s.%s...\n", config->addr, config->db,
            config->coll);
    }
  else
    {
      VLOG ("Connecting to %s:%d/%s.%s...\n", config->addr, config->port,
            config->db, config->coll);
    }
  conn = mongo_sync_connect (config->addr, config->port, config->slaveok);

  if (!conn)
    {
      e = errno;

      mongo_sync_cmd_get_last_error (conn, config->db, &error);
      fprintf (stderr, "Error connecting to %s:%d: %s\n", config->addr,
               config->port, (error) ? error : strerror (e));
      g_free (error);
      exit (1);
    }

  if (config->master_sync)
    {
      VLOG ("Syncing to master...\n");
      conn = mongo_sync_reconnect (conn, TRUE);
      if (!conn)
        {
          e = errno;

          mongo_sync_cmd_get_last_error (conn, config->db, &error);
          fprintf (stderr, "Error reconnecting to the master of %s:%d: %s\n",
                   config->addr, config->port, (error) ? error : strerror (e));
          exit (1);
        }
    }

  VLOG ("Counting documents...\n");
  cnt = mongo_sync_cmd_count (conn, config->db, config->coll, NULL);
  if (cnt < 0)
    {
      e = errno;

      mongo_sync_cmd_get_last_error (conn, config->db, &error);
      fprintf (stderr, "Error counting documents in %s.%s: %s\n",
               config->db, config->coll, (error) ? error : strerror (e));
      mongo_sync_disconnect (conn);
      exit (1);
    }

  VLOG ("Opening output file '%s'...\n", config->output);
  if (strcmp (config->output, "-") == 0)
    fd = 1;
  else
    {
      fd = open (config->output, O_RDWR | O_CREAT | O_TRUNC, 0600);
      if (fd == -1)
        {
          fprintf (stderr, "Error opening output file '%s': %s\n",
                   config->output, strerror (errno));
          mongo_sync_disconnect (conn);
          exit (1);
        }
    }

  VLOG ("Launching initial query...\n");
  b = bson_new ();
  bson_finish (b);
  cursor = mongo_sync_cursor_new (conn, config->ns,
                                  mongo_sync_cmd_query (conn, config->ns,
                                                        MONGO_WIRE_FLAG_QUERY_NO_CURSOR_TIMEOUT,
                                                        0, 10, b, NULL));
  bson_free (b);

  while ((pos < cnt) && mongo_sync_cursor_next (cursor))
    {
      bson *b = mongo_sync_cursor_get_data (cursor);
      pos++;

      if (!b)
        {
          e = errno;

          mongo_sync_cmd_get_last_error (conn, config->db, &error);
          fprintf (stderr, "Error advancing the cursor: %s\n",
                   (error) ? error : strerror (e));
          mongo_sync_disconnect (conn);
          exit (1);
        }

      if (pos % 10 == 0)
        VLOG ("\rDumping... %03.2f%%", (pos * 1.0) / (cnt * 1.0) * 100);

      if (write (fd, bson_data (b), bson_size (b)) != bson_size (b))
        {
          perror ("write()");
          exit (1);
        }
      bson_free (b);
    }
  VLOG ("\rDumping... %03.2f%%\n", (double)((pos / cnt) * 100));

  mongo_sync_cursor_free (cursor);

  close (fd);
  mongo_sync_disconnect (conn);
}
Пример #12
0
void
tut_sync_query_complex (void)
{
  mongo_sync_connection *conn;
  mongo_packet *p;
  mongo_sync_cursor *cursor;
  bson *query, *select;
  gint i = 0;

  conn = mongo_sync_connect ("localhost", 27017, FALSE);
  if (!conn)
    {
      perror ("mongo_sync_connect()");
      exit (1);
    }

  query = bson_build_full (BSON_TYPE_DOCUMENT, "$query", TRUE,
			   bson_build (BSON_TYPE_BOOLEAN, "yes?", FALSE,
				       BSON_TYPE_NONE),
			   BSON_TYPE_DOCUMENT, "$orderby", TRUE,
			   bson_build (BSON_TYPE_INT32, "n", 1,
				       BSON_TYPE_NONE),
			   BSON_TYPE_NONE);
  bson_finish (query);

  select = bson_build (BSON_TYPE_INT32, "hello", 1,
		       BSON_TYPE_INT32, "n", 1,
		       BSON_TYPE_INT32, "yes?", 1,
		       BSON_TYPE_NONE);
  bson_finish (select);

  p = mongo_sync_cmd_query (conn, "tutorial.docs", 0,
			    0, 10, query, select);
  if (!p)
    {
      perror ("mongo_sync_cmd_query()");
      exit (1);
    }
  bson_free (query);
  bson_free (select);

  cursor = mongo_sync_cursor_new (conn, "tutorial.docs", p);
  if (!cursor)
    {
      perror ("mongo_sync_cursor_new()");
      exit (1);
    }

  while (mongo_sync_cursor_next (cursor))
    {
      const char *hello;
      gint32 n;
      gboolean yes;

      bson *result;
      bson_cursor *c;

      result = mongo_sync_cursor_get_data (cursor);
      if (!result)
	{
	  perror ("mongo_sync_cursor_get_data()");
	  exit (1);
	}

      c = bson_find (result, "hello");
      if (!bson_cursor_get_string (c, &hello))
	{
	  perror ("bson_cursor_get_string()");
	  exit (1);
	}
      bson_cursor_free (c);

      c = bson_find (result, "n");
      if (!bson_cursor_get_int32 (c, &n))
	{
	  perror ("bson_cursor_get_int32()");
	  exit (1);
	}
      bson_cursor_free (c);

      c = bson_find (result, "yes?");
      if (!bson_cursor_get_boolean (c, &yes))
	{
	  perror ("bson_cursor_get_boolean()");
	  exit (1);
	}
      bson_cursor_free (c);

      printf ("Document #%d: hello=%s; n=%d; yes?=%s\n",
	      i, hello, n, (yes) ? "TRUE" : "FALSE");

      bson_free (result);
      i++;
    }

  mongo_sync_cursor_free (cursor);
  mongo_sync_disconnect (conn);
}
Пример #13
0
NEOERR* mmg_query(mmg_conn *db, char *dsn, char *prefix, HDF *outnode)
{
    int count;
    char key[LEN_HDF_KEY];
    HDF *node, *cnode;
    bson *doc;
    NEOERR *err;
    
    MCS_NOT_NULLB(db, dsn);

    db->p = mongo_sync_cmd_query(db->con, dsn, db->flags & 0x3FF, db->skip, db->limit,
                                 db->docq, db->docs);
    if (!db->p) {
        if (errno == ENOENT) {
            mtc_noise("queried %s 0 result", dsn);
            if (db->flags & MMG_FLAG_EMPTY) {
                if (db->query_callback && !db->incallback) {
                    /*
                     * empty result, call callback
                     */
                    db->incallback = true;

                    err = db->query_callback(db, NULL, true);
                    TRACE_NOK(err);

                    db->incallback = false;

                    db->query_callback = NULL;
                    db->callbackdata = NULL;
                }
                return STATUS_OK;
            }
            return nerr_raise(NERR_NOT_FOUND, "无此记录");
        }
        return nerr_raise(NERR_DB, "query: %s %d", strerror(errno), errno);
    }

    /*
     * process result
     */
    if (outnode || (db->query_callback && !db->incallback)) {
        if (outnode) node = outnode; /* need store result */
        else hdf_init(&node);

        db->c = mongo_sync_cursor_new(db->con, dsn, db->p);
        if (!db->c) return nerr_raise(NERR_DB, "cursor: %s", strerror(errno));

        cnode = NULL;
        count = 0;
        while (mongo_sync_cursor_next(db->c) && count < db->limit) {
            memset(key, sizeof(key), 0x0);
            
            if (prefix) {
                if (!(db->flags & MMG_FLAG_MIXROWS) && db->limit > 1)
                    snprintf(key, sizeof(key), "%s.%d", prefix, count);
                else snprintf(key, sizeof(key), "%s", prefix);
            } else {
                if (!(db->flags & MMG_FLAG_MIXROWS) && db->limit > 1)
                    sprintf(key, "%d", count);
                else key[0] = '\0';
            }
            
            doc = mongo_sync_cursor_get_data(db->c);
            err = mbson_export_to_hdf(node, doc, key, MBSON_EXPORT_TYPE, true);
            if (err != STATUS_OK) return nerr_pass(err);

            if (!cnode) cnode = hdf_get_obj(node, key);
            count++;
        }
        db->rescount = count;

        mongo_sync_cursor_free(db->c);
        db->c = NULL;
        db->p = NULL;
        
        mtc_noise("queried %s %d result", dsn, count);

        /*
         * call callback at last. because we don't want declare more mmg_conn*
         * it's safe to do new query in callback on result stored (db->c freeed)
         * we can call mmg_query() recursive, the callback won't.
         */
        if (db->query_callback && !db->incallback) {
            db->incallback = true;

            count = 0;
            while (cnode) {
                count++;
                if (db->rescount == count) err = db->query_callback(db, cnode, true);
                else err = db->query_callback(db, cnode, false);
                TRACE_NOK(err);
                
                cnode = hdf_obj_next(cnode);
            }
            
            db->incallback = false;

            /*
             * query_callback can't be shared with multiply query
             * later query must set them again even if TheSameOne
             */
            db->query_callback = NULL;
            db->callbackdata = NULL;
        }

        if (!outnode) hdf_destroy(&node);
    } else {
        /* don't need result */
        mongo_wire_packet_free(db->p);
        db->c = NULL;
        db->p = NULL;
    }

    return STATUS_OK;
}
Пример #14
0
int
mongo_dump (config_t *config)
{
  mongo_sync_connection *conn;
  bson *b;
  int fd;

  mongo_packet *p;
  mongo_reply_packet_header rh;
  gint64 cid;
  gdouble cnt, pos = 0;

  gchar *error;
  int e;

  VLOG ("Connecting to %s:%d/%s.%s...\n", config->host, config->port,
	config->db, config->coll);

  conn = mongo_sync_connect (config->host, config->port, config->slaveok);
  if (!conn)
    {
      e = errno;

      mongo_sync_cmd_get_last_error (conn, config->db, &error);
      fprintf (stderr, "Error connecting to %s:%d: %s\n", config->host,
	       config->port, (error) ? error : strerror (e));
      g_free (error);
      exit (1);
    }

  if (config->master_sync)
    {
      VLOG ("Syncing to master...\n");
      conn = mongo_sync_reconnect (conn, TRUE);
      if (!conn)
	{
	  e = errno;

	  mongo_sync_cmd_get_last_error (conn, config->db, &error);
	  fprintf (stderr, "Error reconnecting to the master of %s:%d: %s\n",
		   config->host, config->port, (error) ? error : strerror (e));
	  exit (1);
	}
    }

  VLOG ("Counting documents...\n");
  cnt = mongo_sync_cmd_count (conn, config->db, config->coll, NULL);
  if (cnt < 0)
    {
      e = errno;

      mongo_sync_cmd_get_last_error (conn, config->db, &error);
      fprintf (stderr, "Error counting documents in %s.%s: %s\n",
	       config->db, config->coll, (error) ? error : strerror (e));
      mongo_sync_disconnect (conn);
      exit (1);
    }

  VLOG ("Opening output file '%s'...\n", config->output);
  if (strcmp (config->output, "-") == 0)
    fd = 1;
  else
    {
      fd = open (config->output, O_RDWR | O_CREAT | O_TRUNC, 0600);
      if (fd == -1)
	{
	  fprintf (stderr, "Error opening output file '%s': %s\n",
		   config->output, strerror (errno));
	  mongo_sync_disconnect (conn);
	  exit (1);
	}
    }

  VLOG ("Launching initial query...\n");
  b = bson_new ();
  bson_finish (b);
  p = mongo_sync_cmd_query (conn, config->ns,
			    MONGO_WIRE_FLAG_QUERY_NO_CURSOR_TIMEOUT,
			    0, 10, b, NULL);
  if (!p)
    {
      e = errno;

      bson_free (b);
      unlink (config->output);
      close (fd);

      mongo_sync_cmd_get_last_error (conn, config->db, &error);
      fprintf (stderr, "Error retrieving the cursor: %s\n",
	       (error) ? error : strerror (e));
      mongo_sync_disconnect (conn);
      exit (1);
    }
  bson_free (b);

  mongo_wire_reply_packet_get_header (p, &rh);
  cid = rh.cursor_id;
  pos = mongo_dump_packet (config, p, pos, fd);
  mongo_wire_packet_free (p);

  while (pos < cnt)
    {
      gdouble pr = (pos + 10) / cnt;

      VLOG ("\rDumping... %03.2f%%", ((pr > 1) ? 1 : pr) * 100);
      if (config->verbose)
	fflush (stderr);

      p = mongo_sync_cmd_get_more (conn, config->ns, 10, cid);
      if (!p)
	{
	  e = errno;

	  unlink (config->output);
	  close (fd);

	  mongo_sync_cmd_get_last_error (conn, config->db, &error);
	  fprintf (stderr, "Error advancing the cursor: %s\n",
		   (error) ? error : strerror (e));

	  mongo_sync_disconnect (conn);
	  exit (1);
	}
      pos = mongo_dump_packet (config, p, pos, fd);
      mongo_wire_packet_free (p);
    }

  close (fd);
  mongo_sync_disconnect (conn);

  return 0;
}