Пример #1
0
 ~frame() {
     if (is_array) {
         bson_append_array_end(parent, &bson);
     } else {
         bson_append_document_end(parent, &bson);
     }
 }
static bool append_value(bson_t* bson, const char* key, size_t length, object_t* value) {
    switch (value->type) {
        case type_nil:    bson_append_null(bson, key, length);                       break; 
        case type_bool:   bson_append_bool(bson, key, length, value->b);             break; 
        case type_double: bson_append_double(bson, key, length, value->d);           break; 
        case type_str:    bson_append_utf8(bson, key, length, value->str, value->l); break; 

        case type_int:    append_int(bson, key, length, value->i);                   break; 
        case type_uint:   append_int(bson, key, length, (int64_t)value->u);          break;

        case type_map: {
            bson_t child;
            bson_append_document_begin(bson, key, length, &child);
            append_document(&child, value);
            bson_append_document_end(bson, &child);
        } break;

        case type_array: {
            bson_t child;
            bson_append_array_begin(bson, key, length, &child);
            append_array(&child, value);
            bson_append_array_end(bson, &child);
        } break;

        default:
            return false;
    }
    return true;
}
static void
copy_labels_plus_unknown_commit_result (const bson_t *src, bson_t *dst)
{
   bson_iter_t iter;
   bson_iter_t src_label;
   bson_t dst_labels;
   char str[16];
   uint32_t i = 0;
   const char *key;

   BSON_APPEND_ARRAY_BEGIN (dst, "errorLabels", &dst_labels);
   BSON_APPEND_UTF8 (&dst_labels, "0", UNKNOWN_COMMIT_RESULT);

   /* append any other errorLabels already in "src" */
   if (bson_iter_init_find (&iter, src, "errorLabels") &&
       bson_iter_recurse (&iter, &src_label)) {
      while (bson_iter_next (&src_label) && BSON_ITER_HOLDS_UTF8 (&src_label)) {
         if (strcmp (bson_iter_utf8 (&src_label, NULL),
                     UNKNOWN_COMMIT_RESULT) != 0) {
            i++;
            bson_uint32_to_string (i, &key, str, sizeof str);
            BSON_APPEND_UTF8 (
               &dst_labels, key, bson_iter_utf8 (&src_label, NULL));
         }
      }
   }

   bson_append_array_end (dst, &dst_labels);
}
Пример #4
0
static void
test_bson_build_child_array (void)
{
   bson_t b;
   bson_t child;
   bson_t *b2;
   bson_t *child2;

   bson_init(&b);
   assert(bson_append_array_begin(&b, "foo", -1, &child));
   assert(bson_append_utf8(&child, "0", -1, "baz", -1));
   assert(bson_append_array_end(&b, &child));

   b2 = bson_new();
   child2 = bson_new();
   assert(bson_append_utf8(child2, "0", -1, "baz", -1));
   assert(bson_append_array(b2, "foo", -1, child2));
   bson_destroy(child2);

   assert(b.len == b2->len);
   assert_bson_equal(&b, b2);

   bson_destroy(&b);
   bson_destroy(b2);
}
Пример #5
0
void
_append_array_from_command (mongoc_write_command_t *command, bson_t *bson)
{
   bson_t ar;
   bson_reader_t *reader;
   char str[16];
   uint32_t i = 0;
   const char *key;
   bool eof;
   const bson_t *current;


   reader =
      bson_reader_new_from_data (command->payload.data, command->payload.len);

   bson_append_array_begin (bson,
                            gCommandFields[command->type],
                            gCommandFieldLens[command->type],
                            &ar);

   while ((current = bson_reader_read (reader, &eof))) {
      bson_uint32_to_string (i, &key, str, sizeof str);
      BSON_APPEND_DOCUMENT (&ar, key, current);
      i++;
   }

   bson_append_array_end (bson, &ar);
   bson_reader_destroy (reader);
}
Пример #6
0
static void
_mongoc_client_killcursors_command (mongoc_cluster_t       *cluster,
                                    mongoc_server_stream_t *server_stream,
                                    int64_t                 cursor_id,
                                    const char             *db,
                                    const char             *collection)
{
   bson_t command = BSON_INITIALIZER;
   bson_t child;

   bson_append_utf8 (&command, "killCursors", 11, collection, -1);
   bson_append_array_begin (&command, "cursors", 7, &child);
   bson_append_int64 (&child, "0", 1, cursor_id);
   bson_append_array_end (&command, &child);

   /* Find, getMore And killCursors Commands Spec: "The result from the
    * killCursors command MAY be safely ignored."
    */
   mongoc_cluster_run_command (cluster, server_stream->stream,
                               server_stream->sd->id,
                               MONGOC_QUERY_SLAVE_OK, db, &command,
                               NULL, NULL);

   bson_destroy (&command);
}
Пример #7
0
int
main (int argc, char *argv[])
{
   int i;
   int n;
   int bcon;
   bson_t bson, foo, bar, baz;
   bson_init (&bson);

   if (argc != 3) {
      fprintf (stderr,
               "usage: bcon-speed NUM_ITERATIONS [y|n]\n"
               "\n"
               "  y = perform speed tests with bcon\n"
               "  n = perform speed tests with bson_append\n"
               "\n");
      return EXIT_FAILURE;
   }

   assert (argc == 3);

   n = atoi (argv[1]);
   bcon = (argv[2][0] == 'y') ? 1 : 0;

   for (i = 0; i < n; i++) {
      if (bcon) {
         BCON_APPEND (&bson,
                      "foo",
                      "{",
                      "bar",
                      "{",
                      "baz",
                      "[",
                      BCON_INT32 (1),
                      BCON_INT32 (2),
                      BCON_INT32 (3),
                      "]",
                      "}",
                      "}");
      } else {
         bson_append_document_begin (&bson, "foo", -1, &foo);
         bson_append_document_begin (&foo, "bar", -1, &bar);
         bson_append_array_begin (&bar, "baz", -1, &baz);
         bson_append_int32 (&baz, "0", -1, 1);
         bson_append_int32 (&baz, "1", -1, 2);
         bson_append_int32 (&baz, "2", -1, 3);
         bson_append_array_end (&bar, &baz);
         bson_append_document_end (&foo, &bar);
         bson_append_document_end (&bson, &foo);
      }

      bson_reinit (&bson);
   }

   bson_destroy (&bson);

   return 0;
}
Пример #8
0
/* Construct the aggregate command in cmd:
 * { aggregate: collname, pipeline: [], cursor: { batchSize: x } } */
static void
_make_command (mongoc_change_stream_t *stream, bson_t *command)
{
   bson_iter_t iter;
   bson_t change_stream_stage; /* { $changeStream: <change_stream_doc> } */
   bson_t change_stream_doc;
   bson_t pipeline;
   bson_t cursor_doc;

   bson_init (command);
   bson_append_utf8 (command,
                     "aggregate",
                     9,
                     stream->coll->collection,
                     stream->coll->collectionlen);
   bson_append_array_begin (command, "pipeline", 8, &pipeline);

   /* Append the $changeStream stage */
   bson_append_document_begin (&pipeline, "0", 1, &change_stream_stage);
   bson_append_document_begin (
      &change_stream_stage, "$changeStream", 13, &change_stream_doc);
   bson_concat (&change_stream_doc, &stream->full_document);
   if (!bson_empty (&stream->resume_token)) {
      bson_concat (&change_stream_doc, &stream->resume_token);
   }
   bson_append_document_end (&change_stream_stage, &change_stream_doc);
   bson_append_document_end (&pipeline, &change_stream_stage);

   /* Append user pipeline if it exists */
   if (bson_iter_init_find (&iter, &stream->pipeline_to_append, "pipeline") &&
       BSON_ITER_HOLDS_ARRAY (&iter)) {
      bson_iter_t child_iter;
      uint32_t key_int = 1;
      char buf[16];
      const char *key_str;

      BSON_ASSERT (bson_iter_recurse (&iter, &child_iter));
      while (bson_iter_next (&child_iter)) {
         /* The user pipeline may consist of invalid stages or non-documents.
          * Append anyway, and rely on the server error. */
         size_t keyLen =
            bson_uint32_to_string (key_int, &key_str, buf, sizeof (buf));
         bson_append_value (
            &pipeline, key_str, (int) keyLen, bson_iter_value (&child_iter));
         ++key_int;
      }
   }

   bson_append_array_end (command, &pipeline);

   /* Add batch size if needed */
   bson_append_document_begin (command, "cursor", 6, &cursor_doc);
   if (stream->batch_size > 0) {
      bson_append_int32 (&cursor_doc, "batchSize", 9, stream->batch_size);
   }
   bson_append_document_end (command, &cursor_doc);
}
Пример #9
0
void SettingsOutput::SetSubbasinIDs()
{
	bson_t *b = bson_new();
	bson_t *child = bson_new();
	bson_t *child2 = bson_new();
	bson_t *child3 = bson_new();
	BSON_APPEND_DOCUMENT_BEGIN(b, "$query", child);
	BSON_APPEND_DOCUMENT_BEGIN(child, PARAM_FLD_NAME, child2);
	BSON_APPEND_ARRAY_BEGIN(child2, "$in", child3);
	BSON_APPEND_UTF8(child3,PARAM_FLD_NAME, VAR_OUTLETID);
	BSON_APPEND_UTF8(child3,PARAM_FLD_NAME, VAR_SUBBSNID_NUM);
	bson_append_array_end(child2, child3);
	bson_append_document_end(child, child2);
	bson_append_document_end(b, child);
	//printf("%s\n",bson_as_json(b,NULL));

	mongoc_cursor_t *cursor;
	const bson_t *bsonTable;
	mongoc_collection_t *collection;

	collection = mongoc_client_get_collection(m_conn, m_dbName.c_str(), DB_TAB_PARAMETERS);
	cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, b, NULL, NULL);

	bson_iter_t iter;
	while (mongoc_cursor_more(cursor) && mongoc_cursor_next(cursor, &bsonTable))
	{
		string nameTmp = "";
		int numTmp = -1;
		if (bson_iter_init_find(&iter, bsonTable, PARAM_FLD_NAME))
			nameTmp = GetStringFromBSONITER(&iter);
		if (bson_iter_init_find(&iter, bsonTable, PARAM_FLD_VALUE))
			numTmp = GetIntFromBSONITER(&iter);
		if(!StringMatch(nameTmp, "") && numTmp != -1)
		{
			if(StringMatch(nameTmp, VAR_OUTLETID))
				m_outletID = GetIntFromBSONITER(&iter);
			else if (StringMatch(nameTmp, VAR_SUBBSNID_NUM))
				m_nSubbasins = GetIntFromBSONITER(&iter);
		}
		else
			throw ModelException("SettingOutput","SetSubbasinIDs","No valid values found in MongoDB!");
	}
	bson_destroy(child);
	bson_destroy(child2);
	bson_destroy(child3);
	bson_destroy(b);
	mongoc_collection_destroy(collection);
	mongoc_cursor_destroy(cursor);
	return;
}
Пример #10
0
void arrayToBSON(const Array& value, const char* key, bson_t* bson) {
  bson_t child;
  bool isDocument = arrayIsDocument(value);
  if (isDocument) {
    bson_append_document_begin(bson, key, -1, &child);
  } else {
    bson_append_array_begin(bson, key, -1, &child);
  }

  fillBSONWithArray(value, &child);

  if (isDocument) {
    bson_append_document_end(bson, &child);
  } else {
    bson_append_array_end(bson, &child);
  }
}
Пример #11
0
int lua_mongo_collection_aggregate (lua_State *L)
{
    collection_t *collection;
    bson_t aggregation_pipeline = BSON_INITIALIZER;
    bson_t inner_aggregation_pipeline = BSON_INITIALIZER;
    mongoc_cursor_t *cursor = NULL;
    bson_error_t error;
    bool throw_error = false;

    collection = (collection_t *)luaL_checkudata(L, 1, "lua_mongoc_collection");

    if (!(lua_istable(L, 2)) || !(lua_table_is_array(L, 2))) {
        luaL_error(L, "aggregation pipeline must be an array");
    } else {
        bson_append_array_begin(&aggregation_pipeline, "pipeline", -1,
                                &inner_aggregation_pipeline);

        if (!(lua_table_to_bson(L, &inner_aggregation_pipeline, 2, false, &error))) {
            throw_error = true;
            goto DONE;
        }

        bson_append_array_end(&aggregation_pipeline, &inner_aggregation_pipeline);
    }

    cursor = mongoc_collection_aggregate (collection->c_collection, MONGOC_QUERY_NONE,
                                          &aggregation_pipeline,
                                          NULL, NULL);

DONE:
    bson_destroy(&aggregation_pipeline);
    bson_destroy(&inner_aggregation_pipeline);

    if (throw_error) {
        if (cursor) {
            mongoc_cursor_destroy (cursor);
        }
        luaL_error(L, error.message);
    }

    lua_mongo_cursor_new(L, cursor);

    return 1;
}
Пример #12
0
static void
append_documents_from_cmd (const mongoc_cmd_t *cmd,
                           mongoc_apm_command_started_t *event)
{
   int32_t doc_len;
   bson_t doc;
   const uint8_t *pos;
   const char *field_name;
   bson_t bson;
   char str[16];
   const char *key;
   uint32_t i;

   if (!cmd->payload || !cmd->payload_size) {
      return;
   }

   if (!event->command_owned) {
      event->command = bson_copy (event->command);
      event->command_owned = true;
   }

   /* make array from outgoing OP_MSG payload type 1 on an "insert",
    * "update", or "delete" command. */
   field_name = _mongoc_get_documents_field_name (cmd->command_name);
   BSON_ASSERT (field_name);
   BSON_ASSERT (BSON_APPEND_ARRAY_BEGIN (event->command, field_name, &bson));

   pos = cmd->payload;
   i = 0;
   while (pos < cmd->payload + cmd->payload_size) {
      memcpy (&doc_len, pos, sizeof (doc_len));
      doc_len = BSON_UINT32_FROM_LE (doc_len);
      BSON_ASSERT (bson_init_static (&doc, pos, (size_t) doc_len));
      bson_uint32_to_string (i, &key, str, sizeof (str));
      BSON_APPEND_DOCUMENT (&bson, key, &doc);

      pos += doc_len;
      i++;
   }

   bson_append_array_end (event->command, &bson);
}
Пример #13
0
bool
bson_append_int32_array_from_s (bson_t     *bson,
                                const char *key,
                                const char *value)
{
    bool ret = true;
    bson_t child;
    char *s, *p;

    if (value && strcmp ("\\N", value) != 0) {
        s = strdup (value);
        BSON_APPEND_ARRAY_BEGIN (bson, key, &child);
        p = strtok (s, "{,}");
        while (p) {
            ret = bson_append_int32_from_s (&child, "0", p);
            p = strtok (NULL, "{,}");
        }
        bson_append_array_end (bson, &child);
        free (s);
    }
    return ret;
}
Пример #14
0
bool
bson_append_point_from_s (bson_t     *bson,
                          const char *key,
                          const char *value)
{
    bool ret = true;
    bson_t child;
    char *s, *p;

    if (value && strcmp ("\\N", value) != 0) {
        s = strdup (value);
        BSON_APPEND_ARRAY_BEGIN (bson, key, &child);
        p = strtok (s, "(,)");
        if (!p) DIE;
        ret = bson_append_double_from_s (&child, "0", p);
        p = strtok (NULL, "(,)");
        if (!p) DIE;
        ret = ret && bson_append_double_from_s (&child, "1", p);
        bson_append_array_end (bson, &child);
        free (s);
    }
    return ret;
}
Пример #15
0
static void
_append_write_err_legacy (mongoc_write_result_t *result,
                          const char *err,
                          mongoc_error_domain_t domain,
                          int32_t code,
                          uint32_t offset)
{
   bson_t holder, write_errors, child;
   bson_iter_t iter;

   BSON_ASSERT (code > 0);

   if (!result->error.domain) {
      bson_set_error (&result->error, domain, (uint32_t) code, "%s", err);
   }

   /* stop processing, if result->ordered */
   result->failed = true;

   bson_init (&holder);
   bson_append_array_begin (&holder, "0", 1, &write_errors);
   bson_append_document_begin (&write_errors, "0", 1, &child);

   /* set error's "index" to 0; fixed up in _mongoc_write_result_merge_arrays */
   bson_append_int32 (&child, "index", 5, 0);
   bson_append_int32 (&child, "code", 4, code);
   bson_append_utf8 (&child, "errmsg", 6, err, -1);
   bson_append_document_end (&write_errors, &child);
   bson_append_array_end (&holder, &write_errors);
   bson_iter_init (&iter, &holder);
   bson_iter_next (&iter);

   _mongoc_write_result_merge_arrays (
      offset, result, &result->writeErrors, &iter);

   bson_destroy (&holder);
}
Пример #16
0
static void
_mongoc_write_opquery (mongoc_write_command_t *command,
                       mongoc_client_t *client,
                       mongoc_server_stream_t *server_stream,
                       const char *database,
                       const char *collection,
                       const mongoc_write_concern_t *write_concern,
                       uint32_t offset,
                       mongoc_write_result_t *result,
                       bson_error_t *error)
{
   mongoc_cmd_parts_t parts;
   bson_iter_t iter;
   const char *key;
   uint32_t len = 0;
   bson_t ar;
   bson_t cmd;
   bson_t reply;
   char str[16];
   bool has_more;
   bool ret = false;
   uint32_t i;
   int32_t max_bson_obj_size;
   int32_t max_write_batch_size;
   uint32_t overhead;
   uint32_t key_len;
   int data_offset = 0;
   bson_reader_t *reader;
   const bson_t *bson;
   bool eof;

   ENTRY;

   BSON_ASSERT (command);
   BSON_ASSERT (client);
   BSON_ASSERT (database);
   BSON_ASSERT (server_stream);
   BSON_ASSERT (collection);

   bson_init (&cmd);
   max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream);
   max_write_batch_size =
      mongoc_server_stream_max_write_batch_size (server_stream);

again:
   has_more = false;
   i = 0;

   _mongoc_write_command_init (&cmd, command, collection);

   /* 1 byte to specify array type, 1 byte for field name's null terminator */
   overhead = cmd.len + 2 + gCommandFieldLens[command->type];


   reader = bson_reader_new_from_data (command->payload.data + data_offset,
                                       command->payload.len - data_offset);

   bson_append_array_begin (&cmd,
                            gCommandFields[command->type],
                            gCommandFieldLens[command->type],
                            &ar);

   while ((bson = bson_reader_read (reader, &eof))) {
      key_len = (uint32_t) bson_uint32_to_string (i, &key, str, sizeof str);
      len = bson->len;
      /* 1 byte to specify document type, 1 byte for key's null terminator */
      if (_mongoc_write_command_will_overflow (overhead,
                                               key_len + len + 2 + ar.len,
                                               i,
                                               max_bson_obj_size,
                                               max_write_batch_size)) {
         has_more = true;
         break;
      }
      BSON_APPEND_DOCUMENT (&ar, key, bson);
      data_offset += len;
      i++;
   }

   bson_append_array_end (&cmd, &ar);

   if (!i) {
      _mongoc_write_command_too_large_error (error, i, len, max_bson_obj_size);
      result->failed = true;
      result->must_stop = true;
      ret = false;
      if (bson) {
         data_offset += len;
      }
   } else {
      mongoc_cmd_parts_init (&parts, client, database, MONGOC_QUERY_NONE, &cmd);
      parts.is_write_command = true;
      parts.assembled.operation_id = command->operation_id;
      if (!mongoc_cmd_parts_set_write_concern (
             &parts,
             write_concern,
             server_stream->sd->max_wire_version,
             error)) {
         bson_reader_destroy (reader);
         bson_destroy (&cmd);
         mongoc_cmd_parts_cleanup (&parts);
         EXIT;
      }

      BSON_ASSERT (bson_iter_init (&iter, &command->cmd_opts));
      if (!mongoc_cmd_parts_append_opts (
             &parts, &iter, server_stream->sd->max_wire_version, error)) {
         bson_reader_destroy (reader);
         bson_destroy (&cmd);
         mongoc_cmd_parts_cleanup (&parts);
         EXIT;
      }

      ret = mongoc_cmd_parts_assemble (&parts, server_stream, error);
      if (ret) {
         ret = mongoc_cluster_run_command_monitored (
            &client->cluster, &parts.assembled, &reply, error);
      } else {
         /* assembling failed */
         result->must_stop = true;
         bson_init (&reply);
      }

      if (!ret) {
         result->failed = true;
         if (bson_empty (&reply)) {
            /* assembling failed, or a network error running the command */
            result->must_stop = true;
         }
      }

      _mongoc_write_result_merge (result, command, &reply, offset);
      offset += i;
      bson_destroy (&reply);
      mongoc_cmd_parts_cleanup (&parts);
   }
   bson_reader_destroy (reader);

   if (has_more && (ret || !command->flags.ordered) && !result->must_stop) {
      bson_reinit (&cmd);
      GOTO (again);
   }

   bson_destroy (&cmd);
   EXIT;
}
/*********************************************************************************************
F_SECUNDARIA: Creando un BSON del archivo, para insertalo en la DB                 TESTEADO =)
****************************/
bson_t * crearDocumentoParaLaDB(char * nombreDelArchivo, long tamanioDelArchivo, int dirPadreDelArchivo, t_dictionary * diccionarioDeBloques)
//Va eliminando el diccionario que ingresa por parametro :D
{
	bson_t child; bson_t child2; bson_t child3; bson_t child4;
	bson_oid_t oid;

	int cantidadTotalDeBloques;
	int identificadorDelBloque = 0;

	t_dictionary* copiasDelBloqueX;
	t_copiaX* copiaX;

	char * iDelBloque;
	//FIN DECLARACION DE VARIABLES


	bson_t * documento = bson_new();
	// ::: Estructura BASICA del documento :::
		bson_oid_init (&oid, NULL);
        BSON_APPEND_OID (documento, "_id", &oid);
		BSON_APPEND_UTF8 (documento, "nombreDelArchivo", nombreDelArchivo);
	 	BSON_APPEND_INT32 (documento, "tamanio", tamanioDelArchivo);
	 	BSON_APPEND_INT32 (documento, "dirPadre", dirPadreDelArchivo);
		BSON_APPEND_INT32 (documento, "estado", 1);

	cantidadTotalDeBloques = dictionary_size(diccionarioDeBloques);

		BSON_APPEND_INT32 (documento, "cantidadDeBloques", cantidadTotalDeBloques);
	// ::: Estructura de BLOQUES del documento :::
	//Guardando los N bloques con copias 3
	bson_append_document_begin (documento, "Bloques", 7, &child);

		while(identificadorDelBloque < cantidadTotalDeBloques)
		{
			iDelBloque = string_itoa(identificadorDelBloque);

			bson_append_document_begin (&child, iDelBloque, 1, &child2);

				copiasDelBloqueX = (t_dictionary*) dictionary_get( diccionarioDeBloques, iDelBloque );

				//Guardando la cantidad de copias del bloque X
					BSON_APPEND_INT32 (&child2, "cantidadDeCopias", 3);

				//Guardando las 3 copias para el bloque X
				bson_append_array_begin (&child2, "copias", 6, &child4);

					copiaX = (t_copiaX*) dictionary_get( copiasDelBloqueX, "1" );

					int Guachin= dictionary_size(copiasDelBloqueX);
					bson_append_document_begin (&child4, "0", 1, &child3);
						bson_append_int32(&child3,"IP", 2, (*copiaX).IP);
						bson_append_int32(&child3, "puerto", 6, (*copiaX).puerto);
						bson_append_int32(&child3, "numBloque", 9, (*copiaX).numBloque);
					bson_append_document_end (&child4, &child3);

					copiaX = (t_copiaX*) dictionary_get( copiasDelBloqueX, "2" );

					bson_append_document_begin (&child4, "1", 1, &child3);
						bson_append_int32(&child3,"IP", 2, (*copiaX).IP);
						bson_append_int32(&child3, "puerto", 6, (*copiaX).puerto);
						bson_append_int32(&child3, "numBloque", 9, (*copiaX).numBloque);
					bson_append_document_end (&child4, &child3);

					copiaX = (t_copiaX*) dictionary_get( copiasDelBloqueX, "3" );

					bson_append_document_begin (&child4, "2", 1, &child3);
						bson_append_int32(&child3,"IP", 2, (*copiaX).IP);
						bson_append_int32(&child3, "puerto", 6, (*copiaX).puerto);
						bson_append_int32(&child3, "numBloque", 9, (*copiaX).numBloque);
					bson_append_document_end (&child4, &child3);

				bson_append_array_end (&child2, &child4);

				dictionary_clean(copiasDelBloqueX);
				dictionary_destroy(copiasDelBloqueX);

			//Anido las 3 copias al bloque X
			bson_append_document_end (&child, &child2);

			free(iDelBloque);
			identificadorDelBloque++;
		};
	//::Estructura BASICA + estructura BLOQUES::
	bson_append_document_end (documento, &child);

	//Elimino el diccionarioDeBloques
	dictionary_clean(diccionarioDeBloques);
	dictionary_destroy(diccionarioDeBloques);

	return documento;
}
Пример #18
0
void VariantToBsonConverter::convertDocument(bson_t *bson, const char *property_name, Variant v)
{
	bson_t child;
	int unmangle = 0;
	Array document;

	/* if we are not at a top-level, we need to check (and convert) special
	 * BSON types too */
	if (v.isObject()) {
		if (convertSpecialObject(bson, property_name, v.toObject())) {
			return;
		}
		/* The "convertSpecialObject" method didn't understand this type, so we
		 * will continue treating this as a normal document */
	}

	document = v.toObject()->o_toIterArray(null_string, ObjectData::PreserveRefs);

	if (_isPackedArray(document) && !v.isObject()) {
		if (property_name != NULL) {
			bson_append_array_begin(bson, property_name, -1, &child);
		}
	} else {
		unmangle = 1;
		if (property_name != NULL) {
			bson_append_document_begin(bson, property_name, -1, &child);
		}
	}

	for (ArrayIter iter(document); iter; ++iter) {
		Variant key(iter.first());
		const Variant& data(iter.secondRef());
		String s_key = key.toString();

		if (m_level == 0 && (m_flags & HIPPO_BSON_ADD_ID)) {
			/* If we have an ID, we don't need to add it. But we also need to
			 * set m_out to the value! */
			if (strncmp(s_key.c_str(), "_id", s_key.length()) == 0) {
				m_flags &= ~HIPPO_BSON_ADD_ID;
				if (m_flags & HIPPO_BSON_RETURN_ID) {
					/* FIXME: Should we add a ref here? */
					m_out = data;
				}
			}
		}

		m_level++;
		if (unmangle) {
			const char *unmangledName;

			unmangledName = _getUnmangledPropertyName(s_key);
			convertElement(property_name != NULL ? &child : bson, unmangledName, data);
			free((void*) unmangledName);
		} else {
			convertElement(property_name != NULL ? &child : bson, s_key.c_str(), data);
		}
		m_level--;
	}

	if (m_level == 0 && (m_flags & HIPPO_BSON_ADD_ID)) {
		bson_oid_t oid;

		bson_oid_init(&oid, NULL);
		bson_append_oid(bson, "_id", strlen("_id"), &oid);

		if (m_flags & HIPPO_BSON_RETURN_ID) {
			static Class* c_objectId;
			c_objectId = Unit::lookupClass(s_MongoBsonObjectID_className.get());
			assert(c_objectId);
			Object obj = Object{c_objectId};

			MongoDBBsonObjectIDData* obj_data = Native::data<MongoDBBsonObjectIDData>(obj.get());
			bson_oid_copy(&oid, &obj_data->m_oid);

			m_out = obj;
		}
	}

	if (property_name != NULL) {
		if (_isPackedArray(document)) {
			bson_append_array_end(bson, &child);
		} else {
			bson_append_document_end(bson, &child);
		}
	}
}
Пример #19
0
int main( int argc, char **argv )
{
   SHM_INFO        region;
   long            RingKey;         /* Key to the transport ring to read from */
   MSG_LOGO        getlogo[NLOGO], logo;
   long            gotsize;
   char            msg[MAX_TRACEBUF_SIZ];
   char           *getSta, *getComp, *getNet, *getLoc, *inRing;
   char            wildSta, wildComp, wildNet, wildLoc;
   unsigned char   Type_Mseed;
   unsigned char   Type_TraceBuf,Type_TraceBuf2;
   unsigned char   Type_TraceComp, Type_TraceComp2;
   unsigned char   InstWildcard, ModWildcard;
   short          *short_data;
   int            *long_data;
   TRACE2_HEADER  *trh;
   char            orig_datatype[3];
   char            stime[256];
   char            etime[256];
   int             i;
   int             rc;
   int             nLogo = NLOGO;
   static unsigned char InstId;        /* local installation id              */
   char            ModName[MAX_MOD_STR];
   char		   *modid_name;
   unsigned char   sequence_number = 0;
   // int             statistics_flag;
   time_t monitor_start_time = 0;
   double start_time, end_time;
   unsigned long packet_total=0;
   unsigned long packet_total_size=0;
   MSRecord *msr = NULL;	/* mseed record */
   logit_init("ring2mongo", 200, 256, 1); 
   char *mongo_user = getenv("MONGO_USER");
   char *mongo_passwd=getenv("MONGO_PASSWD");
   char *mongo_host=getenv("MONGO_HOST");
   char *mongo_port=getenv("MONGO_PORT");
   if(mongo_user == NULL ||
      mongo_passwd==NULL ||
      mongo_host== NULL  ||
      mongo_port==NULL){
        printf("Ensure the following ENV varibles are set\n *MONGO_USER\n *MONGO_PASSWD\n *MONGO_HOST\n *MONGO_PORT\n");
        exit(1);
        return(1);
      }
   char mongo_str[128]="mongodb://";
   
   strcat(mongo_str, mongo_user);
   strcat(mongo_str, ":");
   strcat(mongo_str, mongo_passwd);
   strcat(mongo_str, "@");
   strcat(mongo_str, mongo_host);
   strcat(mongo_str, ":");
   strcat(mongo_str, mongo_port);   
   strcat(mongo_str, "/");
   //mongo stuff
   mongoc_client_t *m_client;
   mongoc_collection_t *m_collection;
   mongoc_init ();
   m_client = mongoc_client_new (mongo_str);
   m_collection = mongoc_client_get_collection (m_client, "waveforms", "ring");
  
   mongoc_bulk_operation_t *m_bulk;
   bson_error_t m_error;
   bson_t *m_doc;
   bson_t m_reply;
   bson_t *m_data;
   /*wait for this many messages before performing bulk write
   For real time continuous data it shoudl be ~ number of channels on ring*/
   int MONGO_BULK_MAX = 30; 
   int m_count = 0; /* counter for mongo bulk */
   bool m_ret;
   /*end mongo stuff*/
   
   
   

  /* Initialize pointers
  **********************/
  trh  = (TRACE2_HEADER *) msg;
  long_data  =  (int *)( msg + sizeof(TRACE2_HEADER) );
  short_data = (short *)( msg + sizeof(TRACE2_HEADER) );


  /* Check command line argument
  
  *****************************/
  if ( argc < 2 || argc > 6)
  {
     if(argc > 6)
     fprintf(stderr, "ring2mongo: Too many parameters\n");
     fprintf(stderr,"Usage: %s <ring name> [sta] [comp] [net] [loc] \n", argv[0]);
     fprintf(stderr, " Note: All parameters are positional, and all but first are optional.\n");
     fprintf(stderr, " the full data contained in the packet is printed out.\n");
     fprintf(stderr, " If sta comp net (but not loc) are specified then only TraceBuf\n");
     fprintf(stderr, " packets will be fetched (not TraceBuf2); otherwise both are fetched.\n");
     fprintf(stderr, " Example: %s WAVE_RING PHOB wild NC wild n\n", argv[0]);
     fprintf(stderr, " MSEED capability starting with version 2.5.1, prints mseed headers\n");
     fprintf(stderr, " of TYPE_MSEED packets (no filtering yet).\n");
     exit( 1 );
     return 1;
  }

  /* process given parameters */
  inRing  = argv[1];         /* first parameter is ring name */

  /* any parameters not given are set as wildcards */
  getSta = getComp = getNet = getLoc = "";
  wildSta = wildComp = wildNet = wildLoc = 1;
  if(argc > 2)
  {  /* at least station parameter given */
    getSta = argv[2];
    wildSta  = IsWild(getSta);
    if(argc > 3)
    {  /* channel (component) parameter given */
      getComp = argv[3];
      wildComp = IsWild(getComp);
      if(argc > 4)
      {  /* network parameter given */
        getNet = argv[4];
        wildNet = IsWild(getNet);
        if(argc > 5)
        {  /* location parameter given (SCNL) */
          getLoc  = argv[5];
          wildLoc = IsWild(getLoc);
        }
        else
        {  /* SCN without location parameter given */
          nLogo = 3;    /* do not include tracebuf2s in search */
        }
      }
    }
  }


  /* Attach to ring
  *****************/
  if ((RingKey = GetKey( inRing )) == -1 )
  {
    fprintf( stderr, "Invalid RingName; exiting!\n" );
    exit( -1 );
    return -1;
  }
  tport_attach( &region, RingKey );

/* Look up local installation id
   *****************************/
   if ( GetLocalInst( &InstId ) != 0 )
   {
      fprintf(stderr, "ring2mongo: error getting local installation id; exiting!\n" );
      exit( -1 );
      return -1;
   }

  /* Specify logos to get
  ***********************/
  if ( GetType( "TYPE_MSEED", &Type_Mseed ) != 0 ) {
     fprintf(stderr, "%s: WARNING: Invalid message type <TYPE_MSEED>! Missing from earthworm.d or earthworm_global.d\n", argv[0] );
     Type_Mseed = TYPE_NOTUSED;
  }
  if ( GetType( "TYPE_TRACEBUF", &Type_TraceBuf ) != 0 ) {
     fprintf(stderr, "%s: Invalid message type <TYPE_TRACEBUF>! Missing from earthworm.d or earthworm_global.d\n", argv[0] );
     exit( -1 );
     return -1;
  }
  if ( GetType( "TYPE_TRACE_COMP_UA", &Type_TraceComp ) != 0 ) {
     fprintf(stderr, "%s: Invalid message type <TYPE_TRACE_COMP_UA>! Missing from earthworm.d or earthworm_global.d\n", argv[0] );
     exit( -1 );
     return -1;
  }
  if ( GetType( "TYPE_TRACEBUF2", &Type_TraceBuf2 ) != 0 ) {
     fprintf(stderr, "%s: Invalid message type <TYPE_TRACEBUF2>! Missing from earthworm.d or earthworm_global.d\n", argv[0] );
     exit( -1 );
     return -1;
  }
  if ( GetType( "TYPE_TRACE2_COMP_UA", &Type_TraceComp2 ) != 0 ) {
     fprintf(stderr,"%s: Invalid message type <TYPE_TRACE2_COMP_UA>! Missing from earthworm.d or earthworm_global.d\n", argv[0] );
     exit( -1 );
     return -1;
  }
  if ( GetModId( "MOD_WILDCARD", &ModWildcard ) != 0 ) {
     fprintf(stderr, "%s: Invalid moduleid <MOD_WILDCARD>! Missing from earthworm.d or earthworm_global.d\n", argv[0] );
     exit( -1 );
     return -1;
  }
  if ( GetInst( "INST_WILDCARD", &InstWildcard ) != 0 ) {
     fprintf(stderr, "%s: Invalid instid <INST_WILDCARD>! Missing from earthworm.d or earthworm_global.d\n", argv[0] );
     exit( -1 );
     return -1;
  }

  for( i=0; i<nLogo; i++ ) {
      getlogo[i].instid = InstWildcard;
      getlogo[i].mod    = ModWildcard;
  }
  getlogo[0].type = Type_Mseed;
  getlogo[1].type = Type_TraceBuf;
  getlogo[2].type = Type_TraceComp;
  if (nLogo >= 4) {     /* if nLogo=5 then include TraceBuf2s */
      getlogo[3].type = Type_TraceBuf2;
      getlogo[4].type = Type_TraceComp2;
  }
  logit("", "Starting ring2mongo");
  /* Flush the ring
  *****************/
  while ( tport_copyfrom( &region, getlogo, nLogo, &logo, &gotsize,
            (char *)&msg, MAX_TRACEBUF_SIZ, &sequence_number ) != GET_NONE ){
         packet_total++;
         packet_total_size+=gotsize;
  }
  logit( "et",  "ring2mongo: inRing flushed %ld packets of %ld bytes total.\n",
	packet_total, packet_total_size);

  while (tport_getflag( &region ) != TERMINATE ) {
    rc = tport_copyfrom( &region, getlogo, nLogo,
               &logo, &gotsize, msg, MAX_TRACEBUF_SIZ, &sequence_number );

    if ( rc == GET_NONE ){
      sleep_ew( 200 );
      continue;
    }

    if ( rc == GET_TOOBIG ){
      logit("et", "ring2mongo: retrieved message too big (%ld) for msg\n",
        gotsize );
      continue;
    }
    if ( rc == GET_NOTRACK )
      logit("et", "ring2mongo: Tracking error.\n");

    if ( rc == GET_MISS_LAPPED )
      logit("et", "ring2mongo: Got lapped on the ring.\n");

    if ( rc == GET_MISS_SEQGAP )
      logit( "et", "ring2mongo: Gap in sequence numbers\n");

    if ( rc == GET_MISS )
      logit( "et", "ring2mongo: Missed messages\n");

    /* Check SCNL of the retrieved message */


    if (Type_Mseed != TYPE_NOTUSED && logo.type == Type_Mseed) {
      /* Unpack record header and not data samples */
      /*hard coded zero for dataflag(1) and verbose(0)for ring2mongo*/
      if ( msr_unpack (msg, gotsize, &msr, 1, 0) != MS_NOERROR) {
         logit("et", "Error parsing mseed record\n");
         continue;
      }

      /* Print record information */
      msr_print (msr, 0);

      msr_free (&msr);
      continue;
    }
    /*end Mseed*/
    
    if ( (wildSta  || (strcmp(getSta,trh->sta)  ==0)) &&
         (wildComp || (strcmp(getComp,trh->chan)==0)) &&
         (wildNet  || (strcmp(getNet,trh->net)  ==0)) &&
         (((logo.type == Type_TraceBuf2 ||
            logo.type == Type_TraceComp2) &&
         (wildLoc  || (strcmp(getLoc,trh->loc) == 0))) ||
         ( (logo.type == Type_TraceBuf ||
             logo.type == Type_TraceComp))))
    {
      
      
      strcpy(orig_datatype, trh->datatype);
      char scnl[20];     
      scnl[0] = 0;
      strcat( scnl, trh->sta);
      strcat( scnl, ".");
      strcat( scnl, trh->chan);
      strcat( scnl, ".");
      strcat( scnl, trh->net);
      strcat( scnl, ".");
      strcat( scnl, trh->loc);
      
      if(WaveMsg2MakeLocal( trh ) < 0){
        
        char  dt[3];        
        
        /* now put a space if there are any punctuation marks */

        for ( i=0; i<15; i++ ) {
          if ( !isalnum(scnl[i]) && !ispunct(scnl[i]))
            scnl[i] = ' ';
        }
        strncpy( dt, trh->datatype, 2 );
        for ( i=0; i<2; i++ ) {
          if ( !isalnum(dt[i]) && !ispunct(dt[i]))
            dt[i] = ' ';
        }
        dt[i] = 0;
        logit("et", "WARNING: WaveMsg2MakeLocal rejected tracebuf.  Discard (%s).\n",
          scnl );
        logit("et", "\tdatatype=[%s]\n", dt);
        continue;
      }
        
      /*lets get ready to mongo....*/
      if(m_count < MONGO_BULK_MAX){
        /*initialize when m_count ==0 */
        if(m_count==0){
          m_bulk = mongoc_collection_create_bulk_operation (m_collection, true, NULL);
        }       
        m_data = bson_new ();
        m_doc = BCON_NEW ("key",   BCON_UTF8 (scnl),
                          "nsamp", BCON_INT32 (trh->nsamp),
                          "starttime", BCON_DOUBLE (trh->starttime*1000),
                          "endtime", BCON_DOUBLE (trh->endtime*1000),
                          "samprate", BCON_DOUBLE (trh->samprate),
                          "datatype", BCON_UTF8 (trh->datatype)
        );
       char index[4];
       bson_append_array_begin (m_doc, "data", -1, m_data);
        for ( i = 0; i < trh->nsamp; i++ ){
          snprintf(index, 4, "%d", i);
          if ( (strcmp (trh->datatype, "s2")==0) || (strcmp (trh->datatype, "i2")==0) ){
            bson_append_int32 (m_data, index, -1, short_data[i]);
           }else{
             bson_append_int32 (m_data, index, -1, long_data[i]);
           }
          }
        bson_append_array_end (m_doc, m_data);                             
        mongoc_bulk_operation_insert (m_bulk, m_doc);
        bson_destroy (m_doc);
        bson_destroy (m_data);
        
        m_count++;
        if(m_count==MONGO_BULK_MAX){
          
          /*write and destroty above stuff */  
          m_ret = mongoc_bulk_operation_execute (m_bulk, &m_reply, &m_error);
          if (!m_ret){
             logit ("et", "Error: %s\n", m_error.message);
           }
          bson_destroy (&m_reply);
          mongoc_bulk_operation_destroy (m_bulk);
          m_count = 0;
        }
      } 
    }
  } /* end of while loop */
  logit("et", "signing off"); 
  exit (0);
  return 0;
}
static void
_mongoc_write_command(mongoc_write_command_t       *command,
                      mongoc_client_t              *client,
                      mongoc_server_stream_t       *server_stream,
                      const char                   *database,
                      const char                   *collection,
                      const mongoc_write_concern_t *write_concern,
                      uint32_t                      offset,
                      mongoc_write_result_t        *result,
                      bson_error_t                 *error)
{
   const uint8_t *data;
   bson_iter_t iter;
   const char *key;
   uint32_t len = 0;
   bson_t tmp;
   bson_t ar;
   bson_t cmd;
   bson_t reply;
   char str [16];
   bool has_more;
   bool ret = false;
   uint32_t i;
   int32_t max_bson_obj_size;
   int32_t max_write_batch_size;
   int32_t min_wire_version;
   uint32_t key_len;

   ENTRY;

   BSON_ASSERT (command);
   BSON_ASSERT (client);
   BSON_ASSERT (database);
   BSON_ASSERT (server_stream);
   BSON_ASSERT (collection);

   max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream);
   max_write_batch_size = mongoc_server_stream_max_write_batch_size (server_stream);

   /*
    * If we have an unacknowledged write and the server supports the legacy
    * opcodes, then submit the legacy opcode so we don't need to wait for
    * a response from the server.
    */

   min_wire_version = server_stream->sd->min_wire_version;
   if ((min_wire_version == 0) &&
       !_mongoc_write_concern_needs_gle (write_concern)) {
      if (command->flags.bypass_document_validation != MONGOC_BYPASS_DOCUMENT_VALIDATION_DEFAULT) {
         bson_set_error (error,
                         MONGOC_ERROR_COMMAND,
                         MONGOC_ERROR_COMMAND_INVALID_ARG,
                         "Cannot set bypassDocumentValidation for unacknowledged writes");
         EXIT;
      }
      gLegacyWriteOps[command->type] (command, client, server_stream, database,
                                      collection, write_concern, offset,
                                      result, error);
      EXIT;
   }

   if (!command->n_documents ||
       !bson_iter_init (&iter, command->documents) ||
       !bson_iter_next (&iter)) {
      _empty_error (command, error);
      result->failed = true;
      EXIT;
   }

again:
   bson_init (&cmd);
   has_more = false;
   i = 0;

   BSON_APPEND_UTF8 (&cmd, gCommandNames[command->type], collection);
   BSON_APPEND_DOCUMENT (&cmd, "writeConcern",
                         WRITE_CONCERN_DOC (write_concern));
   BSON_APPEND_BOOL (&cmd, "ordered", command->flags.ordered);
   if (command->flags.bypass_document_validation != MONGOC_BYPASS_DOCUMENT_VALIDATION_DEFAULT) {
      BSON_APPEND_BOOL (&cmd, "bypassDocumentValidation",
                        !!command->flags.bypass_document_validation);
   }

   if (!_mongoc_write_command_will_overflow (0,
                                             command->documents->len,
                                             command->n_documents,
                                             max_bson_obj_size,
                                             max_write_batch_size)) {
      /* copy the whole documents buffer as e.g. "updates": [...] */
      BSON_APPEND_ARRAY (&cmd,
                         gCommandFields[command->type],
                         command->documents);
      i = command->n_documents;
   } else {
      bson_append_array_begin (&cmd, gCommandFields[command->type], -1, &ar);

      do {
         if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) {
            BSON_ASSERT (false);
         }

         bson_iter_document (&iter, &len, &data);
         key_len = (uint32_t) bson_uint32_to_string (i, &key, str, sizeof str);

         if (_mongoc_write_command_will_overflow (ar.len,
                                                  key_len + len + 2,
                                                  i,
                                                  max_bson_obj_size,
                                                  max_write_batch_size)) {
            has_more = true;
            break;
         }

         if (!bson_init_static (&tmp, data, len)) {
            BSON_ASSERT (false);
         }

         BSON_APPEND_DOCUMENT (&ar, key, &tmp);

         bson_destroy (&tmp);

         i++;
      } while (bson_iter_next (&iter));

      bson_append_array_end (&cmd, &ar);
   }

   if (!i) {
      too_large_error (error, i, len, max_bson_obj_size, NULL);
      result->failed = true;
      ret = false;
   } else {
      ret = mongoc_cluster_run_command (&client->cluster, server_stream->stream,
                                        MONGOC_QUERY_NONE, database, &cmd,
                                        &reply, error);

      if (!ret) {
         result->failed = true;
      }

      _mongoc_write_result_merge (result, command, &reply, offset);
      offset += i;
      bson_destroy (&reply);
   }

   bson_destroy (&cmd);

   if (has_more && (ret || !command->flags.ordered)) {
      GOTO (again);
   }

   EXIT;
}
void
_mongoc_write_result_merge_legacy (mongoc_write_result_t  *result,  /* IN */
                                   mongoc_write_command_t *command, /* IN */
                                   const bson_t           *reply,   /* IN */
                                   mongoc_error_code_t     default_code,
                                   uint32_t                offset)
{
   const bson_value_t *value;
   bson_t holder, write_errors, child;
   bson_iter_t iter;
   bson_iter_t ar;
   bson_iter_t citer;
   const char *err = NULL;
   int32_t code = 0;
   int32_t n = 0;
   int32_t upsert_idx = 0;

   ENTRY;

   BSON_ASSERT (result);
   BSON_ASSERT (reply);

   if (bson_iter_init_find (&iter, reply, "n") &&
       BSON_ITER_HOLDS_INT32 (&iter)) {
      n = bson_iter_int32 (&iter);
   }

   if (bson_iter_init_find (&iter, reply, "err") &&
       BSON_ITER_HOLDS_UTF8 (&iter)) {
      err = bson_iter_utf8 (&iter, NULL);
   }

   if (bson_iter_init_find (&iter, reply, "code") &&
       BSON_ITER_HOLDS_INT32 (&iter)) {
      code = bson_iter_int32 (&iter);
   }

   if (code || err) {
      if (!code) {
         code = default_code;
      }

      if (!err) {
         err = "unknown error";
      }

      bson_set_error (&result->error,
                      MONGOC_ERROR_COLLECTION,
                      code,
                      "%s", err);
      result->failed = true;

      bson_init(&holder);
      bson_append_array_begin(&holder, "0", 1, &write_errors);
      bson_append_document_begin(&write_errors, "0", 1, &child);
      bson_append_int32(&child, "index", 5, 0);
      bson_append_int32(&child, "code", 4, code);
      bson_append_utf8(&child, "errmsg", 6, err, -1);
      bson_append_document_end(&write_errors, &child);
      bson_append_array_end(&holder, &write_errors);
      bson_iter_init(&iter, &holder);
      bson_iter_next(&iter);

      _mongoc_write_result_merge_arrays (offset, result, &result->writeErrors,
                                         &iter);

      bson_destroy(&holder);
   }

   switch (command->type) {
   case MONGOC_WRITE_COMMAND_INSERT:
      if (n) {
         result->nInserted += n;
      }
      break;
   case MONGOC_WRITE_COMMAND_DELETE:
      result->nRemoved += n;
      break;
   case MONGOC_WRITE_COMMAND_UPDATE:
      if (bson_iter_init_find (&iter, reply, "upserted") &&
         !BSON_ITER_HOLDS_ARRAY (&iter)) {
         result->nUpserted += n;
         value = bson_iter_value (&iter);
         _mongoc_write_result_append_upsert (result, offset, value);
      } else if (bson_iter_init_find (&iter, reply, "upserted") &&
                 BSON_ITER_HOLDS_ARRAY (&iter)) {
         result->nUpserted += n;
         if (bson_iter_recurse (&iter, &ar)) {
            while (bson_iter_next (&ar)) {
               if (BSON_ITER_HOLDS_DOCUMENT (&ar) &&
                   bson_iter_recurse (&ar, &citer) &&
                   bson_iter_find (&citer, "_id")) {
                  value = bson_iter_value (&citer);
                  _mongoc_write_result_append_upsert (result,
                                                      offset + upsert_idx,
                                                      value);
                  upsert_idx++;
               }
            }
         }
      } else if ((n == 1) &&
                 bson_iter_init_find (&iter, reply, "updatedExisting") &&
                 BSON_ITER_HOLDS_BOOL (&iter) &&
                 !bson_iter_bool (&iter)) {
         result->nUpserted += n;
      } else {
         result->nMatched += n;
      }
      break;
   default:
      break;
   }

   result->omit_nModified = true;

   EXIT;
}
Пример #22
0
void transaction_bson(struct transaction const* tx, bson_t* out)
{
    char key[9];

    bson_t* input_list = bson_new();

    // Version
    BSON_APPEND_INT32(out, "version", (int)transaction_version(tx));

    // Inputs
    BSON_APPEND_ARRAY_BEGIN(out, "inputs", input_list);
    size_t num_inputs = transaction_num_inputs(tx);
    for(size_t i = 0; i < num_inputs; i++) {
        struct transaction_input* input = transaction_input(tx, i);
        
        bson_snprintf(key, sizeof(key), "%u", (unsigned int)i);
        key[sizeof(key) - 1] = '\0';

        bson_t* member = bson_new();
        bson_append_document_begin(input_list, key, -1, member);

        // Output Reference
        struct transaction_output_reference* output_reference = transaction_input_output_reference(input);
        unsigned char prevout_hash[32];
        transaction_output_reference_hash(output_reference, prevout_hash);
        bson_t* prevout = bson_new();
        bson_append_document_begin(member, "output_reference", -1, prevout);
        BSON_APPEND_BINARY(prevout, "hash", BSON_SUBTYPE_BINARY, (uint8_t*)prevout_hash, 32);
        BSON_APPEND_INT32(prevout, "index", transaction_output_reference_index(output_reference));
        bson_append_document_end(member, prevout);

        // Script
        struct script* script = transaction_input_script(input);
        BSON_APPEND_BINARY(member, "script", BSON_SUBTYPE_BINARY, (uint8_t*)script_data(script), script_size(script));

        // Sequence
        BSON_APPEND_INT32(member, "sequence", transaction_input_sequence(input));

        bson_append_document_end(input_list, member);
    }
    bson_append_array_end(out, input_list);

    // Outputs
    bson_t* output_list = bson_new();
    BSON_APPEND_ARRAY_BEGIN(out, "outputs", output_list);
    size_t num_outputs = transaction_num_outputs(tx);
    for(size_t i = 0; i < num_outputs; i++) {
        struct transaction_output* output = transaction_output(tx, i);
        
        bson_snprintf(key, sizeof(key), "%u", (unsigned int)i);
        key[sizeof(key) - 1] = '\0';

        bson_t* member = bson_new();
        bson_append_document_begin(output_list, key, -1, member);

        // Value
        BSON_APPEND_INT64(member, "value", transaction_output_value(output));

        // Script
        struct script* script = transaction_output_script(output);
        BSON_APPEND_BINARY(member, "script", BSON_SUBTYPE_BINARY, (uint8_t*)script_data(script), script_size(script));

        bson_append_document_end(output_list, member);
    }
    bson_append_array_end(out, output_list);

    // Lock time
    BSON_APPEND_INT32(out, "lock_time", (int)transaction_lock_time(tx));
}
Пример #23
0
/* Uses old way of querying system.namespaces. */
bson_t *
_mongoc_database_get_collection_info_legacy (mongoc_database_t *database,
                                             const bson_t      *filter,
                                             bson_error_t      *error)
{
   mongoc_collection_t *col;
   mongoc_cursor_t *cursor;
   mongoc_read_prefs_t *read_prefs;
   uint32_t dbname_len;
   const bson_t *doc;
   bson_t legacy_filter;
   bson_iter_t iter;
   const char *name;
   const char *col_filter;
   bson_t q = BSON_INITIALIZER;
   bson_t *ret = NULL;
   bson_t col_array = BSON_INITIALIZER;
   const char *key;
   char keystr[16];
   uint32_t n_cols = 0;

   BSON_ASSERT (database);

   col = mongoc_client_get_collection (database->client,
                                       database->name,
                                       "system.namespaces");

   BSON_ASSERT (col);

   dbname_len = (uint32_t)strlen (database->name);

   /* Filtering on name needs to be handled differently for old servers. */
   if (filter && bson_iter_init_find (&iter, filter, "name")) {
      /* on legacy servers, this must be a string (i.e. not a regex) */
      if (!BSON_ITER_HOLDS_UTF8 (&iter)) {
         bson_set_error (error,
                         MONGOC_ERROR_NAMESPACE,
                         MONGOC_ERROR_NAMESPACE_INVALID_FILTER_TYPE,
                         "On legacy servers, a filter on name can only be a string.");
         goto cleanup_filter;
      }
      BSON_ASSERT (BSON_ITER_HOLDS_UTF8 (&iter));
      col_filter = bson_iter_utf8 (&iter, NULL);
      bson_init (&legacy_filter);
      bson_copy_to_excluding_noinit (filter, &legacy_filter, "name", NULL);
      /* We must db-qualify filters on name. */
      bson_string_t *buf = bson_string_new (database->name);
      bson_string_append_c (buf, '.');
      bson_string_append (buf, col_filter);
      BSON_APPEND_UTF8 (&legacy_filter, "name", buf->str);
      bson_string_free (buf, true);
      filter = &legacy_filter;
   }

   read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY);

   cursor = mongoc_collection_find (col, MONGOC_QUERY_NONE, 0, 0, 0,
                                    filter ? filter : &q, NULL, read_prefs);

   ret = bson_new();

   BSON_APPEND_ARRAY_BEGIN (ret, "collections", &col_array);

   while (mongoc_cursor_more (cursor) &&
          !mongoc_cursor_error (cursor, error)) {
      if (mongoc_cursor_next (cursor, &doc)) {
         /* 2 gotchas here.
          * 1. need to ignore any system collections (prefixed with $)
          * 2. need to remove the database name from the collection so that clients
          *    don't need to specialize their logic for old versions of the server.
          */
         if (bson_iter_init_find (&iter, doc, "name") &&
             BSON_ITER_HOLDS_UTF8 (&iter) &&
             (name = bson_iter_utf8 (&iter, NULL)) &&
             !strchr (name, '$') &&
             (0 == strncmp (name, database->name, dbname_len))) {
            bson_t nprefix_col = BSON_INITIALIZER;
            bson_copy_to_excluding_noinit (doc, &nprefix_col, "name", NULL);
            BSON_APPEND_UTF8 (&nprefix_col, "name", name + (dbname_len + 1));  /* +1 for the '.' */
            /* need to construct a key for this array element. */
            bson_uint32_to_string(n_cols, &key, keystr, sizeof (keystr));
            BSON_APPEND_DOCUMENT (&col_array, key, &nprefix_col);
            ++n_cols;
         }
      }
   }

   bson_append_array_end (ret, &col_array);

   mongoc_cursor_destroy (cursor);
   mongoc_read_prefs_destroy (read_prefs);
 cleanup_filter:
   mongoc_collection_destroy (col);
   return ret;
}
Пример #24
0
static bool appendBsonValue(bson_t *bson, const QString &key, const QVariant &value)
{
    const QLatin1String oidkey("_id");
    bool ok = true;
    int type = value.type();

    // _id
    if (key == oidkey) {
        QByteArray oidVal = value.toByteArray();
        if (oidVal.length() == 24) {
            // ObjectId
            bson_oid_t oid;
            bson_oid_init_from_string(&oid, oidVal.data());
            BSON_APPEND_OID(bson, oidkey.latin1(), &oid);
        } else {
            int id = value.toInt(&ok);
            if (ok) {
                BSON_APPEND_INT32(bson, oidkey.latin1(), id);
            } else {
                BSON_APPEND_UTF8(bson, oidkey.latin1(), value.toString().toUtf8().data());
            }
        }
        return true;
    }

    switch (type) {
    case QVariant::Int:
        BSON_APPEND_INT32(bson, qPrintable(key), value.toInt(&ok));
        break;

    case QVariant::String:
        BSON_APPEND_UTF8(bson, qPrintable(key), value.toString().toUtf8().data());
        break;

    case QVariant::LongLong:
        BSON_APPEND_INT64(bson, qPrintable(key), value.toLongLong(&ok));
        break;

    case QVariant::Map:
        BSON_APPEND_DOCUMENT(bson, qPrintable(key), (const bson_t *)TBson::toBson(value.toMap()).constData());
        break;

    case QVariant::Double:
        BSON_APPEND_DOUBLE(bson, qPrintable(key), value.toDouble(&ok));
        break;

    case QVariant::Bool:
        BSON_APPEND_BOOL(bson, qPrintable(key), value.toBool());
        break;

    case QVariant::DateTime: {
#if QT_VERSION >= 0x040700
        BSON_APPEND_DATE_TIME(bson, qPrintable(key), value.toDateTime().toMSecsSinceEpoch());
#else
        QDateTime utcDate = value.toDateTime().toUTC();
        qint64 ms = utcDate.time().msec();
        qint64 tm = utcDate.toTime_t() * 1000LL;
        if (ms > 0) {
          tm += ms;
        }
        BSON_APPEND_DATE_TIME(bson, qPrintable(key), tm);
#endif
        break; }

    case QVariant::ByteArray: {
        QByteArray ba = value.toByteArray();
        BSON_APPEND_BINARY(bson, qPrintable(key), BSON_SUBTYPE_BINARY, (uint8_t *)ba.constData(), ba.length());
        break; }

    case QVariant::List:  // FALL THROUGH
    case QVariant::StringList: {
        bson_t child;
        BSON_APPEND_ARRAY_BEGIN(bson, qPrintable(key), &child);

        int i = 0;
        for (auto &var : value.toList()) {
            appendBsonValue(&child, QString::number(i++), var);
        }
        bson_append_array_end(bson, &child);
        break; }

    case QVariant::Invalid:
        BSON_APPEND_UNDEFINED(bson, qPrintable(key));
        break;

    default:
        tError("toBson() failed to convert  name:%s  type:%d", qPrintable(key), type);
        ok = false;
        break;
    }
    return ok;
}
Пример #25
0
void switch_value(lua_State *L, int index, bson_t* bson, int level, const char* key)
{
    switch(lua_type(L, index))
    {
      case LUA_TTABLE:
      {
        int is_a=is_array(L, index);

        if (is_a)
        {
          bson_t child;
          //start array
          BSON_APPEND_ARRAY_BEGIN(bson, key, &child);
          iterate_table(L, index, &child, 0, level+1, NULL);
          bson_append_array_end(bson, &child);
        }
        else
        {
          bson_t child;
          //start map
          BSON_APPEND_DOCUMENT_BEGIN(bson, key, &child);
          iterate_table(L, index, &child, 1, level+1, NULL);
          bson_append_document_end(bson, &child);
        }
        break;
      }

      case LUA_TNIL:
      {
        BSON_APPEND_NULL(bson, key);
        break;
      }

      case LUA_TNUMBER:
      {
        BSON_APPEND_DOUBLE(bson, key, lua_tonumber(L, index));
        break;
      }

      case LUA_TBOOLEAN:
      {
        BSON_APPEND_BOOL(bson, key, lua_toboolean(L, index));
        break;
      }

      case LUA_TSTRING:
      {
        BSON_APPEND_UTF8(bson, key, lua_tostring(L, index));
        break;
      }

      case LUA_TUSERDATA:
      {
        // switch userdata type
        if (luaL_checkudata_ex(L, index, REGEX_METATABLE))
        {
          cbson_regex_t* regex = check_cbson_regex(L, index);

          BSON_APPEND_REGEX (bson, key, regex->regex, regex->options);
        }
        else if (luaL_checkudata_ex(L, index, OID_METATABLE))
        {
          cbson_oid_t* oid = check_cbson_oid(L, index);
          bson_oid_t boid;

          bson_oid_init_from_string (&boid, oid->oid);

          BSON_APPEND_OID (bson, key, &boid);
        }
        else if (luaL_checkudata_ex(L, index, BINARY_METATABLE))
        {
          cbson_binary_t* bin = check_cbson_binary(L, index);

          size_t binary_len = b64_pton (bin->data, NULL, 0);
          unsigned char* buf=malloc(binary_len+1);
          b64_pton(bin->data, buf, binary_len+1);

          BSON_APPEND_BINARY(bson, key, bin->type, buf, binary_len);

          free(buf);
        }
        else if (luaL_checkudata_ex(L, index, SYMBOL_METATABLE))
        {
          cbson_symbol_t* sym = check_cbson_symbol(L, index);

          BSON_APPEND_SYMBOL(bson, key, sym->symbol);
        }
        else if (luaL_checkudata_ex(L, index, REF_METATABLE))
        {
          cbson_ref_t* ref = check_cbson_ref(L, index);

          bson_oid_t boid;
          bson_oid_init_from_string (&boid, ref->id);

          BSON_APPEND_DBPOINTER(bson, key, ref->ref, &boid);
        }
        else if (luaL_checkudata_ex(L, index, MINKEY_METATABLE))
        {
          check_cbson_minkey(L, index);
          BSON_APPEND_MINKEY(bson, key);
        }
        else if (luaL_checkudata_ex(L, index, MAXKEY_METATABLE))
        {
          check_cbson_maxkey(L, index);
          BSON_APPEND_MAXKEY(bson, key);
        }
        else if (luaL_checkudata_ex(L, index, TIMESTAMP_METATABLE))
        {
          cbson_timestamp_t* time = check_cbson_timestamp(L, index);
          BSON_APPEND_TIMESTAMP(bson, key, time->timestamp, time->increment);
        }
        else if (luaL_checkudata_ex(L, index, INT64_METATABLE) || luaL_checkudata_ex(L, index, UINT64_METATABLE))
        {
          cbson_int64_t i = cbson_int64_check(L, index);
          if (i < INT32_MIN || i > INT32_MAX)
          {
            BSON_APPEND_INT64(bson, key, i);
          }
          else
          {
            BSON_APPEND_INT32(bson, key, (int32_t)i);
          }
        }
        else if (luaL_checkudata_ex(L, index, CODE_METATABLE))
        {
          cbson_code_t* code = check_cbson_code(L, index);
          BSON_APPEND_CODE(bson, key, code->code);
        }
        else if (luaL_checkudata_ex(L, index, CODEWSCOPE_METATABLE))
        {
          cbson_codewscope_t* code = check_cbson_codewscope(L, index);
          BSON_APPEND_CODE_WITH_SCOPE(bson, key, code->code, NULL);
        }
        else if (luaL_checkudata_ex(L, index, UNDEFINED_METATABLE))
        {
          check_cbson_undefined(L, index);
          BSON_APPEND_UNDEFINED(bson, key);
        }
        else if (luaL_checkudata_ex(L, index, DATE_METATABLE))
        {
          BSON_APPEND_DATE_TIME(bson, key, cbson_date_check(L, index));
        }
        break;
      }
      case LUA_TFUNCTION:
      case LUA_TTHREAD:
      case LUA_TLIGHTUSERDATA:
      default:
        break; // or bail out?
    }

}
Пример #26
0
/* construct the aggregate command in cmd. looks like one of the following:
 * for a collection change stream:
 *   { aggregate: collname, pipeline: [], cursor: { batchSize: x } }
 * for a database change stream:
 *   { aggregate: 1, pipeline: [], cursor: { batchSize: x } }
 * for a client change stream:
 *   { aggregate: 1, pipeline: [{$changeStream: {allChangesForCluster: true}}],
 *     cursor: { batchSize: x } }
 */
static void
_make_command (mongoc_change_stream_t *stream, bson_t *command)
{
   bson_iter_t iter;
   bson_t change_stream_stage; /* { $changeStream: <change_stream_doc> } */
   bson_t change_stream_doc;
   bson_t pipeline;
   bson_t cursor_doc;

   bson_init (command);
   if (stream->change_stream_type == MONGOC_CHANGE_STREAM_COLLECTION) {
      bson_append_utf8 (
         command, "aggregate", 9, stream->coll, (int) strlen (stream->coll));
   } else {
      bson_append_int32 (command, "aggregate", 9, 1);
   }

   bson_append_array_begin (command, "pipeline", 8, &pipeline);

   /* append the $changeStream stage. */
   bson_append_document_begin (&pipeline, "0", 1, &change_stream_stage);
   bson_append_document_begin (
      &change_stream_stage, "$changeStream", 13, &change_stream_doc);
   bson_concat (&change_stream_doc, stream->full_document);
   if (!bson_empty (&stream->resume_token)) {
      bson_concat (&change_stream_doc, &stream->resume_token);
   }
   /* Change streams spec: "startAtOperationTime and resumeAfter are mutually
    * exclusive; if both startAtOperationTime and resumeAfter are set, the
    * server will return an error. Drivers MUST NOT throw a custom error, and
    * MUST defer to the server error." */
   if (!_mongoc_timestamp_empty (&stream->operation_time)) {
      _mongoc_timestamp_append (
         &stream->operation_time, &change_stream_doc, "startAtOperationTime");
   }

   if (stream->change_stream_type == MONGOC_CHANGE_STREAM_CLIENT) {
      bson_append_bool (&change_stream_doc, "allChangesForCluster", 20, true);
   }
   bson_append_document_end (&change_stream_stage, &change_stream_doc);
   bson_append_document_end (&pipeline, &change_stream_stage);

   /* Append user pipeline if it exists */
   if (bson_iter_init_find (&iter, &stream->pipeline_to_append, "pipeline") &&
       BSON_ITER_HOLDS_ARRAY (&iter)) {
      bson_iter_t child_iter;
      uint32_t key_int = 1;
      char buf[16];
      const char *key_str;

      BSON_ASSERT (bson_iter_recurse (&iter, &child_iter));
      while (bson_iter_next (&child_iter)) {
         /* the user pipeline may consist of invalid stages or non-documents.
          * append anyway, and rely on the server error. */
         size_t keyLen =
            bson_uint32_to_string (key_int, &key_str, buf, sizeof (buf));
         bson_append_value (
            &pipeline, key_str, (int) keyLen, bson_iter_value (&child_iter));
         ++key_int;
      }
   }

   bson_append_array_end (command, &pipeline);

   /* Add batch size if needed */
   bson_append_document_begin (command, "cursor", 6, &cursor_doc);
   if (stream->batch_size > 0) {
      bson_append_int32 (&cursor_doc, "batchSize", 9, stream->batch_size);
   }
   bson_append_document_end (command, &cursor_doc);
}
Пример #27
0
/**
 * mongoc_database_add_user:
 * @database: A #mongoc_database_t.
 * @username: A string containing the username.
 * @password: (allow-none): A string containing password, or NULL.
 * @roles: (allow-none): An optional bson_t of roles.
 * @custom_data: (allow-none): An optional bson_t of data to store.
 * @error: (out) (allow-none): A location for a bson_error_t or %NULL.
 *
 * Creates a new user with access to @database.
 *
 * Returns: None.
 * Side effects: None.
 */
bool
mongoc_database_add_user (mongoc_database_t *database,
                          const char        *username,
                          const char        *password,
                          const bson_t      *roles,
                          const bson_t      *custom_data,
                          bson_error_t      *error)
{
   bson_error_t lerror;
   bson_t cmd;
   bson_t ar;
   char *input;
   char *hashed_password;
   bool ret = false;

   ENTRY;

   BSON_ASSERT (database);
   BSON_ASSERT (username);

   /*
    * CDRIVER-232:
    *
    * Perform a (slow and tedious) round trip to mongod to determine if
    * we can safely call createUser. Otherwise, we will fallback and
    * perform legacy insertion into users collection.
    */
   bson_init (&cmd);
   BSON_APPEND_UTF8 (&cmd, "usersInfo", username);
   ret = mongoc_database_command_simple (database, &cmd, NULL, NULL, &lerror);
   bson_destroy (&cmd);

   if (!ret && (lerror.code == MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND)) {
      ret = mongoc_database_add_user_legacy (database, username, password, error);
   } else if (ret || (lerror.code == 13)) {
      /* usersInfo succeeded or failed with auth err, we're on modern mongod */
      input = bson_strdup_printf ("%s:mongo:%s", username, password);
      hashed_password = _mongoc_hex_md5 (input);
      bson_free (input);

      bson_init (&cmd);
      BSON_APPEND_UTF8 (&cmd, "createUser", username);
      BSON_APPEND_UTF8 (&cmd, "pwd", hashed_password);
      BSON_APPEND_BOOL (&cmd, "digestPassword", false);
      if (custom_data) {
         BSON_APPEND_DOCUMENT (&cmd, "customData", custom_data);
      }
      if (roles) {
         BSON_APPEND_ARRAY (&cmd, "roles", roles);
      } else {
         bson_append_array_begin (&cmd, "roles", 5, &ar);
         bson_append_array_end (&cmd, &ar);
      }

      ret = mongoc_database_command_simple (database, &cmd, NULL, NULL, error);

      bson_free (hashed_password);
      bson_destroy (&cmd);
   } else if (error) {
      memcpy (error, &lerror, sizeof *error);
   }

   RETURN (ret);
}
Пример #28
0
static void
ha_replica_set_configure (ha_replica_set_t *replica_set,
                          ha_node_t        *primary)
{
   mongoc_database_t *database;
   mongoc_client_t *client;
   mongoc_cursor_t *cursor;
   const bson_t *doc;
   bson_error_t error;
   bson_iter_t iter;
   ha_node_t *node;
   bson_t ar;
   bson_t cmd;
   bson_t config;
   bson_t member;
   char *str;
   char *uristr;
   char hoststr[32];
   char key[8];
   int i = 0;

   uristr = bson_strdup_printf("mongodb://127.0.0.1:%hu/", primary->port);
   client = mongoc_client_new(uristr);
#ifdef MONGOC_ENABLE_SSL
   if (replica_set->ssl_opt) {
      mongoc_client_set_ssl_opts(client, replica_set->ssl_opt);
   }
#endif
   bson_free(uristr);

   bson_init(&cmd);
   bson_append_document_begin(&cmd, "replSetInitiate", -1, &config);
   bson_append_utf8(&config, "_id", 3, replica_set->name, -1);
   bson_append_array_begin(&config, "members", -1, &ar);
   for (node = replica_set->nodes; node; node = node->next) {
      snprintf(key, sizeof key, "%u", i);
      key[sizeof key - 1] = '\0';

      snprintf(hoststr, sizeof hoststr, "127.0.0.1:%hu", node->port);
      hoststr[sizeof hoststr - 1] = '\0';

      bson_append_document_begin(&ar, key, -1, &member);
      bson_append_int32(&member, "_id", -1, i);
      bson_append_utf8(&member, "host", -1, hoststr, -1);
      bson_append_bool(&member, "arbiterOnly", -1, node->is_arbiter);
      bson_append_document_end(&ar, &member);

      i++;
   }
   bson_append_array_end(&config, &ar);
   bson_append_document_end(&cmd, &config);

   str = bson_as_json(&cmd, NULL);
   MONGOC_DEBUG("Config: %s", str);
   bson_free(str);

   database = mongoc_client_get_database(client, "admin");

again:
   cursor = mongoc_database_command(database,
                                    MONGOC_QUERY_NONE,
                                    0,
                                    1,
                                    &cmd,
                                    NULL,
                                    NULL);

   while (mongoc_cursor_next(cursor, &doc)) {
      str = bson_as_json(doc, NULL);
      MONGOC_DEBUG("Reply: %s", str);
      bson_free(str);
      if (bson_iter_init_find(&iter, doc, "ok") &&
          bson_iter_as_bool(&iter)) {
         goto cleanup;
      }
   }

   if (mongoc_cursor_error(cursor, &error)) {
      mongoc_cursor_destroy(cursor);
      MONGOC_WARNING("%s: Retrying in 1 second.", error.message);
      sleep(1);
      goto again;
   }

cleanup:
   mongoc_cursor_destroy(cursor);
   mongoc_database_destroy(database);
   mongoc_client_destroy(client);
   bson_destroy(&cmd);
}
Пример #29
0
void
_mongoc_matcher_op_to_bson (mongoc_matcher_op_t *op,   /* IN */
                            bson_t              *bson) /* IN */
{
   const char *str;
   bson_t child;
   bson_t child2;

   BSON_ASSERT (op);
   BSON_ASSERT (bson);

   switch (op->base.opcode) {
   case MONGOC_MATCHER_OPCODE_EQ:
      bson_append_iter (bson, op->compare.path, -1, &op->compare.iter);
      break;
   case MONGOC_MATCHER_OPCODE_GT:
   case MONGOC_MATCHER_OPCODE_GTE:
   case MONGOC_MATCHER_OPCODE_IN:
   case MONGOC_MATCHER_OPCODE_LT:
   case MONGOC_MATCHER_OPCODE_LTE:
   case MONGOC_MATCHER_OPCODE_NE:
   case MONGOC_MATCHER_OPCODE_NIN:
      switch ((int)op->base.opcode) {
      case MONGOC_MATCHER_OPCODE_GT:
         str = "$gt";
         break;
      case MONGOC_MATCHER_OPCODE_GTE:
         str = "$gte";
         break;
      case MONGOC_MATCHER_OPCODE_IN:
         str = "$in";
         break;
      case MONGOC_MATCHER_OPCODE_LT:
         str = "$lt";
         break;
      case MONGOC_MATCHER_OPCODE_LTE:
         str = "$lte";
         break;
      case MONGOC_MATCHER_OPCODE_NE:
         str = "$ne";
         break;
      case MONGOC_MATCHER_OPCODE_NIN:
         str = "$nin";
         break;
      default:
         str = "???";
         break;
      }
      bson_append_document_begin (bson, op->compare.path, -1, &child);
      bson_append_iter (&child, str, -1, &op->compare.iter);
      bson_append_document_end (bson, &child);
      break;
   case MONGOC_MATCHER_OPCODE_OR:
   case MONGOC_MATCHER_OPCODE_AND:
   case MONGOC_MATCHER_OPCODE_NOR:
      if (op->base.opcode == MONGOC_MATCHER_OPCODE_OR) {
         str = "$or";
      } else if (op->base.opcode == MONGOC_MATCHER_OPCODE_AND) {
         str = "$and";
      } else if (op->base.opcode == MONGOC_MATCHER_OPCODE_NOR) {
         str = "$nor";
      } else {
         BSON_ASSERT (false);
         str = NULL;
      }
      bson_append_array_begin (bson, str, -1, &child);
      bson_append_document_begin (&child, "0", 1, &child2);
      _mongoc_matcher_op_to_bson (op->logical.left, &child2);
      bson_append_document_end (&child, &child2);
      if (op->logical.right) {
         bson_append_document_begin (&child, "1", 1, &child2);
         _mongoc_matcher_op_to_bson (op->logical.right, &child2);
         bson_append_document_end (&child, &child2);
      }
      bson_append_array_end (bson, &child);
      break;
   case MONGOC_MATCHER_OPCODE_NOT:
      bson_append_document_begin (bson, op->not.path, -1, &child);
      bson_append_document_begin (&child, "$not", 4, &child2);
      _mongoc_matcher_op_to_bson (op->not.child, &child2);
      bson_append_document_end (&child, &child2);
      bson_append_document_end (bson, &child);
      break;
   case MONGOC_MATCHER_OPCODE_EXISTS:
      BSON_APPEND_BOOL (bson, "$exists", op->exists.exists);
      break;
   case MONGOC_MATCHER_OPCODE_TYPE:
      BSON_APPEND_INT32 (bson, "$type", (int)op->type.type);
      break;
   default:
      BSON_ASSERT (false);
      break;
   }
}
Пример #30
0
bool BsonAppendFinishArray(BSON *b, BSON* c)
{
    return bson_append_array_end(b, c);
}