Ejemplo n.º 1
0
bool
bson_find_create_table (bson_t      *bson_schema,
                        const char  *table_name,
                        bson_iter_t *iter_col)
{
    bson_iter_t iter_json, iter_ary, iter_sql, iter_table_prop;

    bson_iter_init_find (&iter_json, bson_schema, "json") || DIE;
    BSON_ITER_HOLDS_ARRAY (&iter_json) || DIE;
    bson_iter_recurse (&iter_json, &iter_ary) || DIE;
    while (bson_iter_next (&iter_ary)) {
        (BSON_ITER_HOLDS_DOCUMENT (&iter_ary) || DIE);
        bson_iter_recurse (&iter_ary, &iter_sql) || DIE;
        if (bson_iter_find (&iter_sql, "create_table") &&
            (BSON_ITER_HOLDS_DOCUMENT (&iter_sql) || DIE) &&
            (bson_iter_recurse (&iter_sql, &iter_table_prop) || DIE) &&
            (bson_iter_find (&iter_table_prop, "table_name") || DIE) &&
            (BSON_ITER_HOLDS_UTF8 (&iter_table_prop) || DIE) &&
            (strcmp (bson_iter_utf8 (&iter_table_prop, NULL), table_name) == 0) &&
            (bson_iter_find (&iter_table_prop, "columns") || DIE) &&
            (BSON_ITER_HOLDS_ARRAY (&iter_table_prop) || DIE)) {
            bson_iter_recurse (&iter_table_prop, iter_col) || DIE;
            return true;
        }
    }
    return (false);
}
/*
 * Start iterating the reply to an "aggregate", "find", "getMore" etc. command:
 *
 *    {cursor: {id: 1234, ns: "db.collection", firstBatch: [...]}}
 */
bool
_mongoc_cursor_cursorid_start_batch (mongoc_cursor_t *cursor)
{
   mongoc_cursor_cursorid_t *cid;
   bson_iter_t iter;
   bson_iter_t child;
   const char *ns;
   uint32_t nslen;

   cid = (mongoc_cursor_cursorid_t *)cursor->iface_data;

   BSON_ASSERT (cid);

   if (bson_iter_init_find (&iter, &cid->array, "cursor") &&
       BSON_ITER_HOLDS_DOCUMENT (&iter) &&
       bson_iter_recurse (&iter, &child)) {
      while (bson_iter_next (&child)) {
         if (BSON_ITER_IS_KEY (&child, "id")) {
            cursor->rpc.reply.cursor_id = bson_iter_as_int64 (&child);
         } else if (BSON_ITER_IS_KEY (&child, "ns")) {
            ns = bson_iter_utf8 (&child, &nslen);
            _mongoc_set_cursor_ns (cursor, ns, nslen);
         } else if (BSON_ITER_IS_KEY (&child, "firstBatch") ||
                    BSON_ITER_IS_KEY (&child, "nextBatch")) {
            if (BSON_ITER_HOLDS_ARRAY (&child) &&
                bson_iter_recurse (&child, &cid->batch_iter)) {
               cid->in_batch = true;
            }
         }
      }
   }

   return cid->in_batch;
}
Ejemplo n.º 3
0
void _aggregate_recurse_fill(bson_iter_t *iter, bson_t* new_doc, bson_t* existing_aggregate_doc, bson_t* merged_aggregate_doc, const char *key) {
    bson_iter_t child_iter;
    bson_t child_doc;

    while (bson_iter_next (iter)) {
        int new_key_length = strlen(bson_iter_key(iter));
        if (strcmp("", key) != 0) {
            new_key_length += strlen(key) + 1;
        }

        char new_key[new_key_length];
        if (strcmp("", key) == 0) {
            strcpy(new_key, bson_iter_key(iter));
        } else {
            strcpy(new_key, key);
            strcat(new_key, ".");
            strcat(new_key, bson_iter_key(iter));
        }

        if (strcmp("_id", new_key) == 0) {
            bson_value_t *existing_id = _aggregate_get_value_at_key(existing_aggregate_doc, "_id");
            bson_append_value(merged_aggregate_doc, "_id", -1, existing_id);
            continue;
        }

        if (BSON_ITER_HOLDS_DOCUMENT (iter)) {

            const char *agg_key = NULL;
            const bson_value_t *agg_field = NULL;

            if (bson_iter_recurse (iter, &child_iter)) {
                if (bson_iter_next (&child_iter) &&
                    _aggregate_is_agg_operator(bson_iter_key(&child_iter))) {
                    agg_key = bson_iter_key(&child_iter);
                    agg_field = bson_iter_value(&child_iter);
                }

                if (agg_key && !bson_iter_next (&child_iter)) {
                    bson_value_t *existing_value = _aggregate_get_value_at_key(existing_aggregate_doc, new_key);
                    bson_value_t *new_doc_value = _aggregate_get_value_at_key(new_doc, (*agg_field).value.v_utf8.str + 1);
                    bson_value_t * agg_result = _aggregate(existing_value, new_doc_value, agg_key);
                    bson_append_value(merged_aggregate_doc, bson_iter_key(iter), -1, agg_result);
                    continue;

                }
            }

            bson_append_document_begin (merged_aggregate_doc, bson_iter_key(iter), -1, &child_doc);

            if (bson_iter_recurse (iter, &child_iter)) {
                _aggregate_recurse_fill (&child_iter, new_doc, existing_aggregate_doc, &child_doc, new_key);
            }

            bson_append_document_end (merged_aggregate_doc, &child_doc);
        } else {
            bson_append_value(merged_aggregate_doc, bson_iter_key(iter), -1, bson_iter_value(iter));
        }
    }
}
Ejemplo n.º 4
0
void
ha_replica_set_wait_for_healthy (ha_replica_set_t *replica_set)
{
   bson_iter_t iter;
   bson_iter_t ar;
   bson_iter_t member;
   const char *stateStr;
   bson_t status;

again:
   sleep(1);

   if (!ha_replica_set_get_status(replica_set, &status)) {
      MONGOC_INFO("Failed to get replicaSet status. "
                  "Sleeping 1 second.");
      goto again;
   }

#if 0
   {
      char *str;

      str = bson_as_json(&status, NULL);
      printf("%s\n", str);
      bson_free(str);
   }
#endif

   if (!bson_iter_init_find(&iter, &status, "members") ||
       !BSON_ITER_HOLDS_ARRAY(&iter) ||
       !bson_iter_recurse(&iter, &ar)) {
      bson_destroy(&status);
      MONGOC_INFO("ReplicaSet has not yet come online. "
                  "Sleeping 1 second.");
      goto again;
   }

   while (bson_iter_next(&ar)) {
      if (BSON_ITER_HOLDS_DOCUMENT(&ar) &&
          bson_iter_recurse(&ar, &member) &&
          bson_iter_find(&member, "stateStr") &&
          (stateStr = bson_iter_utf8(&member, NULL))) {
         if (!!strcmp(stateStr, "PRIMARY") &&
             !!strcmp(stateStr, "SECONDARY") &&
             !!strcmp(stateStr, "ARBITER")) {
            bson_destroy(&status);
            MONGOC_INFO("Found unhealthy node. Sleeping 1 second.");
            goto again;
         }
      }
   }

   bson_destroy(&status);
}
Ejemplo n.º 5
0
static void
_test_topology_events (bool pooled)
{
   mongoc_client_t *client;
   mongoc_client_pool_t *pool = NULL;
   context_t context;
   bool r;
   bson_error_t error;
   bson_iter_t events_iter;
   bson_iter_t event_iter;
   uint32_t i;

   context_init (&context);

   if (pooled) {
      pool = test_framework_client_pool_new ();
      pool_set_topology_event_callbacks (pool, &context);
      client = mongoc_client_pool_pop (pool);
   } else {
      client = test_framework_client_new ();
      client_set_topology_event_callbacks (client, &context);
   }

   r = mongoc_client_command_simple (client, "admin", tmp_bson ("{'ping': 1}"),
                                     NULL, NULL, &error);
   ASSERT_OR_PRINT (r, error);

   if (pooled) {
      mongoc_client_pool_push (pool, client);
      mongoc_client_pool_destroy (pool);
   } else {
      mongoc_client_destroy (client);
   }

   /* first event is topology opening */
   bson_iter_init (&events_iter, &context.events);
   bson_iter_next (&events_iter);
   ASSERT (bson_iter_recurse (&events_iter, &event_iter));
   ASSERT (bson_iter_find (&event_iter, "topology_opening_event"));

   /* last event is topology closed */
   for (i = 1; i < context.n_events; i++) {
      ASSERT (bson_iter_next (&events_iter));
   }

   ASSERT (bson_iter_recurse (&events_iter, &event_iter));
   ASSERT (bson_iter_find (&event_iter, "topology_closed_event"));

   /* no more events */
   ASSERT (!bson_iter_next (&events_iter));

   context_destroy (&context);
}
Ejemplo n.º 6
0
int32_t
_mongoc_write_result_merge_arrays (uint32_t offset,
                                   mongoc_write_result_t *result, /* IN */
                                   bson_t *dest,                  /* IN */
                                   bson_iter_t *iter)             /* IN */
{
   const bson_value_t *value;
   bson_iter_t ar;
   bson_iter_t citer;
   int32_t idx;
   int32_t count = 0;
   int32_t aridx;
   bson_t child;
   const char *keyptr = NULL;
   char key[12];
   int len;

   ENTRY;

   BSON_ASSERT (result);
   BSON_ASSERT (dest);
   BSON_ASSERT (iter);
   BSON_ASSERT (BSON_ITER_HOLDS_ARRAY (iter));

   aridx = bson_count_keys (dest);

   if (bson_iter_recurse (iter, &ar)) {
      while (bson_iter_next (&ar)) {
         if (BSON_ITER_HOLDS_DOCUMENT (&ar) &&
             bson_iter_recurse (&ar, &citer)) {
            len =
               (int) bson_uint32_to_string (aridx++, &keyptr, key, sizeof key);
            bson_append_document_begin (dest, keyptr, len, &child);
            while (bson_iter_next (&citer)) {
               if (BSON_ITER_IS_KEY (&citer, "index")) {
                  idx = bson_iter_int32 (&citer) + offset;
                  BSON_APPEND_INT32 (&child, "index", idx);
               } else {
                  value = bson_iter_value (&citer);
                  BSON_APPEND_VALUE (&child, bson_iter_key (&citer), value);
               }
            }
            bson_append_document_end (dest, &child);
            count++;
         }
      }
   }

   RETURN (count);
}
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);
}
Ejemplo n.º 8
0
/*
 * If error is not set, set code from first document in array like
 * [{"code": 64, "errmsg": "duplicate"}, ...]. Format the error message
 * from all errors in array.
 */
static void
_set_error_from_response (bson_t *bson_array,
                          mongoc_error_domain_t domain,
                          const char *error_type,
                          bson_error_t *error /* OUT */)
{
   bson_iter_t array_iter;
   bson_iter_t doc_iter;
   bson_string_t *compound_err;
   const char *errmsg = NULL;
   int32_t code = 0;
   uint32_t n_keys, i;

   compound_err = bson_string_new (NULL);
   n_keys = bson_count_keys (bson_array);
   if (n_keys > 1) {
      bson_string_append_printf (
         compound_err, "Multiple %s errors: ", error_type);
   }

   if (!bson_empty0 (bson_array) && bson_iter_init (&array_iter, bson_array)) {
      /* get first code and all error messages */
      i = 0;

      while (bson_iter_next (&array_iter)) {
         if (BSON_ITER_HOLDS_DOCUMENT (&array_iter) &&
             bson_iter_recurse (&array_iter, &doc_iter)) {
            /* parse doc, which is like {"code": 64, "errmsg": "duplicate"} */
            while (bson_iter_next (&doc_iter)) {
               /* use the first error code we find */
               if (BSON_ITER_IS_KEY (&doc_iter, "code") && code == 0) {
                  code = bson_iter_int32 (&doc_iter);
               } else if (BSON_ITER_IS_KEY (&doc_iter, "errmsg")) {
                  errmsg = bson_iter_utf8 (&doc_iter, NULL);

                  /* build message like 'Multiple write errors: "foo", "bar"' */
                  if (n_keys > 1) {
                     bson_string_append_printf (compound_err, "\"%s\"", errmsg);
                     if (i < n_keys - 1) {
                        bson_string_append (compound_err, ", ");
                     }
                  } else {
                     /* single error message */
                     bson_string_append (compound_err, errmsg);
                  }
               }
            }

            i++;
         }
      }

      if (code && compound_err->len) {
         bson_set_error (
            error, domain, (uint32_t) code, "%s", compound_err->str);
      }
   }

   bson_string_free (compound_err, true);
}
bool
_mongoc_cursor_array_prime (mongoc_cursor_t *cursor)
{
   bool ret = true;
   mongoc_cursor_array_t *arr;
   bson_iter_t iter;

   ENTRY;

   arr = (mongoc_cursor_array_t *)cursor->iface_data;
   if (!arr->has_array) {
      arr->has_array = true;

      ret = _mongoc_cursor_next (cursor, &arr->result);

      if (!(ret &&
            bson_iter_init_find (&iter, arr->result, arr->field_name) &&
            BSON_ITER_HOLDS_ARRAY (&iter) &&
            bson_iter_recurse (&iter, &arr->iter))) {
         ret = false;
      }
   }

   return ret;
}
Ejemplo n.º 10
0
/* {{{ proto array WriteResult::getUpsertedIds()
   Returns the identifiers generated by the server for upsert operations. */
PHP_METHOD(WriteResult, getUpsertedIds)
{
	bson_iter_t iter, child;
	php_phongo_writeresult_t *intern;
	SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used)


	intern = Z_WRITERESULT_OBJ_P(getThis());

	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}


	array_init(return_value);

	if (bson_iter_init_find(&iter, intern->reply, "upserted") && BSON_ITER_HOLDS_ARRAY(&iter) && bson_iter_recurse(&iter, &child)) {
		while (bson_iter_next(&child)) {
			int32_t index;
			bson_iter_t outer;

			if (!BSON_ITER_HOLDS_DOCUMENT(&child) || !bson_iter_recurse(&child, &outer)) {
				continue;
			}
			if (!bson_iter_find(&outer, "index") || !BSON_ITER_HOLDS_INT32(&outer)) {
				continue;
			}

			index = bson_iter_int32(&outer);

			if (!bson_iter_find(&outer, "_id")) {
				continue;
			}

			if (BSON_ITER_HOLDS_OID(&outer)) {
#if PHP_VERSION_ID >= 70000
				zval zid;

				php_phongo_objectid_new_from_oid(&zid, bson_iter_oid(&outer) TSRMLS_CC);
				add_index_zval(return_value, index, &zid);
#else
				zval *zid = NULL;
				MAKE_STD_ZVAL(zid);

				php_phongo_objectid_new_from_oid(zid, bson_iter_oid(&outer) TSRMLS_CC);
				add_index_zval(return_value, index, zid);
#endif
			} else if (BSON_ITER_HOLDS_INT32(&outer)) {
				int32_t val = bson_iter_int32(&outer);

				add_index_long(return_value, index, val);
			} else if (BSON_ITER_HOLDS_INT64(&outer)) {
				int64_t val = bson_iter_int64(&outer);

				ADD_INDEX_INT64(return_value, index, val);
			}
		}
	}
}
Ejemplo n.º 11
0
static void
test_topology_events_disabled (void)
{
   mongoc_client_t *client;
   context_t context;
   bool r;
   bson_error_t error;
   bson_iter_t events_iter;
   bson_iter_t event_iter;
   uint32_t i;

   context_init (&context);

   client = test_framework_client_new ();
   client_set_topology_event_callbacks (client, &context);

   r = mongoc_client_command_simple (
      client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &error);
   ASSERT_OR_PRINT (r, error);

   /* disable callbacks before destroying so we don't see a topology closed
    * event */
   mongoc_client_set_apm_callbacks (client, NULL, NULL);
   mongoc_client_destroy (client);

   /* first event is topology opening */
   bson_iter_init (&events_iter, &context.events);
   bson_iter_next (&events_iter);
   ASSERT (bson_iter_recurse (&events_iter, &event_iter));
   ASSERT (bson_iter_find (&event_iter, "topology_opening_event"));

   /* move forward to the last event */
   for (i = 1; i < context.n_events; i++) {
      ASSERT (bson_iter_next (&events_iter));
   }

   /* verify we didn't receive a topology closed event */
   ASSERT (bson_iter_recurse (&events_iter, &event_iter));
   ASSERT (!bson_iter_find (&event_iter, "topology_closed_event"));

   /* no more events */
   ASSERT (!bson_iter_next (&events_iter));

   context_destroy (&context);
}
Ejemplo n.º 12
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);
}
Ejemplo n.º 13
0
static int
_score_tags (const bson_t *read_tags,
             const bson_t *node_tags)
{
   uint32_t len;
   bson_iter_t iter;
   bson_iter_t sub_iter;
   const char *key;
   const char *str;
   int count;
   bool node_matches_set;

   bson_return_val_if_fail(read_tags, -1);
   bson_return_val_if_fail(node_tags, -1);

   count = bson_count_keys(read_tags);

   /* Execute this block if read tags were provided, else bail and return 0 (all nodes equal) */
   if (!bson_empty(read_tags) && bson_iter_init(&iter, read_tags)) {

      /*
       * Iterate over array of read tag sets provided (each element is a tag set)
       * Tag sets are provided in order of preference so return the count of the
       * first set that matches the node or -1 if no set matched the node.
       */
      while (count && bson_iter_next(&iter)) {
         if (BSON_ITER_HOLDS_DOCUMENT(&iter) && bson_iter_recurse(&iter, &sub_iter)) {
            node_matches_set = true;

            /* Iterate over the key/value pairs (tags) in the current set */
            while (bson_iter_next(&sub_iter) && BSON_ITER_HOLDS_UTF8(&sub_iter)) {
               key = bson_iter_key(&sub_iter);
               str = bson_iter_utf8(&sub_iter, &len);

               /* If any of the tags do not match, this node cannot satisfy this tag set. */
               if (!_contains_tag(node_tags, key, str, len)) {
                   node_matches_set = false;
                   break;
               }
            }

            /* This set matched, return the count as the score */
            if (node_matches_set) {
                return count;
            }

            /* Decrement the score and try to match the next set. */
            count--;
         }
      }
      return -1;
   }

   return 0;
}
Ejemplo n.º 14
0
SEXP ConvertValue(bson_iter_t* iter){
  if(BSON_ITER_HOLDS_INT32(iter)){
    return ScalarInteger(bson_iter_int32(iter));
  } else if(BSON_ITER_HOLDS_NULL(iter)){
    return R_NilValue;
  } else if(BSON_ITER_HOLDS_BOOL(iter)){
    return ScalarLogical(bson_iter_bool(iter));
  } else if(BSON_ITER_HOLDS_DOUBLE(iter)){
    return ScalarReal(bson_iter_double(iter));
  } else if(BSON_ITER_HOLDS_INT64(iter)){
    return ScalarReal((double) bson_iter_int64(iter));
  } else if(BSON_ITER_HOLDS_UTF8(iter)){
    return mkStringUTF8(bson_iter_utf8(iter, NULL));
  } else if(BSON_ITER_HOLDS_CODE(iter)){
    return mkStringUTF8(bson_iter_code(iter, NULL));
  } else if(BSON_ITER_HOLDS_BINARY(iter)){
    return ConvertBinary(iter);
  } else if(BSON_ITER_HOLDS_DATE_TIME(iter)){
    return ConvertDate(iter);
  } else if(BSON_ITER_HOLDS_OID(iter)){
    const bson_oid_t *val = bson_iter_oid(iter);
    char str[25];
    bson_oid_to_string(val, str);
    return mkString(str);
  } else if(BSON_ITER_HOLDS_ARRAY(iter)){
    bson_iter_t child1;
    bson_iter_t child2;
    bson_iter_recurse (iter, &child1);
    bson_iter_recurse (iter, &child2);
    return ConvertArray(&child1, &child2);
  } else if(BSON_ITER_HOLDS_DOCUMENT(iter)){
    bson_iter_t child1;
    bson_iter_t child2;
    bson_iter_recurse (iter, &child1);
    bson_iter_recurse (iter, &child2);
    return ConvertObject(&child1, &child2);
  } else {
    stop("Unimplemented BSON type %d\n", bson_iter_type(iter));
  }
}
Ejemplo n.º 15
0
Archivo: bson.c Proyecto: CDC/mongolite
SEXP ConvertValue(bson_iter_t* iter){
  if(BSON_ITER_HOLDS_INT32(iter)){
    return ScalarInteger(bson_iter_int32(iter));
  } else if(BSON_ITER_HOLDS_NULL(iter)){
    return R_NilValue;
  } else if(BSON_ITER_HOLDS_BOOL(iter)){
    return ScalarLogical(bson_iter_bool(iter));
  } else if(BSON_ITER_HOLDS_DOUBLE(iter)){
    return ScalarReal(bson_iter_double(iter));
  } else if(BSON_ITER_HOLDS_INT64(iter)){
    return ScalarReal((double) bson_iter_int64(iter));
  } else if(BSON_ITER_HOLDS_UTF8(iter)){
    return mkStringUTF8(bson_iter_utf8(iter, NULL));
  } else if(BSON_ITER_HOLDS_CODE(iter)){
    return mkStringUTF8(bson_iter_code(iter, NULL));
  } else if(BSON_ITER_HOLDS_BINARY(iter)){
    return ConvertBinary(iter);
  } else if(BSON_ITER_HOLDS_DATE_TIME(iter)){
    return ConvertDate(iter);
  } else if(BSON_ITER_HOLDS_OID(iter)){
    //not sure if this casting works
    return mkRaw((unsigned char *) bson_iter_oid(iter), 12);
  } else if(BSON_ITER_HOLDS_ARRAY(iter)){
    bson_iter_t child1;
    bson_iter_t child2;
    bson_iter_recurse (iter, &child1);
    bson_iter_recurse (iter, &child2);
    return ConvertArray(&child1, &child2);
  } else if(BSON_ITER_HOLDS_DOCUMENT(iter)){
    bson_iter_t child1;
    bson_iter_t child2;
    bson_iter_recurse (iter, &child1);
    bson_iter_recurse (iter, &child2);
    return ConvertObject(&child1, &child2);
  } else {
    stop("Unimplemented BSON type %d\n", bson_iter_type(iter));
  }
}
static mongoc_matcher_op_t *
_mongoc_matcher_parse (bson_iter_t  *iter,  /* IN */
                       bson_error_t *error) /* OUT */
{
   bson_iter_t child;
   const char *key;

   BSON_ASSERT (iter);

   key = bson_iter_key (iter);

   if (*key != '$') {
      return _mongoc_matcher_parse_compare (iter, key, error);
   } else {
      BSON_ASSERT (bson_iter_type(iter) == BSON_TYPE_ARRAY);

      if (!bson_iter_recurse (iter, &child)) {
         bson_set_error (error,
                         MONGOC_ERROR_MATCHER,
                         MONGOC_ERROR_MATCHER_INVALID,
                         "Invalid value for operator \"%s\"",
                         key);
         return NULL;
      }

      if (strcmp (key, "$or") == 0) {
         return _mongoc_matcher_parse_logical (MONGOC_MATCHER_OPCODE_OR,
                                               &child, false, error);
      } else if (strcmp(key, "$and") == 0) {
         return _mongoc_matcher_parse_logical (MONGOC_MATCHER_OPCODE_AND,
                                               &child, false, error);
      } else if (strcmp(key, "$nor") == 0) {
         return _mongoc_matcher_parse_logical (MONGOC_MATCHER_OPCODE_NOR,
                                               &child, false, error);
      }
   }

   bson_set_error (error,
                   MONGOC_ERROR_MATCHER,
                   MONGOC_ERROR_MATCHER_INVALID,
                   "Invalid operator \"%s\"",
                   key);

   return NULL;
}
Ejemplo n.º 17
0
int
get_column_map (bson_t        *bson_schema,
                const char    *table_name,
                column_map_t **column_map,
                int           *column_map_size)
{
    bson_iter_t iter_col, iter_dup;
    int size;
    column_map_t *column_map_p;
    const char *data_type;
    data_type_map_t *data_type_map_p;

    bson_find_create_table (bson_schema, table_name, &iter_col) || DIE;
    for (iter_dup = iter_col, size = 0; bson_iter_next (&iter_dup); size++)
        ;
    *column_map = calloc (sizeof (column_map_t), size);
    *column_map_size = size;
    column_map_p = *column_map;
    while (bson_iter_next (&iter_col)) {
        bson_iter_t iter_col_prop;

        BSON_ITER_HOLDS_DOCUMENT (&iter_col) || DIE;
        bson_iter_recurse (&iter_col, &iter_col_prop) || DIE;
        bson_iter_find (&iter_col_prop, "column_name") || DIE;
        BSON_ITER_HOLDS_UTF8 (&iter_col_prop) || DIE;
        column_map_p->column_name = bson_iter_dup_utf8 (&iter_col_prop, NULL);
        bson_iter_find (&iter_col_prop, "data_type") || DIE;
        BSON_ITER_HOLDS_UTF8 (&iter_col_prop) || DIE;
        data_type = bson_iter_utf8 (&iter_col_prop, NULL);
        column_map_p->data_type = data_type;
        for (data_type_map_p = data_type_map;
             data_type_map_p < (data_type_map + sizeof (data_type_map)) &&
             strcmp (data_type_map_p->data_type, data_type) != 0;
             data_type_map_p++)
            ;
        if (data_type_map < (data_type_map + sizeof (data_type_map)))
            column_map_p->bson_append_from_s = data_type_map_p->bson_append_from_s ?
                data_type_map_p->bson_append_from_s : bson_append_utf8_from_s;
        else
            DIE;
        column_map_p++;
    }
    return true;
}
int
get_n_members (bson_t *ismaster_response)
{
   bson_iter_t iter;
   bson_iter_t hosts_iter;
   char *name;
   int n;

   if ((name = set_name (ismaster_response))) {
      bson_free (name);
      assert (bson_iter_init_find (&iter, ismaster_response, "hosts"));
      bson_iter_recurse (&iter, &hosts_iter);
      n = 0;
      while (bson_iter_next (&hosts_iter)) n++;
      return n;
   } else {
      return 1;
   }
}
bson_bool_t
_mongoc_cursor_cursorid_next (mongoc_cursor_t *cursor,
                              const bson_t   **bson)
{
   bson_bool_t ret;
   mongoc_cursor_cursorid_t *cid;
   bson_iter_t iter;
   bson_iter_t child;
   const char *ns;

   ENTRY;

   cid = cursor->interface_data;

   ret = _mongoc_cursor_next (cursor, bson);

   if (!cid->has_cursor) {
      cid->has_cursor = TRUE;

      if (ret &&
          bson_iter_init_find (&iter, *bson, "cursor") &&
          BSON_ITER_HOLDS_DOCUMENT (&iter) &&
          bson_iter_recurse (&iter, &child)) {
         while (bson_iter_next (&child)) {
            if (strcmp (bson_iter_key (&child), "id") == 0) {
               cursor->rpc.reply.cursor_id = bson_iter_int64 (&child);
            } else if (strcmp (bson_iter_key (&child), "ns") == 0) {
               ns = bson_iter_utf8 (&child, &cursor->nslen);
               strncpy (cursor->ns, ns, sizeof cursor->ns - 1);
            }
         }

         cursor->is_command = FALSE;

         ret = _mongoc_cursor_next (cursor, bson);
      }
   }


   RETURN (ret);
}
Ejemplo n.º 20
0
static bool
_mongoc_matcher_op_in_match (mongoc_matcher_op_compare_t *compare, /* IN */
                             bson_iter_t                 *iter)    /* IN */
{
   mongoc_matcher_op_compare_t op;

   op.base.opcode = MONGOC_MATCHER_OPCODE_EQ;
   op.path = compare->path;

   if (!BSON_ITER_HOLDS_ARRAY (&compare->iter) ||
       !bson_iter_recurse (&compare->iter, &op.iter)) {
      return false;
   }

   while (bson_iter_next (&op.iter)) {
      if (_mongoc_matcher_op_eq_match (&op, iter)) {
         return true;
      }
   }

   return false;
}
Ejemplo n.º 21
0
// Check an embedded document of the form { "article/#": "r", "article/+/comments": "rw", "ballotbox": "w" }
bool be_mongo_check_acl_topics_map(const bson_iter_t *topics, const char *req_topic, int req_access, const char *clientid, const char *username)
{
	bson_iter_t iter;
	bson_iter_recurse(topics, &iter);
	bool granted = false;

	// Loop through mapped topics, allowing for the fact that a two different ACLs may have complementary permissions.
	while (bson_iter_next(&iter) && !granted) {
		const char *permitted_topic = bson_iter_key(&iter);
		bool topic_matches = false;

		char *expanded;

		t_expand(clientid, username, permitted_topic, &expanded);
		if (expanded && *expanded) {
			mosquitto_topic_matches_sub(expanded, req_topic, &topic_matches);
			free(expanded);

			if (topic_matches) {
				bson_type_t val_type = bson_iter_type(&iter);
				if (val_type == BSON_TYPE_UTF8) {
					// NOTE: can req_access be any other value than 1 or 2?
					// in that case this may not be correct:
					// e.g. req_access == 3 (rw) -> granted = (3 & 1 > 0) == true
					const char *permission = bson_iter_utf8(&iter, NULL);
					if (strcmp(permission, "r") == 0) {
						granted = (req_access & 1) > 0;
					} else if (strcmp(permission, "w") == 0) {
						granted = (req_access & 2) > 0;
					} else if (strcmp(permission, "rw") == 0) {
						granted = true;
					}
				}
			}
		}
	}
	return granted;
}
Ejemplo n.º 22
0
const char *
_mongoc_get_command_name (const bson_t *command)
{
   bson_iter_t iter;
   const char *name;
   bson_iter_t child;
   const char *wrapper_name = NULL;

   BSON_ASSERT (command);

   if (!bson_iter_init (&iter, command) ||
       !bson_iter_next (&iter)) {
      return NULL;
   }

   name = bson_iter_key (&iter);

   /* wrapped in "$query" or "query"?
    *
    *   {$query: {count: "collection"}, $readPreference: {...}}
    */
   if (name[0] == '$') {
      wrapper_name = "$query";
   } else if (!strcmp (name, "query")) {
      wrapper_name = "query";
   }

   if (wrapper_name &&
       bson_iter_init_find (&iter, command, wrapper_name) &&
       BSON_ITER_HOLDS_DOCUMENT (&iter) &&
       bson_iter_recurse (&iter, &child) &&
       bson_iter_next (&child)) {

      name = bson_iter_key (&child);
   }

   return name;
}
bool
_mongoc_cursor_array_next (mongoc_cursor_t *cursor,
                           const bson_t   **bson)
{
   bool ret = true;
   mongoc_cursor_array_t *arr;
   bson_iter_t iter;

   ENTRY;

   arr = cursor->iface_data;
   *bson = NULL;

   if (!arr->has_array) {
      arr->has_array = true;

      ret = _mongoc_cursor_next (cursor, &arr->result);

      if (!(ret &&
            bson_iter_init_find (&iter, arr->result, "result") &&
            BSON_ITER_HOLDS_ARRAY (&iter) &&
            bson_iter_recurse (&iter, &arr->iter) &&
            bson_iter_next (&arr->iter))) {
         ret = false;
      }
   } else {
      ret = bson_iter_next (&arr->iter);
   }

   if (ret) {
      bson_iter_document (&arr->iter, &arr->document_len, &arr->document);
      bson_init_static (&arr->bson, arr->document, arr->document_len);

      *bson = &arr->bson;
   }

   RETURN (ret);
}
bool
_mongoc_cursor_array_prime (mongoc_cursor_t *cursor)
{
   const bson_t *bson;
   mongoc_cursor_array_t *arr;
   bson_iter_t iter;

   ENTRY;

   arr = (mongoc_cursor_array_t *)cursor->iface_data;

   BSON_ASSERT (arr);

   if (_mongoc_cursor_run_command (cursor, &cursor->query) &&
       _mongoc_read_from_buffer (cursor, &bson) &&
       bson_iter_init_find (&iter, bson, arr->field_name) &&
       BSON_ITER_HOLDS_ARRAY (&iter) &&
       bson_iter_recurse (&iter, &arr->iter)) {
      arr->has_array = true;
   }

   return arr->has_array;
}
Ejemplo n.º 25
0
// Check an embedded array of the form [ "public/#", "private/myid/#" ]
bool be_mongo_check_acl_topics_array(const bson_iter_t *topics, const char *req_topic, const char *clientid, const char *username)
{
	bson_iter_t iter;
	bson_iter_recurse(topics, &iter);

	while (bson_iter_next(&iter)) {
		const char *permitted_topic = bson_iter_utf8(&iter, NULL);
		bool topic_matches = false;

		char *expanded;

		t_expand(clientid, username, permitted_topic, &expanded);
		if (expanded && *expanded) {
			mosquitto_topic_matches_sub(expanded, req_topic, &topic_matches);
			free(expanded);

			if (topic_matches) {
				return true;
			}
		}
	}
	return false;
}
Ejemplo n.º 26
0
int monary_load_length_value(const bson_iter_t* bsonit,
                             monary_column_item* citem,
                             int idx)
{
    bson_type_t type;
    bson_iter_t child;
    const char* discard;
    uint32_t length;
    uint32_t* dest;

    type = bson_iter_type(bsonit);
    switch (type) {
        case BSON_TYPE_UTF8:
        case BSON_TYPE_CODE:
            discard = bson_iter_utf8(bsonit, &length);
            for (length = 0; *discard; length++) {
                discard = bson_utf8_next_char(discard);
            }
            break;
        case BSON_TYPE_ARRAY:
        case BSON_TYPE_DOCUMENT:
            if (!bson_iter_recurse(bsonit, &child)) {
                return 0;
            }
            for (length = 0; bson_iter_next(&child); length++);
            break;
        case BSON_TYPE_BINARY:
            bson_iter_binary(bsonit, NULL, &length, (const uint8_t**) &discard);
            break;
        default:
            return 0;
    }

    dest = ((uint32_t*) citem->storage) + idx;
    memcpy(dest, &length, sizeof(uint32_t));
    return 1;
}
Ejemplo n.º 27
0
static void
test_bson_iter_recurse (void)
{
   bson_iter_t iter;
   bson_iter_t child;
   bson_t b;
   bson_t cb;

   bson_init(&b);
   bson_init(&cb);
   assert(bson_append_int32(&cb, "0", 1, 0));
   assert(bson_append_int32(&cb, "1", 1, 1));
   assert(bson_append_int32(&cb, "2", 1, 2));
   assert(bson_append_array(&b, "key", -1, &cb));
   assert(bson_iter_init_find(&iter, &b, "key"));
   assert(BSON_ITER_HOLDS_ARRAY(&iter));
   assert(bson_iter_recurse(&iter, &child));
   assert(bson_iter_find(&child, "0"));
   assert(bson_iter_find(&child, "1"));
   assert(bson_iter_find(&child, "2"));
   assert(!bson_iter_next(&child));
   bson_destroy(&b);
   bson_destroy(&cb);
}
Ejemplo n.º 28
0
void
_mongoc_handshake_parse_sasl_supported_mechs (
   const bson_t *ismaster,
   mongoc_handshake_sasl_supported_mechs_t *sasl_supported_mechs)
{
   bson_iter_t iter;
   memset (sasl_supported_mechs, 0, sizeof (*sasl_supported_mechs));
   if (bson_iter_init_find (&iter, ismaster, "saslSupportedMechs")) {
      bson_iter_t array_iter;
      if (BSON_ITER_HOLDS_ARRAY (&iter) &&
          bson_iter_recurse (&iter, &array_iter)) {
         while (bson_iter_next (&array_iter)) {
            if (BSON_ITER_HOLDS_UTF8 (&array_iter)) {
               const char *mechanism_name = bson_iter_utf8 (&array_iter, NULL);
               if (0 == strcmp (mechanism_name, "SCRAM-SHA-256")) {
                  sasl_supported_mechs->scram_sha_256 = true;
               } else if (0 == strcmp (mechanism_name, "SCRAM-SHA-1")) {
                  sasl_supported_mechs->scram_sha_1 = true;
               }
            }
         }
      }
   }
}
/**
 * _mongoc_parse_wc_err:
 * @doc: (in): A bson document.
 * @error: (out): A bson_error_t.
 *
 * Parses a document, usually a server reply,
 * looking for a writeConcernError. Returns true if
 * there is a writeConcernError, false otherwise.
 */
bool
_mongoc_parse_wc_err (const bson_t *doc, bson_error_t *error) {
   bson_iter_t iter;
   bson_iter_t inner;

   if (bson_iter_init_find(&iter, doc, "writeConcernError") &&
       BSON_ITER_HOLDS_DOCUMENT (&iter))
   {
      const char *errmsg = NULL;
      int32_t code = 0;
      bson_iter_recurse(&iter, &inner);
      while (bson_iter_next(&inner)) {
         if (BSON_ITER_IS_KEY (&inner, "code")) {
            code = bson_iter_int32 (&inner);
         } else if (BSON_ITER_IS_KEY (&inner, "errmsg")) {
            errmsg = bson_iter_utf8 (&inner, NULL);
         }
      }
      bson_set_error(error, MONGOC_ERROR_WRITE_CONCERN, code,
                     "Write Concern error: %s", errmsg);
      return true;
   }
   return false;
}
/* a uri with one bogus host */
mongoc_uri_t *
uri_from_ismaster_plus_one (bson_t *ismaster_response)
{
   /* start with one bad host and a comma */
   bson_string_t *uri_str = bson_string_new ("mongodb://" BAD_HOST ",");
   char *name;
   bson_iter_t iter;
   bson_iter_t hosts_iter;

   if ((name = set_name (ismaster_response))) {
      bson_iter_init_find (&iter, ismaster_response, "hosts");
      bson_iter_recurse (&iter, &hosts_iter);
      while (bson_iter_next (&hosts_iter)) {
         assert (BSON_ITER_HOLDS_UTF8 (&hosts_iter));
         bson_string_append (uri_str, bson_iter_utf8 (&hosts_iter, NULL));
         while (bson_iter_next (&hosts_iter)) {
            bson_string_append (uri_str, ",");
            bson_string_append (uri_str, bson_iter_utf8 (&hosts_iter, NULL));
         }

         bson_string_append_printf (
            uri_str, "/?replicaSet=%s&connecttimeoutms=1000", name);
      }

      bson_free (name);
   } else {
      char *host = test_framework_get_host ();

      bson_string_append (uri_str, host);
      bson_string_append (uri_str, "/?connecttimeoutms=1000");

      bson_free (host);
   }

   return mongoc_uri_new (bson_string_free (uri_str, false));
}